diff options
author | Andrew Patterson <andrew.patterson@hp.com> | 2009-06-02 08:48:39 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2009-06-02 08:48:39 -0400 |
commit | 7fe063268e73681cdca1a6496a25f93d3332f517 (patch) | |
tree | 97c9b5f53012908343af83c481c0b8fad888690e | |
parent | 88f627ae394eadd75ada669904269f1a4a77b3bd (diff) |
cciss: add cciss driver sysfs entries
Add sysfs entries to the cciss driver needed for the dm/multipath tools.
A file for vendor, model, rev, and unique_id is added for each logical
drive under directory /sys/bus/pci/devices/<dev>/ccissX/cXdY. Where X =
the controller (or host) number and Y is the logical drive number.
A link from /sys/bus/pci/devices/<dev>/ccissX/cXdY/block:cciss!cXdY to
/sys/block/cciss!cXdY/device is also created. A bus is created in
/sys/bus/cciss. A link is created from the pci ccissX entry to
/sys/bus/cciss/devices/ccissX. Please consider this for inclusion.
Signed-off-by: Mike Miller <mike.miller@hp.com>
Cc: Stephen M. Cameron <scameron@beardog.cca.cpqcorp.net>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
-rw-r--r-- | Documentation/ABI/testing/sysfs-bus-pci-devices-cciss | 33 | ||||
-rw-r--r-- | drivers/block/cciss.c | 267 | ||||
-rw-r--r-- | drivers/block/cciss.h | 24 |
3 files changed, 314 insertions, 10 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss b/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss new file mode 100644 index 000000000000..0a92a7c93a62 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss | |||
@@ -0,0 +1,33 @@ | |||
1 | Where: /sys/bus/pci/devices/<dev>/ccissX/cXdY/model | ||
2 | Date: March 2009 | ||
3 | Kernel Version: 2.6.30 | ||
4 | Contact: iss_storagedev@hp.com | ||
5 | Description: Displays the SCSI INQUIRY page 0 model for logical drive | ||
6 | Y of controller X. | ||
7 | |||
8 | Where: /sys/bus/pci/devices/<dev>/ccissX/cXdY/rev | ||
9 | Date: March 2009 | ||
10 | Kernel Version: 2.6.30 | ||
11 | Contact: iss_storagedev@hp.com | ||
12 | Description: Displays the SCSI INQUIRY page 0 revision for logical | ||
13 | drive Y of controller X. | ||
14 | |||
15 | Where: /sys/bus/pci/devices/<dev>/ccissX/cXdY/unique_id | ||
16 | Date: March 2009 | ||
17 | Kernel Version: 2.6.30 | ||
18 | Contact: iss_storagedev@hp.com | ||
19 | Description: Displays the SCSI INQUIRY page 83 serial number for logical | ||
20 | drive Y of controller X. | ||
21 | |||
22 | Where: /sys/bus/pci/devices/<dev>/ccissX/cXdY/vendor | ||
23 | Date: March 2009 | ||
24 | Kernel Version: 2.6.30 | ||
25 | Contact: iss_storagedev@hp.com | ||
26 | Description: Displays the SCSI INQUIRY page 0 vendor for logical drive | ||
27 | Y of controller X. | ||
28 | |||
29 | Where: /sys/bus/pci/devices/<dev>/ccissX/cXdY/block:cciss!cXdY | ||
30 | Date: March 2009 | ||
31 | Kernel Version: 2.6.30 | ||
32 | Contact: iss_storagedev@hp.com | ||
33 | Description: A symbolic link to /sys/block/cciss!cXdY | ||
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index cb43fb3af159..e7d00952dd4f 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -437,6 +437,194 @@ static void __devinit cciss_procinit(int i) | |||
437 | } | 437 | } |
438 | #endif /* CONFIG_PROC_FS */ | 438 | #endif /* CONFIG_PROC_FS */ |
439 | 439 | ||
440 | #define MAX_PRODUCT_NAME_LEN 19 | ||
441 | |||
442 | #define to_hba(n) container_of(n, struct ctlr_info, dev) | ||
443 | #define to_drv(n) container_of(n, drive_info_struct, dev) | ||
444 | |||
445 | static struct device_type cciss_host_type = { | ||
446 | .name = "cciss_host", | ||
447 | }; | ||
448 | |||
449 | static ssize_t dev_show_unique_id(struct device *dev, | ||
450 | struct device_attribute *attr, | ||
451 | char *buf) | ||
452 | { | ||
453 | drive_info_struct *drv = to_drv(dev); | ||
454 | struct ctlr_info *h = to_hba(drv->dev.parent); | ||
455 | __u8 sn[16]; | ||
456 | unsigned long flags; | ||
457 | int ret = 0; | ||
458 | |||
459 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | ||
460 | if (h->busy_configuring) | ||
461 | ret = -EBUSY; | ||
462 | else | ||
463 | memcpy(sn, drv->serial_no, sizeof(sn)); | ||
464 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
465 | |||
466 | if (ret) | ||
467 | return ret; | ||
468 | else | ||
469 | return snprintf(buf, 16 * 2 + 2, | ||
470 | "%02X%02X%02X%02X%02X%02X%02X%02X" | ||
471 | "%02X%02X%02X%02X%02X%02X%02X%02X\n", | ||
472 | sn[0], sn[1], sn[2], sn[3], | ||
473 | sn[4], sn[5], sn[6], sn[7], | ||
474 | sn[8], sn[9], sn[10], sn[11], | ||
475 | sn[12], sn[13], sn[14], sn[15]); | ||
476 | } | ||
477 | DEVICE_ATTR(unique_id, S_IRUGO, dev_show_unique_id, NULL); | ||
478 | |||
479 | static ssize_t dev_show_vendor(struct device *dev, | ||
480 | struct device_attribute *attr, | ||
481 | char *buf) | ||
482 | { | ||
483 | drive_info_struct *drv = to_drv(dev); | ||
484 | struct ctlr_info *h = to_hba(drv->dev.parent); | ||
485 | char vendor[VENDOR_LEN + 1]; | ||
486 | unsigned long flags; | ||
487 | int ret = 0; | ||
488 | |||
489 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | ||
490 | if (h->busy_configuring) | ||
491 | ret = -EBUSY; | ||
492 | else | ||
493 | memcpy(vendor, drv->vendor, VENDOR_LEN + 1); | ||
494 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
495 | |||
496 | if (ret) | ||
497 | return ret; | ||
498 | else | ||
499 | return snprintf(buf, sizeof(vendor) + 1, "%s\n", drv->vendor); | ||
500 | } | ||
501 | DEVICE_ATTR(vendor, S_IRUGO, dev_show_vendor, NULL); | ||
502 | |||
503 | static ssize_t dev_show_model(struct device *dev, | ||
504 | struct device_attribute *attr, | ||
505 | char *buf) | ||
506 | { | ||
507 | drive_info_struct *drv = to_drv(dev); | ||
508 | struct ctlr_info *h = to_hba(drv->dev.parent); | ||
509 | char model[MODEL_LEN + 1]; | ||
510 | unsigned long flags; | ||
511 | int ret = 0; | ||
512 | |||
513 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | ||
514 | if (h->busy_configuring) | ||
515 | ret = -EBUSY; | ||
516 | else | ||
517 | memcpy(model, drv->model, MODEL_LEN + 1); | ||
518 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
519 | |||
520 | if (ret) | ||
521 | return ret; | ||
522 | else | ||
523 | return snprintf(buf, sizeof(model) + 1, "%s\n", drv->model); | ||
524 | } | ||
525 | DEVICE_ATTR(model, S_IRUGO, dev_show_model, NULL); | ||
526 | |||
527 | static ssize_t dev_show_rev(struct device *dev, | ||
528 | struct device_attribute *attr, | ||
529 | char *buf) | ||
530 | { | ||
531 | drive_info_struct *drv = to_drv(dev); | ||
532 | struct ctlr_info *h = to_hba(drv->dev.parent); | ||
533 | char rev[REV_LEN + 1]; | ||
534 | unsigned long flags; | ||
535 | int ret = 0; | ||
536 | |||
537 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | ||
538 | if (h->busy_configuring) | ||
539 | ret = -EBUSY; | ||
540 | else | ||
541 | memcpy(rev, drv->rev, REV_LEN + 1); | ||
542 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
543 | |||
544 | if (ret) | ||
545 | return ret; | ||
546 | else | ||
547 | return snprintf(buf, sizeof(rev) + 1, "%s\n", drv->rev); | ||
548 | } | ||
549 | DEVICE_ATTR(rev, S_IRUGO, dev_show_rev, NULL); | ||
550 | |||
551 | static struct attribute *cciss_dev_attrs[] = { | ||
552 | &dev_attr_unique_id.attr, | ||
553 | &dev_attr_model.attr, | ||
554 | &dev_attr_vendor.attr, | ||
555 | &dev_attr_rev.attr, | ||
556 | NULL | ||
557 | }; | ||
558 | |||
559 | static struct attribute_group cciss_dev_attr_group = { | ||
560 | .attrs = cciss_dev_attrs, | ||
561 | }; | ||
562 | |||
563 | static struct attribute_group *cciss_dev_attr_groups[] = { | ||
564 | &cciss_dev_attr_group, | ||
565 | NULL | ||
566 | }; | ||
567 | |||
568 | static struct device_type cciss_dev_type = { | ||
569 | .name = "cciss_device", | ||
570 | .groups = cciss_dev_attr_groups, | ||
571 | }; | ||
572 | |||
573 | static struct bus_type cciss_bus_type = { | ||
574 | .name = "cciss", | ||
575 | }; | ||
576 | |||
577 | |||
578 | /* | ||
579 | * Initialize sysfs entry for each controller. This sets up and registers | ||
580 | * the 'cciss#' directory for each individual controller under | ||
581 | * /sys/bus/pci/devices/<dev>/. | ||
582 | */ | ||
583 | static int cciss_create_hba_sysfs_entry(struct ctlr_info *h) | ||
584 | { | ||
585 | device_initialize(&h->dev); | ||
586 | h->dev.type = &cciss_host_type; | ||
587 | h->dev.bus = &cciss_bus_type; | ||
588 | dev_set_name(&h->dev, "%s", h->devname); | ||
589 | h->dev.parent = &h->pdev->dev; | ||
590 | |||
591 | return device_add(&h->dev); | ||
592 | } | ||
593 | |||
594 | /* | ||
595 | * Remove sysfs entries for an hba. | ||
596 | */ | ||
597 | static void cciss_destroy_hba_sysfs_entry(struct ctlr_info *h) | ||
598 | { | ||
599 | device_del(&h->dev); | ||
600 | } | ||
601 | |||
602 | /* | ||
603 | * Initialize sysfs for each logical drive. This sets up and registers | ||
604 | * the 'c#d#' directory for each individual logical drive under | ||
605 | * /sys/bus/pci/devices/<dev/ccis#/. We also create a link from | ||
606 | * /sys/block/cciss!c#d# to this entry. | ||
607 | */ | ||
608 | static int cciss_create_ld_sysfs_entry(struct ctlr_info *h, | ||
609 | drive_info_struct *drv, | ||
610 | int drv_index) | ||
611 | { | ||
612 | device_initialize(&drv->dev); | ||
613 | drv->dev.type = &cciss_dev_type; | ||
614 | drv->dev.bus = &cciss_bus_type; | ||
615 | dev_set_name(&drv->dev, "c%dd%d", h->ctlr, drv_index); | ||
616 | drv->dev.parent = &h->dev; | ||
617 | return device_add(&drv->dev); | ||
618 | } | ||
619 | |||
620 | /* | ||
621 | * Remove sysfs entries for a logical drive. | ||
622 | */ | ||
623 | static void cciss_destroy_ld_sysfs_entry(drive_info_struct *drv) | ||
624 | { | ||
625 | device_del(&drv->dev); | ||
626 | } | ||
627 | |||
440 | /* | 628 | /* |
441 | * For operations that cannot sleep, a command block is allocated at init, | 629 | * For operations that cannot sleep, a command block is allocated at init, |
442 | * and managed by cmd_alloc() and cmd_free() using a simple bitmap to track | 630 | * and managed by cmd_alloc() and cmd_free() using a simple bitmap to track |
@@ -1332,6 +1520,45 @@ static void cciss_softirq_done(struct request *rq) | |||
1332 | spin_unlock_irqrestore(&h->lock, flags); | 1520 | spin_unlock_irqrestore(&h->lock, flags); |
1333 | } | 1521 | } |
1334 | 1522 | ||
1523 | /* This function gets the SCSI vendor, model, and revision of a logical drive | ||
1524 | * via the inquiry page 0. Model, vendor, and rev are set to empty strings if | ||
1525 | * they cannot be read. | ||
1526 | */ | ||
1527 | static void cciss_get_device_descr(int ctlr, int logvol, int withirq, | ||
1528 | char *vendor, char *model, char *rev) | ||
1529 | { | ||
1530 | int rc; | ||
1531 | InquiryData_struct *inq_buf; | ||
1532 | |||
1533 | *vendor = '\0'; | ||
1534 | *model = '\0'; | ||
1535 | *rev = '\0'; | ||
1536 | |||
1537 | inq_buf = kzalloc(sizeof(InquiryData_struct), GFP_KERNEL); | ||
1538 | if (!inq_buf) | ||
1539 | return; | ||
1540 | |||
1541 | if (withirq) | ||
1542 | rc = sendcmd_withirq(CISS_INQUIRY, ctlr, inq_buf, | ||
1543 | sizeof(InquiryData_struct), 1, logvol, | ||
1544 | 0, TYPE_CMD); | ||
1545 | else | ||
1546 | rc = sendcmd(CISS_INQUIRY, ctlr, inq_buf, | ||
1547 | sizeof(InquiryData_struct), 1, logvol, 0, NULL, | ||
1548 | TYPE_CMD); | ||
1549 | if (rc == IO_OK) { | ||
1550 | memcpy(vendor, &inq_buf->data_byte[8], VENDOR_LEN); | ||
1551 | vendor[VENDOR_LEN] = '\0'; | ||
1552 | memcpy(model, &inq_buf->data_byte[16], MODEL_LEN); | ||
1553 | model[MODEL_LEN] = '\0'; | ||
1554 | memcpy(rev, &inq_buf->data_byte[32], REV_LEN); | ||
1555 | rev[REV_LEN] = '\0'; | ||
1556 | } | ||
1557 | |||
1558 | kfree(inq_buf); | ||
1559 | return; | ||
1560 | } | ||
1561 | |||
1335 | /* This function gets the serial number of a logical drive via | 1562 | /* This function gets the serial number of a logical drive via |
1336 | * inquiry page 0x83. Serial no. is 16 bytes. If the serial | 1563 | * inquiry page 0x83. Serial no. is 16 bytes. If the serial |
1337 | * number cannot be had, for whatever reason, 16 bytes of 0xff | 1564 | * number cannot be had, for whatever reason, 16 bytes of 0xff |
@@ -1372,7 +1599,7 @@ static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk, | |||
1372 | disk->first_minor = drv_index << NWD_SHIFT; | 1599 | disk->first_minor = drv_index << NWD_SHIFT; |
1373 | disk->fops = &cciss_fops; | 1600 | disk->fops = &cciss_fops; |
1374 | disk->private_data = &h->drv[drv_index]; | 1601 | disk->private_data = &h->drv[drv_index]; |
1375 | disk->driverfs_dev = &h->pdev->dev; | 1602 | disk->driverfs_dev = &h->drv[drv_index].dev; |
1376 | 1603 | ||
1377 | /* Set up queue information */ | 1604 | /* Set up queue information */ |
1378 | blk_queue_bounce_limit(disk->queue, h->pdev->dma_mask); | 1605 | blk_queue_bounce_limit(disk->queue, h->pdev->dma_mask); |
@@ -1463,6 +1690,8 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time) | |||
1463 | drvinfo->block_size = block_size; | 1690 | drvinfo->block_size = block_size; |
1464 | drvinfo->nr_blocks = total_size + 1; | 1691 | drvinfo->nr_blocks = total_size + 1; |
1465 | 1692 | ||
1693 | cciss_get_device_descr(ctlr, drv_index, 1, drvinfo->vendor, | ||
1694 | drvinfo->model, drvinfo->rev); | ||
1466 | cciss_get_serial_no(ctlr, drv_index, 1, drvinfo->serial_no, | 1695 | cciss_get_serial_no(ctlr, drv_index, 1, drvinfo->serial_no, |
1467 | sizeof(drvinfo->serial_no)); | 1696 | sizeof(drvinfo->serial_no)); |
1468 | 1697 | ||
@@ -1512,6 +1741,9 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time) | |||
1512 | h->drv[drv_index].cylinders = drvinfo->cylinders; | 1741 | h->drv[drv_index].cylinders = drvinfo->cylinders; |
1513 | h->drv[drv_index].raid_level = drvinfo->raid_level; | 1742 | h->drv[drv_index].raid_level = drvinfo->raid_level; |
1514 | memcpy(h->drv[drv_index].serial_no, drvinfo->serial_no, 16); | 1743 | memcpy(h->drv[drv_index].serial_no, drvinfo->serial_no, 16); |
1744 | memcpy(h->drv[drv_index].vendor, drvinfo->vendor, VENDOR_LEN + 1); | ||
1745 | memcpy(h->drv[drv_index].model, drvinfo->model, MODEL_LEN + 1); | ||
1746 | memcpy(h->drv[drv_index].rev, drvinfo->rev, REV_LEN + 1); | ||
1515 | 1747 | ||
1516 | ++h->num_luns; | 1748 | ++h->num_luns; |
1517 | disk = h->gendisk[drv_index]; | 1749 | disk = h->gendisk[drv_index]; |
@@ -1586,6 +1818,8 @@ static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid, int controller_node) | |||
1586 | } | 1818 | } |
1587 | } | 1819 | } |
1588 | h->drv[drv_index].LunID = lunid; | 1820 | h->drv[drv_index].LunID = lunid; |
1821 | if (cciss_create_ld_sysfs_entry(h, &h->drv[drv_index], drv_index)) | ||
1822 | goto err_free_disk; | ||
1589 | 1823 | ||
1590 | /* Don't need to mark this busy because nobody */ | 1824 | /* Don't need to mark this busy because nobody */ |
1591 | /* else knows about this disk yet to contend */ | 1825 | /* else knows about this disk yet to contend */ |
@@ -1593,6 +1827,11 @@ static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid, int controller_node) | |||
1593 | h->drv[drv_index].busy_configuring = 0; | 1827 | h->drv[drv_index].busy_configuring = 0; |
1594 | wmb(); | 1828 | wmb(); |
1595 | return drv_index; | 1829 | return drv_index; |
1830 | |||
1831 | err_free_disk: | ||
1832 | put_disk(h->gendisk[drv_index]); | ||
1833 | h->gendisk[drv_index] = NULL; | ||
1834 | return -1; | ||
1596 | } | 1835 | } |
1597 | 1836 | ||
1598 | /* This is for the special case of a controller which | 1837 | /* This is for the special case of a controller which |
@@ -1713,6 +1952,7 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time) | |||
1713 | h->drv[i].busy_configuring = 1; | 1952 | h->drv[i].busy_configuring = 1; |
1714 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | 1953 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); |
1715 | return_code = deregister_disk(h, i, 1); | 1954 | return_code = deregister_disk(h, i, 1); |
1955 | cciss_destroy_ld_sysfs_entry(&h->drv[i]); | ||
1716 | h->drv[i].busy_configuring = 0; | 1956 | h->drv[i].busy_configuring = 0; |
1717 | } | 1957 | } |
1718 | } | 1958 | } |
@@ -3719,12 +3959,15 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
3719 | INIT_HLIST_HEAD(&hba[i]->reqQ); | 3959 | INIT_HLIST_HEAD(&hba[i]->reqQ); |
3720 | 3960 | ||
3721 | if (cciss_pci_init(hba[i], pdev) != 0) | 3961 | if (cciss_pci_init(hba[i], pdev) != 0) |
3722 | goto clean1; | 3962 | goto clean0; |
3723 | 3963 | ||
3724 | sprintf(hba[i]->devname, "cciss%d", i); | 3964 | sprintf(hba[i]->devname, "cciss%d", i); |
3725 | hba[i]->ctlr = i; | 3965 | hba[i]->ctlr = i; |
3726 | hba[i]->pdev = pdev; | 3966 | hba[i]->pdev = pdev; |
3727 | 3967 | ||
3968 | if (cciss_create_hba_sysfs_entry(hba[i])) | ||
3969 | goto clean0; | ||
3970 | |||
3728 | /* configure PCI DMA stuff */ | 3971 | /* configure PCI DMA stuff */ |
3729 | if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) | 3972 | if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) |
3730 | dac = 1; | 3973 | dac = 1; |
@@ -3868,6 +4111,8 @@ clean4: | |||
3868 | clean2: | 4111 | clean2: |
3869 | unregister_blkdev(hba[i]->major, hba[i]->devname); | 4112 | unregister_blkdev(hba[i]->major, hba[i]->devname); |
3870 | clean1: | 4113 | clean1: |
4114 | cciss_destroy_hba_sysfs_entry(hba[i]); | ||
4115 | clean0: | ||
3871 | hba[i]->busy_initializing = 0; | 4116 | hba[i]->busy_initializing = 0; |
3872 | /* cleanup any queues that may have been initialized */ | 4117 | /* cleanup any queues that may have been initialized */ |
3873 | for (j=0; j <= hba[i]->highest_lun; j++){ | 4118 | for (j=0; j <= hba[i]->highest_lun; j++){ |
@@ -3978,6 +4223,7 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev) | |||
3978 | */ | 4223 | */ |
3979 | pci_release_regions(pdev); | 4224 | pci_release_regions(pdev); |
3980 | pci_set_drvdata(pdev, NULL); | 4225 | pci_set_drvdata(pdev, NULL); |
4226 | cciss_destroy_hba_sysfs_entry(hba[i]); | ||
3981 | free_hba(i); | 4227 | free_hba(i); |
3982 | } | 4228 | } |
3983 | 4229 | ||
@@ -3995,6 +4241,8 @@ static struct pci_driver cciss_pci_driver = { | |||
3995 | */ | 4241 | */ |
3996 | static int __init cciss_init(void) | 4242 | static int __init cciss_init(void) |
3997 | { | 4243 | { |
4244 | int err; | ||
4245 | |||
3998 | /* | 4246 | /* |
3999 | * The hardware requires that commands are aligned on a 64-bit | 4247 | * The hardware requires that commands are aligned on a 64-bit |
4000 | * boundary. Given that we use pci_alloc_consistent() to allocate an | 4248 | * boundary. Given that we use pci_alloc_consistent() to allocate an |
@@ -4004,8 +4252,20 @@ static int __init cciss_init(void) | |||
4004 | 4252 | ||
4005 | printk(KERN_INFO DRIVER_NAME "\n"); | 4253 | printk(KERN_INFO DRIVER_NAME "\n"); |
4006 | 4254 | ||
4255 | err = bus_register(&cciss_bus_type); | ||
4256 | if (err) | ||
4257 | return err; | ||
4258 | |||
4007 | /* Register for our PCI devices */ | 4259 | /* Register for our PCI devices */ |
4008 | return pci_register_driver(&cciss_pci_driver); | 4260 | err = pci_register_driver(&cciss_pci_driver); |
4261 | if (err) | ||
4262 | goto err_bus_register; | ||
4263 | |||
4264 | return 0; | ||
4265 | |||
4266 | err_bus_register: | ||
4267 | bus_unregister(&cciss_bus_type); | ||
4268 | return err; | ||
4009 | } | 4269 | } |
4010 | 4270 | ||
4011 | static void __exit cciss_cleanup(void) | 4271 | static void __exit cciss_cleanup(void) |
@@ -4022,6 +4282,7 @@ static void __exit cciss_cleanup(void) | |||
4022 | } | 4282 | } |
4023 | } | 4283 | } |
4024 | remove_proc_entry("driver/cciss", NULL); | 4284 | remove_proc_entry("driver/cciss", NULL); |
4285 | bus_unregister(&cciss_bus_type); | ||
4025 | } | 4286 | } |
4026 | 4287 | ||
4027 | static void fail_all_cmds(unsigned long ctlr) | 4288 | static void fail_all_cmds(unsigned long ctlr) |
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h index 703e08038fb9..dd1926d8cd97 100644 --- a/drivers/block/cciss.h +++ b/drivers/block/cciss.h | |||
@@ -12,6 +12,10 @@ | |||
12 | #define IO_OK 0 | 12 | #define IO_OK 0 |
13 | #define IO_ERROR 1 | 13 | #define IO_ERROR 1 |
14 | 14 | ||
15 | #define VENDOR_LEN 8 | ||
16 | #define MODEL_LEN 16 | ||
17 | #define REV_LEN 4 | ||
18 | |||
15 | struct ctlr_info; | 19 | struct ctlr_info; |
16 | typedef struct ctlr_info ctlr_info_t; | 20 | typedef struct ctlr_info ctlr_info_t; |
17 | 21 | ||
@@ -34,13 +38,18 @@ typedef struct _drive_info_struct | |||
34 | int cylinders; | 38 | int cylinders; |
35 | int raid_level; /* set to -1 to indicate that | 39 | int raid_level; /* set to -1 to indicate that |
36 | * the drive is not in use/configured | 40 | * the drive is not in use/configured |
37 | */ | 41 | */ |
38 | int busy_configuring; /*This is set when the drive is being removed | 42 | int busy_configuring; /* This is set when a drive is being removed |
39 | *to prevent it from being opened or it's queue | 43 | * to prevent it from being opened or it's |
40 | *from being started. | 44 | * queue from being started. |
41 | */ | 45 | */ |
42 | __u8 serial_no[16]; /* from inquiry page 0x83, */ | 46 | struct device dev; |
43 | /* not necc. null terminated. */ | 47 | __u8 serial_no[16]; /* from inquiry page 0x83, |
48 | * not necc. null terminated. | ||
49 | */ | ||
50 | char vendor[VENDOR_LEN + 1]; /* SCSI vendor string */ | ||
51 | char model[MODEL_LEN + 1]; /* SCSI model string */ | ||
52 | char rev[REV_LEN + 1]; /* SCSI revision string */ | ||
44 | } drive_info_struct; | 53 | } drive_info_struct; |
45 | 54 | ||
46 | #ifdef CONFIG_CISS_SCSI_TAPE | 55 | #ifdef CONFIG_CISS_SCSI_TAPE |
@@ -123,6 +132,7 @@ struct ctlr_info | |||
123 | unsigned char alive; | 132 | unsigned char alive; |
124 | struct completion *rescan_wait; | 133 | struct completion *rescan_wait; |
125 | struct task_struct *cciss_scan_thread; | 134 | struct task_struct *cciss_scan_thread; |
135 | struct device dev; | ||
126 | }; | 136 | }; |
127 | 137 | ||
128 | /* Defining the diffent access_menthods */ | 138 | /* Defining the diffent access_menthods */ |