diff options
-rw-r--r-- | drivers/scsi/aacraid/aachba.c | 181 | ||||
-rw-r--r-- | drivers/scsi/aacraid/aacraid.h | 43 |
2 files changed, 194 insertions, 30 deletions
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index b03c8dee76b7..d6c999cd7f78 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c | |||
@@ -133,6 +133,7 @@ struct inquiry_data { | |||
133 | 133 | ||
134 | static unsigned long aac_build_sg(struct scsi_cmnd* scsicmd, struct sgmap* sgmap); | 134 | static unsigned long aac_build_sg(struct scsi_cmnd* scsicmd, struct sgmap* sgmap); |
135 | static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* psg); | 135 | static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* psg); |
136 | static unsigned long aac_build_sgraw(struct scsi_cmnd* scsicmd, struct sgmapraw* psg); | ||
136 | static int aac_send_srb_fib(struct scsi_cmnd* scsicmd); | 137 | static int aac_send_srb_fib(struct scsi_cmnd* scsicmd); |
137 | #ifdef AAC_DETAILED_STATUS_INFO | 138 | #ifdef AAC_DETAILED_STATUS_INFO |
138 | static char *aac_get_status_string(u32 status); | 139 | static char *aac_get_status_string(u32 status); |
@@ -777,34 +778,36 @@ int aac_get_adapter_info(struct aac_dev* dev) | |||
777 | /* | 778 | /* |
778 | * 57 scatter gather elements | 779 | * 57 scatter gather elements |
779 | */ | 780 | */ |
780 | dev->scsi_host_ptr->sg_tablesize = (dev->max_fib_size - | 781 | if (!(dev->raw_io_interface)) { |
781 | sizeof(struct aac_fibhdr) - | 782 | dev->scsi_host_ptr->sg_tablesize = (dev->max_fib_size - |
782 | sizeof(struct aac_write) + sizeof(struct sgmap)) / | ||
783 | sizeof(struct sgmap); | ||
784 | if (dev->dac_support) { | ||
785 | /* | ||
786 | * 38 scatter gather elements | ||
787 | */ | ||
788 | dev->scsi_host_ptr->sg_tablesize = | ||
789 | (dev->max_fib_size - | ||
790 | sizeof(struct aac_fibhdr) - | 783 | sizeof(struct aac_fibhdr) - |
791 | sizeof(struct aac_write64) + | 784 | sizeof(struct aac_write) + sizeof(struct sgmap)) / |
792 | sizeof(struct sgmap64)) / | 785 | sizeof(struct sgmap); |
793 | sizeof(struct sgmap64); | 786 | if (dev->dac_support) { |
794 | } | 787 | /* |
795 | dev->scsi_host_ptr->max_sectors = AAC_MAX_32BIT_SGBCOUNT; | 788 | * 38 scatter gather elements |
796 | if(!(dev->adapter_info.options & AAC_OPT_NEW_COMM)) { | 789 | */ |
797 | /* | 790 | dev->scsi_host_ptr->sg_tablesize = |
798 | * Worst case size that could cause sg overflow when | 791 | (dev->max_fib_size - |
799 | * we break up SG elements that are larger than 64KB. | 792 | sizeof(struct aac_fibhdr) - |
800 | * Would be nice if we could tell the SCSI layer what | 793 | sizeof(struct aac_write64) + |
801 | * the maximum SG element size can be. Worst case is | 794 | sizeof(struct sgmap64)) / |
802 | * (sg_tablesize-1) 4KB elements with one 64KB | 795 | sizeof(struct sgmap64); |
803 | * element. | 796 | } |
804 | * 32bit -> 468 or 238KB 64bit -> 424 or 212KB | 797 | dev->scsi_host_ptr->max_sectors = AAC_MAX_32BIT_SGBCOUNT; |
805 | */ | 798 | if(!(dev->adapter_info.options & AAC_OPT_NEW_COMM)) { |
806 | dev->scsi_host_ptr->max_sectors = | 799 | /* |
807 | (dev->scsi_host_ptr->sg_tablesize * 8) + 112; | 800 | * Worst case size that could cause sg overflow when |
801 | * we break up SG elements that are larger than 64KB. | ||
802 | * Would be nice if we could tell the SCSI layer what | ||
803 | * the maximum SG element size can be. Worst case is | ||
804 | * (sg_tablesize-1) 4KB elements with one 64KB | ||
805 | * element. | ||
806 | * 32bit -> 468 or 238KB 64bit -> 424 or 212KB | ||
807 | */ | ||
808 | dev->scsi_host_ptr->max_sectors = | ||
809 | (dev->scsi_host_ptr->sg_tablesize * 8) + 112; | ||
810 | } | ||
808 | } | 811 | } |
809 | 812 | ||
810 | fib_complete(fibptr); | 813 | fib_complete(fibptr); |
@@ -905,7 +908,32 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) | |||
905 | 908 | ||
906 | fib_init(cmd_fibcontext); | 909 | fib_init(cmd_fibcontext); |
907 | 910 | ||
908 | if (dev->dac_support == 1) { | 911 | if (dev->raw_io_interface) { |
912 | struct aac_raw_io *readcmd; | ||
913 | readcmd = (struct aac_raw_io *) fib_data(cmd_fibcontext); | ||
914 | readcmd->block[0] = cpu_to_le32(lba); | ||
915 | readcmd->block[1] = 0; | ||
916 | readcmd->count = cpu_to_le32(count<<9); | ||
917 | readcmd->cid = cpu_to_le16(cid); | ||
918 | readcmd->flags = cpu_to_le16(1); | ||
919 | readcmd->bpTotal = 0; | ||
920 | readcmd->bpComplete = 0; | ||
921 | |||
922 | aac_build_sgraw(scsicmd, &readcmd->sg); | ||
923 | fibsize = sizeof(struct aac_raw_io) + ((le32_to_cpu(readcmd->sg.count) - 1) * sizeof (struct sgentryraw)); | ||
924 | if (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr))) | ||
925 | BUG(); | ||
926 | /* | ||
927 | * Now send the Fib to the adapter | ||
928 | */ | ||
929 | status = fib_send(ContainerRawIo, | ||
930 | cmd_fibcontext, | ||
931 | fibsize, | ||
932 | FsaNormal, | ||
933 | 0, 1, | ||
934 | (fib_callback) io_callback, | ||
935 | (void *) scsicmd); | ||
936 | } else if (dev->dac_support == 1) { | ||
909 | struct aac_read64 *readcmd; | 937 | struct aac_read64 *readcmd; |
910 | readcmd = (struct aac_read64 *) fib_data(cmd_fibcontext); | 938 | readcmd = (struct aac_read64 *) fib_data(cmd_fibcontext); |
911 | readcmd->command = cpu_to_le32(VM_CtHostRead64); | 939 | readcmd->command = cpu_to_le32(VM_CtHostRead64); |
@@ -1012,7 +1040,32 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid) | |||
1012 | } | 1040 | } |
1013 | fib_init(cmd_fibcontext); | 1041 | fib_init(cmd_fibcontext); |
1014 | 1042 | ||
1015 | if(dev->dac_support == 1) { | 1043 | if (dev->raw_io_interface) { |
1044 | struct aac_raw_io *writecmd; | ||
1045 | writecmd = (struct aac_raw_io *) fib_data(cmd_fibcontext); | ||
1046 | writecmd->block[0] = cpu_to_le32(lba); | ||
1047 | writecmd->block[1] = 0; | ||
1048 | writecmd->count = cpu_to_le32(count<<9); | ||
1049 | writecmd->cid = cpu_to_le16(cid); | ||
1050 | writecmd->flags = 0; | ||
1051 | writecmd->bpTotal = 0; | ||
1052 | writecmd->bpComplete = 0; | ||
1053 | |||
1054 | aac_build_sgraw(scsicmd, &writecmd->sg); | ||
1055 | fibsize = sizeof(struct aac_raw_io) + ((le32_to_cpu(writecmd->sg.count) - 1) * sizeof (struct sgentryraw)); | ||
1056 | if (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr))) | ||
1057 | BUG(); | ||
1058 | /* | ||
1059 | * Now send the Fib to the adapter | ||
1060 | */ | ||
1061 | status = fib_send(ContainerRawIo, | ||
1062 | cmd_fibcontext, | ||
1063 | fibsize, | ||
1064 | FsaNormal, | ||
1065 | 0, 1, | ||
1066 | (fib_callback) io_callback, | ||
1067 | (void *) scsicmd); | ||
1068 | } else if (dev->dac_support == 1) { | ||
1016 | struct aac_write64 *writecmd; | 1069 | struct aac_write64 *writecmd; |
1017 | writecmd = (struct aac_write64 *) fib_data(cmd_fibcontext); | 1070 | writecmd = (struct aac_write64 *) fib_data(cmd_fibcontext); |
1018 | writecmd->command = cpu_to_le32(VM_CtHostWrite64); | 1071 | writecmd->command = cpu_to_le32(VM_CtHostWrite64); |
@@ -2028,6 +2081,76 @@ static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* p | |||
2028 | return byte_count; | 2081 | return byte_count; |
2029 | } | 2082 | } |
2030 | 2083 | ||
2084 | static unsigned long aac_build_sgraw(struct scsi_cmnd* scsicmd, struct sgmapraw* psg) | ||
2085 | { | ||
2086 | struct Scsi_Host *host = scsicmd->device->host; | ||
2087 | struct aac_dev *dev = (struct aac_dev *)host->hostdata; | ||
2088 | unsigned long byte_count = 0; | ||
2089 | |||
2090 | // Get rid of old data | ||
2091 | psg->count = 0; | ||
2092 | psg->sg[0].next = 0; | ||
2093 | psg->sg[0].prev = 0; | ||
2094 | psg->sg[0].addr[0] = 0; | ||
2095 | psg->sg[0].addr[1] = 0; | ||
2096 | psg->sg[0].count = 0; | ||
2097 | psg->sg[0].flags = 0; | ||
2098 | if (scsicmd->use_sg) { | ||
2099 | struct scatterlist *sg; | ||
2100 | int i; | ||
2101 | int sg_count; | ||
2102 | sg = (struct scatterlist *) scsicmd->request_buffer; | ||
2103 | |||
2104 | sg_count = pci_map_sg(dev->pdev, sg, scsicmd->use_sg, | ||
2105 | scsicmd->sc_data_direction); | ||
2106 | |||
2107 | for (i = 0; i < sg_count; i++) { | ||
2108 | int count = sg_dma_len(sg); | ||
2109 | u64 addr = sg_dma_address(sg); | ||
2110 | psg->sg[i].next = 0; | ||
2111 | psg->sg[i].prev = 0; | ||
2112 | psg->sg[i].addr[1] = cpu_to_le32((u32)(addr>>32)); | ||
2113 | psg->sg[i].addr[0] = cpu_to_le32((u32)(addr & 0xffffffff)); | ||
2114 | psg->sg[i].count = cpu_to_le32(count); | ||
2115 | psg->sg[i].flags = 0; | ||
2116 | byte_count += count; | ||
2117 | sg++; | ||
2118 | } | ||
2119 | psg->count = cpu_to_le32(sg_count); | ||
2120 | /* hba wants the size to be exact */ | ||
2121 | if(byte_count > scsicmd->request_bufflen){ | ||
2122 | u32 temp = le32_to_cpu(psg->sg[i-1].count) - | ||
2123 | (byte_count - scsicmd->request_bufflen); | ||
2124 | psg->sg[i-1].count = cpu_to_le32(temp); | ||
2125 | byte_count = scsicmd->request_bufflen; | ||
2126 | } | ||
2127 | /* Check for command underflow */ | ||
2128 | if(scsicmd->underflow && (byte_count < scsicmd->underflow)){ | ||
2129 | printk(KERN_WARNING"aacraid: cmd len %08lX cmd underflow %08X\n", | ||
2130 | byte_count, scsicmd->underflow); | ||
2131 | } | ||
2132 | } | ||
2133 | else if(scsicmd->request_bufflen) { | ||
2134 | int count; | ||
2135 | u64 addr; | ||
2136 | scsicmd->SCp.dma_handle = pci_map_single(dev->pdev, | ||
2137 | scsicmd->request_buffer, | ||
2138 | scsicmd->request_bufflen, | ||
2139 | scsicmd->sc_data_direction); | ||
2140 | addr = scsicmd->SCp.dma_handle; | ||
2141 | count = scsicmd->request_bufflen; | ||
2142 | psg->count = cpu_to_le32(1); | ||
2143 | psg->sg[0].next = 0; | ||
2144 | psg->sg[0].prev = 0; | ||
2145 | psg->sg[0].addr[1] = cpu_to_le32((u32)(addr>>32)); | ||
2146 | psg->sg[0].addr[0] = cpu_to_le32((u32)(addr & 0xffffffff)); | ||
2147 | psg->sg[0].count = cpu_to_le32(count); | ||
2148 | psg->sg[0].flags = 0; | ||
2149 | byte_count = scsicmd->request_bufflen; | ||
2150 | } | ||
2151 | return byte_count; | ||
2152 | } | ||
2153 | |||
2031 | #ifdef AAC_DETAILED_STATUS_INFO | 2154 | #ifdef AAC_DETAILED_STATUS_INFO |
2032 | 2155 | ||
2033 | struct aac_srb_status_info { | 2156 | struct aac_srb_status_info { |
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 6f4906ee9a5e..bc91e7ce5e59 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h | |||
@@ -114,6 +114,22 @@ struct user_sgentry64 { | |||
114 | u32 count; /* Length. */ | 114 | u32 count; /* Length. */ |
115 | }; | 115 | }; |
116 | 116 | ||
117 | struct sgentryraw { | ||
118 | __le32 next; /* reserved for F/W use */ | ||
119 | __le32 prev; /* reserved for F/W use */ | ||
120 | __le32 addr[2]; | ||
121 | __le32 count; | ||
122 | __le32 flags; /* reserved for F/W use */ | ||
123 | }; | ||
124 | |||
125 | struct user_sgentryraw { | ||
126 | u32 next; /* reserved for F/W use */ | ||
127 | u32 prev; /* reserved for F/W use */ | ||
128 | u32 addr[2]; | ||
129 | u32 count; | ||
130 | u32 flags; /* reserved for F/W use */ | ||
131 | }; | ||
132 | |||
117 | /* | 133 | /* |
118 | * SGMAP | 134 | * SGMAP |
119 | * | 135 | * |
@@ -141,6 +157,16 @@ struct user_sgmap64 { | |||
141 | struct user_sgentry64 sg[1]; | 157 | struct user_sgentry64 sg[1]; |
142 | }; | 158 | }; |
143 | 159 | ||
160 | struct sgmapraw { | ||
161 | __le32 count; | ||
162 | struct sgentryraw sg[1]; | ||
163 | }; | ||
164 | |||
165 | struct user_sgmapraw { | ||
166 | u32 count; | ||
167 | struct user_sgentryraw sg[1]; | ||
168 | }; | ||
169 | |||
144 | struct creation_info | 170 | struct creation_info |
145 | { | 171 | { |
146 | u8 buildnum; /* e.g., 588 */ | 172 | u8 buildnum; /* e.g., 588 */ |
@@ -355,6 +381,7 @@ struct hw_fib { | |||
355 | */ | 381 | */ |
356 | #define ContainerCommand 500 | 382 | #define ContainerCommand 500 |
357 | #define ContainerCommand64 501 | 383 | #define ContainerCommand64 501 |
384 | #define ContainerRawIo 502 | ||
358 | /* | 385 | /* |
359 | * Cluster Commands | 386 | * Cluster Commands |
360 | */ | 387 | */ |
@@ -986,6 +1013,9 @@ struct aac_dev | |||
986 | u8 nondasd_support; | 1013 | u8 nondasd_support; |
987 | u8 dac_support; | 1014 | u8 dac_support; |
988 | u8 raid_scsi_mode; | 1015 | u8 raid_scsi_mode; |
1016 | /* macro side-effects BEWARE */ | ||
1017 | # define raw_io_interface \ | ||
1018 | init->InitStructRevision==cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4) | ||
989 | u8 printf_enabled; | 1019 | u8 printf_enabled; |
990 | }; | 1020 | }; |
991 | 1021 | ||
@@ -1164,6 +1194,17 @@ struct aac_write_reply | |||
1164 | __le32 committed; | 1194 | __le32 committed; |
1165 | }; | 1195 | }; |
1166 | 1196 | ||
1197 | struct aac_raw_io | ||
1198 | { | ||
1199 | __le32 block[2]; | ||
1200 | __le32 count; | ||
1201 | __le16 cid; | ||
1202 | __le16 flags; /* 00 W, 01 R */ | ||
1203 | __le16 bpTotal; /* reserved for F/W use */ | ||
1204 | __le16 bpComplete; /* reserved for F/W use */ | ||
1205 | struct sgmapraw sg; | ||
1206 | }; | ||
1207 | |||
1167 | #define CT_FLUSH_CACHE 129 | 1208 | #define CT_FLUSH_CACHE 129 |
1168 | struct aac_synchronize { | 1209 | struct aac_synchronize { |
1169 | __le32 command; /* VM_ContainerConfig */ | 1210 | __le32 command; /* VM_ContainerConfig */ |
@@ -1204,7 +1245,7 @@ struct aac_srb | |||
1204 | }; | 1245 | }; |
1205 | 1246 | ||
1206 | /* | 1247 | /* |
1207 | * This and assocated data structs are used by the | 1248 | * This and associated data structs are used by the |
1208 | * ioctl caller and are in cpu order. | 1249 | * ioctl caller and are in cpu order. |
1209 | */ | 1250 | */ |
1210 | struct user_aac_srb | 1251 | struct user_aac_srb |