loader: remove shouting from ORB's variable name
[hvf.git] / cp / drivers / device.c
blobd803e4607c1ceb28771310920b1cf4510af063a3
1 /*
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
5 * details.
6 */
8 #include <list.h>
9 #include <channel.h>
10 #include <io.h>
11 #include <slab.h>
12 #include <device.h>
13 #include <spinlock.h>
14 #include <sched.h>
16 static LOCK_CLASS(device_lock_lc);
18 struct static_device {
19 u16 dev_num;
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),
43 .reg = NULL,
44 .interrupt = NULL,
45 .snprintf = NULL,
46 .type = 0,
47 .model = 0,
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);
63 /**
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) {
74 if (dev == entry ||
75 (dev->type == entry->type && dev->model == entry->model)) {
76 spin_unlock(&dev_types_lock);
77 return -EEXIST;
81 list_add_tail(&dev->types, &device_types);
83 spin_unlock(&dev_types_lock);
85 return 0;
88 /**
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)
94 struct device *dev;
96 spin_lock(&devs_lock);
98 list_for_each_entry(dev, &devices, devices) {
99 if (dev->ccuu == ccuu) {
100 dev_get(dev);
101 spin_unlock(&devs_lock);
102 return dev;
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)
117 struct device *dev;
119 spin_lock(&devs_lock);
121 list_for_each_entry(dev, &devices, devices) {
122 if (dev->sch == sch) {
123 dev_get(dev);
124 spin_unlock(&devs_lock);
125 return dev;
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)
141 struct device *dev;
143 spin_lock(&devs_lock);
145 list_for_each_entry(dev, &devices, devices) {
146 if (dev->type == type &&
147 dev->model == model) {
148 dev_get(dev);
149 spin_unlock(&devs_lock);
150 return dev;
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;
167 int err = 0;
169 spin_double_lock(&devs_lock, &dev_types_lock);
171 list_for_each_entry(type, &device_types, types) {
172 if (type->type == dev->type &&
173 (type->all_models ||
174 type->model == dev->model))
175 goto found;
178 err = -ENOENT;
179 type = NULL;
181 found:
182 spin_double_unlock(&devs_lock, &dev_types_lock);
184 atomic_set(&dev->refcnt, 1);
186 mutex_init(&dev->lock, &device_lock_lc);
187 dev->in_use = 0;
189 dev->dev = type;
191 if (type && type->reg) {
192 err = type->reg(dev);
194 if (err)
195 dev->dev = NULL;
198 spin_double_lock(&devs_lock, &dev_types_lock);
199 if (remove)
200 list_del(&dev->devices);
201 list_add_tail(&dev->devices, &devices);
202 spin_double_unlock(&devs_lock, &dev_types_lock);
204 return err;
207 static int do_sense_id(struct device *dev, u16 dev_num, struct senseid_struct *buf)
209 struct io_op ioop;
210 struct ccw ccw;
211 int ret;
212 int idx;
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));
223 return 0;
228 * Set up IO op for Sense-ID
230 ioop.handler = NULL;
231 ioop.dtor = NULL;
233 memset(&ioop.orb, 0, sizeof(struct orb));
234 ioop.orb.lpm = 0xff;
235 ioop.orb.addr = ADDR31(&ccw);
236 ioop.orb.f = 1;
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);
245 * issue SENSE-ID
247 ret = submit_io(dev, &ioop, CAN_LOOP);
248 BUG_ON(ret);
250 return ioop.err;
254 * Scan all subchannel ids, and register each device
256 void scan_devices(void)
258 struct schib schib;
259 struct device *dev = NULL;
260 struct senseid_struct buf;
261 u32 sch;
262 int ret;
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
274 * there is a device
276 if (store_sch(sch, &schib))
277 continue;
279 if (!schib.pmcw.v)
280 continue;
283 * The following code tries to take the following steps:
284 * - alloc device struct
285 * - enable the subchannel
286 * - MSCH
287 * - issue SENSE-ID IO op & wait for completion
288 * - register device with apropriate subsystem
291 if (!dev) {
292 dev = malloc(sizeof(struct device), ZONE_NORMAL);
295 * if we failed to allocate memory, there's not much we can
296 * do
298 BUG_ON(!dev);
300 atomic_set(&dev->attention, 0);
301 INIT_LIST_HEAD(&dev->q_out);
302 dev->dev = &__fake_dev_type;
305 schib.pmcw.e = 1;
307 if (modify_sch(sch, &schib))
308 continue;
310 dev->sch = sch;
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);
319 if (ret)
320 continue;
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
332 * enabled bit.
334 schib.pmcw.e = 0;
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 */
341 dev = NULL;
344 unregister_device_type(&__fake_dev_type);
346 free(dev);
349 void list_devices(void (*f)(struct device*, void*), void *priv)
351 struct device *dev;
353 spin_lock(&devs_lock);
355 list_for_each_entry(dev, &devices, devices) {
356 dev_get(dev);
357 f(dev, priv);
358 dev_put(dev);
361 spin_unlock(&devs_lock);
364 void register_drivers(void)
366 register_driver_3215();
367 register_driver_dasd();