diff options
| -rw-r--r-- | drivers/s390/block/dasd_alias.c | 117 | ||||
| -rw-r--r-- | drivers/s390/block/dasd_devmap.c | 174 | ||||
| -rw-r--r-- | drivers/s390/block/dasd_eckd.c | 78 | ||||
| -rw-r--r-- | drivers/s390/block/dasd_int.h | 44 |
4 files changed, 218 insertions, 195 deletions
diff --git a/drivers/s390/block/dasd_alias.c b/drivers/s390/block/dasd_alias.c index a564b9941114..4155805dcdff 100644 --- a/drivers/s390/block/dasd_alias.c +++ b/drivers/s390/block/dasd_alias.c | |||
| @@ -190,20 +190,21 @@ int dasd_alias_make_device_known_to_lcu(struct dasd_device *device) | |||
| 190 | struct alias_server *server, *newserver; | 190 | struct alias_server *server, *newserver; |
| 191 | struct alias_lcu *lcu, *newlcu; | 191 | struct alias_lcu *lcu, *newlcu; |
| 192 | int is_lcu_known; | 192 | int is_lcu_known; |
| 193 | struct dasd_uid *uid; | 193 | struct dasd_uid uid; |
| 194 | 194 | ||
| 195 | private = (struct dasd_eckd_private *) device->private; | 195 | private = (struct dasd_eckd_private *) device->private; |
| 196 | uid = &private->uid; | 196 | |
| 197 | device->discipline->get_uid(device, &uid); | ||
| 197 | spin_lock_irqsave(&aliastree.lock, flags); | 198 | spin_lock_irqsave(&aliastree.lock, flags); |
| 198 | is_lcu_known = 1; | 199 | is_lcu_known = 1; |
| 199 | server = _find_server(uid); | 200 | server = _find_server(&uid); |
| 200 | if (!server) { | 201 | if (!server) { |
| 201 | spin_unlock_irqrestore(&aliastree.lock, flags); | 202 | spin_unlock_irqrestore(&aliastree.lock, flags); |
| 202 | newserver = _allocate_server(uid); | 203 | newserver = _allocate_server(&uid); |
| 203 | if (IS_ERR(newserver)) | 204 | if (IS_ERR(newserver)) |
| 204 | return PTR_ERR(newserver); | 205 | return PTR_ERR(newserver); |
| 205 | spin_lock_irqsave(&aliastree.lock, flags); | 206 | spin_lock_irqsave(&aliastree.lock, flags); |
| 206 | server = _find_server(uid); | 207 | server = _find_server(&uid); |
| 207 | if (!server) { | 208 | if (!server) { |
| 208 | list_add(&newserver->server, &aliastree.serverlist); | 209 | list_add(&newserver->server, &aliastree.serverlist); |
| 209 | server = newserver; | 210 | server = newserver; |
| @@ -214,14 +215,14 @@ int dasd_alias_make_device_known_to_lcu(struct dasd_device *device) | |||
| 214 | } | 215 | } |
| 215 | } | 216 | } |
| 216 | 217 | ||
| 217 | lcu = _find_lcu(server, uid); | 218 | lcu = _find_lcu(server, &uid); |
| 218 | if (!lcu) { | 219 | if (!lcu) { |
| 219 | spin_unlock_irqrestore(&aliastree.lock, flags); | 220 | spin_unlock_irqrestore(&aliastree.lock, flags); |
| 220 | newlcu = _allocate_lcu(uid); | 221 | newlcu = _allocate_lcu(&uid); |
| 221 | if (IS_ERR(newlcu)) | 222 | if (IS_ERR(newlcu)) |
| 222 | return PTR_ERR(newlcu); | 223 | return PTR_ERR(newlcu); |
| 223 | spin_lock_irqsave(&aliastree.lock, flags); | 224 | spin_lock_irqsave(&aliastree.lock, flags); |
| 224 | lcu = _find_lcu(server, uid); | 225 | lcu = _find_lcu(server, &uid); |
| 225 | if (!lcu) { | 226 | if (!lcu) { |
| 226 | list_add(&newlcu->lcu, &server->lculist); | 227 | list_add(&newlcu->lcu, &server->lculist); |
| 227 | lcu = newlcu; | 228 | lcu = newlcu; |
| @@ -256,20 +257,20 @@ void dasd_alias_lcu_setup_complete(struct dasd_device *device) | |||
| 256 | unsigned long flags; | 257 | unsigned long flags; |
| 257 | struct alias_server *server; | 258 | struct alias_server *server; |
| 258 | struct alias_lcu *lcu; | 259 | struct alias_lcu *lcu; |
| 259 | struct dasd_uid *uid; | 260 | struct dasd_uid uid; |
| 260 | 261 | ||
| 261 | private = (struct dasd_eckd_private *) device->private; | 262 | private = (struct dasd_eckd_private *) device->private; |
| 262 | uid = &private->uid; | 263 | device->discipline->get_uid(device, &uid); |
| 263 | lcu = NULL; | 264 | lcu = NULL; |
| 264 | spin_lock_irqsave(&aliastree.lock, flags); | 265 | spin_lock_irqsave(&aliastree.lock, flags); |
| 265 | server = _find_server(uid); | 266 | server = _find_server(&uid); |
| 266 | if (server) | 267 | if (server) |
| 267 | lcu = _find_lcu(server, uid); | 268 | lcu = _find_lcu(server, &uid); |
| 268 | spin_unlock_irqrestore(&aliastree.lock, flags); | 269 | spin_unlock_irqrestore(&aliastree.lock, flags); |
| 269 | if (!lcu) { | 270 | if (!lcu) { |
| 270 | DBF_EVENT_DEVID(DBF_ERR, device->cdev, | 271 | DBF_EVENT_DEVID(DBF_ERR, device->cdev, |
| 271 | "could not find lcu for %04x %02x", | 272 | "could not find lcu for %04x %02x", |
| 272 | uid->ssid, uid->real_unit_addr); | 273 | uid.ssid, uid.real_unit_addr); |
| 273 | WARN_ON(1); | 274 | WARN_ON(1); |
| 274 | return; | 275 | return; |
| 275 | } | 276 | } |
| @@ -282,20 +283,20 @@ void dasd_alias_wait_for_lcu_setup(struct dasd_device *device) | |||
| 282 | unsigned long flags; | 283 | unsigned long flags; |
| 283 | struct alias_server *server; | 284 | struct alias_server *server; |
| 284 | struct alias_lcu *lcu; | 285 | struct alias_lcu *lcu; |
| 285 | struct dasd_uid *uid; | 286 | struct dasd_uid uid; |
| 286 | 287 | ||
| 287 | private = (struct dasd_eckd_private *) device->private; | 288 | private = (struct dasd_eckd_private *) device->private; |
| 288 | uid = &private->uid; | 289 | device->discipline->get_uid(device, &uid); |
| 289 | lcu = NULL; | 290 | lcu = NULL; |
| 290 | spin_lock_irqsave(&aliastree.lock, flags); | 291 | spin_lock_irqsave(&aliastree.lock, flags); |
| 291 | server = _find_server(uid); | 292 | server = _find_server(&uid); |
| 292 | if (server) | 293 | if (server) |
| 293 | lcu = _find_lcu(server, uid); | 294 | lcu = _find_lcu(server, &uid); |
| 294 | spin_unlock_irqrestore(&aliastree.lock, flags); | 295 | spin_unlock_irqrestore(&aliastree.lock, flags); |
| 295 | if (!lcu) { | 296 | if (!lcu) { |
| 296 | DBF_EVENT_DEVID(DBF_ERR, device->cdev, | 297 | DBF_EVENT_DEVID(DBF_ERR, device->cdev, |
| 297 | "could not find lcu for %04x %02x", | 298 | "could not find lcu for %04x %02x", |
| 298 | uid->ssid, uid->real_unit_addr); | 299 | uid.ssid, uid.real_unit_addr); |
| 299 | WARN_ON(1); | 300 | WARN_ON(1); |
| 300 | return; | 301 | return; |
| 301 | } | 302 | } |
| @@ -314,9 +315,11 @@ void dasd_alias_disconnect_device_from_lcu(struct dasd_device *device) | |||
| 314 | struct alias_lcu *lcu; | 315 | struct alias_lcu *lcu; |
| 315 | struct alias_server *server; | 316 | struct alias_server *server; |
| 316 | int was_pending; | 317 | int was_pending; |
| 318 | struct dasd_uid uid; | ||
| 317 | 319 | ||
| 318 | private = (struct dasd_eckd_private *) device->private; | 320 | private = (struct dasd_eckd_private *) device->private; |
| 319 | lcu = private->lcu; | 321 | lcu = private->lcu; |
| 322 | device->discipline->get_uid(device, &uid); | ||
| 320 | spin_lock_irqsave(&lcu->lock, flags); | 323 | spin_lock_irqsave(&lcu->lock, flags); |
| 321 | list_del_init(&device->alias_list); | 324 | list_del_init(&device->alias_list); |
| 322 | /* make sure that the workers don't use this device */ | 325 | /* make sure that the workers don't use this device */ |
| @@ -353,7 +356,7 @@ void dasd_alias_disconnect_device_from_lcu(struct dasd_device *device) | |||
| 353 | _schedule_lcu_update(lcu, NULL); | 356 | _schedule_lcu_update(lcu, NULL); |
| 354 | spin_unlock(&lcu->lock); | 357 | spin_unlock(&lcu->lock); |
| 355 | } | 358 | } |
| 356 | server = _find_server(&private->uid); | 359 | server = _find_server(&uid); |
| 357 | if (server && list_empty(&server->lculist)) { | 360 | if (server && list_empty(&server->lculist)) { |
| 358 | list_del(&server->server); | 361 | list_del(&server->server); |
| 359 | _free_server(server); | 362 | _free_server(server); |
| @@ -366,19 +369,30 @@ void dasd_alias_disconnect_device_from_lcu(struct dasd_device *device) | |||
| 366 | * in the lcu is up to date and will update the device uid before | 369 | * in the lcu is up to date and will update the device uid before |
| 367 | * adding it to a pav group. | 370 | * adding it to a pav group. |
| 368 | */ | 371 | */ |
| 372 | |||
| 369 | static int _add_device_to_lcu(struct alias_lcu *lcu, | 373 | static int _add_device_to_lcu(struct alias_lcu *lcu, |
| 370 | struct dasd_device *device) | 374 | struct dasd_device *device, |
| 375 | struct dasd_device *pos) | ||
| 371 | { | 376 | { |
| 372 | 377 | ||
| 373 | struct dasd_eckd_private *private; | 378 | struct dasd_eckd_private *private; |
| 374 | struct alias_pav_group *group; | 379 | struct alias_pav_group *group; |
| 375 | struct dasd_uid *uid; | 380 | struct dasd_uid uid; |
| 381 | unsigned long flags; | ||
| 376 | 382 | ||
| 377 | private = (struct dasd_eckd_private *) device->private; | 383 | private = (struct dasd_eckd_private *) device->private; |
| 378 | uid = &private->uid; | 384 | |
| 379 | uid->type = lcu->uac->unit[uid->real_unit_addr].ua_type; | 385 | /* only lock if not already locked */ |
| 380 | uid->base_unit_addr = lcu->uac->unit[uid->real_unit_addr].base_ua; | 386 | if (device != pos) |
| 381 | dasd_set_uid(device->cdev, &private->uid); | 387 | spin_lock_irqsave_nested(get_ccwdev_lock(device->cdev), flags, |
| 388 | CDEV_NESTED_SECOND); | ||
| 389 | private->uid.type = lcu->uac->unit[private->uid.real_unit_addr].ua_type; | ||
| 390 | private->uid.base_unit_addr = | ||
| 391 | lcu->uac->unit[private->uid.real_unit_addr].base_ua; | ||
| 392 | uid = private->uid; | ||
| 393 | |||
| 394 | if (device != pos) | ||
| 395 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); | ||
| 382 | 396 | ||
| 383 | /* if we have no PAV anyway, we don't need to bother with PAV groups */ | 397 | /* if we have no PAV anyway, we don't need to bother with PAV groups */ |
| 384 | if (lcu->pav == NO_PAV) { | 398 | if (lcu->pav == NO_PAV) { |
| @@ -386,25 +400,25 @@ static int _add_device_to_lcu(struct alias_lcu *lcu, | |||
| 386 | return 0; | 400 | return 0; |
| 387 | } | 401 | } |
| 388 | 402 | ||
| 389 | group = _find_group(lcu, uid); | 403 | group = _find_group(lcu, &uid); |
| 390 | if (!group) { | 404 | if (!group) { |
| 391 | group = kzalloc(sizeof(*group), GFP_ATOMIC); | 405 | group = kzalloc(sizeof(*group), GFP_ATOMIC); |
| 392 | if (!group) | 406 | if (!group) |
| 393 | return -ENOMEM; | 407 | return -ENOMEM; |
| 394 | memcpy(group->uid.vendor, uid->vendor, sizeof(uid->vendor)); | 408 | memcpy(group->uid.vendor, uid.vendor, sizeof(uid.vendor)); |
| 395 | memcpy(group->uid.serial, uid->serial, sizeof(uid->serial)); | 409 | memcpy(group->uid.serial, uid.serial, sizeof(uid.serial)); |
| 396 | group->uid.ssid = uid->ssid; | 410 | group->uid.ssid = uid.ssid; |
| 397 | if (uid->type == UA_BASE_DEVICE) | 411 | if (uid.type == UA_BASE_DEVICE) |
| 398 | group->uid.base_unit_addr = uid->real_unit_addr; | 412 | group->uid.base_unit_addr = uid.real_unit_addr; |
| 399 | else | 413 | else |
| 400 | group->uid.base_unit_addr = uid->base_unit_addr; | 414 | group->uid.base_unit_addr = uid.base_unit_addr; |
| 401 | memcpy(group->uid.vduit, uid->vduit, sizeof(uid->vduit)); | 415 | memcpy(group->uid.vduit, uid.vduit, sizeof(uid.vduit)); |
| 402 | INIT_LIST_HEAD(&group->group); | 416 | INIT_LIST_HEAD(&group->group); |
| 403 | INIT_LIST_HEAD(&group->baselist); | 417 | INIT_LIST_HEAD(&group->baselist); |
| 404 | INIT_LIST_HEAD(&group->aliaslist); | 418 | INIT_LIST_HEAD(&group->aliaslist); |
| 405 | list_add(&group->group, &lcu->grouplist); | 419 | list_add(&group->group, &lcu->grouplist); |
| 406 | } | 420 | } |
| 407 | if (uid->type == UA_BASE_DEVICE) | 421 | if (uid.type == UA_BASE_DEVICE) |
| 408 | list_move(&device->alias_list, &group->baselist); | 422 | list_move(&device->alias_list, &group->baselist); |
| 409 | else | 423 | else |
| 410 | list_move(&device->alias_list, &group->aliaslist); | 424 | list_move(&device->alias_list, &group->aliaslist); |
| @@ -525,7 +539,10 @@ static int _lcu_update(struct dasd_device *refdev, struct alias_lcu *lcu) | |||
| 525 | if (rc) | 539 | if (rc) |
| 526 | return rc; | 540 | return rc; |
| 527 | 541 | ||
| 528 | spin_lock_irqsave(&lcu->lock, flags); | 542 | /* need to take cdev lock before lcu lock */ |
| 543 | spin_lock_irqsave_nested(get_ccwdev_lock(refdev->cdev), flags, | ||
| 544 | CDEV_NESTED_FIRST); | ||
| 545 | spin_lock(&lcu->lock); | ||
| 529 | lcu->pav = NO_PAV; | 546 | lcu->pav = NO_PAV; |
| 530 | for (i = 0; i < MAX_DEVICES_PER_LCU; ++i) { | 547 | for (i = 0; i < MAX_DEVICES_PER_LCU; ++i) { |
| 531 | switch (lcu->uac->unit[i].ua_type) { | 548 | switch (lcu->uac->unit[i].ua_type) { |
| @@ -542,9 +559,10 @@ static int _lcu_update(struct dasd_device *refdev, struct alias_lcu *lcu) | |||
| 542 | 559 | ||
| 543 | list_for_each_entry_safe(device, tempdev, &lcu->active_devices, | 560 | list_for_each_entry_safe(device, tempdev, &lcu->active_devices, |
| 544 | alias_list) { | 561 | alias_list) { |
| 545 | _add_device_to_lcu(lcu, device); | 562 | _add_device_to_lcu(lcu, device, refdev); |
| 546 | } | 563 | } |
| 547 | spin_unlock_irqrestore(&lcu->lock, flags); | 564 | spin_unlock(&lcu->lock); |
| 565 | spin_unlock_irqrestore(get_ccwdev_lock(refdev->cdev), flags); | ||
| 548 | return 0; | 566 | return 0; |
| 549 | } | 567 | } |
| 550 | 568 | ||
| @@ -628,9 +646,12 @@ int dasd_alias_add_device(struct dasd_device *device) | |||
| 628 | private = (struct dasd_eckd_private *) device->private; | 646 | private = (struct dasd_eckd_private *) device->private; |
| 629 | lcu = private->lcu; | 647 | lcu = private->lcu; |
| 630 | rc = 0; | 648 | rc = 0; |
| 631 | spin_lock_irqsave(&lcu->lock, flags); | 649 | |
| 650 | /* need to take cdev lock before lcu lock */ | ||
| 651 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); | ||
| 652 | spin_lock(&lcu->lock); | ||
| 632 | if (!(lcu->flags & UPDATE_PENDING)) { | 653 | if (!(lcu->flags & UPDATE_PENDING)) { |
| 633 | rc = _add_device_to_lcu(lcu, device); | 654 | rc = _add_device_to_lcu(lcu, device, device); |
| 634 | if (rc) | 655 | if (rc) |
| 635 | lcu->flags |= UPDATE_PENDING; | 656 | lcu->flags |= UPDATE_PENDING; |
| 636 | } | 657 | } |
| @@ -638,7 +659,8 @@ int dasd_alias_add_device(struct dasd_device *device) | |||
| 638 | list_move(&device->alias_list, &lcu->active_devices); | 659 | list_move(&device->alias_list, &lcu->active_devices); |
| 639 | _schedule_lcu_update(lcu, device); | 660 | _schedule_lcu_update(lcu, device); |
| 640 | } | 661 | } |
| 641 | spin_unlock_irqrestore(&lcu->lock, flags); | 662 | spin_unlock(&lcu->lock); |
| 663 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); | ||
| 642 | return rc; | 664 | return rc; |
| 643 | } | 665 | } |
| 644 | 666 | ||
| @@ -748,19 +770,30 @@ static void _restart_all_base_devices_on_lcu(struct alias_lcu *lcu) | |||
| 748 | struct alias_pav_group *pavgroup; | 770 | struct alias_pav_group *pavgroup; |
| 749 | struct dasd_device *device; | 771 | struct dasd_device *device; |
| 750 | struct dasd_eckd_private *private; | 772 | struct dasd_eckd_private *private; |
| 773 | unsigned long flags; | ||
| 751 | 774 | ||
| 752 | /* active and inactive list can contain alias as well as base devices */ | 775 | /* active and inactive list can contain alias as well as base devices */ |
| 753 | list_for_each_entry(device, &lcu->active_devices, alias_list) { | 776 | list_for_each_entry(device, &lcu->active_devices, alias_list) { |
| 754 | private = (struct dasd_eckd_private *) device->private; | 777 | private = (struct dasd_eckd_private *) device->private; |
| 755 | if (private->uid.type != UA_BASE_DEVICE) | 778 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); |
| 779 | if (private->uid.type != UA_BASE_DEVICE) { | ||
| 780 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), | ||
| 781 | flags); | ||
| 756 | continue; | 782 | continue; |
| 783 | } | ||
| 784 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); | ||
| 757 | dasd_schedule_block_bh(device->block); | 785 | dasd_schedule_block_bh(device->block); |
| 758 | dasd_schedule_device_bh(device); | 786 | dasd_schedule_device_bh(device); |
| 759 | } | 787 | } |
| 760 | list_for_each_entry(device, &lcu->inactive_devices, alias_list) { | 788 | list_for_each_entry(device, &lcu->inactive_devices, alias_list) { |
| 761 | private = (struct dasd_eckd_private *) device->private; | 789 | private = (struct dasd_eckd_private *) device->private; |
| 762 | if (private->uid.type != UA_BASE_DEVICE) | 790 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); |
| 791 | if (private->uid.type != UA_BASE_DEVICE) { | ||
| 792 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), | ||
| 793 | flags); | ||
| 763 | continue; | 794 | continue; |
| 795 | } | ||
| 796 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); | ||
| 764 | dasd_schedule_block_bh(device->block); | 797 | dasd_schedule_block_bh(device->block); |
| 765 | dasd_schedule_device_bh(device); | 798 | dasd_schedule_device_bh(device); |
| 766 | } | 799 | } |
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c index eff9c812c5c2..34d51dd4c539 100644 --- a/drivers/s390/block/dasd_devmap.c +++ b/drivers/s390/block/dasd_devmap.c | |||
| @@ -49,7 +49,6 @@ struct dasd_devmap { | |||
| 49 | unsigned int devindex; | 49 | unsigned int devindex; |
| 50 | unsigned short features; | 50 | unsigned short features; |
| 51 | struct dasd_device *device; | 51 | struct dasd_device *device; |
| 52 | struct dasd_uid uid; | ||
| 53 | }; | 52 | }; |
| 54 | 53 | ||
| 55 | /* | 54 | /* |
| @@ -936,42 +935,46 @@ dasd_device_status_show(struct device *dev, struct device_attribute *attr, | |||
| 936 | 935 | ||
| 937 | static DEVICE_ATTR(status, 0444, dasd_device_status_show, NULL); | 936 | static DEVICE_ATTR(status, 0444, dasd_device_status_show, NULL); |
| 938 | 937 | ||
| 939 | static ssize_t | 938 | static ssize_t dasd_alias_show(struct device *dev, |
| 940 | dasd_alias_show(struct device *dev, struct device_attribute *attr, char *buf) | 939 | struct device_attribute *attr, char *buf) |
| 941 | { | 940 | { |
| 942 | struct dasd_devmap *devmap; | 941 | struct dasd_device *device; |
| 943 | int alias; | 942 | struct dasd_uid uid; |
| 944 | 943 | ||
| 945 | devmap = dasd_find_busid(dev_name(dev)); | 944 | device = dasd_device_from_cdev(to_ccwdev(dev)); |
| 946 | spin_lock(&dasd_devmap_lock); | 945 | if (IS_ERR(device)) |
| 947 | if (IS_ERR(devmap) || strlen(devmap->uid.vendor) == 0) { | ||
| 948 | spin_unlock(&dasd_devmap_lock); | ||
| 949 | return sprintf(buf, "0\n"); | 946 | return sprintf(buf, "0\n"); |
| 947 | |||
| 948 | if (device->discipline && device->discipline->get_uid && | ||
| 949 | !device->discipline->get_uid(device, &uid)) { | ||
| 950 | if (uid.type == UA_BASE_PAV_ALIAS || | ||
| 951 | uid.type == UA_HYPER_PAV_ALIAS) | ||
| 952 | return sprintf(buf, "1\n"); | ||
| 950 | } | 953 | } |
| 951 | if (devmap->uid.type == UA_BASE_PAV_ALIAS || | 954 | dasd_put_device(device); |
| 952 | devmap->uid.type == UA_HYPER_PAV_ALIAS) | 955 | |
| 953 | alias = 1; | 956 | return sprintf(buf, "0\n"); |
| 954 | else | ||
| 955 | alias = 0; | ||
| 956 | spin_unlock(&dasd_devmap_lock); | ||
| 957 | return sprintf(buf, alias ? "1\n" : "0\n"); | ||
| 958 | } | 957 | } |
| 959 | 958 | ||
| 960 | static DEVICE_ATTR(alias, 0444, dasd_alias_show, NULL); | 959 | static DEVICE_ATTR(alias, 0444, dasd_alias_show, NULL); |
| 961 | 960 | ||
| 962 | static ssize_t | 961 | static ssize_t dasd_vendor_show(struct device *dev, |
| 963 | dasd_vendor_show(struct device *dev, struct device_attribute *attr, char *buf) | 962 | struct device_attribute *attr, char *buf) |
| 964 | { | 963 | { |
| 965 | struct dasd_devmap *devmap; | 964 | struct dasd_device *device; |
| 965 | struct dasd_uid uid; | ||
| 966 | char *vendor; | 966 | char *vendor; |
| 967 | 967 | ||
| 968 | devmap = dasd_find_busid(dev_name(dev)); | 968 | device = dasd_device_from_cdev(to_ccwdev(dev)); |
| 969 | spin_lock(&dasd_devmap_lock); | 969 | vendor = ""; |
| 970 | if (!IS_ERR(devmap) && strlen(devmap->uid.vendor) > 0) | 970 | if (IS_ERR(device)) |
| 971 | vendor = devmap->uid.vendor; | 971 | return snprintf(buf, PAGE_SIZE, "%s\n", vendor); |
| 972 | else | 972 | |
| 973 | vendor = ""; | 973 | if (device->discipline && device->discipline->get_uid && |
| 974 | spin_unlock(&dasd_devmap_lock); | 974 | !device->discipline->get_uid(device, &uid)) |
| 975 | vendor = uid.vendor; | ||
| 976 | |||
| 977 | dasd_put_device(device); | ||
| 975 | 978 | ||
| 976 | return snprintf(buf, PAGE_SIZE, "%s\n", vendor); | 979 | return snprintf(buf, PAGE_SIZE, "%s\n", vendor); |
| 977 | } | 980 | } |
| @@ -985,48 +988,51 @@ static DEVICE_ATTR(vendor, 0444, dasd_vendor_show, NULL); | |||
| 985 | static ssize_t | 988 | static ssize_t |
| 986 | dasd_uid_show(struct device *dev, struct device_attribute *attr, char *buf) | 989 | dasd_uid_show(struct device *dev, struct device_attribute *attr, char *buf) |
| 987 | { | 990 | { |
| 988 | struct dasd_devmap *devmap; | 991 | struct dasd_device *device; |
| 992 | struct dasd_uid uid; | ||
| 989 | char uid_string[UID_STRLEN]; | 993 | char uid_string[UID_STRLEN]; |
| 990 | char ua_string[3]; | 994 | char ua_string[3]; |
| 991 | struct dasd_uid *uid; | ||
| 992 | 995 | ||
| 993 | devmap = dasd_find_busid(dev_name(dev)); | 996 | device = dasd_device_from_cdev(to_ccwdev(dev)); |
| 994 | spin_lock(&dasd_devmap_lock); | 997 | uid_string[0] = 0; |
| 995 | if (IS_ERR(devmap) || strlen(devmap->uid.vendor) == 0) { | 998 | if (IS_ERR(device)) |
| 996 | spin_unlock(&dasd_devmap_lock); | 999 | return snprintf(buf, PAGE_SIZE, "%s\n", uid_string); |
| 997 | return sprintf(buf, "\n"); | 1000 | |
| 998 | } | 1001 | if (device->discipline && device->discipline->get_uid && |
| 999 | uid = &devmap->uid; | 1002 | !device->discipline->get_uid(device, &uid)) { |
| 1000 | switch (uid->type) { | 1003 | switch (uid.type) { |
| 1001 | case UA_BASE_DEVICE: | 1004 | case UA_BASE_DEVICE: |
| 1002 | sprintf(ua_string, "%02x", uid->real_unit_addr); | 1005 | snprintf(ua_string, sizeof(ua_string), "%02x", |
| 1003 | break; | 1006 | uid.real_unit_addr); |
| 1004 | case UA_BASE_PAV_ALIAS: | 1007 | break; |
| 1005 | sprintf(ua_string, "%02x", uid->base_unit_addr); | 1008 | case UA_BASE_PAV_ALIAS: |
| 1006 | break; | 1009 | snprintf(ua_string, sizeof(ua_string), "%02x", |
| 1007 | case UA_HYPER_PAV_ALIAS: | 1010 | uid.base_unit_addr); |
| 1008 | sprintf(ua_string, "xx"); | 1011 | break; |
| 1009 | break; | 1012 | case UA_HYPER_PAV_ALIAS: |
| 1010 | default: | 1013 | snprintf(ua_string, sizeof(ua_string), "xx"); |
| 1011 | /* should not happen, treat like base device */ | 1014 | break; |
| 1012 | sprintf(ua_string, "%02x", uid->real_unit_addr); | 1015 | default: |
| 1013 | break; | 1016 | /* should not happen, treat like base device */ |
| 1017 | snprintf(ua_string, sizeof(ua_string), "%02x", | ||
| 1018 | uid.real_unit_addr); | ||
| 1019 | break; | ||
| 1020 | } | ||
| 1021 | |||
| 1022 | if (strlen(uid.vduit) > 0) | ||
| 1023 | snprintf(uid_string, sizeof(uid_string), | ||
| 1024 | "%s.%s.%04x.%s.%s", | ||
| 1025 | uid.vendor, uid.serial, uid.ssid, ua_string, | ||
| 1026 | uid.vduit); | ||
| 1027 | else | ||
| 1028 | snprintf(uid_string, sizeof(uid_string), | ||
| 1029 | "%s.%s.%04x.%s", | ||
| 1030 | uid.vendor, uid.serial, uid.ssid, ua_string); | ||
| 1014 | } | 1031 | } |
| 1015 | if (strlen(uid->vduit) > 0) | 1032 | dasd_put_device(device); |
| 1016 | snprintf(uid_string, sizeof(uid_string), | 1033 | |
| 1017 | "%s.%s.%04x.%s.%s", | ||
| 1018 | uid->vendor, uid->serial, | ||
| 1019 | uid->ssid, ua_string, | ||
| 1020 | uid->vduit); | ||
| 1021 | else | ||
| 1022 | snprintf(uid_string, sizeof(uid_string), | ||
| 1023 | "%s.%s.%04x.%s", | ||
| 1024 | uid->vendor, uid->serial, | ||
| 1025 | uid->ssid, ua_string); | ||
| 1026 | spin_unlock(&dasd_devmap_lock); | ||
| 1027 | return snprintf(buf, PAGE_SIZE, "%s\n", uid_string); | 1034 | return snprintf(buf, PAGE_SIZE, "%s\n", uid_string); |
| 1028 | } | 1035 | } |
| 1029 | |||
| 1030 | static DEVICE_ATTR(uid, 0444, dasd_uid_show, NULL); | 1036 | static DEVICE_ATTR(uid, 0444, dasd_uid_show, NULL); |
| 1031 | 1037 | ||
| 1032 | /* | 1038 | /* |
| @@ -1094,50 +1100,6 @@ static struct attribute_group dasd_attr_group = { | |||
| 1094 | }; | 1100 | }; |
| 1095 | 1101 | ||
| 1096 | /* | 1102 | /* |
| 1097 | * Return copy of the device unique identifier. | ||
| 1098 | */ | ||
| 1099 | int | ||
| 1100 | dasd_get_uid(struct ccw_device *cdev, struct dasd_uid *uid) | ||
| 1101 | { | ||
| 1102 | struct dasd_devmap *devmap; | ||
| 1103 | |||
| 1104 | devmap = dasd_find_busid(dev_name(&cdev->dev)); | ||
| 1105 | if (IS_ERR(devmap)) | ||
| 1106 | return PTR_ERR(devmap); | ||
| 1107 | spin_lock(&dasd_devmap_lock); | ||
| 1108 | *uid = devmap->uid; | ||
| 1109 | spin_unlock(&dasd_devmap_lock); | ||
| 1110 | return 0; | ||
| 1111 | } | ||
| 1112 | EXPORT_SYMBOL_GPL(dasd_get_uid); | ||
| 1113 | |||
| 1114 | /* | ||
| 1115 | * Register the given device unique identifier into devmap struct. | ||
| 1116 | * In addition check if the related storage server subsystem ID is already | ||
| 1117 | * contained in the dasd_server_ssid_list. If subsystem ID is not contained, | ||
| 1118 | * create new entry. | ||
| 1119 | * Return 0 if server was already in serverlist, | ||
| 1120 | * 1 if the server was added successful | ||
| 1121 | * <0 in case of error. | ||
| 1122 | */ | ||
| 1123 | int | ||
| 1124 | dasd_set_uid(struct ccw_device *cdev, struct dasd_uid *uid) | ||
| 1125 | { | ||
| 1126 | struct dasd_devmap *devmap; | ||
| 1127 | |||
| 1128 | devmap = dasd_find_busid(dev_name(&cdev->dev)); | ||
| 1129 | if (IS_ERR(devmap)) | ||
| 1130 | return PTR_ERR(devmap); | ||
| 1131 | |||
| 1132 | spin_lock(&dasd_devmap_lock); | ||
| 1133 | devmap->uid = *uid; | ||
| 1134 | spin_unlock(&dasd_devmap_lock); | ||
| 1135 | |||
| 1136 | return 0; | ||
| 1137 | } | ||
| 1138 | EXPORT_SYMBOL_GPL(dasd_set_uid); | ||
| 1139 | |||
| 1140 | /* | ||
| 1141 | * Return value of the specified feature. | 1103 | * Return value of the specified feature. |
| 1142 | */ | 1104 | */ |
| 1143 | int | 1105 | int |
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 4305c23c57a4..5b1cd8d6e971 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c | |||
| @@ -692,18 +692,20 @@ dasd_eckd_cdl_reclen(int recid) | |||
| 692 | /* | 692 | /* |
| 693 | * Generate device unique id that specifies the physical device. | 693 | * Generate device unique id that specifies the physical device. |
| 694 | */ | 694 | */ |
| 695 | static int dasd_eckd_generate_uid(struct dasd_device *device, | 695 | static int dasd_eckd_generate_uid(struct dasd_device *device) |
| 696 | struct dasd_uid *uid) | ||
| 697 | { | 696 | { |
| 698 | struct dasd_eckd_private *private; | 697 | struct dasd_eckd_private *private; |
| 698 | struct dasd_uid *uid; | ||
| 699 | int count; | 699 | int count; |
| 700 | unsigned long flags; | ||
| 700 | 701 | ||
| 701 | private = (struct dasd_eckd_private *) device->private; | 702 | private = (struct dasd_eckd_private *) device->private; |
| 702 | if (!private) | 703 | if (!private) |
| 703 | return -ENODEV; | 704 | return -ENODEV; |
| 704 | if (!private->ned || !private->gneq) | 705 | if (!private->ned || !private->gneq) |
| 705 | return -ENODEV; | 706 | return -ENODEV; |
| 706 | 707 | uid = &private->uid; | |
| 708 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); | ||
| 707 | memset(uid, 0, sizeof(struct dasd_uid)); | 709 | memset(uid, 0, sizeof(struct dasd_uid)); |
| 708 | memcpy(uid->vendor, private->ned->HDA_manufacturer, | 710 | memcpy(uid->vendor, private->ned->HDA_manufacturer, |
| 709 | sizeof(uid->vendor) - 1); | 711 | sizeof(uid->vendor) - 1); |
| @@ -726,9 +728,25 @@ static int dasd_eckd_generate_uid(struct dasd_device *device, | |||
| 726 | private->vdsneq->uit[count]); | 728 | private->vdsneq->uit[count]); |
| 727 | } | 729 | } |
| 728 | } | 730 | } |
| 731 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); | ||
| 729 | return 0; | 732 | return 0; |
| 730 | } | 733 | } |
| 731 | 734 | ||
| 735 | static int dasd_eckd_get_uid(struct dasd_device *device, struct dasd_uid *uid) | ||
| 736 | { | ||
| 737 | struct dasd_eckd_private *private; | ||
| 738 | unsigned long flags; | ||
| 739 | |||
| 740 | if (device->private) { | ||
| 741 | private = (struct dasd_eckd_private *)device->private; | ||
| 742 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); | ||
| 743 | *uid = private->uid; | ||
| 744 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); | ||
| 745 | return 0; | ||
| 746 | } | ||
| 747 | return -EINVAL; | ||
| 748 | } | ||
| 749 | |||
| 732 | static struct dasd_ccw_req *dasd_eckd_build_rcd_lpm(struct dasd_device *device, | 750 | static struct dasd_ccw_req *dasd_eckd_build_rcd_lpm(struct dasd_device *device, |
| 733 | void *rcd_buffer, | 751 | void *rcd_buffer, |
| 734 | struct ciw *ciw, __u8 lpm) | 752 | struct ciw *ciw, __u8 lpm) |
| @@ -1088,6 +1106,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device) | |||
| 1088 | { | 1106 | { |
| 1089 | struct dasd_eckd_private *private; | 1107 | struct dasd_eckd_private *private; |
| 1090 | struct dasd_block *block; | 1108 | struct dasd_block *block; |
| 1109 | struct dasd_uid temp_uid; | ||
| 1091 | int is_known, rc; | 1110 | int is_known, rc; |
| 1092 | int readonly; | 1111 | int readonly; |
| 1093 | 1112 | ||
| @@ -1124,13 +1143,13 @@ dasd_eckd_check_characteristics(struct dasd_device *device) | |||
| 1124 | if (rc) | 1143 | if (rc) |
| 1125 | goto out_err1; | 1144 | goto out_err1; |
| 1126 | 1145 | ||
| 1127 | /* Generate device unique id and register in devmap */ | 1146 | /* Generate device unique id */ |
| 1128 | rc = dasd_eckd_generate_uid(device, &private->uid); | 1147 | rc = dasd_eckd_generate_uid(device); |
| 1129 | if (rc) | 1148 | if (rc) |
| 1130 | goto out_err1; | 1149 | goto out_err1; |
| 1131 | dasd_set_uid(device->cdev, &private->uid); | ||
| 1132 | 1150 | ||
| 1133 | if (private->uid.type == UA_BASE_DEVICE) { | 1151 | dasd_eckd_get_uid(device, &temp_uid); |
| 1152 | if (temp_uid.type == UA_BASE_DEVICE) { | ||
| 1134 | block = dasd_alloc_block(); | 1153 | block = dasd_alloc_block(); |
| 1135 | if (IS_ERR(block)) { | 1154 | if (IS_ERR(block)) { |
| 1136 | DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s", | 1155 | DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s", |
| @@ -3305,15 +3324,16 @@ static int dasd_eckd_restore_device(struct dasd_device *device) | |||
| 3305 | if (rc) | 3324 | if (rc) |
| 3306 | goto out_err; | 3325 | goto out_err; |
| 3307 | 3326 | ||
| 3308 | /* Generate device unique id and register in devmap */ | 3327 | dasd_eckd_get_uid(device, &temp_uid); |
| 3309 | rc = dasd_eckd_generate_uid(device, &private->uid); | 3328 | /* Generate device unique id */ |
| 3310 | dasd_get_uid(device->cdev, &temp_uid); | 3329 | rc = dasd_eckd_generate_uid(device); |
| 3330 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); | ||
| 3311 | if (memcmp(&private->uid, &temp_uid, sizeof(struct dasd_uid)) != 0) | 3331 | if (memcmp(&private->uid, &temp_uid, sizeof(struct dasd_uid)) != 0) |
| 3312 | dev_err(&device->cdev->dev, "The UID of the DASD has " | 3332 | dev_err(&device->cdev->dev, "The UID of the DASD has " |
| 3313 | "changed\n"); | 3333 | "changed\n"); |
| 3334 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); | ||
| 3314 | if (rc) | 3335 | if (rc) |
| 3315 | goto out_err; | 3336 | goto out_err; |
| 3316 | dasd_set_uid(device->cdev, &private->uid); | ||
| 3317 | 3337 | ||
| 3318 | /* register lcu with alias handling, enable PAV if this is a new lcu */ | 3338 | /* register lcu with alias handling, enable PAV if this is a new lcu */ |
| 3319 | is_known = dasd_alias_make_device_known_to_lcu(device); | 3339 | is_known = dasd_alias_make_device_known_to_lcu(device); |
| @@ -3358,42 +3378,45 @@ static int dasd_eckd_reload_device(struct dasd_device *device) | |||
| 3358 | { | 3378 | { |
| 3359 | struct dasd_eckd_private *private; | 3379 | struct dasd_eckd_private *private; |
| 3360 | int rc, old_base; | 3380 | int rc, old_base; |
| 3361 | char uid[60]; | 3381 | char print_uid[60]; |
| 3382 | struct dasd_uid uid; | ||
| 3383 | unsigned long flags; | ||
| 3362 | 3384 | ||
| 3363 | private = (struct dasd_eckd_private *) device->private; | 3385 | private = (struct dasd_eckd_private *) device->private; |
| 3386 | |||
| 3387 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); | ||
| 3364 | old_base = private->uid.base_unit_addr; | 3388 | old_base = private->uid.base_unit_addr; |
| 3389 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); | ||
| 3390 | |||
| 3365 | /* Read Configuration Data */ | 3391 | /* Read Configuration Data */ |
| 3366 | rc = dasd_eckd_read_conf(device); | 3392 | rc = dasd_eckd_read_conf(device); |
| 3367 | if (rc) | 3393 | if (rc) |
| 3368 | goto out_err; | 3394 | goto out_err; |
| 3369 | 3395 | ||
| 3370 | rc = dasd_eckd_generate_uid(device, &private->uid); | 3396 | rc = dasd_eckd_generate_uid(device); |
| 3371 | if (rc) | 3397 | if (rc) |
| 3372 | goto out_err; | 3398 | goto out_err; |
| 3373 | |||
| 3374 | dasd_set_uid(device->cdev, &private->uid); | ||
| 3375 | |||
| 3376 | /* | 3399 | /* |
| 3377 | * update unit address configuration and | 3400 | * update unit address configuration and |
| 3378 | * add device to alias management | 3401 | * add device to alias management |
| 3379 | */ | 3402 | */ |
| 3380 | dasd_alias_update_add_device(device); | 3403 | dasd_alias_update_add_device(device); |
| 3381 | 3404 | ||
| 3382 | if (old_base != private->uid.base_unit_addr) { | 3405 | dasd_eckd_get_uid(device, &uid); |
| 3383 | if (strlen(private->uid.vduit) > 0) | 3406 | |
| 3384 | snprintf(uid, 60, "%s.%s.%04x.%02x.%s", | 3407 | if (old_base != uid.base_unit_addr) { |
| 3385 | private->uid.vendor, private->uid.serial, | 3408 | if (strlen(uid.vduit) > 0) |
| 3386 | private->uid.ssid, private->uid.base_unit_addr, | 3409 | snprintf(print_uid, sizeof(print_uid), |
| 3387 | private->uid.vduit); | 3410 | "%s.%s.%04x.%02x.%s", uid.vendor, uid.serial, |
| 3411 | uid.ssid, uid.base_unit_addr, uid.vduit); | ||
| 3388 | else | 3412 | else |
| 3389 | snprintf(uid, 60, "%s.%s.%04x.%02x", | 3413 | snprintf(print_uid, sizeof(print_uid), |
| 3390 | private->uid.vendor, private->uid.serial, | 3414 | "%s.%s.%04x.%02x", uid.vendor, uid.serial, |
| 3391 | private->uid.ssid, | 3415 | uid.ssid, uid.base_unit_addr); |
| 3392 | private->uid.base_unit_addr); | ||
| 3393 | 3416 | ||
| 3394 | dev_info(&device->cdev->dev, | 3417 | dev_info(&device->cdev->dev, |
| 3395 | "An Alias device was reassigned to a new base device " | 3418 | "An Alias device was reassigned to a new base device " |
| 3396 | "with UID: %s\n", uid); | 3419 | "with UID: %s\n", print_uid); |
| 3397 | } | 3420 | } |
| 3398 | return 0; | 3421 | return 0; |
| 3399 | 3422 | ||
| @@ -3455,6 +3478,7 @@ static struct dasd_discipline dasd_eckd_discipline = { | |||
| 3455 | .freeze = dasd_eckd_pm_freeze, | 3478 | .freeze = dasd_eckd_pm_freeze, |
| 3456 | .restore = dasd_eckd_restore_device, | 3479 | .restore = dasd_eckd_restore_device, |
| 3457 | .reload = dasd_eckd_reload_device, | 3480 | .reload = dasd_eckd_reload_device, |
| 3481 | .get_uid = dasd_eckd_get_uid, | ||
| 3458 | }; | 3482 | }; |
| 3459 | 3483 | ||
| 3460 | static int __init | 3484 | static int __init |
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index 1ae7b121628e..32fac186ba3f 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h | |||
| @@ -81,6 +81,10 @@ struct dasd_block; | |||
| 81 | #define DASD_SIM_MSG_TO_OP 0x03 | 81 | #define DASD_SIM_MSG_TO_OP 0x03 |
| 82 | #define DASD_SIM_LOG 0x0C | 82 | #define DASD_SIM_LOG 0x0C |
| 83 | 83 | ||
| 84 | /* lock class for nested cdev lock */ | ||
| 85 | #define CDEV_NESTED_FIRST 1 | ||
| 86 | #define CDEV_NESTED_SECOND 2 | ||
| 87 | |||
| 84 | /* | 88 | /* |
| 85 | * SECTION: MACROs for klogd and s390 debug feature (dbf) | 89 | * SECTION: MACROs for klogd and s390 debug feature (dbf) |
| 86 | */ | 90 | */ |
| @@ -229,6 +233,24 @@ struct dasd_ccw_req { | |||
| 229 | typedef struct dasd_ccw_req *(*dasd_erp_fn_t) (struct dasd_ccw_req *); | 233 | typedef struct dasd_ccw_req *(*dasd_erp_fn_t) (struct dasd_ccw_req *); |
| 230 | 234 | ||
| 231 | /* | 235 | /* |
| 236 | * Unique identifier for dasd device. | ||
| 237 | */ | ||
| 238 | #define UA_NOT_CONFIGURED 0x00 | ||
| 239 | #define UA_BASE_DEVICE 0x01 | ||
| 240 | #define UA_BASE_PAV_ALIAS 0x02 | ||
| 241 | #define UA_HYPER_PAV_ALIAS 0x03 | ||
| 242 | |||
| 243 | struct dasd_uid { | ||
| 244 | __u8 type; | ||
| 245 | char vendor[4]; | ||
| 246 | char serial[15]; | ||
| 247 | __u16 ssid; | ||
| 248 | __u8 real_unit_addr; | ||
| 249 | __u8 base_unit_addr; | ||
| 250 | char vduit[33]; | ||
| 251 | }; | ||
| 252 | |||
| 253 | /* | ||
| 232 | * the struct dasd_discipline is | 254 | * the struct dasd_discipline is |
| 233 | * sth like a table of virtual functions, if you think of dasd_eckd | 255 | * sth like a table of virtual functions, if you think of dasd_eckd |
| 234 | * inheriting dasd... | 256 | * inheriting dasd... |
| @@ -315,29 +337,13 @@ struct dasd_discipline { | |||
| 315 | 337 | ||
| 316 | /* reload device after state change */ | 338 | /* reload device after state change */ |
| 317 | int (*reload) (struct dasd_device *); | 339 | int (*reload) (struct dasd_device *); |
| 340 | |||
| 341 | int (*get_uid) (struct dasd_device *, struct dasd_uid *); | ||
| 318 | }; | 342 | }; |
| 319 | 343 | ||
| 320 | extern struct dasd_discipline *dasd_diag_discipline_pointer; | 344 | extern struct dasd_discipline *dasd_diag_discipline_pointer; |
| 321 | 345 | ||
| 322 | /* | 346 | /* |
| 323 | * Unique identifier for dasd device. | ||
| 324 | */ | ||
| 325 | #define UA_NOT_CONFIGURED 0x00 | ||
| 326 | #define UA_BASE_DEVICE 0x01 | ||
| 327 | #define UA_BASE_PAV_ALIAS 0x02 | ||
| 328 | #define UA_HYPER_PAV_ALIAS 0x03 | ||
| 329 | |||
| 330 | struct dasd_uid { | ||
| 331 | __u8 type; | ||
| 332 | char vendor[4]; | ||
| 333 | char serial[15]; | ||
| 334 | __u16 ssid; | ||
| 335 | __u8 real_unit_addr; | ||
| 336 | __u8 base_unit_addr; | ||
| 337 | char vduit[33]; | ||
| 338 | }; | ||
| 339 | |||
| 340 | /* | ||
| 341 | * Notification numbers for extended error reporting notifications: | 347 | * Notification numbers for extended error reporting notifications: |
| 342 | * The DASD_EER_DISABLE notification is sent before a dasd_device (and it's | 348 | * The DASD_EER_DISABLE notification is sent before a dasd_device (and it's |
| 343 | * eer pointer) is freed. The error reporting module needs to do all necessary | 349 | * eer pointer) is freed. The error reporting module needs to do all necessary |
| @@ -634,8 +640,6 @@ void dasd_devmap_exit(void); | |||
| 634 | struct dasd_device *dasd_create_device(struct ccw_device *); | 640 | struct dasd_device *dasd_create_device(struct ccw_device *); |
| 635 | void dasd_delete_device(struct dasd_device *); | 641 | void dasd_delete_device(struct dasd_device *); |
| 636 | 642 | ||
| 637 | int dasd_get_uid(struct ccw_device *, struct dasd_uid *); | ||
| 638 | int dasd_set_uid(struct ccw_device *, struct dasd_uid *); | ||
| 639 | int dasd_get_feature(struct ccw_device *, int); | 643 | int dasd_get_feature(struct ccw_device *, int); |
| 640 | int dasd_set_feature(struct ccw_device *, int, int); | 644 | int dasd_set_feature(struct ccw_device *, int, int); |
| 641 | 645 | ||
