2 * (C) Copyright 2007-2010 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
4 * This file is released under the GPLv2. See the COPYING file for more
16 static LOCK_CLASS(device_lock_lc
);
18 struct static_device
{
20 struct senseid_struct sense
;
23 #define END_OF_STATIC_DEV_LIST 0xffff
26 * This defines staticly-configured devices - ugly but necessary for devices
27 * that fail to identify themseleves via Sense-ID
29 static struct static_device static_device_list
[] = {
30 { .dev_num
= 0x0009, .sense
= { .dev_type
= 0x3215, .dev_model
= 0 } },
31 { .dev_num
= END_OF_STATIC_DEV_LIST
},
35 * We need this device temporarily because submit_io & friends assume that
36 * the device that's doing IO is on the device list. Unfortunately, that
37 * isn't the case during IO device scanning. We register this device type,
38 * and each device temporarily during the scan to make submit_io & friends
39 * happy. When we're done scanning, we unregister this type.
41 static struct device_type __fake_dev_type
= {
42 .types
= LIST_HEAD_INIT(__fake_dev_type
.types
),
50 static LIST_HEAD(device_types
);
51 static spinlock_t dev_types_lock
;
53 static LIST_HEAD(devices
);
54 static spinlock_t devs_lock
;
56 static void unregister_device_type(struct device_type
*type
)
58 spin_lock(&dev_types_lock
);
59 list_del(&type
->types
);
60 spin_unlock(&dev_types_lock
);
64 * register_device_type - register a new device type/model
65 * @dev: device type to register
67 int register_device_type(struct device_type
*dev
)
69 struct device_type
*entry
;
71 spin_lock(&dev_types_lock
);
73 list_for_each_entry(entry
, &device_types
, types
) {
75 (dev
->type
== entry
->type
&& dev
->model
== entry
->model
)) {
76 spin_unlock(&dev_types_lock
);
81 list_add_tail(&dev
->types
, &device_types
);
83 spin_unlock(&dev_types_lock
);
89 * find_device_by_ccuu - find device struct by ccuu
90 * @ccuu: device ccuu to find
92 struct device
*find_device_by_ccuu(u16 ccuu
)
96 spin_lock(&devs_lock
);
98 list_for_each_entry(dev
, &devices
, devices
) {
99 if (dev
->ccuu
== ccuu
) {
101 spin_unlock(&devs_lock
);
106 spin_unlock(&devs_lock
);
108 return ERR_PTR(-ENOENT
);
112 * find_device_by_sch - find device struct by subchannel number
113 * @sch: device subchannel
115 struct device
*find_device_by_sch(u32 sch
)
119 spin_lock(&devs_lock
);
121 list_for_each_entry(dev
, &devices
, devices
) {
122 if (dev
->sch
== sch
) {
124 spin_unlock(&devs_lock
);
129 spin_unlock(&devs_lock
);
131 return ERR_PTR(-ENOENT
);
135 * find_device_by_type - find device struct by type/model
136 * @type: device type to find
137 * @model: device model to find
139 struct device
*find_device_by_type(u16 type
, u8 model
)
143 spin_lock(&devs_lock
);
145 list_for_each_entry(dev
, &devices
, devices
) {
146 if (dev
->type
== type
&&
147 dev
->model
== model
) {
149 spin_unlock(&devs_lock
);
154 spin_unlock(&devs_lock
);
156 return ERR_PTR(-ENOENT
);
160 * __register_device - helper to register a device
161 * @dev: device to register
162 * @remove: remove the device from the list first
164 static int __register_device(struct device
*dev
, int remove
)
166 struct device_type
*type
;
169 spin_double_lock(&devs_lock
, &dev_types_lock
);
171 list_for_each_entry(type
, &device_types
, types
) {
172 if (type
->type
== dev
->type
&&
174 type
->model
== dev
->model
))
182 spin_double_unlock(&devs_lock
, &dev_types_lock
);
184 atomic_set(&dev
->refcnt
, 1);
186 mutex_init(&dev
->lock
, &device_lock_lc
);
191 if (type
&& type
->reg
) {
192 err
= type
->reg(dev
);
198 spin_double_lock(&devs_lock
, &dev_types_lock
);
200 list_del(&dev
->devices
);
201 list_add_tail(&dev
->devices
, &devices
);
202 spin_double_unlock(&devs_lock
, &dev_types_lock
);
207 static int do_sense_id(struct device
*dev
, u16 dev_num
, struct senseid_struct
*buf
)
213 struct static_device
*sdev
;
216 * Check static configuration; if device is found (by device
217 * number), use that information instead of issuing sense-id
219 for(idx
= 0; sdev
= &static_device_list
[idx
],
220 sdev
->dev_num
!= END_OF_STATIC_DEV_LIST
; idx
++) {
221 if (sdev
->dev_num
== dev_num
) {
222 memcpy(buf
, &sdev
->sense
, sizeof(struct senseid_struct
));
228 * Set up IO op for Sense-ID
233 memset(&ioop
.orb
, 0, sizeof(struct orb
));
235 ioop
.orb
.addr
= ADDR31(&ccw
);
238 memset(&ccw
, 0, sizeof(struct ccw
));
239 ccw
.cmd
= 0xe4; /* Sense-ID */
240 ccw
.flags
= CCW_FLAG_SLI
;
241 ccw
.count
= sizeof(struct senseid_struct
);
242 ccw
.addr
= ADDR31(buf
);
247 ret
= submit_io(dev
, &ioop
, CAN_LOOP
);
254 * Scan all subchannel ids, and register each device
256 void scan_devices(void)
259 struct device
*dev
= NULL
;
260 struct senseid_struct buf
;
264 BUG_ON(register_device_type(&__fake_dev_type
));
266 memset(&schib
, 0, sizeof(struct schib
));
269 * For each possible subchannel id...
271 for(sch
= 0x10000; sch
<= 0x1ffff; sch
++) {
273 * ...call store subchannel, to find out whether or not
276 if (store_sch(sch
, &schib
))
283 * The following code tries to take the following steps:
284 * - alloc device struct
285 * - enable the subchannel
287 * - issue SENSE-ID IO op & wait for completion
288 * - register device with apropriate subsystem
292 dev
= malloc(sizeof(struct device
), ZONE_NORMAL
);
295 * if we failed to allocate memory, there's not much we can
300 atomic_set(&dev
->attention
, 0);
301 INIT_LIST_HEAD(&dev
->q_out
);
302 dev
->dev
= &__fake_dev_type
;
307 if (modify_sch(sch
, &schib
))
311 BUG_ON(__register_device(dev
, 0));
312 BUG_ON(dev
->dev
!= &__fake_dev_type
);
315 * Find out what the device is - whichever way is necessary
317 ret
= do_sense_id(dev
, schib
.pmcw
.dev_num
, &buf
);
322 dev
->type
= buf
.dev_type
;
323 dev
->model
= buf
.dev_model
;
324 dev
->ccuu
= schib
.pmcw
.dev_num
;
326 /* __register_device will remove the fake entry! */
327 if (__register_device(dev
, 1)) {
329 * error registering ... the device struct MUST NOT
330 * be freed as it has been added onto the devices
331 * list. All that needs to be done is to reset the
336 /* msch could fail, but it shouldn't be fatal */
337 modify_sch(sch
, &schib
);
340 /* to prevent a valid device struct from being free'd */
344 unregister_device_type(&__fake_dev_type
);
349 void list_devices(void (*f
)(struct device
*, void*), void *priv
)
353 spin_lock(&devs_lock
);
355 list_for_each_entry(dev
, &devices
, devices
) {
361 spin_unlock(&devs_lock
);
364 void register_drivers(void)
366 register_driver_3215();
367 register_driver_dasd();