diff options
-rw-r--r-- | drivers/block/cciss.c | 473 |
1 files changed, 169 insertions, 304 deletions
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index f9f10a15d253..08255644e80a 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -159,7 +159,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, | |||
159 | static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo); | 159 | static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo); |
160 | 160 | ||
161 | static int cciss_revalidate(struct gendisk *disk); | 161 | static int cciss_revalidate(struct gendisk *disk); |
162 | static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk); | 162 | static int rebuild_lun_table(ctlr_info_t *h, int first_time); |
163 | static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, | 163 | static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, |
164 | int clear_all); | 164 | int clear_all); |
165 | 165 | ||
@@ -171,7 +171,6 @@ static void cciss_geometry_inquiry(int ctlr, int logvol, | |||
171 | int withirq, sector_t total_size, | 171 | int withirq, sector_t total_size, |
172 | unsigned int block_size, InquiryData_struct *inq_buff, | 172 | unsigned int block_size, InquiryData_struct *inq_buff, |
173 | drive_info_struct *drv); | 173 | drive_info_struct *drv); |
174 | static void cciss_getgeometry(int cntl_num); | ||
175 | static void __devinit cciss_interrupt_mode(ctlr_info_t *, struct pci_dev *, | 174 | static void __devinit cciss_interrupt_mode(ctlr_info_t *, struct pci_dev *, |
176 | __u32); | 175 | __u32); |
177 | static void start_io(ctlr_info_t *h); | 176 | static void start_io(ctlr_info_t *h); |
@@ -929,8 +928,10 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, | |||
929 | return 0; | 928 | return 0; |
930 | } | 929 | } |
931 | 930 | ||
931 | case CCISS_DEREGDISK: | ||
932 | case CCISS_REGNEWD: | ||
932 | case CCISS_REVALIDVOLS: | 933 | case CCISS_REVALIDVOLS: |
933 | return rebuild_lun_table(host, NULL); | 934 | return rebuild_lun_table(host, 0); |
934 | 935 | ||
935 | case CCISS_GETLUNINFO:{ | 936 | case CCISS_GETLUNINFO:{ |
936 | LogvolInfo_struct luninfo; | 937 | LogvolInfo_struct luninfo; |
@@ -943,12 +944,6 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, | |||
943 | return -EFAULT; | 944 | return -EFAULT; |
944 | return 0; | 945 | return 0; |
945 | } | 946 | } |
946 | case CCISS_DEREGDISK: | ||
947 | return rebuild_lun_table(host, disk); | ||
948 | |||
949 | case CCISS_REGNEWD: | ||
950 | return rebuild_lun_table(host, NULL); | ||
951 | |||
952 | case CCISS_PASSTHRU: | 947 | case CCISS_PASSTHRU: |
953 | { | 948 | { |
954 | IOCTL_Command_struct iocommand; | 949 | IOCTL_Command_struct iocommand; |
@@ -1361,6 +1356,42 @@ static void cciss_get_serial_no(int ctlr, int logvol, int withirq, | |||
1361 | return; | 1356 | return; |
1362 | } | 1357 | } |
1363 | 1358 | ||
1359 | static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk, | ||
1360 | int drv_index) | ||
1361 | { | ||
1362 | disk->queue = blk_init_queue(do_cciss_request, &h->lock); | ||
1363 | sprintf(disk->disk_name, "cciss/c%dd%d", h->ctlr, drv_index); | ||
1364 | disk->major = h->major; | ||
1365 | disk->first_minor = drv_index << NWD_SHIFT; | ||
1366 | disk->fops = &cciss_fops; | ||
1367 | disk->private_data = &h->drv[drv_index]; | ||
1368 | |||
1369 | /* Set up queue information */ | ||
1370 | blk_queue_bounce_limit(disk->queue, h->pdev->dma_mask); | ||
1371 | |||
1372 | /* This is a hardware imposed limit. */ | ||
1373 | blk_queue_max_hw_segments(disk->queue, MAXSGENTRIES); | ||
1374 | |||
1375 | /* This is a limit in the driver and could be eliminated. */ | ||
1376 | blk_queue_max_phys_segments(disk->queue, MAXSGENTRIES); | ||
1377 | |||
1378 | blk_queue_max_sectors(disk->queue, h->cciss_max_sectors); | ||
1379 | |||
1380 | blk_queue_softirq_done(disk->queue, cciss_softirq_done); | ||
1381 | |||
1382 | disk->queue->queuedata = h; | ||
1383 | |||
1384 | blk_queue_hardsect_size(disk->queue, | ||
1385 | h->drv[drv_index].block_size); | ||
1386 | |||
1387 | /* Make sure all queue data is written out before */ | ||
1388 | /* setting h->drv[drv_index].queue, as setting this */ | ||
1389 | /* allows the interrupt handler to start the queue */ | ||
1390 | wmb(); | ||
1391 | h->drv[drv_index].queue = disk->queue; | ||
1392 | add_disk(disk); | ||
1393 | } | ||
1394 | |||
1364 | /* This function will check the usage_count of the drive to be updated/added. | 1395 | /* This function will check the usage_count of the drive to be updated/added. |
1365 | * If the usage_count is zero and it is a heretofore unknown drive, or, | 1396 | * If the usage_count is zero and it is a heretofore unknown drive, or, |
1366 | * the drive's capacity, geometry, or serial number has changed, | 1397 | * the drive's capacity, geometry, or serial number has changed, |
@@ -1371,7 +1402,7 @@ static void cciss_get_serial_no(int ctlr, int logvol, int withirq, | |||
1371 | * is also the controller node. Any changes to disk 0 will show up on | 1402 | * is also the controller node. Any changes to disk 0 will show up on |
1372 | * the next reboot. | 1403 | * the next reboot. |
1373 | */ | 1404 | */ |
1374 | static void cciss_update_drive_info(int ctlr, int drv_index) | 1405 | static void cciss_update_drive_info(int ctlr, int drv_index, int first_time) |
1375 | { | 1406 | { |
1376 | ctlr_info_t *h = hba[ctlr]; | 1407 | ctlr_info_t *h = hba[ctlr]; |
1377 | struct gendisk *disk; | 1408 | struct gendisk *disk; |
@@ -1381,6 +1412,7 @@ static void cciss_update_drive_info(int ctlr, int drv_index) | |||
1381 | unsigned long flags = 0; | 1412 | unsigned long flags = 0; |
1382 | int ret = 0; | 1413 | int ret = 0; |
1383 | drive_info_struct *drvinfo; | 1414 | drive_info_struct *drvinfo; |
1415 | int was_only_controller_node; | ||
1384 | 1416 | ||
1385 | /* Get information about the disk and modify the driver structure */ | 1417 | /* Get information about the disk and modify the driver structure */ |
1386 | inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); | 1418 | inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); |
@@ -1388,6 +1420,13 @@ static void cciss_update_drive_info(int ctlr, int drv_index) | |||
1388 | if (inq_buff == NULL || drvinfo == NULL) | 1420 | if (inq_buff == NULL || drvinfo == NULL) |
1389 | goto mem_msg; | 1421 | goto mem_msg; |
1390 | 1422 | ||
1423 | /* See if we're trying to update the "controller node" | ||
1424 | * this will happen the when the first logical drive gets | ||
1425 | * created by ACU. | ||
1426 | */ | ||
1427 | was_only_controller_node = (drv_index == 0 && | ||
1428 | h->drv[0].raid_level == -1); | ||
1429 | |||
1391 | /* testing to see if 16-byte CDBs are already being used */ | 1430 | /* testing to see if 16-byte CDBs are already being used */ |
1392 | if (h->cciss_read == CCISS_READ_16) { | 1431 | if (h->cciss_read == CCISS_READ_16) { |
1393 | cciss_read_capacity_16(h->ctlr, drv_index, 1, | 1432 | cciss_read_capacity_16(h->ctlr, drv_index, 1, |
@@ -1427,25 +1466,26 @@ static void cciss_update_drive_info(int ctlr, int drv_index) | |||
1427 | drvinfo->nr_blocks == h->drv[drv_index].nr_blocks && | 1466 | drvinfo->nr_blocks == h->drv[drv_index].nr_blocks && |
1428 | drvinfo->heads == h->drv[drv_index].heads && | 1467 | drvinfo->heads == h->drv[drv_index].heads && |
1429 | drvinfo->sectors == h->drv[drv_index].sectors && | 1468 | drvinfo->sectors == h->drv[drv_index].sectors && |
1430 | drvinfo->cylinders == h->drv[drv_index].cylinders)) { | 1469 | drvinfo->cylinders == h->drv[drv_index].cylinders)) |
1431 | /* The disk is unchanged, nothing to update */ | 1470 | /* The disk is unchanged, nothing to update */ |
1432 | goto freeret; | 1471 | goto freeret; |
1433 | } | ||
1434 | 1472 | ||
1435 | /* Not the same disk, or something's changed, so we need to */ | 1473 | /* If we get here it's not the same disk, or something's changed, |
1436 | /* deregister it, and re-register it, if it's not in use. */ | 1474 | * so we need to * deregister it, and re-register it, if it's not |
1437 | 1475 | * in use. | |
1438 | /* if the disk already exists then deregister it before proceeding */ | 1476 | * If the disk already exists then deregister it before proceeding |
1439 | /* (unless it's the first disk (for the controller node). */ | 1477 | * (unless it's the first disk (for the controller node). |
1478 | */ | ||
1440 | if (h->drv[drv_index].raid_level != -1 && drv_index != 0) { | 1479 | if (h->drv[drv_index].raid_level != -1 && drv_index != 0) { |
1441 | printk(KERN_WARNING "disk %d has changed.\n", drv_index); | 1480 | printk(KERN_WARNING "disk %d has changed.\n", drv_index); |
1442 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | 1481 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); |
1443 | h->drv[drv_index].busy_configuring = 1; | 1482 | h->drv[drv_index].busy_configuring = 1; |
1444 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | 1483 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); |
1445 | 1484 | ||
1446 | /* deregister_disk sets h->drv[drv_index].queue = NULL */ | 1485 | /* deregister_disk sets h->drv[drv_index].queue = NULL |
1447 | /* which keeps the interrupt handler from starting */ | 1486 | * which keeps the interrupt handler from starting |
1448 | /* the queue. */ | 1487 | * the queue. |
1488 | */ | ||
1449 | ret = deregister_disk(h->gendisk[drv_index], | 1489 | ret = deregister_disk(h->gendisk[drv_index], |
1450 | &h->drv[drv_index], 0); | 1490 | &h->drv[drv_index], 0); |
1451 | h->drv[drv_index].busy_configuring = 0; | 1491 | h->drv[drv_index].busy_configuring = 0; |
@@ -1455,8 +1495,9 @@ static void cciss_update_drive_info(int ctlr, int drv_index) | |||
1455 | if (ret) | 1495 | if (ret) |
1456 | goto freeret; | 1496 | goto freeret; |
1457 | 1497 | ||
1458 | /* Save the new information from cciss_geometry_inquiry */ | 1498 | /* Save the new information from cciss_geometry_inquiry |
1459 | /* and serial number inquiry. */ | 1499 | * and serial number inquiry. |
1500 | */ | ||
1460 | h->drv[drv_index].block_size = drvinfo->block_size; | 1501 | h->drv[drv_index].block_size = drvinfo->block_size; |
1461 | h->drv[drv_index].nr_blocks = drvinfo->nr_blocks; | 1502 | h->drv[drv_index].nr_blocks = drvinfo->nr_blocks; |
1462 | h->drv[drv_index].heads = drvinfo->heads; | 1503 | h->drv[drv_index].heads = drvinfo->heads; |
@@ -1469,46 +1510,20 @@ static void cciss_update_drive_info(int ctlr, int drv_index) | |||
1469 | disk = h->gendisk[drv_index]; | 1510 | disk = h->gendisk[drv_index]; |
1470 | set_capacity(disk, h->drv[drv_index].nr_blocks); | 1511 | set_capacity(disk, h->drv[drv_index].nr_blocks); |
1471 | 1512 | ||
1472 | /* if it's the controller (if drv_index == 0) it's already added */ | 1513 | /* If it's not disk 0 (drv_index != 0) |
1473 | if (drv_index) { | 1514 | * or if it was disk 0, but there was previously |
1474 | disk->queue = blk_init_queue(do_cciss_request, &h->lock); | 1515 | * no actual corresponding configured logical drive |
1475 | sprintf(disk->disk_name, "cciss/c%dd%d", ctlr, drv_index); | 1516 | * (raid_leve == -1) then we want to update the |
1476 | disk->major = h->major; | 1517 | * logical drive's information. |
1477 | disk->first_minor = drv_index << NWD_SHIFT; | 1518 | */ |
1478 | disk->fops = &cciss_fops; | 1519 | if (drv_index || first_time) |
1479 | disk->private_data = &h->drv[drv_index]; | 1520 | cciss_add_disk(h, disk, drv_index); |
1480 | |||
1481 | /* Set up queue information */ | ||
1482 | blk_queue_bounce_limit(disk->queue, hba[ctlr]->pdev->dma_mask); | ||
1483 | |||
1484 | /* This is a hardware imposed limit. */ | ||
1485 | blk_queue_max_hw_segments(disk->queue, MAXSGENTRIES); | ||
1486 | |||
1487 | /* This is a limit in the driver and could be eliminated. */ | ||
1488 | blk_queue_max_phys_segments(disk->queue, MAXSGENTRIES); | ||
1489 | |||
1490 | blk_queue_max_sectors(disk->queue, h->cciss_max_sectors); | ||
1491 | |||
1492 | blk_queue_softirq_done(disk->queue, cciss_softirq_done); | ||
1493 | |||
1494 | disk->queue->queuedata = hba[ctlr]; | ||
1495 | |||
1496 | blk_queue_hardsect_size(disk->queue, | ||
1497 | hba[ctlr]->drv[drv_index].block_size); | ||
1498 | |||
1499 | /* Make sure all queue data is written out before */ | ||
1500 | /* setting h->drv[drv_index].queue, as setting this */ | ||
1501 | /* allows the interrupt handler to start the queue */ | ||
1502 | wmb(); | ||
1503 | h->drv[drv_index].queue = disk->queue; | ||
1504 | add_disk(disk); | ||
1505 | } | ||
1506 | 1521 | ||
1507 | freeret: | 1522 | freeret: |
1508 | kfree(inq_buff); | 1523 | kfree(inq_buff); |
1509 | kfree(drvinfo); | 1524 | kfree(drvinfo); |
1510 | return; | 1525 | return; |
1511 | mem_msg: | 1526 | mem_msg: |
1512 | printk(KERN_ERR "cciss: out of memory\n"); | 1527 | printk(KERN_ERR "cciss: out of memory\n"); |
1513 | goto freeret; | 1528 | goto freeret; |
1514 | } | 1529 | } |
@@ -1533,6 +1548,73 @@ static int cciss_find_free_drive_index(int ctlr) | |||
1533 | return -1; | 1548 | return -1; |
1534 | } | 1549 | } |
1535 | 1550 | ||
1551 | /* cciss_add_gendisk finds a free hba[]->drv structure | ||
1552 | * and allocates a gendisk if needed, and sets the lunid | ||
1553 | * in the drvinfo structure. It returns the index into | ||
1554 | * the ->drv[] array, or -1 if none are free. | ||
1555 | * is_controller_node indicates whether highest_lun should | ||
1556 | * count this disk, or if it's only being added to provide | ||
1557 | * a means to talk to the controller in case no logical | ||
1558 | * drives have yet been configured. | ||
1559 | */ | ||
1560 | static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid) | ||
1561 | { | ||
1562 | int drv_index; | ||
1563 | |||
1564 | drv_index = cciss_find_free_drive_index(h->ctlr); | ||
1565 | if (drv_index == -1) | ||
1566 | return -1; | ||
1567 | /*Check if the gendisk needs to be allocated */ | ||
1568 | if (!h->gendisk[drv_index]) { | ||
1569 | h->gendisk[drv_index] = | ||
1570 | alloc_disk(1 << NWD_SHIFT); | ||
1571 | if (!h->gendisk[drv_index]) { | ||
1572 | printk(KERN_ERR "cciss%d: could not " | ||
1573 | "allocate a new disk %d\n", | ||
1574 | h->ctlr, drv_index); | ||
1575 | return -1; | ||
1576 | } | ||
1577 | } | ||
1578 | h->drv[drv_index].LunID = lunid; | ||
1579 | |||
1580 | /* Don't need to mark this busy because nobody */ | ||
1581 | /* else knows about this disk yet to contend */ | ||
1582 | /* for access to it. */ | ||
1583 | h->drv[drv_index].busy_configuring = 0; | ||
1584 | wmb(); | ||
1585 | return drv_index; | ||
1586 | } | ||
1587 | |||
1588 | /* This is for the special case of a controller which | ||
1589 | * has no logical drives. In this case, we still need | ||
1590 | * to register a disk so the controller can be accessed | ||
1591 | * by the Array Config Utility. | ||
1592 | */ | ||
1593 | static void cciss_add_controller_node(ctlr_info_t *h) | ||
1594 | { | ||
1595 | struct gendisk *disk; | ||
1596 | int drv_index; | ||
1597 | |||
1598 | if (h->gendisk[0] != NULL) /* already did this? Then bail. */ | ||
1599 | return; | ||
1600 | |||
1601 | drv_index = cciss_add_gendisk(h, 0); | ||
1602 | if (drv_index == -1) { | ||
1603 | printk(KERN_WARNING "cciss%d: could not " | ||
1604 | "add disk 0.\n", h->ctlr); | ||
1605 | return; | ||
1606 | } | ||
1607 | h->drv[drv_index].block_size = 512; | ||
1608 | h->drv[drv_index].nr_blocks = 0; | ||
1609 | h->drv[drv_index].heads = 0; | ||
1610 | h->drv[drv_index].sectors = 0; | ||
1611 | h->drv[drv_index].cylinders = 0; | ||
1612 | h->drv[drv_index].raid_level = -1; | ||
1613 | memset(h->drv[drv_index].serial_no, 0, 16); | ||
1614 | disk = h->gendisk[drv_index]; | ||
1615 | cciss_add_disk(h, disk, drv_index); | ||
1616 | } | ||
1617 | |||
1536 | /* This function will add and remove logical drives from the Logical | 1618 | /* This function will add and remove logical drives from the Logical |
1537 | * drive array of the controller and maintain persistency of ordering | 1619 | * drive array of the controller and maintain persistency of ordering |
1538 | * so that mount points are preserved until the next reboot. This allows | 1620 | * so that mount points are preserved until the next reboot. This allows |
@@ -1540,10 +1622,8 @@ static int cciss_find_free_drive_index(int ctlr) | |||
1540 | * without a re-ordering of those drives. | 1622 | * without a re-ordering of those drives. |
1541 | * INPUT | 1623 | * INPUT |
1542 | * h = The controller to perform the operations on | 1624 | * h = The controller to perform the operations on |
1543 | * del_disk = The disk to remove if specified. If the value given | ||
1544 | * is NULL then no disk is removed. | ||
1545 | */ | 1625 | */ |
1546 | static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) | 1626 | static int rebuild_lun_table(ctlr_info_t *h, int first_time) |
1547 | { | 1627 | { |
1548 | int ctlr = h->ctlr; | 1628 | int ctlr = h->ctlr; |
1549 | int num_luns; | 1629 | int num_luns; |
@@ -1556,6 +1636,9 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) | |||
1556 | __u32 lunid = 0; | 1636 | __u32 lunid = 0; |
1557 | unsigned long flags; | 1637 | unsigned long flags; |
1558 | 1638 | ||
1639 | if (!capable(CAP_SYS_RAWIO)) | ||
1640 | return -EPERM; | ||
1641 | |||
1559 | /* Set busy_configuring flag for this operation */ | 1642 | /* Set busy_configuring flag for this operation */ |
1560 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | 1643 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); |
1561 | if (h->busy_configuring) { | 1644 | if (h->busy_configuring) { |
@@ -1565,9 +1648,6 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) | |||
1565 | h->busy_configuring = 1; | 1648 | h->busy_configuring = 1; |
1566 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | 1649 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); |
1567 | 1650 | ||
1568 | if (!capable(CAP_SYS_RAWIO)) | ||
1569 | return -EPERM; | ||
1570 | |||
1571 | ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL); | 1651 | ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL); |
1572 | if (ld_buff == NULL) | 1652 | if (ld_buff == NULL) |
1573 | goto mem_msg; | 1653 | goto mem_msg; |
@@ -1593,10 +1673,14 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) | |||
1593 | " this driver.\n"); | 1673 | " this driver.\n"); |
1594 | } | 1674 | } |
1595 | 1675 | ||
1596 | /* Compare controller drive array to driver's drive array */ | 1676 | if (num_luns == 0) |
1597 | /* to see if any drives are missing on the controller due */ | 1677 | cciss_add_controller_node(h); |
1598 | /* to action of Array Config Utility (user deletes drive) */ | 1678 | |
1599 | /* and deregister logical drives which have disappeared. */ | 1679 | /* Compare controller drive array to driver's drive array |
1680 | * to see if any drives are missing on the controller due | ||
1681 | * to action of Array Config Utility (user deletes drive) | ||
1682 | * and deregister logical drives which have disappeared. | ||
1683 | */ | ||
1600 | for (i = 0; i <= h->highest_lun; i++) { | 1684 | for (i = 0; i <= h->highest_lun; i++) { |
1601 | int j; | 1685 | int j; |
1602 | drv_found = 0; | 1686 | drv_found = 0; |
@@ -1648,34 +1732,14 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) | |||
1648 | 1732 | ||
1649 | /* check if the drive was found already in the array */ | 1733 | /* check if the drive was found already in the array */ |
1650 | if (!drv_found) { | 1734 | if (!drv_found) { |
1651 | drv_index = cciss_find_free_drive_index(ctlr); | 1735 | drv_index = cciss_add_gendisk(h, lunid); |
1652 | if (drv_index == -1) | 1736 | if (drv_index == -1) |
1653 | goto freeret; | 1737 | goto freeret; |
1654 | /*Check if the gendisk needs to be allocated */ | ||
1655 | if (!h->gendisk[drv_index]) { | ||
1656 | h->gendisk[drv_index] = | ||
1657 | alloc_disk(1 << NWD_SHIFT); | ||
1658 | if (!h->gendisk[drv_index]){ | ||
1659 | printk(KERN_ERR "cciss: could not " | ||
1660 | "allocate new disk %d\n", | ||
1661 | drv_index); | ||
1662 | goto mem_msg; | ||
1663 | } | ||
1664 | } | ||
1665 | h->drv[drv_index].LunID = lunid; | ||
1666 | |||
1667 | /* Don't need to mark this busy because nobody | ||
1668 | * else knows about this disk yet to contend | ||
1669 | * for access to it. | ||
1670 | */ | ||
1671 | h->drv[drv_index].busy_configuring = 0; | ||
1672 | wmb(); | ||
1673 | |||
1674 | } | 1738 | } |
1675 | cciss_update_drive_info(ctlr, drv_index); | 1739 | cciss_update_drive_info(ctlr, drv_index, first_time); |
1676 | } /* end for */ | 1740 | } /* end for */ |
1677 | 1741 | ||
1678 | freeret: | 1742 | freeret: |
1679 | kfree(ld_buff); | 1743 | kfree(ld_buff); |
1680 | h->busy_configuring = 0; | 1744 | h->busy_configuring = 0; |
1681 | /* We return -1 here to tell the ACU that we have registered/updated | 1745 | /* We return -1 here to tell the ACU that we have registered/updated |
@@ -1683,7 +1747,7 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) | |||
1683 | * additional times. | 1747 | * additional times. |
1684 | */ | 1748 | */ |
1685 | return -1; | 1749 | return -1; |
1686 | mem_msg: | 1750 | mem_msg: |
1687 | printk(KERN_ERR "cciss: out of memory\n"); | 1751 | printk(KERN_ERR "cciss: out of memory\n"); |
1688 | h->busy_configuring = 0; | 1752 | h->busy_configuring = 0; |
1689 | goto freeret; | 1753 | goto freeret; |
@@ -3288,139 +3352,9 @@ err_out_free_res: | |||
3288 | return err; | 3352 | return err; |
3289 | } | 3353 | } |
3290 | 3354 | ||
3291 | /* | 3355 | /* Function to find the first free pointer into our hba[] array |
3292 | * Gets information about the local volumes attached to the controller. | 3356 | * Returns -1 if no free entries are left. |
3293 | */ | 3357 | */ |
3294 | static void cciss_getgeometry(int cntl_num) | ||
3295 | { | ||
3296 | ReportLunData_struct *ld_buff; | ||
3297 | InquiryData_struct *inq_buff; | ||
3298 | int return_code; | ||
3299 | int i; | ||
3300 | int listlength = 0; | ||
3301 | __u32 lunid = 0; | ||
3302 | unsigned block_size; | ||
3303 | sector_t total_size; | ||
3304 | |||
3305 | ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL); | ||
3306 | if (ld_buff == NULL) { | ||
3307 | printk(KERN_ERR "cciss: out of memory\n"); | ||
3308 | return; | ||
3309 | } | ||
3310 | inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); | ||
3311 | if (inq_buff == NULL) { | ||
3312 | printk(KERN_ERR "cciss: out of memory\n"); | ||
3313 | kfree(ld_buff); | ||
3314 | return; | ||
3315 | } | ||
3316 | /* Get the firmware version */ | ||
3317 | return_code = sendcmd(CISS_INQUIRY, cntl_num, inq_buff, | ||
3318 | sizeof(InquiryData_struct), 0, 0, 0, NULL, | ||
3319 | TYPE_CMD); | ||
3320 | if (return_code == IO_OK) { | ||
3321 | hba[cntl_num]->firm_ver[0] = inq_buff->data_byte[32]; | ||
3322 | hba[cntl_num]->firm_ver[1] = inq_buff->data_byte[33]; | ||
3323 | hba[cntl_num]->firm_ver[2] = inq_buff->data_byte[34]; | ||
3324 | hba[cntl_num]->firm_ver[3] = inq_buff->data_byte[35]; | ||
3325 | } else { /* send command failed */ | ||
3326 | |||
3327 | printk(KERN_WARNING "cciss: unable to determine firmware" | ||
3328 | " version of controller\n"); | ||
3329 | } | ||
3330 | /* Get the number of logical volumes */ | ||
3331 | return_code = sendcmd(CISS_REPORT_LOG, cntl_num, ld_buff, | ||
3332 | sizeof(ReportLunData_struct), 0, 0, 0, NULL, | ||
3333 | TYPE_CMD); | ||
3334 | |||
3335 | if (return_code == IO_OK) { | ||
3336 | #ifdef CCISS_DEBUG | ||
3337 | printk("LUN Data\n--------------------------\n"); | ||
3338 | #endif /* CCISS_DEBUG */ | ||
3339 | |||
3340 | listlength |= | ||
3341 | (0xff & (unsigned int)(ld_buff->LUNListLength[0])) << 24; | ||
3342 | listlength |= | ||
3343 | (0xff & (unsigned int)(ld_buff->LUNListLength[1])) << 16; | ||
3344 | listlength |= | ||
3345 | (0xff & (unsigned int)(ld_buff->LUNListLength[2])) << 8; | ||
3346 | listlength |= 0xff & (unsigned int)(ld_buff->LUNListLength[3]); | ||
3347 | } else { /* reading number of logical volumes failed */ | ||
3348 | |||
3349 | printk(KERN_WARNING "cciss: report logical volume" | ||
3350 | " command failed\n"); | ||
3351 | listlength = 0; | ||
3352 | } | ||
3353 | hba[cntl_num]->num_luns = listlength / 8; // 8 bytes pre entry | ||
3354 | if (hba[cntl_num]->num_luns > CISS_MAX_LUN) { | ||
3355 | printk(KERN_ERR | ||
3356 | "ciss: only %d number of logical volumes supported\n", | ||
3357 | CISS_MAX_LUN); | ||
3358 | hba[cntl_num]->num_luns = CISS_MAX_LUN; | ||
3359 | } | ||
3360 | #ifdef CCISS_DEBUG | ||
3361 | printk(KERN_DEBUG "Length = %x %x %x %x = %d\n", | ||
3362 | ld_buff->LUNListLength[0], ld_buff->LUNListLength[1], | ||
3363 | ld_buff->LUNListLength[2], ld_buff->LUNListLength[3], | ||
3364 | hba[cntl_num]->num_luns); | ||
3365 | #endif /* CCISS_DEBUG */ | ||
3366 | |||
3367 | hba[cntl_num]->highest_lun = hba[cntl_num]->num_luns - 1; | ||
3368 | for (i = 0; i < CISS_MAX_LUN; i++) { | ||
3369 | if (i < hba[cntl_num]->num_luns) { | ||
3370 | lunid = (0xff & (unsigned int)(ld_buff->LUN[i][3])) | ||
3371 | << 24; | ||
3372 | lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][2])) | ||
3373 | << 16; | ||
3374 | lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][1])) | ||
3375 | << 8; | ||
3376 | lunid |= 0xff & (unsigned int)(ld_buff->LUN[i][0]); | ||
3377 | |||
3378 | hba[cntl_num]->drv[i].LunID = lunid; | ||
3379 | |||
3380 | #ifdef CCISS_DEBUG | ||
3381 | printk(KERN_DEBUG "LUN[%d]: %x %x %x %x = %x\n", i, | ||
3382 | ld_buff->LUN[i][0], ld_buff->LUN[i][1], | ||
3383 | ld_buff->LUN[i][2], ld_buff->LUN[i][3], | ||
3384 | hba[cntl_num]->drv[i].LunID); | ||
3385 | #endif /* CCISS_DEBUG */ | ||
3386 | |||
3387 | /* testing to see if 16-byte CDBs are already being used */ | ||
3388 | if(hba[cntl_num]->cciss_read == CCISS_READ_16) { | ||
3389 | cciss_read_capacity_16(cntl_num, i, 0, | ||
3390 | &total_size, &block_size); | ||
3391 | goto geo_inq; | ||
3392 | } | ||
3393 | cciss_read_capacity(cntl_num, i, 0, &total_size, &block_size); | ||
3394 | |||
3395 | /* If read_capacity returns all F's the logical is >2TB */ | ||
3396 | /* so we switch to 16-byte CDBs for all read/write ops */ | ||
3397 | if(total_size == 0xFFFFFFFFULL) { | ||
3398 | cciss_read_capacity_16(cntl_num, i, 0, | ||
3399 | &total_size, &block_size); | ||
3400 | hba[cntl_num]->cciss_read = CCISS_READ_16; | ||
3401 | hba[cntl_num]->cciss_write = CCISS_WRITE_16; | ||
3402 | } else { | ||
3403 | hba[cntl_num]->cciss_read = CCISS_READ_10; | ||
3404 | hba[cntl_num]->cciss_write = CCISS_WRITE_10; | ||
3405 | } | ||
3406 | geo_inq: | ||
3407 | cciss_geometry_inquiry(cntl_num, i, 0, total_size, | ||
3408 | block_size, inq_buff, | ||
3409 | &hba[cntl_num]->drv[i]); | ||
3410 | cciss_get_serial_no(cntl_num, i, 0, | ||
3411 | hba[cntl_num]->drv[i].serial_no, | ||
3412 | sizeof(hba[cntl_num]->drv[i].serial_no)); | ||
3413 | } else { | ||
3414 | /* initialize raid_level to indicate a free space */ | ||
3415 | hba[cntl_num]->drv[i].raid_level = -1; | ||
3416 | } | ||
3417 | } | ||
3418 | kfree(ld_buff); | ||
3419 | kfree(inq_buff); | ||
3420 | } | ||
3421 | |||
3422 | /* Function to find the first free pointer into our hba[] array */ | ||
3423 | /* Returns -1 if no free entries are left. */ | ||
3424 | static int alloc_cciss_hba(void) | 3358 | static int alloc_cciss_hba(void) |
3425 | { | 3359 | { |
3426 | int i; | 3360 | int i; |
@@ -3432,11 +3366,6 @@ static int alloc_cciss_hba(void) | |||
3432 | p = kzalloc(sizeof(ctlr_info_t), GFP_KERNEL); | 3366 | p = kzalloc(sizeof(ctlr_info_t), GFP_KERNEL); |
3433 | if (!p) | 3367 | if (!p) |
3434 | goto Enomem; | 3368 | goto Enomem; |
3435 | p->gendisk[0] = alloc_disk(1 << NWD_SHIFT); | ||
3436 | if (!p->gendisk[0]) { | ||
3437 | kfree(p); | ||
3438 | goto Enomem; | ||
3439 | } | ||
3440 | hba[i] = p; | 3369 | hba[i] = p; |
3441 | return i; | 3370 | return i; |
3442 | } | 3371 | } |
@@ -3564,11 +3493,13 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
3564 | ((hba[i]->nr_cmds + BITS_PER_LONG - | 3493 | ((hba[i]->nr_cmds + BITS_PER_LONG - |
3565 | 1) / BITS_PER_LONG) * sizeof(unsigned long)); | 3494 | 1) / BITS_PER_LONG) * sizeof(unsigned long)); |
3566 | 3495 | ||
3567 | #ifdef CCISS_DEBUG | 3496 | hba[i]->num_luns = 0; |
3568 | printk(KERN_DEBUG "Scanning for drives on controller cciss%d\n", i); | 3497 | hba[i]->highest_lun = -1; |
3569 | #endif /* CCISS_DEBUG */ | 3498 | for (j = 0; j < CISS_MAX_LUN; j++) { |
3570 | 3499 | hba[i]->drv[j].raid_level = -1; | |
3571 | cciss_getgeometry(i); | 3500 | hba[i]->drv[j].queue = NULL; |
3501 | hba[i]->gendisk[j] = NULL; | ||
3502 | } | ||
3572 | 3503 | ||
3573 | cciss_scsi_setup(i); | 3504 | cciss_scsi_setup(i); |
3574 | 3505 | ||
@@ -3581,76 +3512,10 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
3581 | 3512 | ||
3582 | hba[i]->busy_initializing = 0; | 3513 | hba[i]->busy_initializing = 0; |
3583 | 3514 | ||
3584 | do { | 3515 | rebuild_lun_table(hba[i], 1); |
3585 | drive_info_struct *drv = &(hba[i]->drv[j]); | ||
3586 | struct gendisk *disk = hba[i]->gendisk[j]; | ||
3587 | struct request_queue *q; | ||
3588 | |||
3589 | /* Check if the disk was allocated already */ | ||
3590 | if (!disk){ | ||
3591 | hba[i]->gendisk[j] = alloc_disk(1 << NWD_SHIFT); | ||
3592 | disk = hba[i]->gendisk[j]; | ||
3593 | } | ||
3594 | |||
3595 | /* Check that the disk was able to be allocated */ | ||
3596 | if (!disk) { | ||
3597 | printk(KERN_ERR "cciss: unable to allocate memory for disk %d\n", j); | ||
3598 | goto clean4; | ||
3599 | } | ||
3600 | |||
3601 | q = blk_init_queue(do_cciss_request, &hba[i]->lock); | ||
3602 | if (!q) { | ||
3603 | printk(KERN_ERR | ||
3604 | "cciss: unable to allocate queue for disk %d\n", | ||
3605 | j); | ||
3606 | goto clean4; | ||
3607 | } | ||
3608 | drv->queue = q; | ||
3609 | |||
3610 | blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask); | ||
3611 | |||
3612 | /* This is a hardware imposed limit. */ | ||
3613 | blk_queue_max_hw_segments(q, MAXSGENTRIES); | ||
3614 | |||
3615 | /* This is a limit in the driver and could be eliminated. */ | ||
3616 | blk_queue_max_phys_segments(q, MAXSGENTRIES); | ||
3617 | |||
3618 | blk_queue_max_sectors(q, hba[i]->cciss_max_sectors); | ||
3619 | |||
3620 | blk_queue_softirq_done(q, cciss_softirq_done); | ||
3621 | |||
3622 | q->queuedata = hba[i]; | ||
3623 | sprintf(disk->disk_name, "cciss/c%dd%d", i, j); | ||
3624 | disk->major = hba[i]->major; | ||
3625 | disk->first_minor = j << NWD_SHIFT; | ||
3626 | disk->fops = &cciss_fops; | ||
3627 | disk->queue = q; | ||
3628 | disk->private_data = drv; | ||
3629 | disk->driverfs_dev = &pdev->dev; | ||
3630 | /* we must register the controller even if no disks exist */ | ||
3631 | /* this is for the online array utilities */ | ||
3632 | if (!drv->heads && j) | ||
3633 | continue; | ||
3634 | blk_queue_hardsect_size(q, drv->block_size); | ||
3635 | set_capacity(disk, drv->nr_blocks); | ||
3636 | j++; | ||
3637 | } while (j <= hba[i]->highest_lun); | ||
3638 | |||
3639 | /* Make sure all queue data is written out before */ | ||
3640 | /* interrupt handler, triggered by add_disk, */ | ||
3641 | /* is allowed to start them. */ | ||
3642 | wmb(); | ||
3643 | |||
3644 | for (j = 0; j <= hba[i]->highest_lun; j++) | ||
3645 | add_disk(hba[i]->gendisk[j]); | ||
3646 | |||
3647 | /* we must register the controller even if no disks exist */ | ||
3648 | if (hba[i]->highest_lun == -1) | ||
3649 | add_disk(hba[i]->gendisk[0]); | ||
3650 | |||
3651 | return 1; | 3516 | return 1; |
3652 | 3517 | ||
3653 | clean4: | 3518 | clean4: |
3654 | #ifdef CONFIG_CISS_SCSI_TAPE | 3519 | #ifdef CONFIG_CISS_SCSI_TAPE |
3655 | kfree(hba[i]->scsi_rejects.complete); | 3520 | kfree(hba[i]->scsi_rejects.complete); |
3656 | #endif | 3521 | #endif |
@@ -3665,9 +3530,9 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
3665 | hba[i]->errinfo_pool, | 3530 | hba[i]->errinfo_pool, |
3666 | hba[i]->errinfo_pool_dhandle); | 3531 | hba[i]->errinfo_pool_dhandle); |
3667 | free_irq(hba[i]->intr[SIMPLE_MODE_INT], hba[i]); | 3532 | free_irq(hba[i]->intr[SIMPLE_MODE_INT], hba[i]); |
3668 | clean2: | 3533 | clean2: |
3669 | unregister_blkdev(hba[i]->major, hba[i]->devname); | 3534 | unregister_blkdev(hba[i]->major, hba[i]->devname); |
3670 | clean1: | 3535 | clean1: |
3671 | hba[i]->busy_initializing = 0; | 3536 | hba[i]->busy_initializing = 0; |
3672 | /* cleanup any queues that may have been initialized */ | 3537 | /* cleanup any queues that may have been initialized */ |
3673 | for (j=0; j <= hba[i]->highest_lun; j++){ | 3538 | for (j=0; j <= hba[i]->highest_lun; j++){ |