aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/aacraid/aachba.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/aacraid/aachba.c')
-rw-r--r--drivers/scsi/aacraid/aachba.c237
1 files changed, 200 insertions, 37 deletions
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 52551662d107..d79457ac8bef 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -135,6 +135,8 @@ struct inquiry_data {
135static unsigned long aac_build_sg(struct scsi_cmnd* scsicmd, struct sgmap* sgmap); 135static unsigned long aac_build_sg(struct scsi_cmnd* scsicmd, struct sgmap* sgmap);
136static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* psg); 136static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* psg);
137static unsigned long aac_build_sgraw(struct scsi_cmnd* scsicmd, struct sgmapraw* psg); 137static unsigned long aac_build_sgraw(struct scsi_cmnd* scsicmd, struct sgmapraw* psg);
138static unsigned long aac_build_sgraw2(struct scsi_cmnd *scsicmd, struct aac_raw_io2 *rio2, int sg_max);
139static int aac_convert_sgraw2(struct aac_raw_io2 *rio2, int pages, int nseg, int nseg_new);
138static int aac_send_srb_fib(struct scsi_cmnd* scsicmd); 140static int aac_send_srb_fib(struct scsi_cmnd* scsicmd);
139#ifdef AAC_DETAILED_STATUS_INFO 141#ifdef AAC_DETAILED_STATUS_INFO
140static char *aac_get_status_string(u32 status); 142static char *aac_get_status_string(u32 status);
@@ -152,10 +154,14 @@ int aac_commit = -1;
152int startup_timeout = 180; 154int startup_timeout = 180;
153int aif_timeout = 120; 155int aif_timeout = 120;
154int aac_sync_mode; /* Only Sync. transfer - disabled */ 156int aac_sync_mode; /* Only Sync. transfer - disabled */
157int aac_convert_sgl = 1; /* convert non-conformable s/g list - enabled */
155 158
156module_param(aac_sync_mode, int, S_IRUGO|S_IWUSR); 159module_param(aac_sync_mode, int, S_IRUGO|S_IWUSR);
157MODULE_PARM_DESC(aac_sync_mode, "Force sync. transfer mode" 160MODULE_PARM_DESC(aac_sync_mode, "Force sync. transfer mode"
158 " 0=off, 1=on"); 161 " 0=off, 1=on");
162module_param(aac_convert_sgl, int, S_IRUGO|S_IWUSR);
163MODULE_PARM_DESC(aac_convert_sgl, "Convert non-conformable s/g list"
164 " 0=off, 1=on");
159module_param(nondasd, int, S_IRUGO|S_IWUSR); 165module_param(nondasd, int, S_IRUGO|S_IWUSR);
160MODULE_PARM_DESC(nondasd, "Control scanning of hba for nondasd devices." 166MODULE_PARM_DESC(nondasd, "Control scanning of hba for nondasd devices."
161 " 0=off, 1=on"); 167 " 0=off, 1=on");
@@ -963,25 +969,44 @@ static void io_callback(void *context, struct fib * fibptr);
963 969
964static int aac_read_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count) 970static int aac_read_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count)
965{ 971{
966 u16 fibsize; 972 struct aac_dev *dev = fib->dev;
967 struct aac_raw_io *readcmd; 973 u16 fibsize, command;
974
968 aac_fib_init(fib); 975 aac_fib_init(fib);
969 readcmd = (struct aac_raw_io *) fib_data(fib); 976 if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2 && !dev->sync_mode) {
970 readcmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff)); 977 struct aac_raw_io2 *readcmd2;
971 readcmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32)); 978 readcmd2 = (struct aac_raw_io2 *) fib_data(fib);
972 readcmd->count = cpu_to_le32(count<<9); 979 memset(readcmd2, 0, sizeof(struct aac_raw_io2));
973 readcmd->cid = cpu_to_le16(scmd_id(cmd)); 980 readcmd2->blockLow = cpu_to_le32((u32)(lba&0xffffffff));
974 readcmd->flags = cpu_to_le16(IO_TYPE_READ); 981 readcmd2->blockHigh = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
975 readcmd->bpTotal = 0; 982 readcmd2->byteCount = cpu_to_le32(count<<9);
976 readcmd->bpComplete = 0; 983 readcmd2->cid = cpu_to_le16(scmd_id(cmd));
984 readcmd2->flags = cpu_to_le16(RIO2_IO_TYPE_READ);
985 aac_build_sgraw2(cmd, readcmd2, dev->scsi_host_ptr->sg_tablesize);
986 command = ContainerRawIo2;
987 fibsize = sizeof(struct aac_raw_io2) +
988 ((le32_to_cpu(readcmd2->sgeCnt)-1) * sizeof(struct sge_ieee1212));
989 } else {
990 struct aac_raw_io *readcmd;
991 readcmd = (struct aac_raw_io *) fib_data(fib);
992 readcmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff));
993 readcmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
994 readcmd->count = cpu_to_le32(count<<9);
995 readcmd->cid = cpu_to_le16(scmd_id(cmd));
996 readcmd->flags = cpu_to_le16(RIO_TYPE_READ);
997 readcmd->bpTotal = 0;
998 readcmd->bpComplete = 0;
999 aac_build_sgraw(cmd, &readcmd->sg);
1000 command = ContainerRawIo;
1001 fibsize = sizeof(struct aac_raw_io) +
1002 ((le32_to_cpu(readcmd->sg.count)-1) * sizeof(struct sgentryraw));
1003 }
977 1004
978 aac_build_sgraw(cmd, &readcmd->sg);
979 fibsize = sizeof(struct aac_raw_io) + ((le32_to_cpu(readcmd->sg.count) - 1) * sizeof (struct sgentryraw));
980 BUG_ON(fibsize > (fib->dev->max_fib_size - sizeof(struct aac_fibhdr))); 1005 BUG_ON(fibsize > (fib->dev->max_fib_size - sizeof(struct aac_fibhdr)));
981 /* 1006 /*
982 * Now send the Fib to the adapter 1007 * Now send the Fib to the adapter
983 */ 1008 */
984 return aac_fib_send(ContainerRawIo, 1009 return aac_fib_send(command,
985 fib, 1010 fib,
986 fibsize, 1011 fibsize,
987 FsaNormal, 1012 FsaNormal,
@@ -1052,28 +1077,50 @@ static int aac_read_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32
1052 1077
1053static int aac_write_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count, int fua) 1078static int aac_write_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count, int fua)
1054{ 1079{
1055 u16 fibsize; 1080 struct aac_dev *dev = fib->dev;
1056 struct aac_raw_io *writecmd; 1081 u16 fibsize, command;
1082
1057 aac_fib_init(fib); 1083 aac_fib_init(fib);
1058 writecmd = (struct aac_raw_io *) fib_data(fib); 1084 if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2 && !dev->sync_mode) {
1059 writecmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff)); 1085 struct aac_raw_io2 *writecmd2;
1060 writecmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32)); 1086 writecmd2 = (struct aac_raw_io2 *) fib_data(fib);
1061 writecmd->count = cpu_to_le32(count<<9); 1087 memset(writecmd2, 0, sizeof(struct aac_raw_io2));
1062 writecmd->cid = cpu_to_le16(scmd_id(cmd)); 1088 writecmd2->blockLow = cpu_to_le32((u32)(lba&0xffffffff));
1063 writecmd->flags = (fua && ((aac_cache & 5) != 1) && 1089 writecmd2->blockHigh = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
1064 (((aac_cache & 5) != 5) || !fib->dev->cache_protected)) ? 1090 writecmd2->byteCount = cpu_to_le32(count<<9);
1065 cpu_to_le16(IO_TYPE_WRITE|IO_SUREWRITE) : 1091 writecmd2->cid = cpu_to_le16(scmd_id(cmd));
1066 cpu_to_le16(IO_TYPE_WRITE); 1092 writecmd2->flags = (fua && ((aac_cache & 5) != 1) &&
1067 writecmd->bpTotal = 0; 1093 (((aac_cache & 5) != 5) || !fib->dev->cache_protected)) ?
1068 writecmd->bpComplete = 0; 1094 cpu_to_le16(RIO2_IO_TYPE_WRITE|RIO2_IO_SUREWRITE) :
1069 1095 cpu_to_le16(RIO2_IO_TYPE_WRITE);
1070 aac_build_sgraw(cmd, &writecmd->sg); 1096 aac_build_sgraw2(cmd, writecmd2, dev->scsi_host_ptr->sg_tablesize);
1071 fibsize = sizeof(struct aac_raw_io) + ((le32_to_cpu(writecmd->sg.count) - 1) * sizeof (struct sgentryraw)); 1097 command = ContainerRawIo2;
1098 fibsize = sizeof(struct aac_raw_io2) +
1099 ((le32_to_cpu(writecmd2->sgeCnt)-1) * sizeof(struct sge_ieee1212));
1100 } else {
1101 struct aac_raw_io *writecmd;
1102 writecmd = (struct aac_raw_io *) fib_data(fib);
1103 writecmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff));
1104 writecmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
1105 writecmd->count = cpu_to_le32(count<<9);
1106 writecmd->cid = cpu_to_le16(scmd_id(cmd));
1107 writecmd->flags = (fua && ((aac_cache & 5) != 1) &&
1108 (((aac_cache & 5) != 5) || !fib->dev->cache_protected)) ?
1109 cpu_to_le16(RIO_TYPE_WRITE|RIO_SUREWRITE) :
1110 cpu_to_le16(RIO_TYPE_WRITE);
1111 writecmd->bpTotal = 0;
1112 writecmd->bpComplete = 0;
1113 aac_build_sgraw(cmd, &writecmd->sg);
1114 command = ContainerRawIo;
1115 fibsize = sizeof(struct aac_raw_io) +
1116 ((le32_to_cpu(writecmd->sg.count)-1) * sizeof (struct sgentryraw));
1117 }
1118
1072 BUG_ON(fibsize > (fib->dev->max_fib_size - sizeof(struct aac_fibhdr))); 1119 BUG_ON(fibsize > (fib->dev->max_fib_size - sizeof(struct aac_fibhdr)));
1073 /* 1120 /*
1074 * Now send the Fib to the adapter 1121 * Now send the Fib to the adapter
1075 */ 1122 */
1076 return aac_fib_send(ContainerRawIo, 1123 return aac_fib_send(command,
1077 fib, 1124 fib,
1078 fibsize, 1125 fibsize,
1079 FsaNormal, 1126 FsaNormal,
@@ -1492,8 +1539,6 @@ int aac_get_adapter_info(struct aac_dev* dev)
1492 dev->a_ops.adapter_write = aac_write_block; 1539 dev->a_ops.adapter_write = aac_write_block;
1493 } 1540 }
1494 dev->scsi_host_ptr->max_sectors = AAC_MAX_32BIT_SGBCOUNT; 1541 dev->scsi_host_ptr->max_sectors = AAC_MAX_32BIT_SGBCOUNT;
1495 if (dev->adapter_info.options & AAC_OPT_NEW_COMM_TYPE1)
1496 dev->adapter_info.options |= AAC_OPT_NEW_COMM;
1497 if (!(dev->adapter_info.options & AAC_OPT_NEW_COMM)) { 1542 if (!(dev->adapter_info.options & AAC_OPT_NEW_COMM)) {
1498 /* 1543 /*
1499 * Worst case size that could cause sg overflow when 1544 * Worst case size that could cause sg overflow when
@@ -2616,12 +2661,18 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
2616 srbreply = (struct aac_srb_reply *) fib_data(fibptr); 2661 srbreply = (struct aac_srb_reply *) fib_data(fibptr);
2617 2662
2618 scsicmd->sense_buffer[0] = '\0'; /* Initialize sense valid flag to false */ 2663 scsicmd->sense_buffer[0] = '\0'; /* Initialize sense valid flag to false */
2619 /*
2620 * Calculate resid for sg
2621 */
2622 2664
2623 scsi_set_resid(scsicmd, scsi_bufflen(scsicmd) 2665 if (fibptr->flags & FIB_CONTEXT_FLAG_FASTRESP) {
2624 - le32_to_cpu(srbreply->data_xfer_length)); 2666 /* fast response */
2667 srbreply->srb_status = cpu_to_le32(SRB_STATUS_SUCCESS);
2668 srbreply->scsi_status = cpu_to_le32(SAM_STAT_GOOD);
2669 } else {
2670 /*
2671 * Calculate resid for sg
2672 */
2673 scsi_set_resid(scsicmd, scsi_bufflen(scsicmd)
2674 - le32_to_cpu(srbreply->data_xfer_length));
2675 }
2625 2676
2626 scsi_dma_unmap(scsicmd); 2677 scsi_dma_unmap(scsicmd);
2627 2678
@@ -2954,6 +3005,118 @@ static unsigned long aac_build_sgraw(struct scsi_cmnd* scsicmd, struct sgmapraw*
2954 return byte_count; 3005 return byte_count;
2955} 3006}
2956 3007
3008static unsigned long aac_build_sgraw2(struct scsi_cmnd *scsicmd, struct aac_raw_io2 *rio2, int sg_max)
3009{
3010 unsigned long byte_count = 0;
3011 int nseg;
3012
3013 nseg = scsi_dma_map(scsicmd);
3014 BUG_ON(nseg < 0);
3015 if (nseg) {
3016 struct scatterlist *sg;
3017 int i, conformable = 0;
3018 u32 min_size = PAGE_SIZE, cur_size;
3019
3020 scsi_for_each_sg(scsicmd, sg, nseg, i) {
3021 int count = sg_dma_len(sg);
3022 u64 addr = sg_dma_address(sg);
3023
3024 BUG_ON(i >= sg_max);
3025 rio2->sge[i].addrHigh = cpu_to_le32((u32)(addr>>32));
3026 rio2->sge[i].addrLow = cpu_to_le32((u32)(addr & 0xffffffff));
3027 cur_size = cpu_to_le32(count);
3028 rio2->sge[i].length = cur_size;
3029 rio2->sge[i].flags = 0;
3030 if (i == 0) {
3031 conformable = 1;
3032 rio2->sgeFirstSize = cur_size;
3033 } else if (i == 1) {
3034 rio2->sgeNominalSize = cur_size;
3035 min_size = cur_size;
3036 } else if ((i+1) < nseg && cur_size != rio2->sgeNominalSize) {
3037 conformable = 0;
3038 if (cur_size < min_size)
3039 min_size = cur_size;
3040 }
3041 byte_count += count;
3042 }
3043
3044 /* hba wants the size to be exact */
3045 if (byte_count > scsi_bufflen(scsicmd)) {
3046 u32 temp = le32_to_cpu(rio2->sge[i-1].length) -
3047 (byte_count - scsi_bufflen(scsicmd));
3048 rio2->sge[i-1].length = cpu_to_le32(temp);
3049 byte_count = scsi_bufflen(scsicmd);
3050 }
3051
3052 rio2->sgeCnt = cpu_to_le32(nseg);
3053 rio2->flags |= cpu_to_le16(RIO2_SG_FORMAT_IEEE1212);
3054 /* not conformable: evaluate required sg elements */
3055 if (!conformable) {
3056 int j, nseg_new = nseg, err_found;
3057 for (i = min_size / PAGE_SIZE; i >= 1; --i) {
3058 err_found = 0;
3059 nseg_new = 2;
3060 for (j = 1; j < nseg - 1; ++j) {
3061 if (rio2->sge[j].length % (i*PAGE_SIZE)) {
3062 err_found = 1;
3063 break;
3064 }
3065 nseg_new += (rio2->sge[j].length / (i*PAGE_SIZE));
3066 }
3067 if (!err_found)
3068 break;
3069 }
3070 if (i > 0 && nseg_new <= sg_max)
3071 aac_convert_sgraw2(rio2, i, nseg, nseg_new);
3072 } else
3073 rio2->flags |= cpu_to_le16(RIO2_SGL_CONFORMANT);
3074
3075 /* Check for command underflow */
3076 if (scsicmd->underflow && (byte_count < scsicmd->underflow)) {
3077 printk(KERN_WARNING"aacraid: cmd len %08lX cmd underflow %08X\n",
3078 byte_count, scsicmd->underflow);
3079 }
3080 }
3081
3082 return byte_count;
3083}
3084
3085static int aac_convert_sgraw2(struct aac_raw_io2 *rio2, int pages, int nseg, int nseg_new)
3086{
3087 struct sge_ieee1212 *sge;
3088 int i, j, pos;
3089 u32 addr_low;
3090
3091 if (aac_convert_sgl == 0)
3092 return 0;
3093
3094 sge = kmalloc(nseg_new * sizeof(struct sge_ieee1212), GFP_ATOMIC);
3095 if (sge == NULL)
3096 return -1;
3097
3098 for (i = 1, pos = 1; i < nseg-1; ++i) {
3099 for (j = 0; j < rio2->sge[i].length / (pages * PAGE_SIZE); ++j) {
3100 addr_low = rio2->sge[i].addrLow + j * pages * PAGE_SIZE;
3101 sge[pos].addrLow = addr_low;
3102 sge[pos].addrHigh = rio2->sge[i].addrHigh;
3103 if (addr_low < rio2->sge[i].addrLow)
3104 sge[pos].addrHigh++;
3105 sge[pos].length = pages * PAGE_SIZE;
3106 sge[pos].flags = 0;
3107 pos++;
3108 }
3109 }
3110 sge[pos] = rio2->sge[nseg-1];
3111 memcpy(&rio2->sge[1], &sge[1], (nseg_new-1)*sizeof(struct sge_ieee1212));
3112
3113 kfree(sge);
3114 rio2->sgeCnt = cpu_to_le32(nseg_new);
3115 rio2->flags |= cpu_to_le16(RIO2_SGL_CONFORMANT);
3116 rio2->sgeNominalSize = pages * PAGE_SIZE;
3117 return 0;
3118}
3119
2957#ifdef AAC_DETAILED_STATUS_INFO 3120#ifdef AAC_DETAILED_STATUS_INFO
2958 3121
2959struct aac_srb_status_info { 3122struct aac_srb_status_info {