diff options
author | Sebastian Ott <sebott@linux.vnet.ibm.com> | 2012-05-15 11:52:07 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2012-05-16 08:42:46 -0400 |
commit | b7a610f7b4cb95150ee58ea7454ca2ace10634c5 (patch) | |
tree | bf8ea737924dc421042740e0243edac8b52313c7 /drivers/s390/cio/ccwgroup.c | |
parent | f2962dae0efd81fed06d0687f300725ab063587a (diff) |
s390/ccwgroup: exploit ccwdev_by_dev_id
Instead of finding devices via driver_find_device use the bus_find_device
wrapper get_ccwdev_by_dev_id. This allows us to get rid of the ccw_driver
argument of ccwgroup_create_dev and thus simplify the interface.
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio/ccwgroup.c')
-rw-r--r-- | drivers/s390/cio/ccwgroup.c | 69 |
1 files changed, 30 insertions, 39 deletions
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index 0c7ed30ac87e..c69cee607aed 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c | |||
@@ -15,10 +15,13 @@ | |||
15 | #include <linux/ctype.h> | 15 | #include <linux/ctype.h> |
16 | #include <linux/dcache.h> | 16 | #include <linux/dcache.h> |
17 | 17 | ||
18 | #include <asm/cio.h> | ||
18 | #include <asm/ccwdev.h> | 19 | #include <asm/ccwdev.h> |
19 | #include <asm/ccwgroup.h> | 20 | #include <asm/ccwgroup.h> |
20 | 21 | ||
21 | #define CCW_BUS_ID_SIZE 20 | 22 | #include "device.h" |
23 | |||
24 | #define CCW_BUS_ID_SIZE 10 | ||
22 | 25 | ||
23 | /* In Linux 2.4, we had a channel device layer called "chandev" | 26 | /* In Linux 2.4, we had a channel device layer called "chandev" |
24 | * that did all sorts of obscure stuff for networking devices. | 27 | * that did all sorts of obscure stuff for networking devices. |
@@ -254,9 +257,10 @@ static int __ccwgroup_create_symlinks(struct ccwgroup_device *gdev) | |||
254 | return 0; | 257 | return 0; |
255 | } | 258 | } |
256 | 259 | ||
257 | static int __get_next_bus_id(const char **buf, char *bus_id) | 260 | static int __get_next_id(const char **buf, struct ccw_dev_id *id) |
258 | { | 261 | { |
259 | int rc, len; | 262 | unsigned int cssid, ssid, devno; |
263 | int ret = 0, len; | ||
260 | char *start, *end; | 264 | char *start, *end; |
261 | 265 | ||
262 | start = (char *)*buf; | 266 | start = (char *)*buf; |
@@ -271,50 +275,42 @@ static int __get_next_bus_id(const char **buf, char *bus_id) | |||
271 | len = end - start + 1; | 275 | len = end - start + 1; |
272 | end++; | 276 | end++; |
273 | } | 277 | } |
274 | if (len < CCW_BUS_ID_SIZE) { | 278 | if (len <= CCW_BUS_ID_SIZE) { |
275 | strlcpy(bus_id, start, len); | 279 | if (sscanf(start, "%2x.%1x.%04x", &cssid, &ssid, &devno) != 3) |
276 | rc = 0; | 280 | ret = -EINVAL; |
277 | } else | 281 | } else |
278 | rc = -EINVAL; | 282 | ret = -EINVAL; |
279 | *buf = end; | ||
280 | return rc; | ||
281 | } | ||
282 | |||
283 | static int __is_valid_bus_id(char bus_id[CCW_BUS_ID_SIZE]) | ||
284 | { | ||
285 | int cssid, ssid, devno; | ||
286 | 283 | ||
287 | /* Must be of form %x.%x.%04x */ | 284 | if (!ret) { |
288 | if (sscanf(bus_id, "%x.%1x.%04x", &cssid, &ssid, &devno) != 3) | 285 | id->ssid = ssid; |
289 | return 0; | 286 | id->devno = devno; |
290 | return 1; | 287 | } |
288 | *buf = end; | ||
289 | return ret; | ||
291 | } | 290 | } |
292 | 291 | ||
293 | /** | 292 | /** |
294 | * ccwgroup_create_dev() - create and register a ccw group device | 293 | * ccwgroup_create_dev() - create and register a ccw group device |
295 | * @parent: parent device for the new device | 294 | * @parent: parent device for the new device |
296 | * @creator_id: identifier of creating driver | 295 | * @creator_id: identifier of creating driver |
297 | * @cdrv: ccw driver of slave devices | ||
298 | * @gdrv: driver for the new group device | 296 | * @gdrv: driver for the new group device |
299 | * @num_devices: number of slave devices | 297 | * @num_devices: number of slave devices |
300 | * @buf: buffer containing comma separated bus ids of slave devices | 298 | * @buf: buffer containing comma separated bus ids of slave devices |
301 | * | 299 | * |
302 | * Create and register a new ccw group device as a child of @parent. Slave | 300 | * Create and register a new ccw group device as a child of @parent. Slave |
303 | * devices are obtained from the list of bus ids given in @buf and must all | 301 | * devices are obtained from the list of bus ids given in @buf. |
304 | * belong to @cdrv. | ||
305 | * Returns: | 302 | * Returns: |
306 | * %0 on success and an error code on failure. | 303 | * %0 on success and an error code on failure. |
307 | * Context: | 304 | * Context: |
308 | * non-atomic | 305 | * non-atomic |
309 | */ | 306 | */ |
310 | int ccwgroup_create_dev(struct device *parent, unsigned int creator_id, | 307 | int ccwgroup_create_dev(struct device *parent, unsigned int creator_id, |
311 | struct ccw_driver *cdrv, struct ccwgroup_driver *gdrv, | 308 | struct ccwgroup_driver *gdrv, int num_devices, |
312 | int num_devices, const char *buf) | 309 | const char *buf) |
313 | { | 310 | { |
314 | struct ccwgroup_device *gdev; | 311 | struct ccwgroup_device *gdev; |
312 | struct ccw_dev_id dev_id; | ||
315 | int rc, i; | 313 | int rc, i; |
316 | char tmp_bus_id[CCW_BUS_ID_SIZE]; | ||
317 | const char *curr_buf; | ||
318 | 314 | ||
319 | gdev = kzalloc(sizeof(*gdev) + num_devices * sizeof(gdev->cdev[0]), | 315 | gdev = kzalloc(sizeof(*gdev) + num_devices * sizeof(gdev->cdev[0]), |
320 | GFP_KERNEL); | 316 | GFP_KERNEL); |
@@ -334,22 +330,18 @@ int ccwgroup_create_dev(struct device *parent, unsigned int creator_id, | |||
334 | gdev->dev.release = ccwgroup_release; | 330 | gdev->dev.release = ccwgroup_release; |
335 | device_initialize(&gdev->dev); | 331 | device_initialize(&gdev->dev); |
336 | 332 | ||
337 | curr_buf = buf; | 333 | for (i = 0; i < num_devices && buf; i++) { |
338 | for (i = 0; i < num_devices && curr_buf; i++) { | 334 | rc = __get_next_id(&buf, &dev_id); |
339 | rc = __get_next_bus_id(&curr_buf, tmp_bus_id); | ||
340 | if (rc != 0) | 335 | if (rc != 0) |
341 | goto error; | 336 | goto error; |
342 | if (!__is_valid_bus_id(tmp_bus_id)) { | 337 | gdev->cdev[i] = get_ccwdev_by_dev_id(&dev_id); |
343 | rc = -EINVAL; | ||
344 | goto error; | ||
345 | } | ||
346 | gdev->cdev[i] = get_ccwdev_by_busid(cdrv, tmp_bus_id); | ||
347 | /* | 338 | /* |
348 | * All devices have to be of the same type in | 339 | * All devices have to be of the same type in |
349 | * order to be grouped. | 340 | * order to be grouped. |
350 | */ | 341 | */ |
351 | if (!gdev->cdev[i] | 342 | if (!gdev->cdev[i] || !gdev->cdev[i]->drv || |
352 | || gdev->cdev[i]->id.driver_info != | 343 | gdev->cdev[i]->drv != gdev->cdev[0]->drv || |
344 | gdev->cdev[i]->id.driver_info != | ||
353 | gdev->cdev[0]->id.driver_info) { | 345 | gdev->cdev[0]->id.driver_info) { |
354 | rc = -EINVAL; | 346 | rc = -EINVAL; |
355 | goto error; | 347 | goto error; |
@@ -365,12 +357,12 @@ int ccwgroup_create_dev(struct device *parent, unsigned int creator_id, | |||
365 | spin_unlock_irq(gdev->cdev[i]->ccwlock); | 357 | spin_unlock_irq(gdev->cdev[i]->ccwlock); |
366 | } | 358 | } |
367 | /* Check for sufficient number of bus ids. */ | 359 | /* Check for sufficient number of bus ids. */ |
368 | if (i < num_devices && !curr_buf) { | 360 | if (i < num_devices) { |
369 | rc = -EINVAL; | 361 | rc = -EINVAL; |
370 | goto error; | 362 | goto error; |
371 | } | 363 | } |
372 | /* Check for trailing stuff. */ | 364 | /* Check for trailing stuff. */ |
373 | if (i == num_devices && strlen(curr_buf) > 0) { | 365 | if (i == num_devices && strlen(buf) > 0) { |
374 | rc = -EINVAL; | 366 | rc = -EINVAL; |
375 | goto error; | 367 | goto error; |
376 | } | 368 | } |
@@ -430,8 +422,7 @@ int ccwgroup_create_from_string(struct device *root, unsigned int creator_id, | |||
430 | struct ccw_driver *cdrv, int num_devices, | 422 | struct ccw_driver *cdrv, int num_devices, |
431 | const char *buf) | 423 | const char *buf) |
432 | { | 424 | { |
433 | return ccwgroup_create_dev(root, creator_id, cdrv, NULL, | 425 | return ccwgroup_create_dev(root, creator_id, NULL, num_devices, buf); |
434 | num_devices, buf); | ||
435 | } | 426 | } |
436 | EXPORT_SYMBOL(ccwgroup_create_from_string); | 427 | EXPORT_SYMBOL(ccwgroup_create_from_string); |
437 | 428 | ||