diff options
author | Mark Haverkamp <markh@osdl.org> | 2005-05-16 21:28:42 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.(none)> | 2005-05-20 16:48:00 -0400 |
commit | 7c00ffa314bf0fb0e23858bbebad33b48b6abbb9 (patch) | |
tree | 4d6b65bb5a2c8fecf48a8c6402c2cc867aa2fe6c /drivers | |
parent | 672b2d38da4fff4c4452685a25fb88b65243d1a6 (diff) |
[SCSI] 2.6 aacraid: Variable FIB size (updated patch)
New code from the Adaptec driver. Performance enhancement for newer
adapters. I hope that this isn't too big for a single patch. I believe
that other than the few small cleanups mentioned, that the changes are
all related.
- Added Variable FIB size negotiation for new adapters.
- Added support to maximize scatter gather tables and thus permit
requests larger than 64KB/each.
- Limit Scatter Gather to 34 elements for ROMB platforms.
- aac_printf is only enabled with AAC_QUIRK_34SG
- Large FIB ioctl support
- some minor cleanup
Passes sparse check.
I have tested it on x86 and ppc64 machines.
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/aacraid/aachba.c | 132 | ||||
-rw-r--r-- | drivers/scsi/aacraid/aacraid.h | 70 | ||||
-rw-r--r-- | drivers/scsi/aacraid/commctrl.c | 180 | ||||
-rw-r--r-- | drivers/scsi/aacraid/comminit.c | 86 | ||||
-rw-r--r-- | drivers/scsi/aacraid/commsup.c | 85 | ||||
-rw-r--r-- | drivers/scsi/aacraid/linit.c | 33 | ||||
-rw-r--r-- | drivers/scsi/aacraid/rkt.c | 39 | ||||
-rw-r--r-- | drivers/scsi/aacraid/rx.c | 40 | ||||
-rw-r--r-- | drivers/scsi/aacraid/sa.c | 31 |
9 files changed, 501 insertions, 195 deletions
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 9946e305055b..f02c99641467 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c | |||
@@ -53,10 +53,6 @@ | |||
53 | #define INQD_PDT_DMASK 0x1F /* Peripheral Device Type Mask */ | 53 | #define INQD_PDT_DMASK 0x1F /* Peripheral Device Type Mask */ |
54 | #define INQD_PDT_QMASK 0xE0 /* Peripheral Device Qualifer Mask */ | 54 | #define INQD_PDT_QMASK 0xE0 /* Peripheral Device Qualifer Mask */ |
55 | 55 | ||
56 | #define MAX_FIB_DATA (sizeof(struct hw_fib) - sizeof(FIB_HEADER)) | ||
57 | |||
58 | #define MAX_DRIVER_SG_SEGMENT_COUNT 17 | ||
59 | |||
60 | /* | 56 | /* |
61 | * Sense codes | 57 | * Sense codes |
62 | */ | 58 | */ |
@@ -158,6 +154,13 @@ MODULE_PARM_DESC(dacmode, "Control whether dma addressing is using 64 bit DAC. 0 | |||
158 | module_param(commit, int, 0); | 154 | module_param(commit, int, 0); |
159 | MODULE_PARM_DESC(commit, "Control whether a COMMIT_CONFIG is issued to the adapter for foreign arrays.\nThis is typically needed in systems that do not have a BIOS. 0=off, 1=on"); | 155 | MODULE_PARM_DESC(commit, "Control whether a COMMIT_CONFIG is issued to the adapter for foreign arrays.\nThis is typically needed in systems that do not have a BIOS. 0=off, 1=on"); |
160 | 156 | ||
157 | int numacb = -1; | ||
158 | module_param(numacb, int, S_IRUGO|S_IWUSR); | ||
159 | MODULE_PARM_DESC(numacb, "Request a limit to the number of adapter control blocks (FIB) allocated. Valid\nvalues are 512 and down. Default is to use suggestion from Firmware."); | ||
160 | |||
161 | int acbsize = -1; | ||
162 | module_param(acbsize, int, S_IRUGO|S_IWUSR); | ||
163 | MODULE_PARM_DESC(acbsize, "Request a specific adapter control block (FIB) size. Valid values are 512,\n2048, 4096 and 8192. Default is to use suggestion from Firmware."); | ||
161 | /** | 164 | /** |
162 | * aac_get_config_status - check the adapter configuration | 165 | * aac_get_config_status - check the adapter configuration |
163 | * @common: adapter to query | 166 | * @common: adapter to query |
@@ -462,7 +465,7 @@ static int probe_container(struct aac_dev *dev, int cid) | |||
462 | 1, 1, | 465 | 1, 1, |
463 | NULL, NULL); | 466 | NULL, NULL); |
464 | if (status < 0) { | 467 | if (status < 0) { |
465 | printk(KERN_WARNING "aacraid: probe_containers query failed.\n"); | 468 | printk(KERN_WARNING "aacraid: probe_container query failed.\n"); |
466 | goto error; | 469 | goto error; |
467 | } | 470 | } |
468 | 471 | ||
@@ -605,35 +608,63 @@ static void set_sense(u8 *sense_buf, u8 sense_key, u8 sense_code, | |||
605 | int aac_get_adapter_info(struct aac_dev* dev) | 608 | int aac_get_adapter_info(struct aac_dev* dev) |
606 | { | 609 | { |
607 | struct fib* fibptr; | 610 | struct fib* fibptr; |
608 | struct aac_adapter_info* info; | ||
609 | int rcode; | 611 | int rcode; |
610 | u32 tmp; | 612 | u32 tmp; |
613 | struct aac_adapter_info * info; | ||
614 | |||
611 | if (!(fibptr = fib_alloc(dev))) | 615 | if (!(fibptr = fib_alloc(dev))) |
612 | return -ENOMEM; | 616 | return -ENOMEM; |
613 | 617 | ||
614 | fib_init(fibptr); | 618 | fib_init(fibptr); |
615 | info = (struct aac_adapter_info*) fib_data(fibptr); | 619 | info = (struct aac_adapter_info *) fib_data(fibptr); |
616 | 620 | memset(info,0,sizeof(*info)); | |
617 | memset(info,0,sizeof(struct aac_adapter_info)); | ||
618 | 621 | ||
619 | rcode = fib_send(RequestAdapterInfo, | 622 | rcode = fib_send(RequestAdapterInfo, |
620 | fibptr, | 623 | fibptr, |
621 | sizeof(struct aac_adapter_info), | 624 | sizeof(*info), |
622 | FsaNormal, | 625 | FsaNormal, |
623 | 1, 1, | 626 | 1, 1, |
624 | NULL, | 627 | NULL, |
625 | NULL); | 628 | NULL); |
629 | |||
630 | if (rcode < 0) { | ||
631 | fib_complete(fibptr); | ||
632 | fib_free(fibptr); | ||
633 | return rcode; | ||
634 | } | ||
635 | memcpy(&dev->adapter_info, info, sizeof(*info)); | ||
626 | 636 | ||
627 | memcpy(&dev->adapter_info, info, sizeof(struct aac_adapter_info)); | 637 | if (dev->adapter_info.options & AAC_OPT_SUPPLEMENT_ADAPTER_INFO) { |
638 | struct aac_supplement_adapter_info * info; | ||
639 | |||
640 | fib_init(fibptr); | ||
641 | |||
642 | info = (struct aac_supplement_adapter_info *) fib_data(fibptr); | ||
643 | |||
644 | memset(info,0,sizeof(*info)); | ||
645 | |||
646 | rcode = fib_send(RequestSupplementAdapterInfo, | ||
647 | fibptr, | ||
648 | sizeof(*info), | ||
649 | FsaNormal, | ||
650 | 1, 1, | ||
651 | NULL, | ||
652 | NULL); | ||
653 | |||
654 | if (rcode >= 0) | ||
655 | memcpy(&dev->supplement_adapter_info, info, sizeof(*info)); | ||
656 | } | ||
628 | 657 | ||
629 | tmp = le32_to_cpu(dev->adapter_info.kernelrev); | 658 | tmp = le32_to_cpu(dev->adapter_info.kernelrev); |
630 | printk(KERN_INFO "%s%d: kernel %d.%d-%d[%d]\n", | 659 | printk(KERN_INFO "%s%d: kernel %d.%d-%d[%d] %.*s\n", |
631 | dev->name, | 660 | dev->name, |
632 | dev->id, | 661 | dev->id, |
633 | tmp>>24, | 662 | tmp>>24, |
634 | (tmp>>16)&0xff, | 663 | (tmp>>16)&0xff, |
635 | tmp&0xff, | 664 | tmp&0xff, |
636 | le32_to_cpu(dev->adapter_info.kernelbuild)); | 665 | le32_to_cpu(dev->adapter_info.kernelbuild), |
666 | (int)sizeof(dev->supplement_adapter_info.BuildDate), | ||
667 | dev->supplement_adapter_info.BuildDate); | ||
637 | tmp = le32_to_cpu(dev->adapter_info.monitorrev); | 668 | tmp = le32_to_cpu(dev->adapter_info.monitorrev); |
638 | printk(KERN_INFO "%s%d: monitor %d.%d-%d[%d]\n", | 669 | printk(KERN_INFO "%s%d: monitor %d.%d-%d[%d]\n", |
639 | dev->name, dev->id, | 670 | dev->name, dev->id, |
@@ -707,6 +738,38 @@ int aac_get_adapter_info(struct aac_dev* dev) | |||
707 | rcode = -ENOMEM; | 738 | rcode = -ENOMEM; |
708 | } | 739 | } |
709 | } | 740 | } |
741 | /* | ||
742 | * 57 scatter gather elements | ||
743 | */ | ||
744 | dev->scsi_host_ptr->sg_tablesize = (dev->max_fib_size - | ||
745 | sizeof(struct aac_fibhdr) - | ||
746 | sizeof(struct aac_write) + sizeof(struct sgmap)) / | ||
747 | sizeof(struct sgmap); | ||
748 | if (dev->dac_support) { | ||
749 | /* | ||
750 | * 38 scatter gather elements | ||
751 | */ | ||
752 | dev->scsi_host_ptr->sg_tablesize = | ||
753 | (dev->max_fib_size - | ||
754 | sizeof(struct aac_fibhdr) - | ||
755 | sizeof(struct aac_write64) + | ||
756 | sizeof(struct sgmap64)) / | ||
757 | sizeof(struct sgmap64); | ||
758 | } | ||
759 | dev->scsi_host_ptr->max_sectors = AAC_MAX_32BIT_SGBCOUNT; | ||
760 | if(!(dev->adapter_info.options & AAC_OPT_NEW_COMM)) { | ||
761 | /* | ||
762 | * Worst case size that could cause sg overflow when | ||
763 | * we break up SG elements that are larger than 64KB. | ||
764 | * Would be nice if we could tell the SCSI layer what | ||
765 | * the maximum SG element size can be. Worst case is | ||
766 | * (sg_tablesize-1) 4KB elements with one 64KB | ||
767 | * element. | ||
768 | * 32bit -> 468 or 238KB 64bit -> 424 or 212KB | ||
769 | */ | ||
770 | dev->scsi_host_ptr->max_sectors = | ||
771 | (dev->scsi_host_ptr->sg_tablesize * 8) + 112; | ||
772 | } | ||
710 | 773 | ||
711 | fib_complete(fibptr); | 774 | fib_complete(fibptr); |
712 | fib_free(fibptr); | 775 | fib_free(fibptr); |
@@ -747,8 +810,10 @@ static void read_callback(void *context, struct fib * fibptr) | |||
747 | if (le32_to_cpu(readreply->status) == ST_OK) | 810 | if (le32_to_cpu(readreply->status) == ST_OK) |
748 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | 811 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; |
749 | else { | 812 | else { |
750 | printk(KERN_WARNING "read_callback: read failed, status = %d\n", | 813 | #ifdef AAC_DETAILED_STATUS_INFO |
751 | le32_to_cpu(readreply->status)); | 814 | printk(KERN_WARNING "read_callback: io failed, status = %d\n", |
815 | le32_to_cpu(readreply->status)); | ||
816 | #endif | ||
752 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION; | 817 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION; |
753 | set_sense((u8 *) &dev->fsa_dev[cid].sense_data, | 818 | set_sense((u8 *) &dev->fsa_dev[cid].sense_data, |
754 | HARDWARE_ERROR, | 819 | HARDWARE_ERROR, |
@@ -842,7 +907,8 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) | |||
842 | lba = (scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5]; | 907 | lba = (scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5]; |
843 | count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8]; | 908 | count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8]; |
844 | } | 909 | } |
845 | dprintk((KERN_DEBUG "aac_read[cpu %d]: lba = %u, t = %ld.\n", smp_processor_id(), lba, jiffies)); | 910 | dprintk((KERN_DEBUG "aac_read[cpu %d]: lba = %u, t = %ld.\n", |
911 | smp_processor_id(), (unsigned long long)lba, jiffies)); | ||
846 | /* | 912 | /* |
847 | * Alocate and initialize a Fib | 913 | * Alocate and initialize a Fib |
848 | */ | 914 | */ |
@@ -852,7 +918,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) | |||
852 | 918 | ||
853 | fib_init(cmd_fibcontext); | 919 | fib_init(cmd_fibcontext); |
854 | 920 | ||
855 | if(dev->dac_support == 1) { | 921 | if (dev->dac_support == 1) { |
856 | struct aac_read64 *readcmd; | 922 | struct aac_read64 *readcmd; |
857 | readcmd = (struct aac_read64 *) fib_data(cmd_fibcontext); | 923 | readcmd = (struct aac_read64 *) fib_data(cmd_fibcontext); |
858 | readcmd->command = cpu_to_le32(VM_CtHostRead64); | 924 | readcmd->command = cpu_to_le32(VM_CtHostRead64); |
@@ -886,14 +952,11 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) | |||
886 | readcmd->block = cpu_to_le32(lba); | 952 | readcmd->block = cpu_to_le32(lba); |
887 | readcmd->count = cpu_to_le32(count * 512); | 953 | readcmd->count = cpu_to_le32(count * 512); |
888 | 954 | ||
889 | if (count * 512 > (64 * 1024)) | ||
890 | BUG(); | ||
891 | |||
892 | aac_build_sg(scsicmd, &readcmd->sg); | 955 | aac_build_sg(scsicmd, &readcmd->sg); |
893 | fibsize = sizeof(struct aac_read) + | 956 | fibsize = sizeof(struct aac_read) + |
894 | ((le32_to_cpu(readcmd->sg.count) - 1) * | 957 | ((le32_to_cpu(readcmd->sg.count) - 1) * |
895 | sizeof (struct sgentry)); | 958 | sizeof (struct sgentry)); |
896 | BUG_ON (fibsize > (sizeof(struct hw_fib) - | 959 | BUG_ON (fibsize > (dev->max_fib_size - |
897 | sizeof(struct aac_fibhdr))); | 960 | sizeof(struct aac_fibhdr))); |
898 | /* | 961 | /* |
899 | * Now send the Fib to the adapter | 962 | * Now send the Fib to the adapter |
@@ -976,7 +1039,7 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid) | |||
976 | fibsize = sizeof(struct aac_write64) + | 1039 | fibsize = sizeof(struct aac_write64) + |
977 | ((le32_to_cpu(writecmd->sg.count) - 1) * | 1040 | ((le32_to_cpu(writecmd->sg.count) - 1) * |
978 | sizeof (struct sgentry64)); | 1041 | sizeof (struct sgentry64)); |
979 | BUG_ON (fibsize > (sizeof(struct hw_fib) - | 1042 | BUG_ON (fibsize > (dev->max_fib_size - |
980 | sizeof(struct aac_fibhdr))); | 1043 | sizeof(struct aac_fibhdr))); |
981 | /* | 1044 | /* |
982 | * Now send the Fib to the adapter | 1045 | * Now send the Fib to the adapter |
@@ -998,15 +1061,11 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid) | |||
998 | writecmd->sg.count = cpu_to_le32(1); | 1061 | writecmd->sg.count = cpu_to_le32(1); |
999 | /* ->stable is not used - it did mean which type of write */ | 1062 | /* ->stable is not used - it did mean which type of write */ |
1000 | 1063 | ||
1001 | if (count * 512 > (64 * 1024)) { | ||
1002 | BUG(); | ||
1003 | } | ||
1004 | |||
1005 | aac_build_sg(scsicmd, &writecmd->sg); | 1064 | aac_build_sg(scsicmd, &writecmd->sg); |
1006 | fibsize = sizeof(struct aac_write) + | 1065 | fibsize = sizeof(struct aac_write) + |
1007 | ((le32_to_cpu(writecmd->sg.count) - 1) * | 1066 | ((le32_to_cpu(writecmd->sg.count) - 1) * |
1008 | sizeof (struct sgentry)); | 1067 | sizeof (struct sgentry)); |
1009 | BUG_ON (fibsize > (sizeof(struct hw_fib) - | 1068 | BUG_ON (fibsize > (dev->max_fib_size - |
1010 | sizeof(struct aac_fibhdr))); | 1069 | sizeof(struct aac_fibhdr))); |
1011 | /* | 1070 | /* |
1012 | * Now send the Fib to the adapter | 1071 | * Now send the Fib to the adapter |
@@ -1025,7 +1084,6 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid) | |||
1025 | */ | 1084 | */ |
1026 | if (status == -EINPROGRESS) | 1085 | if (status == -EINPROGRESS) |
1027 | { | 1086 | { |
1028 | dprintk("write queued.\n"); | ||
1029 | return 0; | 1087 | return 0; |
1030 | } | 1088 | } |
1031 | 1089 | ||
@@ -1111,7 +1169,7 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid) | |||
1111 | return SCSI_MLQUEUE_DEVICE_BUSY; | 1169 | return SCSI_MLQUEUE_DEVICE_BUSY; |
1112 | 1170 | ||
1113 | /* | 1171 | /* |
1114 | * Alocate and initialize a Fib | 1172 | * Allocate and initialize a Fib |
1115 | */ | 1173 | */ |
1116 | if (!(cmd_fibcontext = | 1174 | if (!(cmd_fibcontext = |
1117 | fib_alloc((struct aac_dev *)scsicmd->device->host->hostdata))) | 1175 | fib_alloc((struct aac_dev *)scsicmd->device->host->hostdata))) |
@@ -1403,7 +1461,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
1403 | /* | 1461 | /* |
1404 | * Unhandled commands | 1462 | * Unhandled commands |
1405 | */ | 1463 | */ |
1406 | printk(KERN_WARNING "Unhandled SCSI Command: 0x%x.\n", scsicmd->cmnd[0]); | 1464 | dprintk((KERN_WARNING "Unhandled SCSI Command: 0x%x.\n", scsicmd->cmnd[0])); |
1407 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION; | 1465 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION; |
1408 | set_sense((u8 *) &dev->fsa_dev[cid].sense_data, | 1466 | set_sense((u8 *) &dev->fsa_dev[cid].sense_data, |
1409 | ILLEGAL_REQUEST, SENCODE_INVALID_COMMAND, | 1467 | ILLEGAL_REQUEST, SENCODE_INVALID_COMMAND, |
@@ -1818,7 +1876,7 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd) | |||
1818 | fibsize = sizeof (struct aac_srb) - sizeof (struct sgentry) + | 1876 | fibsize = sizeof (struct aac_srb) - sizeof (struct sgentry) + |
1819 | ((le32_to_cpu(srbcmd->sg.count) & 0xff) * | 1877 | ((le32_to_cpu(srbcmd->sg.count) & 0xff) * |
1820 | sizeof (struct sgentry64)); | 1878 | sizeof (struct sgentry64)); |
1821 | BUG_ON (fibsize > (sizeof(struct hw_fib) - | 1879 | BUG_ON (fibsize > (dev->max_fib_size - |
1822 | sizeof(struct aac_fibhdr))); | 1880 | sizeof(struct aac_fibhdr))); |
1823 | 1881 | ||
1824 | /* | 1882 | /* |
@@ -1840,7 +1898,7 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd) | |||
1840 | fibsize = sizeof (struct aac_srb) + | 1898 | fibsize = sizeof (struct aac_srb) + |
1841 | (((le32_to_cpu(srbcmd->sg.count) & 0xff) - 1) * | 1899 | (((le32_to_cpu(srbcmd->sg.count) & 0xff) - 1) * |
1842 | sizeof (struct sgentry)); | 1900 | sizeof (struct sgentry)); |
1843 | BUG_ON (fibsize > (sizeof(struct hw_fib) - | 1901 | BUG_ON (fibsize > (dev->max_fib_size - |
1844 | sizeof(struct aac_fibhdr))); | 1902 | sizeof(struct aac_fibhdr))); |
1845 | 1903 | ||
1846 | /* | 1904 | /* |
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index a250a6f359b1..42484417cef7 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h | |||
@@ -8,12 +8,18 @@ | |||
8 | 8 | ||
9 | #define MAXIMUM_NUM_CONTAINERS 32 | 9 | #define MAXIMUM_NUM_CONTAINERS 32 |
10 | 10 | ||
11 | #define AAC_NUM_FIB (256 + 64) | 11 | #define AAC_NUM_MGT_FIB 8 |
12 | #define AAC_NUM_IO_FIB 100 | 12 | #define AAC_NUM_IO_FIB (512 - AAC_NUM_MGT_FIB) |
13 | #define AAC_NUM_FIB (AAC_NUM_IO_FIB + AAC_NUM_MGT_FIB) | ||
13 | 14 | ||
14 | #define AAC_MAX_LUN (8) | 15 | #define AAC_MAX_LUN (8) |
15 | 16 | ||
16 | #define AAC_MAX_HOSTPHYSMEMPAGES (0xfffff) | 17 | #define AAC_MAX_HOSTPHYSMEMPAGES (0xfffff) |
18 | /* | ||
19 | * max_sectors is an unsigned short, otherwise limit is 0x100000000 / 512 | ||
20 | * Linux has starvation problems if we permit larger than 4MB I/O ... | ||
21 | */ | ||
22 | #define AAC_MAX_32BIT_SGBCOUNT ((unsigned short)8192) | ||
17 | 23 | ||
18 | /* | 24 | /* |
19 | * These macros convert from physical channels to virtual channels | 25 | * These macros convert from physical channels to virtual channels |
@@ -303,12 +309,9 @@ struct aac_fibhdr { | |||
303 | } _u; | 309 | } _u; |
304 | }; | 310 | }; |
305 | 311 | ||
306 | #define FIB_DATA_SIZE_IN_BYTES (512 - sizeof(struct aac_fibhdr)) | ||
307 | |||
308 | |||
309 | struct hw_fib { | 312 | struct hw_fib { |
310 | struct aac_fibhdr header; | 313 | struct aac_fibhdr header; |
311 | u8 data[FIB_DATA_SIZE_IN_BYTES]; // Command specific data | 314 | u8 data[512-sizeof(struct aac_fibhdr)]; // Command specific data |
312 | }; | 315 | }; |
313 | 316 | ||
314 | /* | 317 | /* |
@@ -370,11 +373,12 @@ struct hw_fib { | |||
370 | #define RequestAdapterInfo 703 | 373 | #define RequestAdapterInfo 703 |
371 | #define IsAdapterPaused 704 | 374 | #define IsAdapterPaused 704 |
372 | #define SendHostTime 705 | 375 | #define SendHostTime 705 |
373 | #define LastMiscCommand 706 | 376 | #define RequestSupplementAdapterInfo 706 |
377 | #define LastMiscCommand 707 | ||
374 | 378 | ||
375 | // | 379 | /* |
376 | // Commands that will target the failover level on the FSA adapter | 380 | * Commands that will target the failover level on the FSA adapter |
377 | // | 381 | */ |
378 | 382 | ||
379 | enum fib_xfer_state { | 383 | enum fib_xfer_state { |
380 | HostOwned = (1<<0), | 384 | HostOwned = (1<<0), |
@@ -407,6 +411,7 @@ enum fib_xfer_state { | |||
407 | */ | 411 | */ |
408 | 412 | ||
409 | #define ADAPTER_INIT_STRUCT_REVISION 3 | 413 | #define ADAPTER_INIT_STRUCT_REVISION 3 |
414 | #define ADAPTER_INIT_STRUCT_REVISION_4 4 // rocket science | ||
410 | 415 | ||
411 | struct aac_init | 416 | struct aac_init |
412 | { | 417 | { |
@@ -424,6 +429,14 @@ struct aac_init | |||
424 | __le32 HostPhysMemPages; /* number of 4k pages of host | 429 | __le32 HostPhysMemPages; /* number of 4k pages of host |
425 | physical memory */ | 430 | physical memory */ |
426 | __le32 HostElapsedSeconds; /* number of seconds since 1970. */ | 431 | __le32 HostElapsedSeconds; /* number of seconds since 1970. */ |
432 | /* | ||
433 | * ADAPTER_INIT_STRUCT_REVISION_4 begins here | ||
434 | */ | ||
435 | __le32 InitFlags; /* flags for supported features */ | ||
436 | #define INITFLAGS_NEW_COMM_SUPPORTED 0x00000001 | ||
437 | __le32 MaxIoCommands; /* max outstanding commands */ | ||
438 | __le32 MaxIoSize; /* largest I/O command */ | ||
439 | __le32 MaxFibSize; /* largest FIB to adapter */ | ||
427 | }; | 440 | }; |
428 | 441 | ||
429 | enum aac_log_level { | 442 | enum aac_log_level { |
@@ -447,7 +460,7 @@ struct adapter_ops | |||
447 | { | 460 | { |
448 | void (*adapter_interrupt)(struct aac_dev *dev); | 461 | void (*adapter_interrupt)(struct aac_dev *dev); |
449 | void (*adapter_notify)(struct aac_dev *dev, u32 event); | 462 | void (*adapter_notify)(struct aac_dev *dev, u32 event); |
450 | int (*adapter_sync_cmd)(struct aac_dev *dev, u32 command, u32 p1, u32 *status); | 463 | 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); |
451 | int (*adapter_check_health)(struct aac_dev *dev); | 464 | int (*adapter_check_health)(struct aac_dev *dev); |
452 | }; | 465 | }; |
453 | 466 | ||
@@ -567,6 +580,7 @@ struct sa_drawbridge_CSR { | |||
567 | #define Mailbox3 SaDbCSR.MAILBOX3 | 580 | #define Mailbox3 SaDbCSR.MAILBOX3 |
568 | #define Mailbox4 SaDbCSR.MAILBOX4 | 581 | #define Mailbox4 SaDbCSR.MAILBOX4 |
569 | #define Mailbox5 SaDbCSR.MAILBOX5 | 582 | #define Mailbox5 SaDbCSR.MAILBOX5 |
583 | #define Mailbox6 SaDbCSR.MAILBOX6 | ||
570 | #define Mailbox7 SaDbCSR.MAILBOX7 | 584 | #define Mailbox7 SaDbCSR.MAILBOX7 |
571 | 585 | ||
572 | #define DoorbellReg_p SaDbCSR.PRISETIRQ | 586 | #define DoorbellReg_p SaDbCSR.PRISETIRQ |
@@ -812,6 +826,25 @@ struct aac_adapter_info | |||
812 | __le32 OEM; | 826 | __le32 OEM; |
813 | }; | 827 | }; |
814 | 828 | ||
829 | struct aac_supplement_adapter_info | ||
830 | { | ||
831 | u8 AdapterTypeText[17+1]; | ||
832 | u8 Pad[2]; | ||
833 | __le32 FlashMemoryByteSize; | ||
834 | __le32 FlashImageId; | ||
835 | __le32 MaxNumberPorts; | ||
836 | __le32 Version; | ||
837 | __le32 FeatureBits; | ||
838 | u8 SlotNumber; | ||
839 | u8 ReservedPad0[0]; | ||
840 | u8 BuildDate[12]; | ||
841 | __le32 CurrentNumberPorts; | ||
842 | __le32 ReservedGrowth[24]; | ||
843 | }; | ||
844 | #define AAC_FEATURE_FALCON 0x00000010 | ||
845 | #define AAC_SIS_VERSION_V3 3 | ||
846 | #define AAC_SIS_SLOT_UNKNOWN 0xFF | ||
847 | |||
815 | /* | 848 | /* |
816 | * Battery platforms | 849 | * Battery platforms |
817 | */ | 850 | */ |
@@ -857,6 +890,12 @@ struct aac_dev | |||
857 | 890 | ||
858 | u16 irq_mask; | 891 | u16 irq_mask; |
859 | /* | 892 | /* |
893 | * negotiated FIB settings | ||
894 | */ | ||
895 | unsigned max_fib_size; | ||
896 | unsigned sg_tablesize; | ||
897 | |||
898 | /* | ||
860 | * Map for 128 fib objects (64k) | 899 | * Map for 128 fib objects (64k) |
861 | */ | 900 | */ |
862 | dma_addr_t hw_fib_pa; | 901 | dma_addr_t hw_fib_pa; |
@@ -915,12 +954,14 @@ struct aac_dev | |||
915 | u32 aif_thread; | 954 | u32 aif_thread; |
916 | struct completion aif_completion; | 955 | struct completion aif_completion; |
917 | struct aac_adapter_info adapter_info; | 956 | struct aac_adapter_info adapter_info; |
957 | struct aac_supplement_adapter_info supplement_adapter_info; | ||
918 | /* These are in adapter info but they are in the io flow so | 958 | /* These are in adapter info but they are in the io flow so |
919 | * lets break them out so we don't have to do an AND to check them | 959 | * lets break them out so we don't have to do an AND to check them |
920 | */ | 960 | */ |
921 | u8 nondasd_support; | 961 | u8 nondasd_support; |
922 | u8 dac_support; | 962 | u8 dac_support; |
923 | u8 raid_scsi_mode; | 963 | u8 raid_scsi_mode; |
964 | u8 printf_enabled; | ||
924 | }; | 965 | }; |
925 | 966 | ||
926 | #define aac_adapter_interrupt(dev) \ | 967 | #define aac_adapter_interrupt(dev) \ |
@@ -929,6 +970,8 @@ struct aac_dev | |||
929 | #define aac_adapter_notify(dev, event) \ | 970 | #define aac_adapter_notify(dev, event) \ |
930 | (dev)->a_ops.adapter_notify(dev, event) | 971 | (dev)->a_ops.adapter_notify(dev, event) |
931 | 972 | ||
973 | #define aac_adapter_sync_cmd(dev, command, p1, p2, p3, p4, p5, p6, status, r1, r2, r3, r4) \ | ||
974 | (dev)->a_ops.adapter_sync_cmd(dev, command, p1, p2, p3, p4, p5, p6, status, r1, r2, r3, r4) | ||
932 | 975 | ||
933 | #define aac_adapter_check_health(dev) \ | 976 | #define aac_adapter_check_health(dev) \ |
934 | (dev)->a_ops.adapter_check_health(dev) | 977 | (dev)->a_ops.adapter_check_health(dev) |
@@ -1327,7 +1370,7 @@ struct aac_commit_config { | |||
1327 | }; | 1370 | }; |
1328 | 1371 | ||
1329 | /* | 1372 | /* |
1330 | * Query for Container Configuration Count | 1373 | * Query for Container Configuration Status |
1331 | */ | 1374 | */ |
1332 | 1375 | ||
1333 | #define CT_GET_CONTAINER_COUNT 4 | 1376 | #define CT_GET_CONTAINER_COUNT 4 |
@@ -1481,6 +1524,7 @@ struct revision | |||
1481 | #define FSACTL_GET_PCI_INFO CTL_CODE(2119, METHOD_BUFFERED) | 1524 | #define FSACTL_GET_PCI_INFO CTL_CODE(2119, METHOD_BUFFERED) |
1482 | #define FSACTL_FORCE_DELETE_DISK CTL_CODE(2120, METHOD_NEITHER) | 1525 | #define FSACTL_FORCE_DELETE_DISK CTL_CODE(2120, METHOD_NEITHER) |
1483 | #define FSACTL_GET_CONTAINERS 2131 | 1526 | #define FSACTL_GET_CONTAINERS 2131 |
1527 | #define FSACTL_SEND_LARGE_FIB CTL_CODE(2138, METHOD_BUFFERED) | ||
1484 | 1528 | ||
1485 | 1529 | ||
1486 | struct aac_common | 1530 | struct aac_common |
@@ -1667,3 +1711,5 @@ int fib_adapter_complete(struct fib * fibptr, unsigned short size); | |||
1667 | struct aac_driver_ident* aac_get_driver_ident(int devtype); | 1711 | struct aac_driver_ident* aac_get_driver_ident(int devtype); |
1668 | int aac_get_adapter_info(struct aac_dev* dev); | 1712 | int aac_get_adapter_info(struct aac_dev* dev); |
1669 | int aac_send_shutdown(struct aac_dev *dev); | 1713 | int aac_send_shutdown(struct aac_dev *dev); |
1714 | extern int numacb; | ||
1715 | extern int acbsize; | ||
diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c index e6da87d17832..fc268a410c27 100644 --- a/drivers/scsi/aacraid/commctrl.c +++ b/drivers/scsi/aacraid/commctrl.c | |||
@@ -51,15 +51,22 @@ | |||
51 | * This routine sends a fib to the adapter on behalf of a user level | 51 | * This routine sends a fib to the adapter on behalf of a user level |
52 | * program. | 52 | * program. |
53 | */ | 53 | */ |
54 | # define AAC_DEBUG_PREAMBLE KERN_INFO | ||
55 | # define AAC_DEBUG_POSTAMBLE | ||
54 | 56 | ||
55 | static int ioctl_send_fib(struct aac_dev * dev, void __user *arg) | 57 | static int ioctl_send_fib(struct aac_dev * dev, void __user *arg) |
56 | { | 58 | { |
57 | struct hw_fib * kfib; | 59 | struct hw_fib * kfib; |
58 | struct fib *fibptr; | 60 | struct fib *fibptr; |
61 | struct hw_fib * hw_fib = (struct hw_fib *)0; | ||
62 | dma_addr_t hw_fib_pa = (dma_addr_t)0LL; | ||
63 | unsigned size; | ||
64 | int retval; | ||
59 | 65 | ||
60 | fibptr = fib_alloc(dev); | 66 | fibptr = fib_alloc(dev); |
61 | if(fibptr == NULL) | 67 | if(fibptr == NULL) { |
62 | return -ENOMEM; | 68 | return -ENOMEM; |
69 | } | ||
63 | 70 | ||
64 | kfib = fibptr->hw_fib; | 71 | kfib = fibptr->hw_fib; |
65 | /* | 72 | /* |
@@ -74,16 +81,21 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg) | |||
74 | * will not overrun the buffer when we copy the memory. Return | 81 | * will not overrun the buffer when we copy the memory. Return |
75 | * an error if we would. | 82 | * an error if we would. |
76 | */ | 83 | */ |
77 | if (le16_to_cpu(kfib->header.Size) > | 84 | size = le16_to_cpu(kfib->header.Size) + sizeof(struct aac_fibhdr); |
78 | sizeof(struct hw_fib) - sizeof(struct aac_fibhdr)) { | 85 | if (size < le16_to_cpu(kfib->header.SenderSize)) |
79 | fib_free(fibptr); | 86 | size = le16_to_cpu(kfib->header.SenderSize); |
80 | return -EINVAL; | 87 | if (size > dev->max_fib_size) { |
88 | /* Highjack the hw_fib */ | ||
89 | hw_fib = fibptr->hw_fib; | ||
90 | hw_fib_pa = fibptr->hw_fib_pa; | ||
91 | fibptr->hw_fib = kfib = pci_alloc_consistent(dev->pdev, size, &fibptr->hw_fib_pa); | ||
92 | memset(((char *)kfib) + dev->max_fib_size, 0, size - dev->max_fib_size); | ||
93 | memcpy(kfib, hw_fib, dev->max_fib_size); | ||
81 | } | 94 | } |
82 | 95 | ||
83 | if (copy_from_user(kfib, arg, le16_to_cpu(kfib->header.Size) + | 96 | if (copy_from_user(kfib, arg, size)) { |
84 | sizeof(struct aac_fibhdr))) { | 97 | retval = -EFAULT; |
85 | fib_free(fibptr); | 98 | goto cleanup; |
86 | return -EFAULT; | ||
87 | } | 99 | } |
88 | 100 | ||
89 | if (kfib->header.Command == cpu_to_le16(TakeABreakPt)) { | 101 | if (kfib->header.Command == cpu_to_le16(TakeABreakPt)) { |
@@ -94,16 +106,15 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg) | |||
94 | */ | 106 | */ |
95 | kfib->header.XferState = 0; | 107 | kfib->header.XferState = 0; |
96 | } else { | 108 | } else { |
97 | int retval = fib_send(le16_to_cpu(kfib->header.Command), fibptr, | 109 | retval = fib_send(le16_to_cpu(kfib->header.Command), fibptr, |
98 | le16_to_cpu(kfib->header.Size) , FsaNormal, | 110 | le16_to_cpu(kfib->header.Size) , FsaNormal, |
99 | 1, 1, NULL, NULL); | 111 | 1, 1, NULL, NULL); |
100 | if (retval) { | 112 | if (retval) { |
101 | fib_free(fibptr); | 113 | goto cleanup; |
102 | return retval; | ||
103 | } | 114 | } |
104 | if (fib_complete(fibptr) != 0) { | 115 | if (fib_complete(fibptr) != 0) { |
105 | fib_free(fibptr); | 116 | retval = -EINVAL; |
106 | return -EINVAL; | 117 | goto cleanup; |
107 | } | 118 | } |
108 | } | 119 | } |
109 | /* | 120 | /* |
@@ -114,12 +125,17 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg) | |||
114 | * was already included by the adapter.) | 125 | * was already included by the adapter.) |
115 | */ | 126 | */ |
116 | 127 | ||
117 | if (copy_to_user(arg, (void *)kfib, le16_to_cpu(kfib->header.Size))) { | 128 | retval = 0; |
118 | fib_free(fibptr); | 129 | if (copy_to_user(arg, (void *)kfib, size)) |
119 | return -EFAULT; | 130 | retval = -EFAULT; |
131 | cleanup: | ||
132 | if (hw_fib) { | ||
133 | pci_free_consistent(dev->pdev, size, kfib, fibptr->hw_fib_pa); | ||
134 | fibptr->hw_fib_pa = hw_fib_pa; | ||
135 | fibptr->hw_fib = hw_fib; | ||
120 | } | 136 | } |
121 | fib_free(fibptr); | 137 | fib_free(fibptr); |
122 | return 0; | 138 | return retval; |
123 | } | 139 | } |
124 | 140 | ||
125 | /** | 141 | /** |
@@ -399,6 +415,7 @@ static int check_revision(struct aac_dev *dev, void __user *arg) | |||
399 | return 0; | 415 | return 0; |
400 | } | 416 | } |
401 | 417 | ||
418 | |||
402 | /** | 419 | /** |
403 | * | 420 | * |
404 | * aac_send_raw_scb | 421 | * aac_send_raw_scb |
@@ -427,7 +444,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
427 | 444 | ||
428 | 445 | ||
429 | if (!capable(CAP_SYS_ADMIN)){ | 446 | if (!capable(CAP_SYS_ADMIN)){ |
430 | printk(KERN_DEBUG"aacraid: No permission to send raw srb\n"); | 447 | dprintk((KERN_DEBUG"aacraid: No permission to send raw srb\n")); |
431 | return -EPERM; | 448 | return -EPERM; |
432 | } | 449 | } |
433 | /* | 450 | /* |
@@ -440,20 +457,26 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
440 | 457 | ||
441 | srbcmd = (struct aac_srb*) fib_data(srbfib); | 458 | srbcmd = (struct aac_srb*) fib_data(srbfib); |
442 | 459 | ||
460 | memset(sg_list, 0, sizeof(sg_list)); /* cleanup may take issue */ | ||
443 | if(copy_from_user(&fibsize, &user_srb->count,sizeof(u32))){ | 461 | if(copy_from_user(&fibsize, &user_srb->count,sizeof(u32))){ |
444 | printk(KERN_DEBUG"aacraid: Could not copy data size from user\n"); | 462 | dprintk((KERN_DEBUG"aacraid: Could not copy data size from user\n")); |
445 | rcode = -EFAULT; | 463 | rcode = -EFAULT; |
446 | goto cleanup; | 464 | goto cleanup; |
447 | } | 465 | } |
448 | 466 | ||
449 | if (fibsize > FIB_DATA_SIZE_IN_BYTES) { | 467 | if (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr))) { |
450 | rcode = -EINVAL; | 468 | rcode = -EINVAL; |
451 | goto cleanup; | 469 | goto cleanup; |
452 | } | 470 | } |
453 | 471 | ||
454 | user_srbcmd = kmalloc(GFP_KERNEL, fibsize); | 472 | user_srbcmd = kmalloc(GFP_KERNEL, fibsize); |
473 | if (!user_srbcmd) { | ||
474 | dprintk((KERN_DEBUG"aacraid: Could not make a copy of the srb\n")); | ||
475 | rcode = -ENOMEM; | ||
476 | goto cleanup; | ||
477 | } | ||
455 | if(copy_from_user(user_srbcmd, user_srb,fibsize)){ | 478 | if(copy_from_user(user_srbcmd, user_srb,fibsize)){ |
456 | printk(KERN_DEBUG"aacraid: Could not copy srb from user\n"); | 479 | dprintk((KERN_DEBUG"aacraid: Could not copy srb from user\n")); |
457 | rcode = -EFAULT; | 480 | rcode = -EFAULT; |
458 | goto cleanup; | 481 | goto cleanup; |
459 | } | 482 | } |
@@ -464,12 +487,12 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
464 | // Fix up srb for endian and force some values | 487 | // Fix up srb for endian and force some values |
465 | 488 | ||
466 | srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi); // Force this | 489 | srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi); // Force this |
467 | srbcmd->channel = cpu_to_le32(user_srbcmd->channel); | 490 | srbcmd->channel = cpu_to_le32(user_srbcmd->channel); |
468 | srbcmd->id = cpu_to_le32(user_srbcmd->id); | 491 | srbcmd->id = cpu_to_le32(user_srbcmd->id); |
469 | srbcmd->lun = cpu_to_le32(user_srbcmd->lun); | 492 | srbcmd->lun = cpu_to_le32(user_srbcmd->lun); |
470 | srbcmd->flags = cpu_to_le32(user_srbcmd->flags); | 493 | srbcmd->flags = cpu_to_le32(flags); |
471 | srbcmd->timeout = cpu_to_le32(user_srbcmd->timeout); | 494 | srbcmd->timeout = cpu_to_le32(user_srbcmd->timeout); |
472 | srbcmd->retry_limit = 0; | 495 | srbcmd->retry_limit =cpu_to_le32(0); // Obsolete parameter |
473 | srbcmd->cdb_size = cpu_to_le32(user_srbcmd->cdb_size); | 496 | srbcmd->cdb_size = cpu_to_le32(user_srbcmd->cdb_size); |
474 | 497 | ||
475 | switch (flags & (SRB_DataIn | SRB_DataOut)) { | 498 | switch (flags & (SRB_DataIn | SRB_DataOut)) { |
@@ -485,75 +508,98 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
485 | default: | 508 | default: |
486 | data_dir = DMA_NONE; | 509 | data_dir = DMA_NONE; |
487 | } | 510 | } |
511 | if (le32_to_cpu(srbcmd->sg.count) > (sizeof(sg_list)/sizeof(sg_list[0]))) { | ||
512 | dprintk((KERN_DEBUG"aacraid: too many sg entries %d\n", | ||
513 | le32_to_cpu(srbcmd->sg.count))); | ||
514 | rcode = -EINVAL; | ||
515 | goto cleanup; | ||
516 | } | ||
488 | if (dev->dac_support == 1) { | 517 | if (dev->dac_support == 1) { |
489 | struct user_sgmap64* upsg = (struct user_sgmap64*)&user_srbcmd->sg; | 518 | struct user_sgmap64* upsg = (struct user_sgmap64*)&user_srbcmd->sg; |
490 | struct sgmap64* psg = (struct sgmap64*)&user_srbcmd->sg; | 519 | struct sgmap64* psg = (struct sgmap64*)&user_srbcmd->sg; |
520 | struct user_sgmap* usg; | ||
491 | byte_count = 0; | 521 | byte_count = 0; |
492 | 522 | ||
493 | /* | 523 | /* |
494 | * This should also catch if user used the 32 bit sgmap | 524 | * This should also catch if user used the 32 bit sgmap |
495 | */ | 525 | */ |
496 | actual_fibsize = sizeof(struct aac_srb) - | 526 | actual_fibsize = sizeof(struct aac_srb) - |
497 | sizeof(struct sgentry) + | 527 | sizeof(struct sgentry) + |
498 | ((user_srbcmd->sg.count & 0xff) * | 528 | ((upsg->count & 0xff) * |
499 | sizeof(struct sgentry64)); | 529 | sizeof(struct sgentry)); |
500 | if(actual_fibsize != fibsize){ // User made a mistake - should not continue | 530 | if(actual_fibsize != fibsize){ // User made a mistake - should not continue |
501 | printk(KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n"); | 531 | dprintk((KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n")); |
502 | rcode = -EINVAL; | 532 | rcode = -EINVAL; |
503 | goto cleanup; | 533 | goto cleanup; |
504 | } | 534 | } |
505 | if ((data_dir == DMA_NONE) && upsg->count) { | 535 | usg = kmalloc(actual_fibsize - sizeof(struct aac_srb) |
506 | printk(KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n"); | 536 | + sizeof(struct sgmap), GFP_KERNEL); |
537 | if (!usg) { | ||
538 | dprintk((KERN_DEBUG"aacraid: Allocation error in Raw SRB command\n")); | ||
539 | rcode = -ENOMEM; | ||
540 | goto cleanup; | ||
541 | } | ||
542 | memcpy (usg, upsg, actual_fibsize - sizeof(struct aac_srb) | ||
543 | + sizeof(struct sgmap)); | ||
544 | actual_fibsize = sizeof(struct aac_srb) - | ||
545 | sizeof(struct sgentry) + ((usg->count & 0xff) * | ||
546 | sizeof(struct sgentry64)); | ||
547 | if ((data_dir == DMA_NONE) && upsg->count) { | ||
548 | kfree (usg); | ||
549 | dprintk((KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n")); | ||
507 | rcode = -EINVAL; | 550 | rcode = -EINVAL; |
508 | goto cleanup; | 551 | goto cleanup; |
509 | } | 552 | } |
510 | 553 | ||
511 | for (i = 0; i < upsg->count; i++) { | 554 | for (i = 0; i < usg->count; i++) { |
512 | u64 addr; | 555 | u64 addr; |
513 | void* p; | 556 | void* p; |
514 | p = kmalloc(upsg->sg[i].count, GFP_KERNEL|__GFP_DMA); | 557 | /* Does this really need to be GFP_DMA? */ |
558 | p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA); | ||
515 | if(p == 0) { | 559 | if(p == 0) { |
516 | printk(KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", | 560 | kfree (usg); |
517 | upsg->sg[i].count,i,upsg->count); | 561 | dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", |
562 | usg->sg[i].count,i,usg->count)); | ||
518 | rcode = -ENOMEM; | 563 | rcode = -ENOMEM; |
519 | goto cleanup; | 564 | goto cleanup; |
520 | } | 565 | } |
521 | sg_user[i] = (void __user *)upsg->sg[i].addr; | 566 | sg_user[i] = (void __user *)usg->sg[i].addr; |
522 | sg_list[i] = p; // save so we can clean up later | 567 | sg_list[i] = p; // save so we can clean up later |
523 | sg_indx = i; | 568 | sg_indx = i; |
524 | 569 | ||
525 | if( flags & SRB_DataOut ){ | 570 | if( flags & SRB_DataOut ){ |
526 | if(copy_from_user(p,sg_user[i],upsg->sg[i].count)){ | 571 | if(copy_from_user(p,sg_user[i],upsg->sg[i].count)){ |
527 | printk(KERN_DEBUG"aacraid: Could not copy sg data from user\n"); | 572 | kfree (usg); |
573 | dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n")); | ||
528 | rcode = -EFAULT; | 574 | rcode = -EFAULT; |
529 | goto cleanup; | 575 | goto cleanup; |
530 | } | 576 | } |
531 | } | 577 | } |
532 | addr = pci_map_single(dev->pdev, p, upsg->sg[i].count, data_dir); | 578 | addr = pci_map_single(dev->pdev, p, usg->sg[i].count, data_dir); |
533 | 579 | ||
534 | psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff); | 580 | psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff); |
535 | psg->sg[i].addr[1] = cpu_to_le32(addr >> 32); | 581 | psg->sg[i].addr[1] = cpu_to_le32(addr>>32); |
536 | psg->sg[i].count = cpu_to_le32(upsg->sg[i].count); | 582 | psg->sg[i].count = cpu_to_le32(usg->sg[i].count); |
537 | byte_count += upsg->sg[i].count; | 583 | byte_count += usg->sg[i].count; |
538 | } | 584 | } |
585 | kfree (usg); | ||
539 | 586 | ||
540 | srbcmd->count = cpu_to_le32(byte_count); | 587 | srbcmd->count = cpu_to_le32(byte_count); |
588 | psg->count = cpu_to_le32(sg_indx+1); | ||
541 | status = fib_send(ScsiPortCommand64, srbfib, actual_fibsize, FsaNormal, 1, 1,NULL,NULL); | 589 | status = fib_send(ScsiPortCommand64, srbfib, actual_fibsize, FsaNormal, 1, 1,NULL,NULL); |
542 | } else { | 590 | } else { |
543 | struct user_sgmap* upsg = &user_srbcmd->sg; | 591 | struct user_sgmap* upsg = &user_srbcmd->sg; |
544 | struct sgmap* psg = &srbcmd->sg; | 592 | struct sgmap* psg = &srbcmd->sg; |
545 | byte_count = 0; | 593 | byte_count = 0; |
546 | 594 | ||
547 | actual_fibsize = sizeof (struct aac_srb) + | 595 | actual_fibsize = sizeof (struct aac_srb) + (((le32_to_cpu(srbcmd->sg.count) & 0xff) - 1) * sizeof (struct sgentry)); |
548 | (((le32_to_cpu(srbcmd->sg.count) & 0xff) - 1) * | ||
549 | sizeof (struct sgentry)); | ||
550 | if(actual_fibsize != fibsize){ // User made a mistake - should not continue | 596 | if(actual_fibsize != fibsize){ // User made a mistake - should not continue |
551 | printk(KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n"); | 597 | dprintk((KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n")); |
552 | rcode = -EINVAL; | 598 | rcode = -EINVAL; |
553 | goto cleanup; | 599 | goto cleanup; |
554 | } | 600 | } |
555 | if ((data_dir == DMA_NONE) && upsg->count) { | 601 | if ((data_dir == DMA_NONE) && upsg->count) { |
556 | printk(KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n"); | 602 | dprintk((KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n")); |
557 | rcode = -EINVAL; | 603 | rcode = -EINVAL; |
558 | goto cleanup; | 604 | goto cleanup; |
559 | } | 605 | } |
@@ -562,44 +608,48 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
562 | void* p; | 608 | void* p; |
563 | p = kmalloc(upsg->sg[i].count, GFP_KERNEL); | 609 | p = kmalloc(upsg->sg[i].count, GFP_KERNEL); |
564 | if(p == 0) { | 610 | if(p == 0) { |
565 | printk(KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", | 611 | dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", |
566 | upsg->sg[i].count, i, upsg->count); | 612 | upsg->sg[i].count, i, upsg->count)); |
567 | rcode = -ENOMEM; | 613 | rcode = -ENOMEM; |
568 | goto cleanup; | 614 | goto cleanup; |
569 | } | 615 | } |
570 | sg_user[i] = (void __user *)upsg->sg[i].addr; | 616 | sg_user[i] = (void __user *)upsg->sg[i].addr; |
571 | sg_list[i] = p; // save so we can clean up later | 617 | sg_list[i] = p; // save so we can clean up later |
572 | sg_indx = i; | 618 | sg_indx = i; |
573 | 619 | ||
574 | if( flags & SRB_DataOut ){ | 620 | if( flags & SRB_DataOut ){ |
575 | if(copy_from_user(p, sg_user[i], | 621 | if(copy_from_user(p, sg_user[i], |
576 | upsg->sg[i].count)) { | 622 | upsg->sg[i].count)) { |
577 | printk(KERN_DEBUG"aacraid: Could not copy sg data from user\n"); | 623 | dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n")); |
578 | rcode = -EFAULT; | 624 | rcode = -EFAULT; |
579 | goto cleanup; | 625 | goto cleanup; |
580 | } | 626 | } |
581 | } | 627 | } |
582 | addr = pci_map_single(dev->pdev, p, | 628 | addr = pci_map_single(dev->pdev, p, |
583 | upsg->sg[i].count, data_dir); | 629 | upsg->sg[i].count, data_dir); |
584 | 630 | ||
585 | psg->sg[i].addr = cpu_to_le32(addr); | 631 | psg->sg[i].addr = cpu_to_le32(addr); |
586 | psg->sg[i].count = cpu_to_le32(upsg->sg[i].count); | 632 | psg->sg[i].count = cpu_to_le32(upsg->sg[i].count); |
587 | byte_count += upsg->sg[i].count; | 633 | byte_count += upsg->sg[i].count; |
588 | } | 634 | } |
589 | srbcmd->count = cpu_to_le32(byte_count); | 635 | srbcmd->count = cpu_to_le32(byte_count); |
636 | psg->count = cpu_to_le32(sg_indx+1); | ||
590 | status = fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL); | 637 | status = fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL); |
591 | } | 638 | } |
592 | 639 | ||
593 | if (status != 0){ | 640 | if (status != 0){ |
594 | printk(KERN_DEBUG"aacraid: Could not send raw srb fib to hba\n"); | 641 | dprintk((KERN_DEBUG"aacraid: Could not send raw srb fib to hba\n")); |
595 | rcode = -1; | 642 | rcode = -1; |
596 | goto cleanup; | 643 | goto cleanup; |
597 | } | 644 | } |
598 | 645 | ||
599 | if( flags & SRB_DataIn ) { | 646 | if( flags & SRB_DataIn ) { |
600 | for(i = 0 ; i <= sg_indx; i++){ | 647 | for(i = 0 ; i <= sg_indx; i++){ |
601 | if(copy_to_user(sg_user[i],sg_list[i],le32_to_cpu(srbcmd->sg.sg[i].count))){ | 648 | byte_count = le32_to_cpu((dev->dac_support == 1) |
602 | printk(KERN_DEBUG"aacraid: Could not copy sg data to user\n"); | 649 | ? ((struct sgmap64*)&srbcmd->sg)->sg[i].count |
650 | : srbcmd->sg.sg[i].count); | ||
651 | if(copy_to_user(sg_user[i], sg_list[i], byte_count)){ | ||
652 | dprintk((KERN_DEBUG"aacraid: Could not copy sg data to user\n")); | ||
603 | rcode = -EFAULT; | 653 | rcode = -EFAULT; |
604 | goto cleanup; | 654 | goto cleanup; |
605 | 655 | ||
@@ -609,7 +659,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
609 | 659 | ||
610 | reply = (struct aac_srb_reply *) fib_data(srbfib); | 660 | reply = (struct aac_srb_reply *) fib_data(srbfib); |
611 | if(copy_to_user(user_reply,reply,sizeof(struct aac_srb_reply))){ | 661 | if(copy_to_user(user_reply,reply,sizeof(struct aac_srb_reply))){ |
612 | printk(KERN_DEBUG"aacraid: Could not copy reply to user\n"); | 662 | dprintk((KERN_DEBUG"aacraid: Could not copy reply to user\n")); |
613 | rcode = -EFAULT; | 663 | rcode = -EFAULT; |
614 | goto cleanup; | 664 | goto cleanup; |
615 | } | 665 | } |
@@ -625,7 +675,6 @@ cleanup: | |||
625 | return rcode; | 675 | return rcode; |
626 | } | 676 | } |
627 | 677 | ||
628 | |||
629 | struct aac_pci_info { | 678 | struct aac_pci_info { |
630 | u32 bus; | 679 | u32 bus; |
631 | u32 slot; | 680 | u32 slot; |
@@ -640,11 +689,11 @@ static int aac_get_pci_info(struct aac_dev* dev, void __user *arg) | |||
640 | pci_info.slot = PCI_SLOT(dev->pdev->devfn); | 689 | pci_info.slot = PCI_SLOT(dev->pdev->devfn); |
641 | 690 | ||
642 | if (copy_to_user(arg, &pci_info, sizeof(struct aac_pci_info))) { | 691 | if (copy_to_user(arg, &pci_info, sizeof(struct aac_pci_info))) { |
643 | printk(KERN_DEBUG "aacraid: Could not copy pci info\n"); | 692 | dprintk((KERN_DEBUG "aacraid: Could not copy pci info\n")); |
644 | return -EFAULT; | 693 | return -EFAULT; |
645 | } | 694 | } |
646 | return 0; | 695 | return 0; |
647 | } | 696 | } |
648 | 697 | ||
649 | 698 | ||
650 | int aac_do_ioctl(struct aac_dev * dev, int cmd, void __user *arg) | 699 | int aac_do_ioctl(struct aac_dev * dev, int cmd, void __user *arg) |
@@ -663,6 +712,7 @@ int aac_do_ioctl(struct aac_dev * dev, int cmd, void __user *arg) | |||
663 | case FSACTL_MINIPORT_REV_CHECK: | 712 | case FSACTL_MINIPORT_REV_CHECK: |
664 | status = check_revision(dev, arg); | 713 | status = check_revision(dev, arg); |
665 | break; | 714 | break; |
715 | case FSACTL_SEND_LARGE_FIB: | ||
666 | case FSACTL_SENDFIB: | 716 | case FSACTL_SENDFIB: |
667 | status = ioctl_send_fib(dev, arg); | 717 | status = ioctl_send_fib(dev, arg); |
668 | break; | 718 | break; |
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c index 34a4feb1dc0d..43557bf661f6 100644 --- a/drivers/scsi/aacraid/comminit.c +++ b/drivers/scsi/aacraid/comminit.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/blkdev.h> | 39 | #include <linux/blkdev.h> |
40 | #include <linux/completion.h> | 40 | #include <linux/completion.h> |
41 | #include <linux/mm.h> | 41 | #include <linux/mm.h> |
42 | #include <scsi/scsi_host.h> | ||
42 | #include <asm/semaphore.h> | 43 | #include <asm/semaphore.h> |
43 | 44 | ||
44 | #include "aacraid.h" | 45 | #include "aacraid.h" |
@@ -49,8 +50,8 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co | |||
49 | { | 50 | { |
50 | unsigned char *base; | 51 | unsigned char *base; |
51 | unsigned long size, align; | 52 | unsigned long size, align; |
52 | unsigned long fibsize = 4096; | 53 | const unsigned long fibsize = 4096; |
53 | unsigned long printfbufsiz = 256; | 54 | const unsigned long printfbufsiz = 256; |
54 | struct aac_init *init; | 55 | struct aac_init *init; |
55 | dma_addr_t phys; | 56 | dma_addr_t phys; |
56 | 57 | ||
@@ -74,6 +75,8 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co | |||
74 | init = dev->init; | 75 | init = dev->init; |
75 | 76 | ||
76 | init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION); | 77 | init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION); |
78 | if (dev->max_fib_size != sizeof(struct hw_fib)) | ||
79 | init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4); | ||
77 | init->MiniPortRevision = cpu_to_le32(Sa_MINIPORT_REVISION); | 80 | init->MiniPortRevision = cpu_to_le32(Sa_MINIPORT_REVISION); |
78 | init->fsrev = cpu_to_le32(dev->fsrev); | 81 | init->fsrev = cpu_to_le32(dev->fsrev); |
79 | 82 | ||
@@ -110,6 +113,10 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co | |||
110 | init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES); | 113 | init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES); |
111 | } | 114 | } |
112 | 115 | ||
116 | init->InitFlags = 0; | ||
117 | init->MaxIoCommands = cpu_to_le32(dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); | ||
118 | init->MaxIoSize = cpu_to_le32(dev->scsi_host_ptr->max_sectors << 9); | ||
119 | init->MaxFibSize = cpu_to_le32(dev->max_fib_size); | ||
113 | 120 | ||
114 | /* | 121 | /* |
115 | * Increment the base address by the amount already used | 122 | * Increment the base address by the amount already used |
@@ -173,6 +180,8 @@ int aac_send_shutdown(struct aac_dev * dev) | |||
173 | int status; | 180 | int status; |
174 | 181 | ||
175 | fibctx = fib_alloc(dev); | 182 | fibctx = fib_alloc(dev); |
183 | if (!fibctx) | ||
184 | return -ENOMEM; | ||
176 | fib_init(fibctx); | 185 | fib_init(fibctx); |
177 | 186 | ||
178 | cmd = (struct aac_close *) fib_data(fibctx); | 187 | cmd = (struct aac_close *) fib_data(fibctx); |
@@ -293,6 +302,79 @@ static int aac_comm_init(struct aac_dev * dev) | |||
293 | 302 | ||
294 | struct aac_dev *aac_init_adapter(struct aac_dev *dev) | 303 | struct aac_dev *aac_init_adapter(struct aac_dev *dev) |
295 | { | 304 | { |
305 | u32 status[5]; | ||
306 | struct Scsi_Host * host = dev->scsi_host_ptr; | ||
307 | |||
308 | /* | ||
309 | * Check the preferred comm settings, defaults from template. | ||
310 | */ | ||
311 | dev->max_fib_size = sizeof(struct hw_fib); | ||
312 | dev->sg_tablesize = host->sg_tablesize = (dev->max_fib_size | ||
313 | - sizeof(struct aac_fibhdr) | ||
314 | - sizeof(struct aac_write) + sizeof(struct sgmap)) | ||
315 | / sizeof(struct sgmap); | ||
316 | if ((!aac_adapter_sync_cmd(dev, GET_COMM_PREFERRED_SETTINGS, | ||
317 | 0, 0, 0, 0, 0, 0, | ||
318 | status+0, status+1, status+2, status+3, status+4)) | ||
319 | && (status[0] == 0x00000001)) { | ||
320 | /* | ||
321 | * status[1] >> 16 maximum command size in KB | ||
322 | * status[1] & 0xFFFF maximum FIB size | ||
323 | * status[2] >> 16 maximum SG elements to driver | ||
324 | * status[2] & 0xFFFF maximum SG elements from driver | ||
325 | * status[3] & 0xFFFF maximum number FIBs outstanding | ||
326 | */ | ||
327 | host->max_sectors = (status[1] >> 16) << 1; | ||
328 | dev->max_fib_size = status[1] & 0xFFFF; | ||
329 | host->sg_tablesize = status[2] >> 16; | ||
330 | dev->sg_tablesize = status[2] & 0xFFFF; | ||
331 | host->can_queue = (status[3] & 0xFFFF) - AAC_NUM_MGT_FIB; | ||
332 | /* | ||
333 | * NOTE: | ||
334 | * All these overrides are based on a fixed internal | ||
335 | * knowledge and understanding of existing adapters, | ||
336 | * acbsize should be set with caution. | ||
337 | */ | ||
338 | if (acbsize == 512) { | ||
339 | host->max_sectors = AAC_MAX_32BIT_SGBCOUNT; | ||
340 | dev->max_fib_size = 512; | ||
341 | dev->sg_tablesize = host->sg_tablesize | ||
342 | = (512 - sizeof(struct aac_fibhdr) | ||
343 | - sizeof(struct aac_write) + sizeof(struct sgmap)) | ||
344 | / sizeof(struct sgmap); | ||
345 | host->can_queue = AAC_NUM_IO_FIB; | ||
346 | } else if (acbsize == 2048) { | ||
347 | host->max_sectors = 512; | ||
348 | dev->max_fib_size = 2048; | ||
349 | host->sg_tablesize = 65; | ||
350 | dev->sg_tablesize = 81; | ||
351 | host->can_queue = 512 - AAC_NUM_MGT_FIB; | ||
352 | } else if (acbsize == 4096) { | ||
353 | host->max_sectors = 1024; | ||
354 | dev->max_fib_size = 4096; | ||
355 | host->sg_tablesize = 129; | ||
356 | dev->sg_tablesize = 166; | ||
357 | host->can_queue = 256 - AAC_NUM_MGT_FIB; | ||
358 | } else if (acbsize == 8192) { | ||
359 | host->max_sectors = 2048; | ||
360 | dev->max_fib_size = 8192; | ||
361 | host->sg_tablesize = 257; | ||
362 | dev->sg_tablesize = 337; | ||
363 | host->can_queue = 128 - AAC_NUM_MGT_FIB; | ||
364 | } else if (acbsize > 0) { | ||
365 | printk("Illegal acbsize=%d ignored\n", acbsize); | ||
366 | } | ||
367 | } | ||
368 | { | ||
369 | |||
370 | if (numacb > 0) { | ||
371 | if (numacb < host->can_queue) | ||
372 | host->can_queue = numacb; | ||
373 | else | ||
374 | printk("numacb=%d ignored\n", numacb); | ||
375 | } | ||
376 | } | ||
377 | |||
296 | /* | 378 | /* |
297 | * Ok now init the communication subsystem | 379 | * Ok now init the communication subsystem |
298 | */ | 380 | */ |
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index e2720b7be652..5322865942e2 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c | |||
@@ -25,7 +25,7 @@ | |||
25 | * commsup.c | 25 | * commsup.c |
26 | * | 26 | * |
27 | * Abstract: Contain all routines that are required for FSA host/adapter | 27 | * Abstract: Contain all routines that are required for FSA host/adapter |
28 | * commuication. | 28 | * communication. |
29 | * | 29 | * |
30 | */ | 30 | */ |
31 | 31 | ||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/completion.h> | 39 | #include <linux/completion.h> |
40 | #include <linux/blkdev.h> | 40 | #include <linux/blkdev.h> |
41 | #include <scsi/scsi_host.h> | ||
41 | #include <asm/semaphore.h> | 42 | #include <asm/semaphore.h> |
42 | 43 | ||
43 | #include "aacraid.h" | 44 | #include "aacraid.h" |
@@ -52,7 +53,13 @@ | |||
52 | 53 | ||
53 | static int fib_map_alloc(struct aac_dev *dev) | 54 | static int fib_map_alloc(struct aac_dev *dev) |
54 | { | 55 | { |
55 | if((dev->hw_fib_va = pci_alloc_consistent(dev->pdev, sizeof(struct hw_fib) * AAC_NUM_FIB, &dev->hw_fib_pa))==NULL) | 56 | dprintk((KERN_INFO |
57 | "allocate hardware fibs pci_alloc_consistent(%p, %d * (%d + %d), %p)\n", | ||
58 | dev->pdev, dev->max_fib_size, dev->scsi_host_ptr->can_queue, | ||
59 | AAC_NUM_MGT_FIB, &dev->hw_fib_pa)); | ||
60 | if((dev->hw_fib_va = pci_alloc_consistent(dev->pdev, dev->max_fib_size | ||
61 | * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB), | ||
62 | &dev->hw_fib_pa))==NULL) | ||
56 | return -ENOMEM; | 63 | return -ENOMEM; |
57 | return 0; | 64 | return 0; |
58 | } | 65 | } |
@@ -67,7 +74,7 @@ static int fib_map_alloc(struct aac_dev *dev) | |||
67 | 74 | ||
68 | void fib_map_free(struct aac_dev *dev) | 75 | void fib_map_free(struct aac_dev *dev) |
69 | { | 76 | { |
70 | pci_free_consistent(dev->pdev, sizeof(struct hw_fib) * AAC_NUM_FIB, dev->hw_fib_va, dev->hw_fib_pa); | 77 | pci_free_consistent(dev->pdev, dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB), dev->hw_fib_va, dev->hw_fib_pa); |
71 | } | 78 | } |
72 | 79 | ||
73 | /** | 80 | /** |
@@ -84,17 +91,22 @@ int fib_setup(struct aac_dev * dev) | |||
84 | struct hw_fib *hw_fib_va; | 91 | struct hw_fib *hw_fib_va; |
85 | dma_addr_t hw_fib_pa; | 92 | dma_addr_t hw_fib_pa; |
86 | int i; | 93 | int i; |
87 | 94 | ||
88 | if(fib_map_alloc(dev)<0) | 95 | while (((i = fib_map_alloc(dev)) == -ENOMEM) |
96 | && (dev->scsi_host_ptr->can_queue > (64 - AAC_NUM_MGT_FIB))) { | ||
97 | dev->init->MaxIoCommands = cpu_to_le32((dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB) >> 1); | ||
98 | dev->scsi_host_ptr->can_queue = le32_to_cpu(dev->init->MaxIoCommands) - AAC_NUM_MGT_FIB; | ||
99 | } | ||
100 | if (i<0) | ||
89 | return -ENOMEM; | 101 | return -ENOMEM; |
90 | 102 | ||
91 | hw_fib_va = dev->hw_fib_va; | 103 | hw_fib_va = dev->hw_fib_va; |
92 | hw_fib_pa = dev->hw_fib_pa; | 104 | hw_fib_pa = dev->hw_fib_pa; |
93 | memset(hw_fib_va, 0, sizeof(struct hw_fib) * AAC_NUM_FIB); | 105 | memset(hw_fib_va, 0, dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB)); |
94 | /* | 106 | /* |
95 | * Initialise the fibs | 107 | * Initialise the fibs |
96 | */ | 108 | */ |
97 | for (i = 0, fibptr = &dev->fibs[i]; i < AAC_NUM_FIB; i++, fibptr++) | 109 | for (i = 0, fibptr = &dev->fibs[i]; i < (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); i++, fibptr++) |
98 | { | 110 | { |
99 | fibptr->dev = dev; | 111 | fibptr->dev = dev; |
100 | fibptr->hw_fib = hw_fib_va; | 112 | fibptr->hw_fib = hw_fib_va; |
@@ -103,15 +115,15 @@ int fib_setup(struct aac_dev * dev) | |||
103 | init_MUTEX_LOCKED(&fibptr->event_wait); | 115 | init_MUTEX_LOCKED(&fibptr->event_wait); |
104 | spin_lock_init(&fibptr->event_lock); | 116 | spin_lock_init(&fibptr->event_lock); |
105 | hw_fib_va->header.XferState = cpu_to_le32(0xffffffff); | 117 | hw_fib_va->header.XferState = cpu_to_le32(0xffffffff); |
106 | hw_fib_va->header.SenderSize = cpu_to_le16(sizeof(struct hw_fib)); | 118 | hw_fib_va->header.SenderSize = cpu_to_le16(dev->max_fib_size); |
107 | fibptr->hw_fib_pa = hw_fib_pa; | 119 | fibptr->hw_fib_pa = hw_fib_pa; |
108 | hw_fib_va = (struct hw_fib *)((unsigned char *)hw_fib_va + sizeof(struct hw_fib)); | 120 | hw_fib_va = (struct hw_fib *)((unsigned char *)hw_fib_va + dev->max_fib_size); |
109 | hw_fib_pa = hw_fib_pa + sizeof(struct hw_fib); | 121 | hw_fib_pa = hw_fib_pa + dev->max_fib_size; |
110 | } | 122 | } |
111 | /* | 123 | /* |
112 | * Add the fib chain to the free list | 124 | * Add the fib chain to the free list |
113 | */ | 125 | */ |
114 | dev->fibs[AAC_NUM_FIB-1].next = NULL; | 126 | dev->fibs[dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB - 1].next = NULL; |
115 | /* | 127 | /* |
116 | * Enable this to debug out of queue space | 128 | * Enable this to debug out of queue space |
117 | */ | 129 | */ |
@@ -124,7 +136,7 @@ int fib_setup(struct aac_dev * dev) | |||
124 | * @dev: Adapter to allocate the fib for | 136 | * @dev: Adapter to allocate the fib for |
125 | * | 137 | * |
126 | * Allocate a fib from the adapter fib pool. If the pool is empty we | 138 | * Allocate a fib from the adapter fib pool. If the pool is empty we |
127 | * wait for fibs to become free. | 139 | * return NULL. |
128 | */ | 140 | */ |
129 | 141 | ||
130 | struct fib * fib_alloc(struct aac_dev *dev) | 142 | struct fib * fib_alloc(struct aac_dev *dev) |
@@ -133,10 +145,10 @@ struct fib * fib_alloc(struct aac_dev *dev) | |||
133 | unsigned long flags; | 145 | unsigned long flags; |
134 | spin_lock_irqsave(&dev->fib_lock, flags); | 146 | spin_lock_irqsave(&dev->fib_lock, flags); |
135 | fibptr = dev->free_fib; | 147 | fibptr = dev->free_fib; |
136 | /* Cannot sleep here or you get hangs. Instead we did the | 148 | if(!fibptr){ |
137 | maths at compile time. */ | 149 | spin_unlock_irqrestore(&dev->fib_lock, flags); |
138 | if(!fibptr) | 150 | return fibptr; |
139 | BUG(); | 151 | } |
140 | dev->free_fib = fibptr->next; | 152 | dev->free_fib = fibptr->next; |
141 | spin_unlock_irqrestore(&dev->fib_lock, flags); | 153 | spin_unlock_irqrestore(&dev->fib_lock, flags); |
142 | /* | 154 | /* |
@@ -196,11 +208,11 @@ void fib_init(struct fib *fibptr) | |||
196 | struct hw_fib *hw_fib = fibptr->hw_fib; | 208 | struct hw_fib *hw_fib = fibptr->hw_fib; |
197 | 209 | ||
198 | hw_fib->header.StructType = FIB_MAGIC; | 210 | hw_fib->header.StructType = FIB_MAGIC; |
199 | hw_fib->header.Size = cpu_to_le16(sizeof(struct hw_fib)); | 211 | hw_fib->header.Size = cpu_to_le16(fibptr->dev->max_fib_size); |
200 | hw_fib->header.XferState = cpu_to_le32(HostOwned | FibInitialized | FibEmpty | FastResponseCapable); | 212 | hw_fib->header.XferState = cpu_to_le32(HostOwned | FibInitialized | FibEmpty | FastResponseCapable); |
201 | hw_fib->header.SenderFibAddress = cpu_to_le32(fibptr->hw_fib_pa); | 213 | hw_fib->header.SenderFibAddress = cpu_to_le32(fibptr->hw_fib_pa); |
202 | hw_fib->header.ReceiverFibAddress = cpu_to_le32(fibptr->hw_fib_pa); | 214 | hw_fib->header.ReceiverFibAddress = cpu_to_le32(fibptr->hw_fib_pa); |
203 | hw_fib->header.SenderSize = cpu_to_le16(sizeof(struct hw_fib)); | 215 | hw_fib->header.SenderSize = cpu_to_le16(fibptr->dev->max_fib_size); |
204 | } | 216 | } |
205 | 217 | ||
206 | /** | 218 | /** |
@@ -279,7 +291,7 @@ static int aac_get_entry (struct aac_dev * dev, u32 qid, struct aac_entry **entr | |||
279 | } | 291 | } |
280 | 292 | ||
281 | if ((*index + 1) == le32_to_cpu(*(q->headers.consumer))) { /* Queue is full */ | 293 | if ((*index + 1) == le32_to_cpu(*(q->headers.consumer))) { /* Queue is full */ |
282 | printk(KERN_WARNING "Queue %d full, %d outstanding.\n", | 294 | printk(KERN_WARNING "Queue %d full, %u outstanding.\n", |
283 | qid, q->numpending); | 295 | qid, q->numpending); |
284 | return 0; | 296 | return 0; |
285 | } else { | 297 | } else { |
@@ -743,22 +755,25 @@ int fib_complete(struct fib * fibptr) | |||
743 | 755 | ||
744 | void aac_printf(struct aac_dev *dev, u32 val) | 756 | void aac_printf(struct aac_dev *dev, u32 val) |
745 | { | 757 | { |
746 | int length = val & 0xffff; | ||
747 | int level = (val >> 16) & 0xffff; | ||
748 | char *cp = dev->printfbuf; | 758 | char *cp = dev->printfbuf; |
749 | 759 | if (dev->printf_enabled) | |
750 | /* | 760 | { |
751 | * The size of the printfbuf is set in port.c | 761 | int length = val & 0xffff; |
752 | * There is no variable or define for it | 762 | int level = (val >> 16) & 0xffff; |
753 | */ | 763 | |
754 | if (length > 255) | 764 | /* |
755 | length = 255; | 765 | * The size of the printfbuf is set in port.c |
756 | if (cp[length] != 0) | 766 | * There is no variable or define for it |
757 | cp[length] = 0; | 767 | */ |
758 | if (level == LOG_AAC_HIGH_ERROR) | 768 | if (length > 255) |
759 | printk(KERN_WARNING "aacraid:%s", cp); | 769 | length = 255; |
760 | else | 770 | if (cp[length] != 0) |
761 | printk(KERN_INFO "aacraid:%s", cp); | 771 | cp[length] = 0; |
772 | if (level == LOG_AAC_HIGH_ERROR) | ||
773 | printk(KERN_WARNING "aacraid:%s", cp); | ||
774 | else | ||
775 | printk(KERN_INFO "aacraid:%s", cp); | ||
776 | } | ||
762 | memset(cp, 0, 256); | 777 | memset(cp, 0, 256); |
763 | } | 778 | } |
764 | 779 | ||
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 5fd8f3ee9804..6f05d86c7bb3 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c | |||
@@ -347,10 +347,16 @@ static int aac_biosparm(struct scsi_device *sdev, struct block_device *bdev, | |||
347 | 347 | ||
348 | static int aac_slave_configure(struct scsi_device *sdev) | 348 | static int aac_slave_configure(struct scsi_device *sdev) |
349 | { | 349 | { |
350 | struct Scsi_Host *host = sdev->host; | ||
351 | |||
350 | if (sdev->tagged_supported) | 352 | if (sdev->tagged_supported) |
351 | scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, 128); | 353 | scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, 128); |
352 | else | 354 | else |
353 | scsi_adjust_queue_depth(sdev, 0, 1); | 355 | scsi_adjust_queue_depth(sdev, 0, 1); |
356 | |||
357 | if (host->max_sectors < AAC_MAX_32BIT_SGBCOUNT) | ||
358 | blk_queue_max_segment_size(sdev->request_queue, 65536); | ||
359 | |||
354 | return 0; | 360 | return 0; |
355 | } | 361 | } |
356 | 362 | ||
@@ -439,11 +445,11 @@ static int aac_eh_reset(struct scsi_cmnd* cmd) | |||
439 | static int aac_cfg_open(struct inode *inode, struct file *file) | 445 | static int aac_cfg_open(struct inode *inode, struct file *file) |
440 | { | 446 | { |
441 | struct aac_dev *aac; | 447 | struct aac_dev *aac; |
442 | unsigned minor = iminor(inode); | 448 | unsigned minor_number = iminor(inode); |
443 | int err = -ENODEV; | 449 | int err = -ENODEV; |
444 | 450 | ||
445 | list_for_each_entry(aac, &aac_devices, entry) { | 451 | list_for_each_entry(aac, &aac_devices, entry) { |
446 | if (aac->id == minor) { | 452 | if (aac->id == minor_number) { |
447 | file->private_data = aac; | 453 | file->private_data = aac; |
448 | err = 0; | 454 | err = 0; |
449 | break; | 455 | break; |
@@ -489,6 +495,7 @@ static long aac_compat_do_ioctl(struct aac_dev *dev, unsigned cmd, unsigned long | |||
489 | case FSACTL_DELETE_DISK: | 495 | case FSACTL_DELETE_DISK: |
490 | case FSACTL_FORCE_DELETE_DISK: | 496 | case FSACTL_FORCE_DELETE_DISK: |
491 | case FSACTL_GET_CONTAINERS: | 497 | case FSACTL_GET_CONTAINERS: |
498 | case FSACTL_SEND_LARGE_FIB: | ||
492 | ret = aac_do_ioctl(dev, cmd, (void __user *)arg); | 499 | ret = aac_do_ioctl(dev, cmd, (void __user *)arg); |
493 | break; | 500 | break; |
494 | 501 | ||
@@ -538,7 +545,7 @@ static struct file_operations aac_cfg_fops = { | |||
538 | static struct scsi_host_template aac_driver_template = { | 545 | static struct scsi_host_template aac_driver_template = { |
539 | .module = THIS_MODULE, | 546 | .module = THIS_MODULE, |
540 | .name = "AAC", | 547 | .name = "AAC", |
541 | .proc_name = "aacraid", | 548 | .proc_name = AAC_DRIVERNAME, |
542 | .info = aac_info, | 549 | .info = aac_info, |
543 | .ioctl = aac_ioctl, | 550 | .ioctl = aac_ioctl, |
544 | #ifdef CONFIG_COMPAT | 551 | #ifdef CONFIG_COMPAT |
@@ -612,7 +619,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, | |||
612 | aac->cardtype = index; | 619 | aac->cardtype = index; |
613 | INIT_LIST_HEAD(&aac->entry); | 620 | INIT_LIST_HEAD(&aac->entry); |
614 | 621 | ||
615 | aac->fibs = kmalloc(sizeof(struct fib) * AAC_NUM_FIB, GFP_KERNEL); | 622 | aac->fibs = kmalloc(sizeof(struct fib) * (shost->can_queue + AAC_NUM_MGT_FIB), GFP_KERNEL); |
616 | if (!aac->fibs) | 623 | if (!aac->fibs) |
617 | goto out_free_host; | 624 | goto out_free_host; |
618 | spin_lock_init(&aac->fib_lock); | 625 | spin_lock_init(&aac->fib_lock); |
@@ -632,6 +639,24 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, | |||
632 | aac_get_adapter_info(aac); | 639 | aac_get_adapter_info(aac); |
633 | 640 | ||
634 | /* | 641 | /* |
642 | * Lets override negotiations and drop the maximum SG limit to 34 | ||
643 | */ | ||
644 | if ((aac_drivers[index].quirks & AAC_QUIRK_34SG) && | ||
645 | (aac->scsi_host_ptr->sg_tablesize > 34)) { | ||
646 | aac->scsi_host_ptr->sg_tablesize = 34; | ||
647 | aac->scsi_host_ptr->max_sectors | ||
648 | = (aac->scsi_host_ptr->sg_tablesize * 8) + 112; | ||
649 | } | ||
650 | |||
651 | /* | ||
652 | * Firware printf works only with older firmware. | ||
653 | */ | ||
654 | if (aac_drivers[index].quirks & AAC_QUIRK_34SG) | ||
655 | aac->printf_enabled = 1; | ||
656 | else | ||
657 | aac->printf_enabled = 0; | ||
658 | |||
659 | /* | ||
635 | * max channel will be the physical channels plus 1 virtual channel | 660 | * max channel will be the physical channels plus 1 virtual channel |
636 | * all containers are on the virtual channel 0 | 661 | * all containers are on the virtual channel 0 |
637 | * physical channels are address by their actual physical number+1 | 662 | * physical channels are address by their actual physical number+1 |
diff --git a/drivers/scsi/aacraid/rkt.c b/drivers/scsi/aacraid/rkt.c index 2d8ecd7f1479..7d68b7825137 100644 --- a/drivers/scsi/aacraid/rkt.c +++ b/drivers/scsi/aacraid/rkt.c | |||
@@ -98,7 +98,9 @@ static irqreturn_t aac_rkt_intr(int irq, void *dev_id, struct pt_regs *regs) | |||
98 | * for its completion. | 98 | * for its completion. |
99 | */ | 99 | */ |
100 | 100 | ||
101 | static int rkt_sync_cmd(struct aac_dev *dev, u32 command, u32 p1, u32 *status) | 101 | static int rkt_sync_cmd(struct aac_dev *dev, u32 command, |
102 | u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, | ||
103 | u32 *status, u32 *r1, u32 *r2, u32 *r3, u32 *r4) | ||
102 | { | 104 | { |
103 | unsigned long start; | 105 | unsigned long start; |
104 | int ok; | 106 | int ok; |
@@ -107,12 +109,12 @@ static int rkt_sync_cmd(struct aac_dev *dev, u32 command, u32 p1, u32 *status) | |||
107 | */ | 109 | */ |
108 | rkt_writel(dev, InboundMailbox0, command); | 110 | rkt_writel(dev, InboundMailbox0, command); |
109 | /* | 111 | /* |
110 | * Write the parameters into Mailboxes 1 - 4 | 112 | * Write the parameters into Mailboxes 1 - 6 |
111 | */ | 113 | */ |
112 | rkt_writel(dev, InboundMailbox1, p1); | 114 | rkt_writel(dev, InboundMailbox1, p1); |
113 | rkt_writel(dev, InboundMailbox2, 0); | 115 | rkt_writel(dev, InboundMailbox2, p2); |
114 | rkt_writel(dev, InboundMailbox3, 0); | 116 | rkt_writel(dev, InboundMailbox3, p3); |
115 | rkt_writel(dev, InboundMailbox4, 0); | 117 | rkt_writel(dev, InboundMailbox4, p4); |
116 | /* | 118 | /* |
117 | * Clear the synch command doorbell to start on a clean slate. | 119 | * Clear the synch command doorbell to start on a clean slate. |
118 | */ | 120 | */ |
@@ -169,6 +171,14 @@ static int rkt_sync_cmd(struct aac_dev *dev, u32 command, u32 p1, u32 *status) | |||
169 | */ | 171 | */ |
170 | if (status) | 172 | if (status) |
171 | *status = rkt_readl(dev, IndexRegs.Mailbox[0]); | 173 | *status = rkt_readl(dev, IndexRegs.Mailbox[0]); |
174 | if (r1) | ||
175 | *r1 = rkt_readl(dev, IndexRegs.Mailbox[1]); | ||
176 | if (r2) | ||
177 | *r2 = rkt_readl(dev, IndexRegs.Mailbox[2]); | ||
178 | if (r3) | ||
179 | *r3 = rkt_readl(dev, IndexRegs.Mailbox[3]); | ||
180 | if (r4) | ||
181 | *r4 = rkt_readl(dev, IndexRegs.Mailbox[4]); | ||
172 | /* | 182 | /* |
173 | * Clear the synch command doorbell. | 183 | * Clear the synch command doorbell. |
174 | */ | 184 | */ |
@@ -190,8 +200,8 @@ static int rkt_sync_cmd(struct aac_dev *dev, u32 command, u32 p1, u32 *status) | |||
190 | 200 | ||
191 | static void aac_rkt_interrupt_adapter(struct aac_dev *dev) | 201 | static void aac_rkt_interrupt_adapter(struct aac_dev *dev) |
192 | { | 202 | { |
193 | u32 ret; | 203 | rkt_sync_cmd(dev, BREAKPOINT_REQUEST, 0, 0, 0, 0, 0, 0, |
194 | rkt_sync_cmd(dev, BREAKPOINT_REQUEST, 0, &ret); | 204 | NULL, NULL, NULL, NULL, NULL); |
195 | } | 205 | } |
196 | 206 | ||
197 | /** | 207 | /** |
@@ -220,7 +230,8 @@ static void aac_rkt_notify_adapter(struct aac_dev *dev, u32 event) | |||
220 | rkt_writel(dev, MUnit.IDR,INBOUNDDOORBELL_3); | 230 | rkt_writel(dev, MUnit.IDR,INBOUNDDOORBELL_3); |
221 | break; | 231 | break; |
222 | case HostShutdown: | 232 | case HostShutdown: |
223 | // rkt_sync_cmd(dev, HOST_CRASHING, 0, 0, 0, 0, &ret); | 233 | // rkt_sync_cmd(dev, HOST_CRASHING, 0, 0, 0, 0, 0, 0, |
234 | // NULL, NULL, NULL, NULL, NULL); | ||
224 | break; | 235 | break; |
225 | case FastIo: | 236 | case FastIo: |
226 | rkt_writel(dev, MUnit.IDR,INBOUNDDOORBELL_6); | 237 | rkt_writel(dev, MUnit.IDR,INBOUNDDOORBELL_6); |
@@ -243,17 +254,11 @@ static void aac_rkt_notify_adapter(struct aac_dev *dev, u32 event) | |||
243 | 254 | ||
244 | static void aac_rkt_start_adapter(struct aac_dev *dev) | 255 | static void aac_rkt_start_adapter(struct aac_dev *dev) |
245 | { | 256 | { |
246 | u32 status; | ||
247 | struct aac_init *init; | 257 | struct aac_init *init; |
248 | 258 | ||
249 | init = dev->init; | 259 | init = dev->init; |
250 | init->HostElapsedSeconds = cpu_to_le32(get_seconds()); | 260 | init->HostElapsedSeconds = cpu_to_le32(get_seconds()); |
251 | /* | 261 | /* |
252 | * Tell the adapter we are back and up and running so it will scan | ||
253 | * its command queues and enable our interrupts | ||
254 | */ | ||
255 | dev->irq_mask = (DoorBellPrintfReady | OUTBOUNDDOORBELL_1 | OUTBOUNDDOORBELL_2 | OUTBOUNDDOORBELL_3 | OUTBOUNDDOORBELL_4); | ||
256 | /* | ||
257 | * First clear out all interrupts. Then enable the one's that we | 262 | * First clear out all interrupts. Then enable the one's that we |
258 | * can handle. | 263 | * can handle. |
259 | */ | 264 | */ |
@@ -263,7 +268,8 @@ static void aac_rkt_start_adapter(struct aac_dev *dev) | |||
263 | rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb); | 268 | rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb); |
264 | 269 | ||
265 | // We can only use a 32 bit address here | 270 | // We can only use a 32 bit address here |
266 | rkt_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa, &status); | 271 | rkt_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa, |
272 | 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL); | ||
267 | } | 273 | } |
268 | 274 | ||
269 | /** | 275 | /** |
@@ -310,7 +316,8 @@ static int aac_rkt_check_health(struct aac_dev *dev) | |||
310 | post->Post_Command = cpu_to_le32(COMMAND_POST_RESULTS); | 316 | post->Post_Command = cpu_to_le32(COMMAND_POST_RESULTS); |
311 | post->Post_Address = cpu_to_le32(baddr); | 317 | post->Post_Address = cpu_to_le32(baddr); |
312 | rkt_writel(dev, MUnit.IMRx[0], paddr); | 318 | rkt_writel(dev, MUnit.IMRx[0], paddr); |
313 | rkt_sync_cmd(dev, COMMAND_POST_RESULTS, baddr, &status); | 319 | rkt_sync_cmd(dev, COMMAND_POST_RESULTS, baddr, 0, 0, 0, 0, 0, |
320 | NULL, NULL, NULL, NULL, NULL); | ||
314 | pci_free_consistent(dev->pdev, sizeof(struct POSTSTATUS), | 321 | pci_free_consistent(dev->pdev, sizeof(struct POSTSTATUS), |
315 | post, paddr); | 322 | post, paddr); |
316 | if ((buffer[0] == '0') && (buffer[1] == 'x')) { | 323 | if ((buffer[0] == '0') && (buffer[1] == 'x')) { |
diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c index d447f45f70d1..1ff25f49fada 100644 --- a/drivers/scsi/aacraid/rx.c +++ b/drivers/scsi/aacraid/rx.c | |||
@@ -98,7 +98,9 @@ static irqreturn_t aac_rx_intr(int irq, void *dev_id, struct pt_regs *regs) | |||
98 | * for its completion. | 98 | * for its completion. |
99 | */ | 99 | */ |
100 | 100 | ||
101 | static int rx_sync_cmd(struct aac_dev *dev, u32 command, u32 p1, u32 *status) | 101 | static int rx_sync_cmd(struct aac_dev *dev, u32 command, |
102 | u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, | ||
103 | u32 *status, u32 * r1, u32 * r2, u32 * r3, u32 * r4) | ||
102 | { | 104 | { |
103 | unsigned long start; | 105 | unsigned long start; |
104 | int ok; | 106 | int ok; |
@@ -107,12 +109,12 @@ static int rx_sync_cmd(struct aac_dev *dev, u32 command, u32 p1, u32 *status) | |||
107 | */ | 109 | */ |
108 | rx_writel(dev, InboundMailbox0, command); | 110 | rx_writel(dev, InboundMailbox0, command); |
109 | /* | 111 | /* |
110 | * Write the parameters into Mailboxes 1 - 4 | 112 | * Write the parameters into Mailboxes 1 - 6 |
111 | */ | 113 | */ |
112 | rx_writel(dev, InboundMailbox1, p1); | 114 | rx_writel(dev, InboundMailbox1, p1); |
113 | rx_writel(dev, InboundMailbox2, 0); | 115 | rx_writel(dev, InboundMailbox2, p2); |
114 | rx_writel(dev, InboundMailbox3, 0); | 116 | rx_writel(dev, InboundMailbox3, p3); |
115 | rx_writel(dev, InboundMailbox4, 0); | 117 | rx_writel(dev, InboundMailbox4, p4); |
116 | /* | 118 | /* |
117 | * Clear the synch command doorbell to start on a clean slate. | 119 | * Clear the synch command doorbell to start on a clean slate. |
118 | */ | 120 | */ |
@@ -120,7 +122,7 @@ static int rx_sync_cmd(struct aac_dev *dev, u32 command, u32 p1, u32 *status) | |||
120 | /* | 122 | /* |
121 | * Disable doorbell interrupts | 123 | * Disable doorbell interrupts |
122 | */ | 124 | */ |
123 | rx_writeb(dev, MUnit.OIMR, dev->OIMR |= 0x04); | 125 | rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff); |
124 | /* | 126 | /* |
125 | * Force the completion of the mask register write before issuing | 127 | * Force the completion of the mask register write before issuing |
126 | * the interrupt. | 128 | * the interrupt. |
@@ -169,6 +171,14 @@ static int rx_sync_cmd(struct aac_dev *dev, u32 command, u32 p1, u32 *status) | |||
169 | */ | 171 | */ |
170 | if (status) | 172 | if (status) |
171 | *status = rx_readl(dev, IndexRegs.Mailbox[0]); | 173 | *status = rx_readl(dev, IndexRegs.Mailbox[0]); |
174 | if (r1) | ||
175 | *r1 = rx_readl(dev, IndexRegs.Mailbox[1]); | ||
176 | if (r2) | ||
177 | *r2 = rx_readl(dev, IndexRegs.Mailbox[2]); | ||
178 | if (r3) | ||
179 | *r3 = rx_readl(dev, IndexRegs.Mailbox[3]); | ||
180 | if (r4) | ||
181 | *r4 = rx_readl(dev, IndexRegs.Mailbox[4]); | ||
172 | /* | 182 | /* |
173 | * Clear the synch command doorbell. | 183 | * Clear the synch command doorbell. |
174 | */ | 184 | */ |
@@ -190,8 +200,7 @@ static int rx_sync_cmd(struct aac_dev *dev, u32 command, u32 p1, u32 *status) | |||
190 | 200 | ||
191 | static void aac_rx_interrupt_adapter(struct aac_dev *dev) | 201 | static void aac_rx_interrupt_adapter(struct aac_dev *dev) |
192 | { | 202 | { |
193 | u32 ret; | 203 | rx_sync_cmd(dev, BREAKPOINT_REQUEST, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL); |
194 | rx_sync_cmd(dev, BREAKPOINT_REQUEST, 0, &ret); | ||
195 | } | 204 | } |
196 | 205 | ||
197 | /** | 206 | /** |
@@ -220,7 +229,8 @@ static void aac_rx_notify_adapter(struct aac_dev *dev, u32 event) | |||
220 | rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_3); | 229 | rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_3); |
221 | break; | 230 | break; |
222 | case HostShutdown: | 231 | case HostShutdown: |
223 | // rx_sync_cmd(dev, HOST_CRASHING, 0, 0, 0, 0, &ret); | 232 | // rx_sync_cmd(dev, HOST_CRASHING, 0, 0, 0, 0, 0, 0, |
233 | // NULL, NULL, NULL, NULL, NULL); | ||
224 | break; | 234 | break; |
225 | case FastIo: | 235 | case FastIo: |
226 | rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_6); | 236 | rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_6); |
@@ -243,17 +253,11 @@ static void aac_rx_notify_adapter(struct aac_dev *dev, u32 event) | |||
243 | 253 | ||
244 | static void aac_rx_start_adapter(struct aac_dev *dev) | 254 | static void aac_rx_start_adapter(struct aac_dev *dev) |
245 | { | 255 | { |
246 | u32 status; | ||
247 | struct aac_init *init; | 256 | struct aac_init *init; |
248 | 257 | ||
249 | init = dev->init; | 258 | init = dev->init; |
250 | init->HostElapsedSeconds = cpu_to_le32(get_seconds()); | 259 | init->HostElapsedSeconds = cpu_to_le32(get_seconds()); |
251 | /* | 260 | /* |
252 | * Tell the adapter we are back and up and running so it will scan | ||
253 | * its command queues and enable our interrupts | ||
254 | */ | ||
255 | dev->irq_mask = (DoorBellPrintfReady | OUTBOUNDDOORBELL_1 | OUTBOUNDDOORBELL_2 | OUTBOUNDDOORBELL_3 | OUTBOUNDDOORBELL_4); | ||
256 | /* | ||
257 | * First clear out all interrupts. Then enable the one's that we | 261 | * First clear out all interrupts. Then enable the one's that we |
258 | * can handle. | 262 | * can handle. |
259 | */ | 263 | */ |
@@ -263,7 +267,8 @@ static void aac_rx_start_adapter(struct aac_dev *dev) | |||
263 | rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb); | 267 | rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb); |
264 | 268 | ||
265 | // We can only use a 32 bit address here | 269 | // We can only use a 32 bit address here |
266 | rx_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa, &status); | 270 | rx_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa, |
271 | 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL); | ||
267 | } | 272 | } |
268 | 273 | ||
269 | /** | 274 | /** |
@@ -310,7 +315,8 @@ static int aac_rx_check_health(struct aac_dev *dev) | |||
310 | post->Post_Command = cpu_to_le32(COMMAND_POST_RESULTS); | 315 | post->Post_Command = cpu_to_le32(COMMAND_POST_RESULTS); |
311 | post->Post_Address = cpu_to_le32(baddr); | 316 | post->Post_Address = cpu_to_le32(baddr); |
312 | rx_writel(dev, MUnit.IMRx[0], paddr); | 317 | rx_writel(dev, MUnit.IMRx[0], paddr); |
313 | rx_sync_cmd(dev, COMMAND_POST_RESULTS, baddr, &status); | 318 | rx_sync_cmd(dev, COMMAND_POST_RESULTS, baddr, 0, 0, 0, 0, 0, |
319 | NULL, NULL, NULL, NULL, NULL); | ||
314 | pci_free_consistent(dev->pdev, sizeof(struct POSTSTATUS), | 320 | pci_free_consistent(dev->pdev, sizeof(struct POSTSTATUS), |
315 | post, paddr); | 321 | post, paddr); |
316 | if ((buffer[0] == '0') && (buffer[1] == 'x')) { | 322 | if ((buffer[0] == '0') && (buffer[1] == 'x')) { |
diff --git a/drivers/scsi/aacraid/sa.c b/drivers/scsi/aacraid/sa.c index 100c5a0866b4..0680249ab861 100644 --- a/drivers/scsi/aacraid/sa.c +++ b/drivers/scsi/aacraid/sa.c | |||
@@ -106,7 +106,10 @@ static void aac_sa_notify_adapter(struct aac_dev *dev, u32 event) | |||
106 | sa_writew(dev, DoorbellReg_s,DOORBELL_3); | 106 | sa_writew(dev, DoorbellReg_s,DOORBELL_3); |
107 | break; | 107 | break; |
108 | case HostShutdown: | 108 | case HostShutdown: |
109 | //sa_sync_cmd(dev, HOST_CRASHING, 0, &ret); | 109 | /* |
110 | sa_sync_cmd(dev, HOST_CRASHING, 0, 0, 0, 0, 0, 0, | ||
111 | NULL, NULL, NULL, NULL, NULL); | ||
112 | */ | ||
110 | break; | 113 | break; |
111 | case FastIo: | 114 | case FastIo: |
112 | sa_writew(dev, DoorbellReg_s,DOORBELL_6); | 115 | sa_writew(dev, DoorbellReg_s,DOORBELL_6); |
@@ -132,7 +135,9 @@ static void aac_sa_notify_adapter(struct aac_dev *dev, u32 event) | |||
132 | * for its completion. | 135 | * for its completion. |
133 | */ | 136 | */ |
134 | 137 | ||
135 | static int sa_sync_cmd(struct aac_dev *dev, u32 command, u32 p1, u32 *ret) | 138 | static int sa_sync_cmd(struct aac_dev *dev, u32 command, |
139 | u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, | ||
140 | u32 *ret, u32 *r1, u32 *r2, u32 *r3, u32 *r4) | ||
136 | { | 141 | { |
137 | unsigned long start; | 142 | unsigned long start; |
138 | int ok; | 143 | int ok; |
@@ -144,9 +149,10 @@ static int sa_sync_cmd(struct aac_dev *dev, u32 command, u32 p1, u32 *ret) | |||
144 | * Write the parameters into Mailboxes 1 - 4 | 149 | * Write the parameters into Mailboxes 1 - 4 |
145 | */ | 150 | */ |
146 | sa_writel(dev, Mailbox1, p1); | 151 | sa_writel(dev, Mailbox1, p1); |
147 | sa_writel(dev, Mailbox2, 0); | 152 | sa_writel(dev, Mailbox2, p2); |
148 | sa_writel(dev, Mailbox3, 0); | 153 | sa_writel(dev, Mailbox3, p3); |
149 | sa_writel(dev, Mailbox4, 0); | 154 | sa_writel(dev, Mailbox4, p4); |
155 | |||
150 | /* | 156 | /* |
151 | * Clear the synch command doorbell to start on a clean slate. | 157 | * Clear the synch command doorbell to start on a clean slate. |
152 | */ | 158 | */ |
@@ -188,6 +194,14 @@ static int sa_sync_cmd(struct aac_dev *dev, u32 command, u32 p1, u32 *ret) | |||
188 | */ | 194 | */ |
189 | if (ret) | 195 | if (ret) |
190 | *ret = sa_readl(dev, Mailbox0); | 196 | *ret = sa_readl(dev, Mailbox0); |
197 | if (r1) | ||
198 | *r1 = sa_readl(dev, Mailbox1); | ||
199 | if (r2) | ||
200 | *r2 = sa_readl(dev, Mailbox2); | ||
201 | if (r3) | ||
202 | *r3 = sa_readl(dev, Mailbox3); | ||
203 | if (r4) | ||
204 | *r4 = sa_readl(dev, Mailbox4); | ||
191 | return 0; | 205 | return 0; |
192 | } | 206 | } |
193 | 207 | ||
@@ -201,7 +215,8 @@ static int sa_sync_cmd(struct aac_dev *dev, u32 command, u32 p1, u32 *ret) | |||
201 | static void aac_sa_interrupt_adapter (struct aac_dev *dev) | 215 | static void aac_sa_interrupt_adapter (struct aac_dev *dev) |
202 | { | 216 | { |
203 | u32 ret; | 217 | u32 ret; |
204 | sa_sync_cmd(dev, BREAKPOINT_REQUEST, 0, &ret); | 218 | sa_sync_cmd(dev, BREAKPOINT_REQUEST, 0, 0, 0, 0, 0, 0, |
219 | &ret, NULL, NULL, NULL, NULL); | ||
205 | } | 220 | } |
206 | 221 | ||
207 | /** | 222 | /** |
@@ -233,7 +248,9 @@ static void aac_sa_start_adapter(struct aac_dev *dev) | |||
233 | sa_writew(dev, SaDbCSR.PRISETIRQMASK, 0xffff); | 248 | sa_writew(dev, SaDbCSR.PRISETIRQMASK, 0xffff); |
234 | sa_writew(dev, SaDbCSR.PRICLEARIRQMASK, (PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4)); | 249 | sa_writew(dev, SaDbCSR.PRICLEARIRQMASK, (PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4)); |
235 | /* We can only use a 32 bit address here */ | 250 | /* We can only use a 32 bit address here */ |
236 | sa_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa, &ret); | 251 | sa_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, |
252 | (u32)(ulong)dev->init_pa, 0, 0, 0, 0, 0, | ||
253 | &ret, NULL, NULL, NULL, NULL); | ||
237 | } | 254 | } |
238 | 255 | ||
239 | /** | 256 | /** |