aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/aacraid/aachba.c181
-rw-r--r--drivers/scsi/aacraid/aacraid.h43
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
134static unsigned long aac_build_sg(struct scsi_cmnd* scsicmd, struct sgmap* sgmap); 134static unsigned long aac_build_sg(struct scsi_cmnd* scsicmd, struct sgmap* sgmap);
135static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* psg); 135static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* psg);
136static unsigned long aac_build_sgraw(struct scsi_cmnd* scsicmd, struct sgmapraw* psg);
136static int aac_send_srb_fib(struct scsi_cmnd* scsicmd); 137static int aac_send_srb_fib(struct scsi_cmnd* scsicmd);
137#ifdef AAC_DETAILED_STATUS_INFO 138#ifdef AAC_DETAILED_STATUS_INFO
138static char *aac_get_status_string(u32 status); 139static 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
2084static 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
2033struct aac_srb_status_info { 2156struct 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
117struct 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
125struct 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
160struct sgmapraw {
161 __le32 count;
162 struct sgentryraw sg[1];
163};
164
165struct user_sgmapraw {
166 u32 count;
167 struct user_sgentryraw sg[1];
168};
169
144struct creation_info 170struct 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
1197struct 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
1168struct aac_synchronize { 1209struct 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 */
1210struct user_aac_srb 1251struct user_aac_srb