Blame view

drivers/mca/mca-bus.c 4.61 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
  /* -*- mode: c; c-basic-offset: 8 -*- */
  
  /*
   * MCA bus support functions for sysfs.
   *
   * (C) 2002 James Bottomley <James.Bottomley@HansenPartnership.com>
   *
  **-----------------------------------------------------------------------------
  **  
  **  This program is free software; you can redistribute it and/or modify
  **  it under the terms of the GNU General Public License as published by
  **  the Free Software Foundation; either version 2 of the License, or
  **  (at your option) any later version.
  **
  **  This program is distributed in the hope that it will be useful,
  **  but WITHOUT ANY WARRANTY; without even the implied warranty of
  **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  **  GNU General Public License for more details.
  **
  **  You should have received a copy of the GNU General Public License
  **  along with this program; if not, write to the Free Software
  **  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  **
  **-----------------------------------------------------------------------------
   */
  
  #include <linux/kernel.h>
  #include <linux/device.h>
  #include <linux/mca.h>
  #include <linux/module.h>
  #include <linux/init.h>
  #include <linux/slab.h>
  
  /* Very few machines have more than one MCA bus.  However, there are
   * those that do (Voyager 35xx/5xxx), so we do it this way for future
   * expansion.  None that I know have more than 2 */
  static struct mca_bus *mca_root_busses[MAX_MCA_BUSSES];
  
  #define MCA_DEVINFO(i,s) { .pos = i, .name = s }
  
  struct mca_device_info {
  	short pos_id;		/* the 2 byte pos id for this card */
ca52a4984   Kay Sievers   driver core: remo...
43
  	char name[50];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
44
45
46
47
48
49
  };
  
  static int mca_bus_match (struct device *dev, struct device_driver *drv)
  {
  	struct mca_device *mca_dev = to_mca_device (dev);
  	struct mca_driver *mca_drv = to_mca_driver (drv);
809aa5048   James Bottomley   mca: fix bus matc...
50
  	const unsigned short *mca_ids = mca_drv->id_table;
8813d1c00   James Bottomley   mca: add integrat...
51
  	int i = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
52

8813d1c00   James Bottomley   mca: add integrat...
53
54
55
56
57
58
  	if (mca_ids) {
  		for(i = 0; mca_ids[i]; i++) {
  			if (mca_ids[i] == mca_dev->pos_id) {
  				mca_dev->index = i;
  				return 1;
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59
60
  		}
  	}
8813d1c00   James Bottomley   mca: add integrat...
61
62
63
64
65
66
67
68
  	/* If the integrated id is present, treat it as though it were an
  	 * additional id in the id_table (it can't be because by definition,
  	 * integrated id's overflow a short */
  	if (mca_drv->integrated_id && mca_dev->pos_id ==
  	    mca_drv->integrated_id) {
  		mca_dev->index = i;
  		return 1;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
69
70
71
72
73
74
75
76
  	return 0;
  }
  
  struct bus_type mca_bus_type = {
  	.name  = "MCA",
  	.match = mca_bus_match,
  };
  EXPORT_SYMBOL (mca_bus_type);
e404e274f   Yani Ioannou   [PATCH] Driver Co...
77
  static ssize_t mca_show_pos_id(struct device *dev, struct device_attribute *attr, char *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
78
79
80
81
82
83
84
85
86
87
88
89
90
91
  {
  	/* four digits, 
   and trailing \0 */
  	struct mca_device *mca_dev = to_mca_device(dev);
  	int len;
  
  	if(mca_dev->pos_id < MCA_DUMMY_POS_START)
  		len = sprintf(buf, "%04x
  ", mca_dev->pos_id);
  	else
  		len = sprintf(buf, "none
  ");
  	return len;
  }
e404e274f   Yani Ioannou   [PATCH] Driver Co...
92
  static ssize_t mca_show_pos(struct device *dev, struct device_attribute *attr, char *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
  {
  	/* enough for 8 two byte hex chars plus space and new line */
  	int j, len=0;
  	struct mca_device *mca_dev = to_mca_device(dev);
  
  	for(j=0; j<8; j++)
  		len += sprintf(buf+len, "%02x ", mca_dev->pos[j]);
  	/* change last trailing space to new line */
  	buf[len-1] = '
  ';
  	return len;
  }
  
  static DEVICE_ATTR(id, S_IRUGO, mca_show_pos_id, NULL);
  static DEVICE_ATTR(pos, S_IRUGO, mca_show_pos, NULL);
  
  int __init mca_register_device(int bus, struct mca_device *mca_dev)
  {
  	struct mca_bus *mca_bus = mca_root_busses[bus];
49a6cbe1c   Jeff Garzik   [PATCH] drivers/m...
112
  	int rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
113
114
115
  
  	mca_dev->dev.parent = &mca_bus->dev;
  	mca_dev->dev.bus = &mca_bus_type;
cf43f4ab3   Kay Sievers   mca: struct devic...
116
  	dev_set_name(&mca_dev->dev, "%02d:%02X", bus, mca_dev->slot);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
117
118
119
  	mca_dev->dma_mask = mca_bus->default_dma_mask;
  	mca_dev->dev.dma_mask = &mca_dev->dma_mask;
  	mca_dev->dev.coherent_dma_mask = mca_dev->dma_mask;
49a6cbe1c   Jeff Garzik   [PATCH] drivers/m...
120
121
122
  	rc = device_register(&mca_dev->dev);
  	if (rc)
  		goto err_out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
123

49a6cbe1c   Jeff Garzik   [PATCH] drivers/m...
124
125
126
127
  	rc = device_create_file(&mca_dev->dev, &dev_attr_id);
  	if (rc) goto err_out_devreg;
  	rc = device_create_file(&mca_dev->dev, &dev_attr_pos);
  	if (rc) goto err_out_id;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
128
129
  
  	return 1;
49a6cbe1c   Jeff Garzik   [PATCH] drivers/m...
130
131
132
133
134
135
136
  
  err_out_id:
  	device_remove_file(&mca_dev->dev, &dev_attr_id);
  err_out_devreg:
  	device_unregister(&mca_dev->dev);
  err_out:
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
  }
  
  /* */
  struct mca_bus * __devinit mca_attach_bus(int bus)
  {
  	struct mca_bus *mca_bus;
  
  	if (unlikely(mca_root_busses[bus] != NULL)) {
  		/* This should never happen, but just in case */
  		printk(KERN_EMERG "MCA tried to add already existing bus %d
  ",
  		       bus);
  		dump_stack();
  		return NULL;
  	}
49a6cbe1c   Jeff Garzik   [PATCH] drivers/m...
152
  	mca_bus = kzalloc(sizeof(struct mca_bus), GFP_KERNEL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
153
154
  	if (!mca_bus)
  		return NULL;
49a6cbe1c   Jeff Garzik   [PATCH] drivers/m...
155

cf43f4ab3   Kay Sievers   mca: struct devic...
156
  	dev_set_name(&mca_bus->dev, "mca%d", bus);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
157
  	sprintf(mca_bus->name,"Host %s MCA Bridge", bus ? "Secondary" : "Primary");
49a6cbe1c   Jeff Garzik   [PATCH] drivers/m...
158
159
160
161
  	if (device_register(&mca_bus->dev)) {
  		kfree(mca_bus);
  		return NULL;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
162
163
164
165
166
167
168
169
170
171
  
  	mca_root_busses[bus] = mca_bus;
  
  	return mca_bus;
  }
  
  int __init mca_system_init (void)
  {
  	return bus_register(&mca_bus_type);
  }