diff options
Diffstat (limited to 'drivers/scsi/aacraid')
-rw-r--r-- | drivers/scsi/aacraid/aachba.c | 60 | ||||
-rw-r--r-- | drivers/scsi/aacraid/aacraid.h | 20 | ||||
-rw-r--r-- | drivers/scsi/aacraid/commctrl.c | 25 | ||||
-rw-r--r-- | drivers/scsi/aacraid/comminit.c | 13 | ||||
-rw-r--r-- | drivers/scsi/aacraid/commsup.c | 279 | ||||
-rw-r--r-- | drivers/scsi/aacraid/dpcsup.c | 10 | ||||
-rw-r--r-- | drivers/scsi/aacraid/linit.c | 35 | ||||
-rw-r--r-- | drivers/scsi/aacraid/rkt.c | 446 | ||||
-rw-r--r-- | drivers/scsi/aacraid/rx.c | 117 | ||||
-rw-r--r-- | drivers/scsi/aacraid/sa.c | 21 |
10 files changed, 495 insertions, 531 deletions
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 83b5c7d085f..ac108f9e267 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c | |||
@@ -169,13 +169,17 @@ MODULE_PARM_DESC(numacb, "Request a limit to the number of adapter control block | |||
169 | int acbsize = -1; | 169 | int acbsize = -1; |
170 | module_param(acbsize, int, S_IRUGO|S_IWUSR); | 170 | module_param(acbsize, int, S_IRUGO|S_IWUSR); |
171 | MODULE_PARM_DESC(acbsize, "Request a specific adapter control block (FIB) size. Valid values are 512, 2048, 4096 and 8192. Default is to use suggestion from Firmware."); | 171 | MODULE_PARM_DESC(acbsize, "Request a specific adapter control block (FIB) size. Valid values are 512, 2048, 4096 and 8192. Default is to use suggestion from Firmware."); |
172 | |||
173 | int expose_physicals = 0; | ||
174 | module_param(expose_physicals, int, S_IRUGO|S_IWUSR); | ||
175 | MODULE_PARM_DESC(expose_physicals, "Expose physical components of the arrays. 0=off, 1=on"); | ||
172 | /** | 176 | /** |
173 | * aac_get_config_status - check the adapter configuration | 177 | * aac_get_config_status - check the adapter configuration |
174 | * @common: adapter to query | 178 | * @common: adapter to query |
175 | * | 179 | * |
176 | * Query config status, and commit the configuration if needed. | 180 | * Query config status, and commit the configuration if needed. |
177 | */ | 181 | */ |
178 | int aac_get_config_status(struct aac_dev *dev) | 182 | int aac_get_config_status(struct aac_dev *dev, int commit_flag) |
179 | { | 183 | { |
180 | int status = 0; | 184 | int status = 0; |
181 | struct fib * fibptr; | 185 | struct fib * fibptr; |
@@ -219,7 +223,7 @@ int aac_get_config_status(struct aac_dev *dev) | |||
219 | aac_fib_complete(fibptr); | 223 | aac_fib_complete(fibptr); |
220 | /* Send a CT_COMMIT_CONFIG to enable discovery of devices */ | 224 | /* Send a CT_COMMIT_CONFIG to enable discovery of devices */ |
221 | if (status >= 0) { | 225 | if (status >= 0) { |
222 | if (commit == 1) { | 226 | if ((commit == 1) || commit_flag) { |
223 | struct aac_commit_config * dinfo; | 227 | struct aac_commit_config * dinfo; |
224 | aac_fib_init(fibptr); | 228 | aac_fib_init(fibptr); |
225 | dinfo = (struct aac_commit_config *) fib_data(fibptr); | 229 | dinfo = (struct aac_commit_config *) fib_data(fibptr); |
@@ -489,6 +493,8 @@ int aac_probe_container(struct aac_dev *dev, int cid) | |||
489 | unsigned instance; | 493 | unsigned instance; |
490 | 494 | ||
491 | fsa_dev_ptr = dev->fsa_dev; | 495 | fsa_dev_ptr = dev->fsa_dev; |
496 | if (!fsa_dev_ptr) | ||
497 | return -ENOMEM; | ||
492 | instance = dev->scsi_host_ptr->unique_id; | 498 | instance = dev->scsi_host_ptr->unique_id; |
493 | 499 | ||
494 | if (!(fibptr = aac_fib_alloc(dev))) | 500 | if (!(fibptr = aac_fib_alloc(dev))) |
@@ -782,8 +788,9 @@ int aac_get_adapter_info(struct aac_dev* dev) | |||
782 | dev->maximum_num_channels = le32_to_cpu(bus_info->BusCount); | 788 | dev->maximum_num_channels = le32_to_cpu(bus_info->BusCount); |
783 | } | 789 | } |
784 | 790 | ||
785 | tmp = le32_to_cpu(dev->adapter_info.kernelrev); | 791 | if (!dev->in_reset) { |
786 | printk(KERN_INFO "%s%d: kernel %d.%d-%d[%d] %.*s\n", | 792 | tmp = le32_to_cpu(dev->adapter_info.kernelrev); |
793 | printk(KERN_INFO "%s%d: kernel %d.%d-%d[%d] %.*s\n", | ||
787 | dev->name, | 794 | dev->name, |
788 | dev->id, | 795 | dev->id, |
789 | tmp>>24, | 796 | tmp>>24, |
@@ -792,20 +799,21 @@ int aac_get_adapter_info(struct aac_dev* dev) | |||
792 | le32_to_cpu(dev->adapter_info.kernelbuild), | 799 | le32_to_cpu(dev->adapter_info.kernelbuild), |
793 | (int)sizeof(dev->supplement_adapter_info.BuildDate), | 800 | (int)sizeof(dev->supplement_adapter_info.BuildDate), |
794 | dev->supplement_adapter_info.BuildDate); | 801 | dev->supplement_adapter_info.BuildDate); |
795 | tmp = le32_to_cpu(dev->adapter_info.monitorrev); | 802 | tmp = le32_to_cpu(dev->adapter_info.monitorrev); |
796 | printk(KERN_INFO "%s%d: monitor %d.%d-%d[%d]\n", | 803 | printk(KERN_INFO "%s%d: monitor %d.%d-%d[%d]\n", |
797 | dev->name, dev->id, | 804 | dev->name, dev->id, |
798 | tmp>>24,(tmp>>16)&0xff,tmp&0xff, | 805 | tmp>>24,(tmp>>16)&0xff,tmp&0xff, |
799 | le32_to_cpu(dev->adapter_info.monitorbuild)); | 806 | le32_to_cpu(dev->adapter_info.monitorbuild)); |
800 | tmp = le32_to_cpu(dev->adapter_info.biosrev); | 807 | tmp = le32_to_cpu(dev->adapter_info.biosrev); |
801 | printk(KERN_INFO "%s%d: bios %d.%d-%d[%d]\n", | 808 | printk(KERN_INFO "%s%d: bios %d.%d-%d[%d]\n", |
802 | dev->name, dev->id, | 809 | dev->name, dev->id, |
803 | tmp>>24,(tmp>>16)&0xff,tmp&0xff, | 810 | tmp>>24,(tmp>>16)&0xff,tmp&0xff, |
804 | le32_to_cpu(dev->adapter_info.biosbuild)); | 811 | le32_to_cpu(dev->adapter_info.biosbuild)); |
805 | if (le32_to_cpu(dev->adapter_info.serial[0]) != 0xBAD0) | 812 | if (le32_to_cpu(dev->adapter_info.serial[0]) != 0xBAD0) |
806 | printk(KERN_INFO "%s%d: serial %x\n", | 813 | printk(KERN_INFO "%s%d: serial %x\n", |
807 | dev->name, dev->id, | 814 | dev->name, dev->id, |
808 | le32_to_cpu(dev->adapter_info.serial[0])); | 815 | le32_to_cpu(dev->adapter_info.serial[0])); |
816 | } | ||
809 | 817 | ||
810 | dev->nondasd_support = 0; | 818 | dev->nondasd_support = 0; |
811 | dev->raid_scsi_mode = 0; | 819 | dev->raid_scsi_mode = 0; |
@@ -1392,6 +1400,7 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid) | |||
1392 | struct scsi_cmnd *cmd; | 1400 | struct scsi_cmnd *cmd; |
1393 | struct scsi_device *sdev = scsicmd->device; | 1401 | struct scsi_device *sdev = scsicmd->device; |
1394 | int active = 0; | 1402 | int active = 0; |
1403 | struct aac_dev *aac; | ||
1395 | unsigned long flags; | 1404 | unsigned long flags; |
1396 | 1405 | ||
1397 | /* | 1406 | /* |
@@ -1413,11 +1422,14 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid) | |||
1413 | if (active) | 1422 | if (active) |
1414 | return SCSI_MLQUEUE_DEVICE_BUSY; | 1423 | return SCSI_MLQUEUE_DEVICE_BUSY; |
1415 | 1424 | ||
1425 | aac = (struct aac_dev *)scsicmd->device->host->hostdata; | ||
1426 | if (aac->in_reset) | ||
1427 | return SCSI_MLQUEUE_HOST_BUSY; | ||
1428 | |||
1416 | /* | 1429 | /* |
1417 | * Allocate and initialize a Fib | 1430 | * Allocate and initialize a Fib |
1418 | */ | 1431 | */ |
1419 | if (!(cmd_fibcontext = | 1432 | if (!(cmd_fibcontext = aac_fib_alloc(aac))) |
1420 | aac_fib_alloc((struct aac_dev *)scsicmd->device->host->hostdata))) | ||
1421 | return SCSI_MLQUEUE_HOST_BUSY; | 1433 | return SCSI_MLQUEUE_HOST_BUSY; |
1422 | 1434 | ||
1423 | aac_fib_init(cmd_fibcontext); | 1435 | aac_fib_init(cmd_fibcontext); |
@@ -1470,6 +1482,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
1470 | struct aac_dev *dev = (struct aac_dev *)host->hostdata; | 1482 | struct aac_dev *dev = (struct aac_dev *)host->hostdata; |
1471 | struct fsa_dev_info *fsa_dev_ptr = dev->fsa_dev; | 1483 | struct fsa_dev_info *fsa_dev_ptr = dev->fsa_dev; |
1472 | 1484 | ||
1485 | if (fsa_dev_ptr == NULL) | ||
1486 | return -1; | ||
1473 | /* | 1487 | /* |
1474 | * If the bus, id or lun is out of range, return fail | 1488 | * If the bus, id or lun is out of range, return fail |
1475 | * Test does not apply to ID 16, the pseudo id for the controller | 1489 | * Test does not apply to ID 16, the pseudo id for the controller |
@@ -1499,6 +1513,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
1499 | case INQUIRY: | 1513 | case INQUIRY: |
1500 | case READ_CAPACITY: | 1514 | case READ_CAPACITY: |
1501 | case TEST_UNIT_READY: | 1515 | case TEST_UNIT_READY: |
1516 | if (dev->in_reset) | ||
1517 | return -1; | ||
1502 | spin_unlock_irq(host->host_lock); | 1518 | spin_unlock_irq(host->host_lock); |
1503 | aac_probe_container(dev, cid); | 1519 | aac_probe_container(dev, cid); |
1504 | if ((fsa_dev_ptr[cid].valid & 1) == 0) | 1520 | if ((fsa_dev_ptr[cid].valid & 1) == 0) |
@@ -1523,7 +1539,9 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
1523 | return 0; | 1539 | return 0; |
1524 | } | 1540 | } |
1525 | } else { /* check for physical non-dasd devices */ | 1541 | } else { /* check for physical non-dasd devices */ |
1526 | if(dev->nondasd_support == 1){ | 1542 | if ((dev->nondasd_support == 1) || expose_physicals) { |
1543 | if (dev->in_reset) | ||
1544 | return -1; | ||
1527 | return aac_send_srb_fib(scsicmd); | 1545 | return aac_send_srb_fib(scsicmd); |
1528 | } else { | 1546 | } else { |
1529 | scsicmd->result = DID_NO_CONNECT << 16; | 1547 | scsicmd->result = DID_NO_CONNECT << 16; |
@@ -1579,6 +1597,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
1579 | scsicmd->scsi_done(scsicmd); | 1597 | scsicmd->scsi_done(scsicmd); |
1580 | return 0; | 1598 | return 0; |
1581 | } | 1599 | } |
1600 | if (dev->in_reset) | ||
1601 | return -1; | ||
1582 | setinqstr(dev, (void *) (inq_data.inqd_vid), fsa_dev_ptr[cid].type); | 1602 | setinqstr(dev, (void *) (inq_data.inqd_vid), fsa_dev_ptr[cid].type); |
1583 | inq_data.inqd_pdt = INQD_PDT_DA; /* Direct/random access device */ | 1603 | inq_data.inqd_pdt = INQD_PDT_DA; /* Direct/random access device */ |
1584 | aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data)); | 1604 | aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data)); |
@@ -1734,6 +1754,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
1734 | case READ_10: | 1754 | case READ_10: |
1735 | case READ_12: | 1755 | case READ_12: |
1736 | case READ_16: | 1756 | case READ_16: |
1757 | if (dev->in_reset) | ||
1758 | return -1; | ||
1737 | /* | 1759 | /* |
1738 | * Hack to keep track of ordinal number of the device that | 1760 | * Hack to keep track of ordinal number of the device that |
1739 | * corresponds to a container. Needed to convert | 1761 | * corresponds to a container. Needed to convert |
@@ -1752,6 +1774,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
1752 | case WRITE_10: | 1774 | case WRITE_10: |
1753 | case WRITE_12: | 1775 | case WRITE_12: |
1754 | case WRITE_16: | 1776 | case WRITE_16: |
1777 | if (dev->in_reset) | ||
1778 | return -1; | ||
1755 | return aac_write(scsicmd, cid); | 1779 | return aac_write(scsicmd, cid); |
1756 | 1780 | ||
1757 | case SYNCHRONIZE_CACHE: | 1781 | case SYNCHRONIZE_CACHE: |
@@ -1782,6 +1806,8 @@ static int query_disk(struct aac_dev *dev, void __user *arg) | |||
1782 | struct fsa_dev_info *fsa_dev_ptr; | 1806 | struct fsa_dev_info *fsa_dev_ptr; |
1783 | 1807 | ||
1784 | fsa_dev_ptr = dev->fsa_dev; | 1808 | fsa_dev_ptr = dev->fsa_dev; |
1809 | if (!fsa_dev_ptr) | ||
1810 | return -EBUSY; | ||
1785 | if (copy_from_user(&qd, arg, sizeof (struct aac_query_disk))) | 1811 | if (copy_from_user(&qd, arg, sizeof (struct aac_query_disk))) |
1786 | return -EFAULT; | 1812 | return -EFAULT; |
1787 | if (qd.cnum == -1) | 1813 | if (qd.cnum == -1) |
@@ -1820,6 +1846,8 @@ static int force_delete_disk(struct aac_dev *dev, void __user *arg) | |||
1820 | struct fsa_dev_info *fsa_dev_ptr; | 1846 | struct fsa_dev_info *fsa_dev_ptr; |
1821 | 1847 | ||
1822 | fsa_dev_ptr = dev->fsa_dev; | 1848 | fsa_dev_ptr = dev->fsa_dev; |
1849 | if (!fsa_dev_ptr) | ||
1850 | return -EBUSY; | ||
1823 | 1851 | ||
1824 | if (copy_from_user(&dd, arg, sizeof (struct aac_delete_disk))) | 1852 | if (copy_from_user(&dd, arg, sizeof (struct aac_delete_disk))) |
1825 | return -EFAULT; | 1853 | return -EFAULT; |
@@ -1843,6 +1871,8 @@ static int delete_disk(struct aac_dev *dev, void __user *arg) | |||
1843 | struct fsa_dev_info *fsa_dev_ptr; | 1871 | struct fsa_dev_info *fsa_dev_ptr; |
1844 | 1872 | ||
1845 | fsa_dev_ptr = dev->fsa_dev; | 1873 | fsa_dev_ptr = dev->fsa_dev; |
1874 | if (!fsa_dev_ptr) | ||
1875 | return -EBUSY; | ||
1846 | 1876 | ||
1847 | if (copy_from_user(&dd, arg, sizeof (struct aac_delete_disk))) | 1877 | if (copy_from_user(&dd, arg, sizeof (struct aac_delete_disk))) |
1848 | return -EFAULT; | 1878 | return -EFAULT; |
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index d0eecd4bec8..eb3ed91bac7 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h | |||
@@ -494,6 +494,7 @@ struct adapter_ops | |||
494 | int (*adapter_sync_cmd)(struct aac_dev *dev, u32 command, u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, u32 *status, u32 *r1, u32 *r2, u32 *r3, u32 *r4); | 494 | int (*adapter_sync_cmd)(struct aac_dev *dev, u32 command, u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, u32 *status, u32 *r1, u32 *r2, u32 *r3, u32 *r4); |
495 | int (*adapter_check_health)(struct aac_dev *dev); | 495 | int (*adapter_check_health)(struct aac_dev *dev); |
496 | int (*adapter_send)(struct fib * fib); | 496 | int (*adapter_send)(struct fib * fib); |
497 | int (*adapter_ioremap)(struct aac_dev * dev, u32 size); | ||
497 | }; | 498 | }; |
498 | 499 | ||
499 | /* | 500 | /* |
@@ -682,14 +683,6 @@ struct rx_inbound { | |||
682 | __le32 Mailbox[8]; | 683 | __le32 Mailbox[8]; |
683 | }; | 684 | }; |
684 | 685 | ||
685 | #define InboundMailbox0 IndexRegs.Mailbox[0] | ||
686 | #define InboundMailbox1 IndexRegs.Mailbox[1] | ||
687 | #define InboundMailbox2 IndexRegs.Mailbox[2] | ||
688 | #define InboundMailbox3 IndexRegs.Mailbox[3] | ||
689 | #define InboundMailbox4 IndexRegs.Mailbox[4] | ||
690 | #define InboundMailbox5 IndexRegs.Mailbox[5] | ||
691 | #define InboundMailbox6 IndexRegs.Mailbox[6] | ||
692 | |||
693 | #define INBOUNDDOORBELL_0 0x00000001 | 686 | #define INBOUNDDOORBELL_0 0x00000001 |
694 | #define INBOUNDDOORBELL_1 0x00000002 | 687 | #define INBOUNDDOORBELL_1 0x00000002 |
695 | #define INBOUNDDOORBELL_2 0x00000004 | 688 | #define INBOUNDDOORBELL_2 0x00000004 |
@@ -1010,6 +1003,8 @@ struct aac_dev | |||
1010 | struct rx_registers __iomem *rx; | 1003 | struct rx_registers __iomem *rx; |
1011 | struct rkt_registers __iomem *rkt; | 1004 | struct rkt_registers __iomem *rkt; |
1012 | } regs; | 1005 | } regs; |
1006 | volatile void __iomem *base; | ||
1007 | volatile struct rx_inbound __iomem *IndexRegs; | ||
1013 | u32 OIMR; /* Mask Register Cache */ | 1008 | u32 OIMR; /* Mask Register Cache */ |
1014 | /* | 1009 | /* |
1015 | * AIF thread states | 1010 | * AIF thread states |
@@ -1029,6 +1024,7 @@ struct aac_dev | |||
1029 | init->InitStructRevision==cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4) | 1024 | init->InitStructRevision==cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4) |
1030 | u8 raw_io_64; | 1025 | u8 raw_io_64; |
1031 | u8 printf_enabled; | 1026 | u8 printf_enabled; |
1027 | u8 in_reset; | ||
1032 | }; | 1028 | }; |
1033 | 1029 | ||
1034 | #define aac_adapter_interrupt(dev) \ | 1030 | #define aac_adapter_interrupt(dev) \ |
@@ -1049,6 +1045,9 @@ struct aac_dev | |||
1049 | #define aac_adapter_send(fib) \ | 1045 | #define aac_adapter_send(fib) \ |
1050 | ((fib)->dev)->a_ops.adapter_send(fib) | 1046 | ((fib)->dev)->a_ops.adapter_send(fib) |
1051 | 1047 | ||
1048 | #define aac_adapter_ioremap(dev, size) \ | ||
1049 | (dev)->a_ops.adapter_ioremap(dev, size) | ||
1050 | |||
1052 | #define FIB_CONTEXT_FLAG_TIMED_OUT (0x00000001) | 1051 | #define FIB_CONTEXT_FLAG_TIMED_OUT (0x00000001) |
1053 | 1052 | ||
1054 | /* | 1053 | /* |
@@ -1524,7 +1523,6 @@ struct aac_get_name { | |||
1524 | __le32 count; /* sizeof(((struct aac_get_name_resp *)NULL)->data) */ | 1523 | __le32 count; /* sizeof(((struct aac_get_name_resp *)NULL)->data) */ |
1525 | }; | 1524 | }; |
1526 | 1525 | ||
1527 | #define CT_OK 218 | ||
1528 | struct aac_get_name_resp { | 1526 | struct aac_get_name_resp { |
1529 | __le32 dummy0; | 1527 | __le32 dummy0; |
1530 | __le32 dummy1; | 1528 | __le32 dummy1; |
@@ -1670,6 +1668,7 @@ extern struct aac_common aac_config; | |||
1670 | #define RCV_TEMP_READINGS 0x00000025 | 1668 | #define RCV_TEMP_READINGS 0x00000025 |
1671 | #define GET_COMM_PREFERRED_SETTINGS 0x00000026 | 1669 | #define GET_COMM_PREFERRED_SETTINGS 0x00000026 |
1672 | #define IOP_RESET 0x00001000 | 1670 | #define IOP_RESET 0x00001000 |
1671 | #define IOP_RESET_ALWAYS 0x00001001 | ||
1673 | #define RE_INIT_ADAPTER 0x000000ee | 1672 | #define RE_INIT_ADAPTER 0x000000ee |
1674 | 1673 | ||
1675 | /* | 1674 | /* |
@@ -1788,7 +1787,7 @@ void aac_consumer_free(struct aac_dev * dev, struct aac_queue * q, u32 qnum); | |||
1788 | int aac_fib_complete(struct fib * context); | 1787 | int aac_fib_complete(struct fib * context); |
1789 | #define fib_data(fibctx) ((void *)(fibctx)->hw_fib->data) | 1788 | #define fib_data(fibctx) ((void *)(fibctx)->hw_fib->data) |
1790 | struct aac_dev *aac_init_adapter(struct aac_dev *dev); | 1789 | struct aac_dev *aac_init_adapter(struct aac_dev *dev); |
1791 | int aac_get_config_status(struct aac_dev *dev); | 1790 | int aac_get_config_status(struct aac_dev *dev, int commit_flag); |
1792 | int aac_get_containers(struct aac_dev *dev); | 1791 | int aac_get_containers(struct aac_dev *dev); |
1793 | int aac_scsi_cmd(struct scsi_cmnd *cmd); | 1792 | int aac_scsi_cmd(struct scsi_cmnd *cmd); |
1794 | int aac_dev_ioctl(struct aac_dev *dev, int cmd, void __user *arg); | 1793 | int aac_dev_ioctl(struct aac_dev *dev, int cmd, void __user *arg); |
@@ -1799,6 +1798,7 @@ int aac_sa_init(struct aac_dev *dev); | |||
1799 | unsigned int aac_response_normal(struct aac_queue * q); | 1798 | unsigned int aac_response_normal(struct aac_queue * q); |
1800 | unsigned int aac_command_normal(struct aac_queue * q); | 1799 | unsigned int aac_command_normal(struct aac_queue * q); |
1801 | unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index); | 1800 | unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index); |
1801 | int aac_check_health(struct aac_dev * dev); | ||
1802 | int aac_command_thread(void *data); | 1802 | int aac_command_thread(void *data); |
1803 | int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context *fibctx); | 1803 | int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context *fibctx); |
1804 | int aac_fib_adapter_complete(struct fib * fibptr, unsigned short size); | 1804 | int aac_fib_adapter_complete(struct fib * fibptr, unsigned short size); |
diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c index 255421de9d1..da1d3a9212f 100644 --- a/drivers/scsi/aacraid/commctrl.c +++ b/drivers/scsi/aacraid/commctrl.c | |||
@@ -38,7 +38,7 @@ | |||
38 | #include <linux/completion.h> | 38 | #include <linux/completion.h> |
39 | #include <linux/dma-mapping.h> | 39 | #include <linux/dma-mapping.h> |
40 | #include <linux/blkdev.h> | 40 | #include <linux/blkdev.h> |
41 | #include <linux/delay.h> | 41 | #include <linux/delay.h> /* ssleep prototype */ |
42 | #include <linux/kthread.h> | 42 | #include <linux/kthread.h> |
43 | #include <asm/semaphore.h> | 43 | #include <asm/semaphore.h> |
44 | #include <asm/uaccess.h> | 44 | #include <asm/uaccess.h> |
@@ -140,7 +140,8 @@ cleanup: | |||
140 | fibptr->hw_fib_pa = hw_fib_pa; | 140 | fibptr->hw_fib_pa = hw_fib_pa; |
141 | fibptr->hw_fib = hw_fib; | 141 | fibptr->hw_fib = hw_fib; |
142 | } | 142 | } |
143 | aac_fib_free(fibptr); | 143 | if (retval != -EINTR) |
144 | aac_fib_free(fibptr); | ||
144 | return retval; | 145 | return retval; |
145 | } | 146 | } |
146 | 147 | ||
@@ -297,7 +298,7 @@ return_fib: | |||
297 | spin_unlock_irqrestore(&dev->fib_lock, flags); | 298 | spin_unlock_irqrestore(&dev->fib_lock, flags); |
298 | /* If someone killed the AIF aacraid thread, restart it */ | 299 | /* If someone killed the AIF aacraid thread, restart it */ |
299 | status = !dev->aif_thread; | 300 | status = !dev->aif_thread; |
300 | if (status && dev->queues && dev->fsa_dev) { | 301 | if (status && !dev->in_reset && dev->queues && dev->fsa_dev) { |
301 | /* Be paranoid, be very paranoid! */ | 302 | /* Be paranoid, be very paranoid! */ |
302 | kthread_stop(dev->thread); | 303 | kthread_stop(dev->thread); |
303 | ssleep(1); | 304 | ssleep(1); |
@@ -621,7 +622,13 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
621 | 622 | ||
622 | actual_fibsize = sizeof (struct aac_srb) + (((user_srbcmd->sg.count & 0xff) - 1) * sizeof (struct sgentry)); | 623 | actual_fibsize = sizeof (struct aac_srb) + (((user_srbcmd->sg.count & 0xff) - 1) * sizeof (struct sgentry)); |
623 | if(actual_fibsize != fibsize){ // User made a mistake - should not continue | 624 | if(actual_fibsize != fibsize){ // User made a mistake - should not continue |
624 | dprintk((KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n")); | 625 | dprintk((KERN_DEBUG"aacraid: Bad Size specified in " |
626 | "Raw SRB command calculated fibsize=%d " | ||
627 | "user_srbcmd->sg.count=%d aac_srb=%d sgentry=%d " | ||
628 | "issued fibsize=%d\n", | ||
629 | actual_fibsize, user_srbcmd->sg.count, | ||
630 | sizeof(struct aac_srb), sizeof(struct sgentry), | ||
631 | fibsize)); | ||
625 | rcode = -EINVAL; | 632 | rcode = -EINVAL; |
626 | goto cleanup; | 633 | goto cleanup; |
627 | } | 634 | } |
@@ -663,6 +670,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
663 | psg->count = cpu_to_le32(sg_indx+1); | 670 | psg->count = cpu_to_le32(sg_indx+1); |
664 | status = aac_fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL); | 671 | status = aac_fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL); |
665 | } | 672 | } |
673 | if (status == -EINTR) { | ||
674 | rcode = -EINTR; | ||
675 | goto cleanup; | ||
676 | } | ||
666 | 677 | ||
667 | if (status != 0){ | 678 | if (status != 0){ |
668 | dprintk((KERN_DEBUG"aacraid: Could not send raw srb fib to hba\n")); | 679 | dprintk((KERN_DEBUG"aacraid: Could not send raw srb fib to hba\n")); |
@@ -696,8 +707,10 @@ cleanup: | |||
696 | for(i=0; i <= sg_indx; i++){ | 707 | for(i=0; i <= sg_indx; i++){ |
697 | kfree(sg_list[i]); | 708 | kfree(sg_list[i]); |
698 | } | 709 | } |
699 | aac_fib_complete(srbfib); | 710 | if (rcode != -EINTR) { |
700 | aac_fib_free(srbfib); | 711 | aac_fib_complete(srbfib); |
712 | aac_fib_free(srbfib); | ||
713 | } | ||
701 | 714 | ||
702 | return rcode; | 715 | return rcode; |
703 | } | 716 | } |
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c index 1cd3584ba7f..d5cf8b91a0e 100644 --- a/drivers/scsi/aacraid/comminit.c +++ b/drivers/scsi/aacraid/comminit.c | |||
@@ -180,7 +180,7 @@ int aac_send_shutdown(struct aac_dev * dev) | |||
180 | -2 /* Timeout silently */, 1, | 180 | -2 /* Timeout silently */, 1, |
181 | NULL, NULL); | 181 | NULL, NULL); |
182 | 182 | ||
183 | if (status == 0) | 183 | if (status >= 0) |
184 | aac_fib_complete(fibctx); | 184 | aac_fib_complete(fibctx); |
185 | aac_fib_free(fibctx); | 185 | aac_fib_free(fibctx); |
186 | return status; | 186 | return status; |
@@ -307,17 +307,12 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev) | |||
307 | if (status[1] & AAC_OPT_NEW_COMM) | 307 | if (status[1] & AAC_OPT_NEW_COMM) |
308 | dev->new_comm_interface = dev->a_ops.adapter_send != 0; | 308 | dev->new_comm_interface = dev->a_ops.adapter_send != 0; |
309 | if (dev->new_comm_interface && (status[2] > dev->base_size)) { | 309 | if (dev->new_comm_interface && (status[2] > dev->base_size)) { |
310 | iounmap(dev->regs.sa); | 310 | aac_adapter_ioremap(dev, 0); |
311 | dev->base_size = status[2]; | 311 | dev->base_size = status[2]; |
312 | dprintk((KERN_DEBUG "ioremap(%lx,%d)\n", | 312 | if (aac_adapter_ioremap(dev, status[2])) { |
313 | host->base, status[2])); | ||
314 | dev->regs.sa = ioremap(host->base, status[2]); | ||
315 | if (dev->regs.sa == NULL) { | ||
316 | /* remap failed, go back ... */ | 313 | /* remap failed, go back ... */ |
317 | dev->new_comm_interface = 0; | 314 | dev->new_comm_interface = 0; |
318 | dev->regs.sa = ioremap(host->base, | 315 | if (aac_adapter_ioremap(dev, AAC_MIN_FOOTPRINT_SIZE)) { |
319 | AAC_MIN_FOOTPRINT_SIZE); | ||
320 | if (dev->regs.sa == NULL) { | ||
321 | printk(KERN_WARNING | 316 | printk(KERN_WARNING |
322 | "aacraid: unable to map adapter.\n"); | 317 | "aacraid: unable to map adapter.\n"); |
323 | return NULL; | 318 | return NULL; |
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 3f27419c66a..8734a045558 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c | |||
@@ -40,8 +40,10 @@ | |||
40 | #include <linux/blkdev.h> | 40 | #include <linux/blkdev.h> |
41 | #include <linux/delay.h> | 41 | #include <linux/delay.h> |
42 | #include <linux/kthread.h> | 42 | #include <linux/kthread.h> |
43 | #include <scsi/scsi.h> | ||
43 | #include <scsi/scsi_host.h> | 44 | #include <scsi/scsi_host.h> |
44 | #include <scsi/scsi_device.h> | 45 | #include <scsi/scsi_device.h> |
46 | #include <scsi/scsi_cmnd.h> | ||
45 | #include <asm/semaphore.h> | 47 | #include <asm/semaphore.h> |
46 | 48 | ||
47 | #include "aacraid.h" | 49 | #include "aacraid.h" |
@@ -464,6 +466,8 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
464 | dprintk((KERN_DEBUG " hw_fib pa being sent=%lx\n",(ulong)fibptr->hw_fib_pa)); | 466 | dprintk((KERN_DEBUG " hw_fib pa being sent=%lx\n",(ulong)fibptr->hw_fib_pa)); |
465 | dprintk((KERN_DEBUG " fib being sent=%p\n",fibptr)); | 467 | dprintk((KERN_DEBUG " fib being sent=%p\n",fibptr)); |
466 | 468 | ||
469 | if (!dev->queues) | ||
470 | return -EBUSY; | ||
467 | q = &dev->queues->queue[AdapNormCmdQueue]; | 471 | q = &dev->queues->queue[AdapNormCmdQueue]; |
468 | 472 | ||
469 | if(wait) | 473 | if(wait) |
@@ -527,8 +531,15 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
527 | } | 531 | } |
528 | udelay(5); | 532 | udelay(5); |
529 | } | 533 | } |
530 | } else | 534 | } else if (down_interruptible(&fibptr->event_wait)) { |
531 | down(&fibptr->event_wait); | 535 | spin_lock_irqsave(&fibptr->event_lock, flags); |
536 | if (fibptr->done == 0) { | ||
537 | fibptr->done = 2; /* Tell interrupt we aborted */ | ||
538 | spin_unlock_irqrestore(&fibptr->event_lock, flags); | ||
539 | return -EINTR; | ||
540 | } | ||
541 | spin_unlock_irqrestore(&fibptr->event_lock, flags); | ||
542 | } | ||
532 | BUG_ON(fibptr->done == 0); | 543 | BUG_ON(fibptr->done == 0); |
533 | 544 | ||
534 | if((fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT)){ | 545 | if((fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT)){ |
@@ -795,7 +806,7 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) | |||
795 | 806 | ||
796 | /* Sniff for container changes */ | 807 | /* Sniff for container changes */ |
797 | 808 | ||
798 | if (!dev) | 809 | if (!dev || !dev->fsa_dev) |
799 | return; | 810 | return; |
800 | container = (u32)-1; | 811 | container = (u32)-1; |
801 | 812 | ||
@@ -1022,13 +1033,7 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) | |||
1022 | if (device) { | 1033 | if (device) { |
1023 | switch (device_config_needed) { | 1034 | switch (device_config_needed) { |
1024 | case DELETE: | 1035 | case DELETE: |
1025 | scsi_remove_device(device); | ||
1026 | break; | ||
1027 | case CHANGE: | 1036 | case CHANGE: |
1028 | if (!dev->fsa_dev[container].valid) { | ||
1029 | scsi_remove_device(device); | ||
1030 | break; | ||
1031 | } | ||
1032 | scsi_rescan_device(&device->sdev_gendev); | 1037 | scsi_rescan_device(&device->sdev_gendev); |
1033 | 1038 | ||
1034 | default: | 1039 | default: |
@@ -1045,6 +1050,262 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) | |||
1045 | 1050 | ||
1046 | } | 1051 | } |
1047 | 1052 | ||
1053 | static int _aac_reset_adapter(struct aac_dev *aac) | ||
1054 | { | ||
1055 | int index, quirks; | ||
1056 | u32 ret; | ||
1057 | int retval; | ||
1058 | struct Scsi_Host *host; | ||
1059 | struct scsi_device *dev; | ||
1060 | struct scsi_cmnd *command; | ||
1061 | struct scsi_cmnd *command_list; | ||
1062 | |||
1063 | /* | ||
1064 | * Assumptions: | ||
1065 | * - host is locked. | ||
1066 | * - in_reset is asserted, so no new i/o is getting to the | ||
1067 | * card. | ||
1068 | * - The card is dead. | ||
1069 | */ | ||
1070 | host = aac->scsi_host_ptr; | ||
1071 | scsi_block_requests(host); | ||
1072 | aac_adapter_disable_int(aac); | ||
1073 | spin_unlock_irq(host->host_lock); | ||
1074 | kthread_stop(aac->thread); | ||
1075 | |||
1076 | /* | ||
1077 | * If a positive health, means in a known DEAD PANIC | ||
1078 | * state and the adapter could be reset to `try again'. | ||
1079 | */ | ||
1080 | retval = aac_adapter_check_health(aac); | ||
1081 | if (retval == 0) | ||
1082 | retval = aac_adapter_sync_cmd(aac, IOP_RESET_ALWAYS, | ||
1083 | 0, 0, 0, 0, 0, 0, &ret, NULL, NULL, NULL, NULL); | ||
1084 | if (retval) | ||
1085 | retval = aac_adapter_sync_cmd(aac, IOP_RESET, | ||
1086 | 0, 0, 0, 0, 0, 0, &ret, NULL, NULL, NULL, NULL); | ||
1087 | |||
1088 | if (retval) | ||
1089 | goto out; | ||
1090 | if (ret != 0x00000001) { | ||
1091 | retval = -ENODEV; | ||
1092 | goto out; | ||
1093 | } | ||
1094 | |||
1095 | index = aac->cardtype; | ||
1096 | |||
1097 | /* | ||
1098 | * Re-initialize the adapter, first free resources, then carefully | ||
1099 | * apply the initialization sequence to come back again. Only risk | ||
1100 | * is a change in Firmware dropping cache, it is assumed the caller | ||
1101 | * will ensure that i/o is queisced and the card is flushed in that | ||
1102 | * case. | ||
1103 | */ | ||
1104 | aac_fib_map_free(aac); | ||
1105 | aac->hw_fib_va = NULL; | ||
1106 | aac->hw_fib_pa = 0; | ||
1107 | pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr, aac->comm_phys); | ||
1108 | aac->comm_addr = NULL; | ||
1109 | aac->comm_phys = 0; | ||
1110 | kfree(aac->queues); | ||
1111 | aac->queues = NULL; | ||
1112 | free_irq(aac->pdev->irq, aac); | ||
1113 | kfree(aac->fsa_dev); | ||
1114 | aac->fsa_dev = NULL; | ||
1115 | if (aac_get_driver_ident(index)->quirks & AAC_QUIRK_31BIT) { | ||
1116 | if (((retval = pci_set_dma_mask(aac->pdev, DMA_32BIT_MASK))) || | ||
1117 | ((retval = pci_set_consistent_dma_mask(aac->pdev, DMA_32BIT_MASK)))) | ||
1118 | goto out; | ||
1119 | } else { | ||
1120 | if (((retval = pci_set_dma_mask(aac->pdev, 0x7FFFFFFFULL))) || | ||
1121 | ((retval = pci_set_consistent_dma_mask(aac->pdev, 0x7FFFFFFFULL)))) | ||
1122 | goto out; | ||
1123 | } | ||
1124 | if ((retval = (*(aac_get_driver_ident(index)->init))(aac))) | ||
1125 | goto out; | ||
1126 | if (aac_get_driver_ident(index)->quirks & AAC_QUIRK_31BIT) | ||
1127 | if ((retval = pci_set_dma_mask(aac->pdev, DMA_32BIT_MASK))) | ||
1128 | goto out; | ||
1129 | aac->thread = kthread_run(aac_command_thread, aac, aac->name); | ||
1130 | if (IS_ERR(aac->thread)) { | ||
1131 | retval = PTR_ERR(aac->thread); | ||
1132 | goto out; | ||
1133 | } | ||
1134 | (void)aac_get_adapter_info(aac); | ||
1135 | quirks = aac_get_driver_ident(index)->quirks; | ||
1136 | if ((quirks & AAC_QUIRK_34SG) && (host->sg_tablesize > 34)) { | ||
1137 | host->sg_tablesize = 34; | ||
1138 | host->max_sectors = (host->sg_tablesize * 8) + 112; | ||
1139 | } | ||
1140 | if ((quirks & AAC_QUIRK_17SG) && (host->sg_tablesize > 17)) { | ||
1141 | host->sg_tablesize = 17; | ||
1142 | host->max_sectors = (host->sg_tablesize * 8) + 112; | ||
1143 | } | ||
1144 | aac_get_config_status(aac, 1); | ||
1145 | aac_get_containers(aac); | ||
1146 | /* | ||
1147 | * This is where the assumption that the Adapter is quiesced | ||
1148 | * is important. | ||
1149 | */ | ||
1150 | command_list = NULL; | ||
1151 | __shost_for_each_device(dev, host) { | ||
1152 | unsigned long flags; | ||
1153 | spin_lock_irqsave(&dev->list_lock, flags); | ||
1154 | list_for_each_entry(command, &dev->cmd_list, list) | ||
1155 | if (command->SCp.phase == AAC_OWNER_FIRMWARE) { | ||
1156 | command->SCp.buffer = (struct scatterlist *)command_list; | ||
1157 | command_list = command; | ||
1158 | } | ||
1159 | spin_unlock_irqrestore(&dev->list_lock, flags); | ||
1160 | } | ||
1161 | while ((command = command_list)) { | ||
1162 | command_list = (struct scsi_cmnd *)command->SCp.buffer; | ||
1163 | command->SCp.buffer = NULL; | ||
1164 | command->result = DID_OK << 16 | ||
1165 | | COMMAND_COMPLETE << 8 | ||
1166 | | SAM_STAT_TASK_SET_FULL; | ||
1167 | command->SCp.phase = AAC_OWNER_ERROR_HANDLER; | ||
1168 | command->scsi_done(command); | ||
1169 | } | ||
1170 | retval = 0; | ||
1171 | |||
1172 | out: | ||
1173 | aac->in_reset = 0; | ||
1174 | scsi_unblock_requests(host); | ||
1175 | spin_lock_irq(host->host_lock); | ||
1176 | return retval; | ||
1177 | } | ||
1178 | |||
1179 | int aac_check_health(struct aac_dev * aac) | ||
1180 | { | ||
1181 | int BlinkLED; | ||
1182 | unsigned long time_now, flagv = 0; | ||
1183 | struct list_head * entry; | ||
1184 | struct Scsi_Host * host; | ||
1185 | |||
1186 | /* Extending the scope of fib_lock slightly to protect aac->in_reset */ | ||
1187 | if (spin_trylock_irqsave(&aac->fib_lock, flagv) == 0) | ||
1188 | return 0; | ||
1189 | |||
1190 | if (aac->in_reset || !(BlinkLED = aac_adapter_check_health(aac))) { | ||
1191 | spin_unlock_irqrestore(&aac->fib_lock, flagv); | ||
1192 | return 0; /* OK */ | ||
1193 | } | ||
1194 | |||
1195 | aac->in_reset = 1; | ||
1196 | |||
1197 | /* Fake up an AIF: | ||
1198 | * aac_aifcmd.command = AifCmdEventNotify = 1 | ||
1199 | * aac_aifcmd.seqnum = 0xFFFFFFFF | ||
1200 | * aac_aifcmd.data[0] = AifEnExpEvent = 23 | ||
1201 | * aac_aifcmd.data[1] = AifExeFirmwarePanic = 3 | ||
1202 | * aac.aifcmd.data[2] = AifHighPriority = 3 | ||
1203 | * aac.aifcmd.data[3] = BlinkLED | ||
1204 | */ | ||
1205 | |||
1206 | time_now = jiffies/HZ; | ||
1207 | entry = aac->fib_list.next; | ||
1208 | |||
1209 | /* | ||
1210 | * For each Context that is on the | ||
1211 | * fibctxList, make a copy of the | ||
1212 | * fib, and then set the event to wake up the | ||
1213 | * thread that is waiting for it. | ||
1214 | */ | ||
1215 | while (entry != &aac->fib_list) { | ||
1216 | /* | ||
1217 | * Extract the fibctx | ||
1218 | */ | ||
1219 | struct aac_fib_context *fibctx = list_entry(entry, struct aac_fib_context, next); | ||
1220 | struct hw_fib * hw_fib; | ||
1221 | struct fib * fib; | ||
1222 | /* | ||
1223 | * Check if the queue is getting | ||
1224 | * backlogged | ||
1225 | */ | ||
1226 | if (fibctx->count > 20) { | ||
1227 | /* | ||
1228 | * It's *not* jiffies folks, | ||
1229 | * but jiffies / HZ, so do not | ||
1230 | * panic ... | ||
1231 | */ | ||
1232 | u32 time_last = fibctx->jiffies; | ||
1233 | /* | ||
1234 | * Has it been > 2 minutes | ||
1235 | * since the last read off | ||
1236 | * the queue? | ||
1237 | */ | ||
1238 | if ((time_now - time_last) > aif_timeout) { | ||
1239 | entry = entry->next; | ||
1240 | aac_close_fib_context(aac, fibctx); | ||
1241 | continue; | ||
1242 | } | ||
1243 | } | ||
1244 | /* | ||
1245 | * Warning: no sleep allowed while | ||
1246 | * holding spinlock | ||
1247 | */ | ||
1248 | hw_fib = kmalloc(sizeof(struct hw_fib), GFP_ATOMIC); | ||
1249 | fib = kmalloc(sizeof(struct fib), GFP_ATOMIC); | ||
1250 | if (fib && hw_fib) { | ||
1251 | struct aac_aifcmd * aif; | ||
1252 | |||
1253 | memset(hw_fib, 0, sizeof(struct hw_fib)); | ||
1254 | memset(fib, 0, sizeof(struct fib)); | ||
1255 | fib->hw_fib = hw_fib; | ||
1256 | fib->dev = aac; | ||
1257 | aac_fib_init(fib); | ||
1258 | fib->type = FSAFS_NTC_FIB_CONTEXT; | ||
1259 | fib->size = sizeof (struct fib); | ||
1260 | fib->data = hw_fib->data; | ||
1261 | aif = (struct aac_aifcmd *)hw_fib->data; | ||
1262 | aif->command = cpu_to_le32(AifCmdEventNotify); | ||
1263 | aif->seqnum = cpu_to_le32(0xFFFFFFFF); | ||
1264 | aif->data[0] = cpu_to_le32(AifEnExpEvent); | ||
1265 | aif->data[1] = cpu_to_le32(AifExeFirmwarePanic); | ||
1266 | aif->data[2] = cpu_to_le32(AifHighPriority); | ||
1267 | aif->data[3] = cpu_to_le32(BlinkLED); | ||
1268 | |||
1269 | /* | ||
1270 | * Put the FIB onto the | ||
1271 | * fibctx's fibs | ||
1272 | */ | ||
1273 | list_add_tail(&fib->fiblink, &fibctx->fib_list); | ||
1274 | fibctx->count++; | ||
1275 | /* | ||
1276 | * Set the event to wake up the | ||
1277 | * thread that will waiting. | ||
1278 | */ | ||
1279 | up(&fibctx->wait_sem); | ||
1280 | } else { | ||
1281 | printk(KERN_WARNING "aifd: didn't allocate NewFib.\n"); | ||
1282 | kfree(fib); | ||
1283 | kfree(hw_fib); | ||
1284 | } | ||
1285 | entry = entry->next; | ||
1286 | } | ||
1287 | |||
1288 | spin_unlock_irqrestore(&aac->fib_lock, flagv); | ||
1289 | |||
1290 | if (BlinkLED < 0) { | ||
1291 | printk(KERN_ERR "%s: Host adapter dead %d\n", aac->name, BlinkLED); | ||
1292 | goto out; | ||
1293 | } | ||
1294 | |||
1295 | printk(KERN_ERR "%s: Host adapter BLINK LED 0x%x\n", aac->name, BlinkLED); | ||
1296 | |||
1297 | host = aac->scsi_host_ptr; | ||
1298 | spin_lock_irqsave(host->host_lock, flagv); | ||
1299 | BlinkLED = _aac_reset_adapter(aac); | ||
1300 | spin_unlock_irqrestore(host->host_lock, flagv); | ||
1301 | return BlinkLED; | ||
1302 | |||
1303 | out: | ||
1304 | aac->in_reset = 0; | ||
1305 | return BlinkLED; | ||
1306 | } | ||
1307 | |||
1308 | |||
1048 | /** | 1309 | /** |
1049 | * aac_command_thread - command processing thread | 1310 | * aac_command_thread - command processing thread |
1050 | * @dev: Adapter to monitor | 1311 | * @dev: Adapter to monitor |
diff --git a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c index b2a5c7262f3..8335f07b772 100644 --- a/drivers/scsi/aacraid/dpcsup.c +++ b/drivers/scsi/aacraid/dpcsup.c | |||
@@ -124,10 +124,15 @@ unsigned int aac_response_normal(struct aac_queue * q) | |||
124 | } else { | 124 | } else { |
125 | unsigned long flagv; | 125 | unsigned long flagv; |
126 | spin_lock_irqsave(&fib->event_lock, flagv); | 126 | spin_lock_irqsave(&fib->event_lock, flagv); |
127 | fib->done = 1; | 127 | if (!fib->done) |
128 | fib->done = 1; | ||
128 | up(&fib->event_wait); | 129 | up(&fib->event_wait); |
129 | spin_unlock_irqrestore(&fib->event_lock, flagv); | 130 | spin_unlock_irqrestore(&fib->event_lock, flagv); |
130 | FIB_COUNTER_INCREMENT(aac_config.NormalRecved); | 131 | FIB_COUNTER_INCREMENT(aac_config.NormalRecved); |
132 | if (fib->done == 2) { | ||
133 | aac_fib_complete(fib); | ||
134 | aac_fib_free(fib); | ||
135 | } | ||
131 | } | 136 | } |
132 | consumed++; | 137 | consumed++; |
133 | spin_lock_irqsave(q->lock, flags); | 138 | spin_lock_irqsave(q->lock, flags); |
@@ -316,7 +321,8 @@ unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index) | |||
316 | unsigned long flagv; | 321 | unsigned long flagv; |
317 | dprintk((KERN_INFO "event_wait up\n")); | 322 | dprintk((KERN_INFO "event_wait up\n")); |
318 | spin_lock_irqsave(&fib->event_lock, flagv); | 323 | spin_lock_irqsave(&fib->event_lock, flagv); |
319 | fib->done = 1; | 324 | if (!fib->done) |
325 | fib->done = 1; | ||
320 | up(&fib->event_wait); | 326 | up(&fib->event_wait); |
321 | spin_unlock_irqrestore(&fib->event_lock, flagv); | 327 | spin_unlock_irqrestore(&fib->event_lock, flagv); |
322 | FIB_COUNTER_INCREMENT(aac_config.NormalRecved); | 328 | FIB_COUNTER_INCREMENT(aac_config.NormalRecved); |
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index e42a479ce64..359e7ddfdb4 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c | |||
@@ -82,6 +82,8 @@ static LIST_HEAD(aac_devices); | |||
82 | static int aac_cfg_major = -1; | 82 | static int aac_cfg_major = -1; |
83 | char aac_driver_version[] = AAC_DRIVER_FULL_VERSION; | 83 | char aac_driver_version[] = AAC_DRIVER_FULL_VERSION; |
84 | 84 | ||
85 | extern int expose_physicals; | ||
86 | |||
85 | /* | 87 | /* |
86 | * Because of the way Linux names scsi devices, the order in this table has | 88 | * Because of the way Linux names scsi devices, the order in this table has |
87 | * become important. Check for on-board Raid first, add-in cards second. | 89 | * become important. Check for on-board Raid first, add-in cards second. |
@@ -394,6 +396,7 @@ static int aac_slave_configure(struct scsi_device *sdev) | |||
394 | sdev->skip_ms_page_3f = 1; | 396 | sdev->skip_ms_page_3f = 1; |
395 | } | 397 | } |
396 | if ((sdev->type == TYPE_DISK) && | 398 | if ((sdev->type == TYPE_DISK) && |
399 | !expose_physicals && | ||
397 | (sdev_channel(sdev) != CONTAINER_CHANNEL)) { | 400 | (sdev_channel(sdev) != CONTAINER_CHANNEL)) { |
398 | struct aac_dev *aac = (struct aac_dev *)sdev->host->hostdata; | 401 | struct aac_dev *aac = (struct aac_dev *)sdev->host->hostdata; |
399 | if (!aac->raid_scsi_mode || (sdev_channel(sdev) != 2)) | 402 | if (!aac->raid_scsi_mode || (sdev_channel(sdev) != 2)) |
@@ -454,17 +457,17 @@ static int aac_eh_reset(struct scsi_cmnd* cmd) | |||
454 | printk(KERN_ERR "%s: Host adapter reset request. SCSI hang ?\n", | 457 | printk(KERN_ERR "%s: Host adapter reset request. SCSI hang ?\n", |
455 | AAC_DRIVERNAME); | 458 | AAC_DRIVERNAME); |
456 | aac = (struct aac_dev *)host->hostdata; | 459 | aac = (struct aac_dev *)host->hostdata; |
457 | if (aac_adapter_check_health(aac)) { | 460 | |
458 | printk(KERN_ERR "%s: Host adapter appears dead\n", | 461 | if ((count = aac_check_health(aac))) |
459 | AAC_DRIVERNAME); | 462 | return count; |
460 | return -ENODEV; | ||
461 | } | ||
462 | /* | 463 | /* |
463 | * Wait for all commands to complete to this specific | 464 | * Wait for all commands to complete to this specific |
464 | * target (block maximum 60 seconds). | 465 | * target (block maximum 60 seconds). |
465 | */ | 466 | */ |
466 | for (count = 60; count; --count) { | 467 | for (count = 60; count; --count) { |
467 | int active = 0; | 468 | int active = aac->in_reset; |
469 | |||
470 | if (active == 0) | ||
468 | __shost_for_each_device(dev, host) { | 471 | __shost_for_each_device(dev, host) { |
469 | spin_lock_irqsave(&dev->list_lock, flags); | 472 | spin_lock_irqsave(&dev->list_lock, flags); |
470 | list_for_each_entry(command, &dev->cmd_list, list) { | 473 | list_for_each_entry(command, &dev->cmd_list, list) { |
@@ -864,13 +867,6 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, | |||
864 | * Map in the registers from the adapter. | 867 | * Map in the registers from the adapter. |
865 | */ | 868 | */ |
866 | aac->base_size = AAC_MIN_FOOTPRINT_SIZE; | 869 | aac->base_size = AAC_MIN_FOOTPRINT_SIZE; |
867 | if ((aac->regs.sa = ioremap( | ||
868 | (unsigned long)aac->scsi_host_ptr->base, AAC_MIN_FOOTPRINT_SIZE)) | ||
869 | == NULL) { | ||
870 | printk(KERN_WARNING "%s: unable to map adapter.\n", | ||
871 | AAC_DRIVERNAME); | ||
872 | goto out_free_fibs; | ||
873 | } | ||
874 | if ((*aac_drivers[index].init)(aac)) | 870 | if ((*aac_drivers[index].init)(aac)) |
875 | goto out_unmap; | 871 | goto out_unmap; |
876 | 872 | ||
@@ -928,12 +924,12 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, | |||
928 | * all containers are on the virtual channel 0 (CONTAINER_CHANNEL) | 924 | * all containers are on the virtual channel 0 (CONTAINER_CHANNEL) |
929 | * physical channels are address by their actual physical number+1 | 925 | * physical channels are address by their actual physical number+1 |
930 | */ | 926 | */ |
931 | if (aac->nondasd_support == 1) | 927 | if ((aac->nondasd_support == 1) || expose_physicals) |
932 | shost->max_channel = aac->maximum_num_channels; | 928 | shost->max_channel = aac->maximum_num_channels; |
933 | else | 929 | else |
934 | shost->max_channel = 0; | 930 | shost->max_channel = 0; |
935 | 931 | ||
936 | aac_get_config_status(aac); | 932 | aac_get_config_status(aac, 0); |
937 | aac_get_containers(aac); | 933 | aac_get_containers(aac); |
938 | list_add(&aac->entry, insert); | 934 | list_add(&aac->entry, insert); |
939 | 935 | ||
@@ -969,8 +965,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, | |||
969 | aac_fib_map_free(aac); | 965 | aac_fib_map_free(aac); |
970 | pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr, aac->comm_phys); | 966 | pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr, aac->comm_phys); |
971 | kfree(aac->queues); | 967 | kfree(aac->queues); |
972 | iounmap(aac->regs.sa); | 968 | aac_adapter_ioremap(aac, 0); |
973 | out_free_fibs: | ||
974 | kfree(aac->fibs); | 969 | kfree(aac->fibs); |
975 | kfree(aac->fsa_dev); | 970 | kfree(aac->fsa_dev); |
976 | out_free_host: | 971 | out_free_host: |
@@ -1005,7 +1000,7 @@ static void __devexit aac_remove_one(struct pci_dev *pdev) | |||
1005 | kfree(aac->queues); | 1000 | kfree(aac->queues); |
1006 | 1001 | ||
1007 | free_irq(pdev->irq, aac); | 1002 | free_irq(pdev->irq, aac); |
1008 | iounmap(aac->regs.sa); | 1003 | aac_adapter_ioremap(aac, 0); |
1009 | 1004 | ||
1010 | kfree(aac->fibs); | 1005 | kfree(aac->fibs); |
1011 | kfree(aac->fsa_dev); | 1006 | kfree(aac->fsa_dev); |
@@ -1013,6 +1008,10 @@ static void __devexit aac_remove_one(struct pci_dev *pdev) | |||
1013 | list_del(&aac->entry); | 1008 | list_del(&aac->entry); |
1014 | scsi_host_put(shost); | 1009 | scsi_host_put(shost); |
1015 | pci_disable_device(pdev); | 1010 | pci_disable_device(pdev); |
1011 | if (list_empty(&aac_devices)) { | ||
1012 | unregister_chrdev(aac_cfg_major, "aac"); | ||
1013 | aac_cfg_major = -1; | ||
1014 | } | ||
1016 | } | 1015 | } |
1017 | 1016 | ||
1018 | static struct pci_driver aac_pci_driver = { | 1017 | static struct pci_driver aac_pci_driver = { |
diff --git a/drivers/scsi/aacraid/rkt.c b/drivers/scsi/aacraid/rkt.c index 458ea897fd7..643f23b5ded 100644 --- a/drivers/scsi/aacraid/rkt.c +++ b/drivers/scsi/aacraid/rkt.c | |||
@@ -28,370 +28,27 @@ | |||
28 | * | 28 | * |
29 | */ | 29 | */ |
30 | 30 | ||
31 | #include <linux/kernel.h> | ||
32 | #include <linux/init.h> | ||
33 | #include <linux/types.h> | ||
34 | #include <linux/sched.h> | ||
35 | #include <linux/pci.h> | ||
36 | #include <linux/spinlock.h> | ||
37 | #include <linux/slab.h> | ||
38 | #include <linux/blkdev.h> | 31 | #include <linux/blkdev.h> |
39 | #include <linux/delay.h> | ||
40 | #include <linux/completion.h> | ||
41 | #include <linux/time.h> | ||
42 | #include <linux/interrupt.h> | ||
43 | #include <asm/semaphore.h> | ||
44 | 32 | ||
45 | #include <scsi/scsi_host.h> | 33 | #include <scsi/scsi_host.h> |
46 | 34 | ||
47 | #include "aacraid.h" | 35 | #include "aacraid.h" |
48 | 36 | ||
49 | static irqreturn_t aac_rkt_intr(int irq, void *dev_id, struct pt_regs *regs) | ||
50 | { | ||
51 | struct aac_dev *dev = dev_id; | ||
52 | |||
53 | if (dev->new_comm_interface) { | ||
54 | u32 Index = rkt_readl(dev, MUnit.OutboundQueue); | ||
55 | if (Index == 0xFFFFFFFFL) | ||
56 | Index = rkt_readl(dev, MUnit.OutboundQueue); | ||
57 | if (Index != 0xFFFFFFFFL) { | ||
58 | do { | ||
59 | if (aac_intr_normal(dev, Index)) { | ||
60 | rkt_writel(dev, MUnit.OutboundQueue, Index); | ||
61 | rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormRespReady); | ||
62 | } | ||
63 | Index = rkt_readl(dev, MUnit.OutboundQueue); | ||
64 | } while (Index != 0xFFFFFFFFL); | ||
65 | return IRQ_HANDLED; | ||
66 | } | ||
67 | } else { | ||
68 | unsigned long bellbits; | ||
69 | u8 intstat; | ||
70 | intstat = rkt_readb(dev, MUnit.OISR); | ||
71 | /* | ||
72 | * Read mask and invert because drawbridge is reversed. | ||
73 | * This allows us to only service interrupts that have | ||
74 | * been enabled. | ||
75 | * Check to see if this is our interrupt. If it isn't just return | ||
76 | */ | ||
77 | if (intstat & ~(dev->OIMR)) | ||
78 | { | ||
79 | bellbits = rkt_readl(dev, OutboundDoorbellReg); | ||
80 | if (bellbits & DoorBellPrintfReady) { | ||
81 | aac_printf(dev, rkt_readl (dev, IndexRegs.Mailbox[5])); | ||
82 | rkt_writel(dev, MUnit.ODR,DoorBellPrintfReady); | ||
83 | rkt_writel(dev, InboundDoorbellReg,DoorBellPrintfDone); | ||
84 | } | ||
85 | else if (bellbits & DoorBellAdapterNormCmdReady) { | ||
86 | rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady); | ||
87 | aac_command_normal(&dev->queues->queue[HostNormCmdQueue]); | ||
88 | // rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady); | ||
89 | } | ||
90 | else if (bellbits & DoorBellAdapterNormRespReady) { | ||
91 | rkt_writel(dev, MUnit.ODR,DoorBellAdapterNormRespReady); | ||
92 | aac_response_normal(&dev->queues->queue[HostNormRespQueue]); | ||
93 | } | ||
94 | else if (bellbits & DoorBellAdapterNormCmdNotFull) { | ||
95 | rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull); | ||
96 | } | ||
97 | else if (bellbits & DoorBellAdapterNormRespNotFull) { | ||
98 | rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull); | ||
99 | rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormRespNotFull); | ||
100 | } | ||
101 | return IRQ_HANDLED; | ||
102 | } | ||
103 | } | ||
104 | return IRQ_NONE; | ||
105 | } | ||
106 | |||
107 | /** | ||
108 | * aac_rkt_disable_interrupt - Disable interrupts | ||
109 | * @dev: Adapter | ||
110 | */ | ||
111 | |||
112 | static void aac_rkt_disable_interrupt(struct aac_dev *dev) | ||
113 | { | ||
114 | rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff); | ||
115 | } | ||
116 | |||
117 | /** | 37 | /** |
118 | * rkt_sync_cmd - send a command and wait | 38 | * aac_rkt_ioremap |
119 | * @dev: Adapter | 39 | * @size: mapping resize request |
120 | * @command: Command to execute | ||
121 | * @p1: first parameter | ||
122 | * @ret: adapter status | ||
123 | * | 40 | * |
124 | * This routine will send a synchronous command to the adapter and wait | ||
125 | * for its completion. | ||
126 | */ | 41 | */ |
127 | 42 | static int aac_rkt_ioremap(struct aac_dev * dev, u32 size) | |
128 | static int rkt_sync_cmd(struct aac_dev *dev, u32 command, | ||
129 | u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, | ||
130 | u32 *status, u32 *r1, u32 *r2, u32 *r3, u32 *r4) | ||
131 | { | 43 | { |
132 | unsigned long start; | 44 | if (!size) { |
133 | int ok; | 45 | iounmap(dev->regs.rkt); |
134 | /* | 46 | return 0; |
135 | * Write the command into Mailbox 0 | ||
136 | */ | ||
137 | rkt_writel(dev, InboundMailbox0, command); | ||
138 | /* | ||
139 | * Write the parameters into Mailboxes 1 - 6 | ||
140 | */ | ||
141 | rkt_writel(dev, InboundMailbox1, p1); | ||
142 | rkt_writel(dev, InboundMailbox2, p2); | ||
143 | rkt_writel(dev, InboundMailbox3, p3); | ||
144 | rkt_writel(dev, InboundMailbox4, p4); | ||
145 | /* | ||
146 | * Clear the synch command doorbell to start on a clean slate. | ||
147 | */ | ||
148 | rkt_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0); | ||
149 | /* | ||
150 | * Disable doorbell interrupts | ||
151 | */ | ||
152 | rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff); | ||
153 | /* | ||
154 | * Force the completion of the mask register write before issuing | ||
155 | * the interrupt. | ||
156 | */ | ||
157 | rkt_readb (dev, MUnit.OIMR); | ||
158 | /* | ||
159 | * Signal that there is a new synch command | ||
160 | */ | ||
161 | rkt_writel(dev, InboundDoorbellReg, INBOUNDDOORBELL_0); | ||
162 | |||
163 | ok = 0; | ||
164 | start = jiffies; | ||
165 | |||
166 | /* | ||
167 | * Wait up to 30 seconds | ||
168 | */ | ||
169 | while (time_before(jiffies, start+30*HZ)) | ||
170 | { | ||
171 | udelay(5); /* Delay 5 microseconds to let Mon960 get info. */ | ||
172 | /* | ||
173 | * Mon960 will set doorbell0 bit when it has completed the command. | ||
174 | */ | ||
175 | if (rkt_readl(dev, OutboundDoorbellReg) & OUTBOUNDDOORBELL_0) { | ||
176 | /* | ||
177 | * Clear the doorbell. | ||
178 | */ | ||
179 | rkt_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0); | ||
180 | ok = 1; | ||
181 | break; | ||
182 | } | ||
183 | /* | ||
184 | * Yield the processor in case we are slow | ||
185 | */ | ||
186 | msleep(1); | ||
187 | } | 47 | } |
188 | if (ok != 1) { | 48 | dev->base = dev->regs.rkt = ioremap(dev->scsi_host_ptr->base, size); |
189 | /* | 49 | if (dev->base == NULL) |
190 | * Restore interrupt mask even though we timed out | ||
191 | */ | ||
192 | if (dev->new_comm_interface) | ||
193 | rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7); | ||
194 | else | ||
195 | rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb); | ||
196 | return -ETIMEDOUT; | ||
197 | } | ||
198 | /* | ||
199 | * Pull the synch status from Mailbox 0. | ||
200 | */ | ||
201 | if (status) | ||
202 | *status = rkt_readl(dev, IndexRegs.Mailbox[0]); | ||
203 | if (r1) | ||
204 | *r1 = rkt_readl(dev, IndexRegs.Mailbox[1]); | ||
205 | if (r2) | ||
206 | *r2 = rkt_readl(dev, IndexRegs.Mailbox[2]); | ||
207 | if (r3) | ||
208 | *r3 = rkt_readl(dev, IndexRegs.Mailbox[3]); | ||
209 | if (r4) | ||
210 | *r4 = rkt_readl(dev, IndexRegs.Mailbox[4]); | ||
211 | /* | ||
212 | * Clear the synch command doorbell. | ||
213 | */ | ||
214 | rkt_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0); | ||
215 | /* | ||
216 | * Restore interrupt mask | ||
217 | */ | ||
218 | if (dev->new_comm_interface) | ||
219 | rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7); | ||
220 | else | ||
221 | rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb); | ||
222 | return 0; | ||
223 | |||
224 | } | ||
225 | |||
226 | /** | ||
227 | * aac_rkt_interrupt_adapter - interrupt adapter | ||
228 | * @dev: Adapter | ||
229 | * | ||
230 | * Send an interrupt to the i960 and breakpoint it. | ||
231 | */ | ||
232 | |||
233 | static void aac_rkt_interrupt_adapter(struct aac_dev *dev) | ||
234 | { | ||
235 | rkt_sync_cmd(dev, BREAKPOINT_REQUEST, 0, 0, 0, 0, 0, 0, | ||
236 | NULL, NULL, NULL, NULL, NULL); | ||
237 | } | ||
238 | |||
239 | /** | ||
240 | * aac_rkt_notify_adapter - send an event to the adapter | ||
241 | * @dev: Adapter | ||
242 | * @event: Event to send | ||
243 | * | ||
244 | * Notify the i960 that something it probably cares about has | ||
245 | * happened. | ||
246 | */ | ||
247 | |||
248 | static void aac_rkt_notify_adapter(struct aac_dev *dev, u32 event) | ||
249 | { | ||
250 | switch (event) { | ||
251 | |||
252 | case AdapNormCmdQue: | ||
253 | rkt_writel(dev, MUnit.IDR,INBOUNDDOORBELL_1); | ||
254 | break; | ||
255 | case HostNormRespNotFull: | ||
256 | rkt_writel(dev, MUnit.IDR,INBOUNDDOORBELL_4); | ||
257 | break; | ||
258 | case AdapNormRespQue: | ||
259 | rkt_writel(dev, MUnit.IDR,INBOUNDDOORBELL_2); | ||
260 | break; | ||
261 | case HostNormCmdNotFull: | ||
262 | rkt_writel(dev, MUnit.IDR,INBOUNDDOORBELL_3); | ||
263 | break; | ||
264 | case HostShutdown: | ||
265 | // rkt_sync_cmd(dev, HOST_CRASHING, 0, 0, 0, 0, 0, 0, | ||
266 | // NULL, NULL, NULL, NULL, NULL); | ||
267 | break; | ||
268 | case FastIo: | ||
269 | rkt_writel(dev, MUnit.IDR,INBOUNDDOORBELL_6); | ||
270 | break; | ||
271 | case AdapPrintfDone: | ||
272 | rkt_writel(dev, MUnit.IDR,INBOUNDDOORBELL_5); | ||
273 | break; | ||
274 | default: | ||
275 | BUG(); | ||
276 | break; | ||
277 | } | ||
278 | } | ||
279 | |||
280 | /** | ||
281 | * aac_rkt_start_adapter - activate adapter | ||
282 | * @dev: Adapter | ||
283 | * | ||
284 | * Start up processing on an i960 based AAC adapter | ||
285 | */ | ||
286 | |||
287 | static void aac_rkt_start_adapter(struct aac_dev *dev) | ||
288 | { | ||
289 | struct aac_init *init; | ||
290 | |||
291 | init = dev->init; | ||
292 | init->HostElapsedSeconds = cpu_to_le32(get_seconds()); | ||
293 | // We can only use a 32 bit address here | ||
294 | rkt_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa, | ||
295 | 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL); | ||
296 | } | ||
297 | |||
298 | /** | ||
299 | * aac_rkt_check_health | ||
300 | * @dev: device to check if healthy | ||
301 | * | ||
302 | * Will attempt to determine if the specified adapter is alive and | ||
303 | * capable of handling requests, returning 0 if alive. | ||
304 | */ | ||
305 | static int aac_rkt_check_health(struct aac_dev *dev) | ||
306 | { | ||
307 | u32 status = rkt_readl(dev, MUnit.OMRx[0]); | ||
308 | |||
309 | /* | ||
310 | * Check to see if the board failed any self tests. | ||
311 | */ | ||
312 | if (status & SELF_TEST_FAILED) | ||
313 | return -1; | 50 | return -1; |
314 | /* | 51 | dev->IndexRegs = &dev->regs.rkt->IndexRegs; |
315 | * Check to see if the board panic'd. | ||
316 | */ | ||
317 | if (status & KERNEL_PANIC) { | ||
318 | char * buffer; | ||
319 | struct POSTSTATUS { | ||
320 | __le32 Post_Command; | ||
321 | __le32 Post_Address; | ||
322 | } * post; | ||
323 | dma_addr_t paddr, baddr; | ||
324 | int ret; | ||
325 | |||
326 | if ((status & 0xFF000000L) == 0xBC000000L) | ||
327 | return (status >> 16) & 0xFF; | ||
328 | buffer = pci_alloc_consistent(dev->pdev, 512, &baddr); | ||
329 | ret = -2; | ||
330 | if (buffer == NULL) | ||
331 | return ret; | ||
332 | post = pci_alloc_consistent(dev->pdev, | ||
333 | sizeof(struct POSTSTATUS), &paddr); | ||
334 | if (post == NULL) { | ||
335 | pci_free_consistent(dev->pdev, 512, buffer, baddr); | ||
336 | return ret; | ||
337 | } | ||
338 | memset(buffer, 0, 512); | ||
339 | post->Post_Command = cpu_to_le32(COMMAND_POST_RESULTS); | ||
340 | post->Post_Address = cpu_to_le32(baddr); | ||
341 | rkt_writel(dev, MUnit.IMRx[0], paddr); | ||
342 | rkt_sync_cmd(dev, COMMAND_POST_RESULTS, baddr, 0, 0, 0, 0, 0, | ||
343 | NULL, NULL, NULL, NULL, NULL); | ||
344 | pci_free_consistent(dev->pdev, sizeof(struct POSTSTATUS), | ||
345 | post, paddr); | ||
346 | if ((buffer[0] == '0') && ((buffer[1] == 'x') || (buffer[1] == 'X'))) { | ||
347 | ret = (buffer[2] <= '9') ? (buffer[2] - '0') : (buffer[2] - 'A' + 10); | ||
348 | ret <<= 4; | ||
349 | ret += (buffer[3] <= '9') ? (buffer[3] - '0') : (buffer[3] - 'A' + 10); | ||
350 | } | ||
351 | pci_free_consistent(dev->pdev, 512, buffer, baddr); | ||
352 | return ret; | ||
353 | } | ||
354 | /* | ||
355 | * Wait for the adapter to be up and running. | ||
356 | */ | ||
357 | if (!(status & KERNEL_UP_AND_RUNNING)) | ||
358 | return -3; | ||
359 | /* | ||
360 | * Everything is OK | ||
361 | */ | ||
362 | return 0; | ||
363 | } | ||
364 | |||
365 | /** | ||
366 | * aac_rkt_send | ||
367 | * @fib: fib to issue | ||
368 | * | ||
369 | * Will send a fib, returning 0 if successful. | ||
370 | */ | ||
371 | static int aac_rkt_send(struct fib * fib) | ||
372 | { | ||
373 | u64 addr = fib->hw_fib_pa; | ||
374 | struct aac_dev *dev = fib->dev; | ||
375 | volatile void __iomem *device = dev->regs.rkt; | ||
376 | u32 Index; | ||
377 | |||
378 | dprintk((KERN_DEBUG "%p->aac_rkt_send(%p->%llx)\n", dev, fib, addr)); | ||
379 | Index = rkt_readl(dev, MUnit.InboundQueue); | ||
380 | if (Index == 0xFFFFFFFFL) | ||
381 | Index = rkt_readl(dev, MUnit.InboundQueue); | ||
382 | dprintk((KERN_DEBUG "Index = 0x%x\n", Index)); | ||
383 | if (Index == 0xFFFFFFFFL) | ||
384 | return Index; | ||
385 | device += Index; | ||
386 | dprintk((KERN_DEBUG "entry = %x %x %u\n", (u32)(addr & 0xffffffff), | ||
387 | (u32)(addr >> 32), (u32)le16_to_cpu(fib->hw_fib->header.Size))); | ||
388 | writel((u32)(addr & 0xffffffff), device); | ||
389 | device += sizeof(u32); | ||
390 | writel((u32)(addr >> 32), device); | ||
391 | device += sizeof(u32); | ||
392 | writel(le16_to_cpu(fib->hw_fib->header.Size), device); | ||
393 | rkt_writel(dev, MUnit.InboundQueue, Index); | ||
394 | dprintk((KERN_DEBUG "aac_rkt_send - return 0\n")); | ||
395 | return 0; | 52 | return 0; |
396 | } | 53 | } |
397 | 54 | ||
@@ -406,78 +63,18 @@ static int aac_rkt_send(struct fib * fib) | |||
406 | 63 | ||
407 | int aac_rkt_init(struct aac_dev *dev) | 64 | int aac_rkt_init(struct aac_dev *dev) |
408 | { | 65 | { |
409 | unsigned long start; | 66 | int retval; |
410 | unsigned long status; | 67 | extern int _aac_rx_init(struct aac_dev *dev); |
411 | int instance; | 68 | extern void aac_rx_start_adapter(struct aac_dev *dev); |
412 | const char * name; | ||
413 | |||
414 | instance = dev->id; | ||
415 | name = dev->name; | ||
416 | 69 | ||
417 | /* | 70 | /* |
418 | * Check to see if the board panic'd while booting. | ||
419 | */ | ||
420 | /* | ||
421 | * Check to see if the board failed any self tests. | ||
422 | */ | ||
423 | if (rkt_readl(dev, MUnit.OMRx[0]) & SELF_TEST_FAILED) { | ||
424 | printk(KERN_ERR "%s%d: adapter self-test failed.\n", dev->name, instance); | ||
425 | goto error_iounmap; | ||
426 | } | ||
427 | /* | ||
428 | * Check to see if the monitor panic'd while booting. | ||
429 | */ | ||
430 | if (rkt_readl(dev, MUnit.OMRx[0]) & MONITOR_PANIC) { | ||
431 | printk(KERN_ERR "%s%d: adapter monitor panic.\n", dev->name, instance); | ||
432 | goto error_iounmap; | ||
433 | } | ||
434 | /* | ||
435 | * Check to see if the board panic'd while booting. | ||
436 | */ | ||
437 | if (rkt_readl(dev, MUnit.OMRx[0]) & KERNEL_PANIC) { | ||
438 | printk(KERN_ERR "%s%d: adapter kernel panic'd.\n", dev->name, instance); | ||
439 | goto error_iounmap; | ||
440 | } | ||
441 | start = jiffies; | ||
442 | /* | ||
443 | * Wait for the adapter to be up and running. Wait up to 3 minutes | ||
444 | */ | ||
445 | while (!(rkt_readl(dev, MUnit.OMRx[0]) & KERNEL_UP_AND_RUNNING)) | ||
446 | { | ||
447 | if(time_after(jiffies, start+startup_timeout*HZ)) | ||
448 | { | ||
449 | status = rkt_readl(dev, MUnit.OMRx[0]); | ||
450 | printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n", | ||
451 | dev->name, instance, status); | ||
452 | goto error_iounmap; | ||
453 | } | ||
454 | msleep(1); | ||
455 | } | ||
456 | if (request_irq(dev->scsi_host_ptr->irq, aac_rkt_intr, IRQF_SHARED|IRQF_DISABLED, "aacraid", (void *)dev)<0) | ||
457 | { | ||
458 | printk(KERN_ERR "%s%d: Interrupt unavailable.\n", name, instance); | ||
459 | goto error_iounmap; | ||
460 | } | ||
461 | /* | ||
462 | * Fill in the function dispatch table. | 71 | * Fill in the function dispatch table. |
463 | */ | 72 | */ |
464 | dev->a_ops.adapter_interrupt = aac_rkt_interrupt_adapter; | 73 | dev->a_ops.adapter_ioremap = aac_rkt_ioremap; |
465 | dev->a_ops.adapter_disable_int = aac_rkt_disable_interrupt; | ||
466 | dev->a_ops.adapter_notify = aac_rkt_notify_adapter; | ||
467 | dev->a_ops.adapter_sync_cmd = rkt_sync_cmd; | ||
468 | dev->a_ops.adapter_check_health = aac_rkt_check_health; | ||
469 | dev->a_ops.adapter_send = aac_rkt_send; | ||
470 | |||
471 | /* | ||
472 | * First clear out all interrupts. Then enable the one's that we | ||
473 | * can handle. | ||
474 | */ | ||
475 | rkt_writeb(dev, MUnit.OIMR, 0xff); | ||
476 | rkt_writel(dev, MUnit.ODR, 0xffffffff); | ||
477 | rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb); | ||
478 | 74 | ||
479 | if (aac_init_adapter(dev) == NULL) | 75 | retval = _aac_rx_init(dev); |
480 | goto error_irq; | 76 | if (retval) |
77 | return retval; | ||
481 | if (dev->new_comm_interface) { | 78 | if (dev->new_comm_interface) { |
482 | /* | 79 | /* |
483 | * FIB Setup has already been done, but we can minimize the | 80 | * FIB Setup has already been done, but we can minimize the |
@@ -494,20 +91,11 @@ int aac_rkt_init(struct aac_dev *dev) | |||
494 | dev->init->MaxIoCommands = cpu_to_le32(246); | 91 | dev->init->MaxIoCommands = cpu_to_le32(246); |
495 | dev->scsi_host_ptr->can_queue = 246 - AAC_NUM_MGT_FIB; | 92 | dev->scsi_host_ptr->can_queue = 246 - AAC_NUM_MGT_FIB; |
496 | } | 93 | } |
497 | rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7); | ||
498 | } | 94 | } |
499 | /* | 95 | /* |
500 | * Tell the adapter that all is configured, and it can start | 96 | * Tell the adapter that all is configured, and it can start |
501 | * accepting requests | 97 | * accepting requests |
502 | */ | 98 | */ |
503 | aac_rkt_start_adapter(dev); | 99 | aac_rx_start_adapter(dev); |
504 | return 0; | 100 | return 0; |
505 | |||
506 | error_irq: | ||
507 | rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff); | ||
508 | free_irq(dev->scsi_host_ptr->irq, (void *)dev); | ||
509 | |||
510 | error_iounmap: | ||
511 | |||
512 | return -1; | ||
513 | } | 101 | } |
diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c index 035018db69b..a1d214d770e 100644 --- a/drivers/scsi/aacraid/rx.c +++ b/drivers/scsi/aacraid/rx.c | |||
@@ -79,7 +79,7 @@ static irqreturn_t aac_rx_intr(int irq, void *dev_id, struct pt_regs *regs) | |||
79 | { | 79 | { |
80 | bellbits = rx_readl(dev, OutboundDoorbellReg); | 80 | bellbits = rx_readl(dev, OutboundDoorbellReg); |
81 | if (bellbits & DoorBellPrintfReady) { | 81 | if (bellbits & DoorBellPrintfReady) { |
82 | aac_printf(dev, rx_readl (dev, IndexRegs.Mailbox[5])); | 82 | aac_printf(dev, readl (&dev->IndexRegs->Mailbox[5])); |
83 | rx_writel(dev, MUnit.ODR,DoorBellPrintfReady); | 83 | rx_writel(dev, MUnit.ODR,DoorBellPrintfReady); |
84 | rx_writel(dev, InboundDoorbellReg,DoorBellPrintfDone); | 84 | rx_writel(dev, InboundDoorbellReg,DoorBellPrintfDone); |
85 | } | 85 | } |
@@ -134,14 +134,14 @@ static int rx_sync_cmd(struct aac_dev *dev, u32 command, | |||
134 | /* | 134 | /* |
135 | * Write the command into Mailbox 0 | 135 | * Write the command into Mailbox 0 |
136 | */ | 136 | */ |
137 | rx_writel(dev, InboundMailbox0, command); | 137 | writel(command, &dev->IndexRegs->Mailbox[0]); |
138 | /* | 138 | /* |
139 | * Write the parameters into Mailboxes 1 - 6 | 139 | * Write the parameters into Mailboxes 1 - 6 |
140 | */ | 140 | */ |
141 | rx_writel(dev, InboundMailbox1, p1); | 141 | writel(p1, &dev->IndexRegs->Mailbox[1]); |
142 | rx_writel(dev, InboundMailbox2, p2); | 142 | writel(p2, &dev->IndexRegs->Mailbox[2]); |
143 | rx_writel(dev, InboundMailbox3, p3); | 143 | writel(p3, &dev->IndexRegs->Mailbox[3]); |
144 | rx_writel(dev, InboundMailbox4, p4); | 144 | writel(p4, &dev->IndexRegs->Mailbox[4]); |
145 | /* | 145 | /* |
146 | * Clear the synch command doorbell to start on a clean slate. | 146 | * Clear the synch command doorbell to start on a clean slate. |
147 | */ | 147 | */ |
@@ -199,15 +199,15 @@ static int rx_sync_cmd(struct aac_dev *dev, u32 command, | |||
199 | * Pull the synch status from Mailbox 0. | 199 | * Pull the synch status from Mailbox 0. |
200 | */ | 200 | */ |
201 | if (status) | 201 | if (status) |
202 | *status = rx_readl(dev, IndexRegs.Mailbox[0]); | 202 | *status = readl(&dev->IndexRegs->Mailbox[0]); |
203 | if (r1) | 203 | if (r1) |
204 | *r1 = rx_readl(dev, IndexRegs.Mailbox[1]); | 204 | *r1 = readl(&dev->IndexRegs->Mailbox[1]); |
205 | if (r2) | 205 | if (r2) |
206 | *r2 = rx_readl(dev, IndexRegs.Mailbox[2]); | 206 | *r2 = readl(&dev->IndexRegs->Mailbox[2]); |
207 | if (r3) | 207 | if (r3) |
208 | *r3 = rx_readl(dev, IndexRegs.Mailbox[3]); | 208 | *r3 = readl(&dev->IndexRegs->Mailbox[3]); |
209 | if (r4) | 209 | if (r4) |
210 | *r4 = rx_readl(dev, IndexRegs.Mailbox[4]); | 210 | *r4 = readl(&dev->IndexRegs->Mailbox[4]); |
211 | /* | 211 | /* |
212 | * Clear the synch command doorbell. | 212 | * Clear the synch command doorbell. |
213 | */ | 213 | */ |
@@ -261,8 +261,6 @@ static void aac_rx_notify_adapter(struct aac_dev *dev, u32 event) | |||
261 | rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_3); | 261 | rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_3); |
262 | break; | 262 | break; |
263 | case HostShutdown: | 263 | case HostShutdown: |
264 | // rx_sync_cmd(dev, HOST_CRASHING, 0, 0, 0, 0, 0, 0, | ||
265 | // NULL, NULL, NULL, NULL, NULL); | ||
266 | break; | 264 | break; |
267 | case FastIo: | 265 | case FastIo: |
268 | rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_6); | 266 | rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_6); |
@@ -283,7 +281,7 @@ static void aac_rx_notify_adapter(struct aac_dev *dev, u32 event) | |||
283 | * Start up processing on an i960 based AAC adapter | 281 | * Start up processing on an i960 based AAC adapter |
284 | */ | 282 | */ |
285 | 283 | ||
286 | static void aac_rx_start_adapter(struct aac_dev *dev) | 284 | void aac_rx_start_adapter(struct aac_dev *dev) |
287 | { | 285 | { |
288 | struct aac_init *init; | 286 | struct aac_init *init; |
289 | 287 | ||
@@ -381,7 +379,7 @@ static int aac_rx_send(struct fib * fib) | |||
381 | dprintk((KERN_DEBUG "Index = 0x%x\n", Index)); | 379 | dprintk((KERN_DEBUG "Index = 0x%x\n", Index)); |
382 | if (Index == 0xFFFFFFFFL) | 380 | if (Index == 0xFFFFFFFFL) |
383 | return Index; | 381 | return Index; |
384 | device += Index; | 382 | device = dev->base + Index; |
385 | dprintk((KERN_DEBUG "entry = %x %x %u\n", (u32)(addr & 0xffffffff), | 383 | dprintk((KERN_DEBUG "entry = %x %x %u\n", (u32)(addr & 0xffffffff), |
386 | (u32)(addr >> 32), (u32)le16_to_cpu(fib->hw_fib->header.Size))); | 384 | (u32)(addr >> 32), (u32)le16_to_cpu(fib->hw_fib->header.Size))); |
387 | writel((u32)(addr & 0xffffffff), device); | 385 | writel((u32)(addr & 0xffffffff), device); |
@@ -395,6 +393,43 @@ static int aac_rx_send(struct fib * fib) | |||
395 | } | 393 | } |
396 | 394 | ||
397 | /** | 395 | /** |
396 | * aac_rx_ioremap | ||
397 | * @size: mapping resize request | ||
398 | * | ||
399 | */ | ||
400 | static int aac_rx_ioremap(struct aac_dev * dev, u32 size) | ||
401 | { | ||
402 | if (!size) { | ||
403 | iounmap(dev->regs.rx); | ||
404 | return 0; | ||
405 | } | ||
406 | dev->base = dev->regs.rx = ioremap(dev->scsi_host_ptr->base, size); | ||
407 | if (dev->base == NULL) | ||
408 | return -1; | ||
409 | dev->IndexRegs = &dev->regs.rx->IndexRegs; | ||
410 | return 0; | ||
411 | } | ||
412 | |||
413 | static int aac_rx_restart_adapter(struct aac_dev *dev) | ||
414 | { | ||
415 | u32 var; | ||
416 | |||
417 | printk(KERN_ERR "%s%d: adapter kernel panic'd.\n", | ||
418 | dev->name, dev->id); | ||
419 | |||
420 | if (aac_rx_check_health(dev) <= 0) | ||
421 | return 1; | ||
422 | if (rx_sync_cmd(dev, IOP_RESET, 0, 0, 0, 0, 0, 0, | ||
423 | &var, NULL, NULL, NULL, NULL)) | ||
424 | return 1; | ||
425 | if (var != 0x00000001) | ||
426 | return 1; | ||
427 | if (rx_readl(dev, MUnit.OMRx[0]) & KERNEL_PANIC) | ||
428 | return 1; | ||
429 | return 0; | ||
430 | } | ||
431 | |||
432 | /** | ||
398 | * aac_rx_init - initialize an i960 based AAC card | 433 | * aac_rx_init - initialize an i960 based AAC card |
399 | * @dev: device to configure | 434 | * @dev: device to configure |
400 | * | 435 | * |
@@ -403,7 +438,7 @@ static int aac_rx_send(struct fib * fib) | |||
403 | * to the comm region. | 438 | * to the comm region. |
404 | */ | 439 | */ |
405 | 440 | ||
406 | int aac_rx_init(struct aac_dev *dev) | 441 | int _aac_rx_init(struct aac_dev *dev) |
407 | { | 442 | { |
408 | unsigned long start; | 443 | unsigned long start; |
409 | unsigned long status; | 444 | unsigned long status; |
@@ -413,27 +448,30 @@ int aac_rx_init(struct aac_dev *dev) | |||
413 | instance = dev->id; | 448 | instance = dev->id; |
414 | name = dev->name; | 449 | name = dev->name; |
415 | 450 | ||
451 | if (aac_adapter_ioremap(dev, dev->base_size)) { | ||
452 | printk(KERN_WARNING "%s: unable to map adapter.\n", name); | ||
453 | goto error_iounmap; | ||
454 | } | ||
455 | |||
416 | /* | 456 | /* |
417 | * Check to see if the board panic'd while booting. | 457 | * Check to see if the board panic'd while booting. |
418 | */ | 458 | */ |
459 | status = rx_readl(dev, MUnit.OMRx[0]); | ||
460 | if (status & KERNEL_PANIC) | ||
461 | if (aac_rx_restart_adapter(dev)) | ||
462 | goto error_iounmap; | ||
419 | /* | 463 | /* |
420 | * Check to see if the board failed any self tests. | 464 | * Check to see if the board failed any self tests. |
421 | */ | 465 | */ |
422 | if (rx_readl(dev, MUnit.OMRx[0]) & SELF_TEST_FAILED) { | 466 | status = rx_readl(dev, MUnit.OMRx[0]); |
467 | if (status & SELF_TEST_FAILED) { | ||
423 | printk(KERN_ERR "%s%d: adapter self-test failed.\n", dev->name, instance); | 468 | printk(KERN_ERR "%s%d: adapter self-test failed.\n", dev->name, instance); |
424 | goto error_iounmap; | 469 | goto error_iounmap; |
425 | } | 470 | } |
426 | /* | 471 | /* |
427 | * Check to see if the board panic'd while booting. | ||
428 | */ | ||
429 | if (rx_readl(dev, MUnit.OMRx[0]) & KERNEL_PANIC) { | ||
430 | printk(KERN_ERR "%s%d: adapter kernel panic.\n", dev->name, instance); | ||
431 | goto error_iounmap; | ||
432 | } | ||
433 | /* | ||
434 | * Check to see if the monitor panic'd while booting. | 472 | * Check to see if the monitor panic'd while booting. |
435 | */ | 473 | */ |
436 | if (rx_readl(dev, MUnit.OMRx[0]) & MONITOR_PANIC) { | 474 | if (status & MONITOR_PANIC) { |
437 | printk(KERN_ERR "%s%d: adapter monitor panic.\n", dev->name, instance); | 475 | printk(KERN_ERR "%s%d: adapter monitor panic.\n", dev->name, instance); |
438 | goto error_iounmap; | 476 | goto error_iounmap; |
439 | } | 477 | } |
@@ -441,12 +479,10 @@ int aac_rx_init(struct aac_dev *dev) | |||
441 | /* | 479 | /* |
442 | * Wait for the adapter to be up and running. Wait up to 3 minutes | 480 | * Wait for the adapter to be up and running. Wait up to 3 minutes |
443 | */ | 481 | */ |
444 | while ((!(rx_readl(dev, IndexRegs.Mailbox[7]) & KERNEL_UP_AND_RUNNING)) | 482 | while (!((status = rx_readl(dev, MUnit.OMRx[0])) & KERNEL_UP_AND_RUNNING)) |
445 | || (!(rx_readl(dev, MUnit.OMRx[0]) & KERNEL_UP_AND_RUNNING))) | ||
446 | { | 483 | { |
447 | if(time_after(jiffies, start+startup_timeout*HZ)) | 484 | if(time_after(jiffies, start+startup_timeout*HZ)) |
448 | { | 485 | { |
449 | status = rx_readl(dev, IndexRegs.Mailbox[7]); | ||
450 | printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n", | 486 | printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n", |
451 | dev->name, instance, status); | 487 | dev->name, instance, status); |
452 | goto error_iounmap; | 488 | goto error_iounmap; |
@@ -481,11 +517,6 @@ int aac_rx_init(struct aac_dev *dev) | |||
481 | if (dev->new_comm_interface) | 517 | if (dev->new_comm_interface) |
482 | rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7); | 518 | rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7); |
483 | 519 | ||
484 | /* | ||
485 | * Tell the adapter that all is configured, and it can start | ||
486 | * accepting requests | ||
487 | */ | ||
488 | aac_rx_start_adapter(dev); | ||
489 | return 0; | 520 | return 0; |
490 | 521 | ||
491 | error_irq: | 522 | error_irq: |
@@ -496,3 +527,23 @@ error_iounmap: | |||
496 | 527 | ||
497 | return -1; | 528 | return -1; |
498 | } | 529 | } |
530 | |||
531 | int aac_rx_init(struct aac_dev *dev) | ||
532 | { | ||
533 | int retval; | ||
534 | |||
535 | /* | ||
536 | * Fill in the function dispatch table. | ||
537 | */ | ||
538 | dev->a_ops.adapter_ioremap = aac_rx_ioremap; | ||
539 | |||
540 | retval = _aac_rx_init(dev); | ||
541 | if (!retval) { | ||
542 | /* | ||
543 | * Tell the adapter that all is configured, and it can | ||
544 | * start accepting requests | ||
545 | */ | ||
546 | aac_rx_start_adapter(dev); | ||
547 | } | ||
548 | return retval; | ||
549 | } | ||
diff --git a/drivers/scsi/aacraid/sa.c b/drivers/scsi/aacraid/sa.c index cd586cc8f9b..f906ead239d 100644 --- a/drivers/scsi/aacraid/sa.c +++ b/drivers/scsi/aacraid/sa.c | |||
@@ -281,6 +281,21 @@ static int aac_sa_check_health(struct aac_dev *dev) | |||
281 | } | 281 | } |
282 | 282 | ||
283 | /** | 283 | /** |
284 | * aac_sa_ioremap | ||
285 | * @size: mapping resize request | ||
286 | * | ||
287 | */ | ||
288 | static int aac_sa_ioremap(struct aac_dev * dev, u32 size) | ||
289 | { | ||
290 | if (!size) { | ||
291 | iounmap(dev->regs.sa); | ||
292 | return 0; | ||
293 | } | ||
294 | dev->base = dev->regs.sa = ioremap(dev->scsi_host_ptr->base, size); | ||
295 | return (dev->base == NULL) ? -1 : 0; | ||
296 | } | ||
297 | |||
298 | /** | ||
284 | * aac_sa_init - initialize an ARM based AAC card | 299 | * aac_sa_init - initialize an ARM based AAC card |
285 | * @dev: device to configure | 300 | * @dev: device to configure |
286 | * | 301 | * |
@@ -299,6 +314,11 @@ int aac_sa_init(struct aac_dev *dev) | |||
299 | instance = dev->id; | 314 | instance = dev->id; |
300 | name = dev->name; | 315 | name = dev->name; |
301 | 316 | ||
317 | if (aac_sa_ioremap(dev, dev->base_size)) { | ||
318 | printk(KERN_WARNING "%s: unable to map adapter.\n", name); | ||
319 | goto error_iounmap; | ||
320 | } | ||
321 | |||
302 | /* | 322 | /* |
303 | * Check to see if the board failed any self tests. | 323 | * Check to see if the board failed any self tests. |
304 | */ | 324 | */ |
@@ -341,6 +361,7 @@ int aac_sa_init(struct aac_dev *dev) | |||
341 | dev->a_ops.adapter_notify = aac_sa_notify_adapter; | 361 | dev->a_ops.adapter_notify = aac_sa_notify_adapter; |
342 | dev->a_ops.adapter_sync_cmd = sa_sync_cmd; | 362 | dev->a_ops.adapter_sync_cmd = sa_sync_cmd; |
343 | dev->a_ops.adapter_check_health = aac_sa_check_health; | 363 | dev->a_ops.adapter_check_health = aac_sa_check_health; |
364 | dev->a_ops.adapter_ioremap = aac_sa_ioremap; | ||
344 | 365 | ||
345 | /* | 366 | /* |
346 | * First clear out all interrupts. Then enable the one's that | 367 | * First clear out all interrupts. Then enable the one's that |