Commit f75884d28a6eae5a422d0454b982da3842f777af
1 parent
688cb30bdc
Exists in
master
and in
7 other branches
[QLOGICPTI]: Handle INQUIRY response sniffing correctly.
These days, in 2.6.x, even INQUIRY commands are sent using scatter gather lists. Bug reported by Tom 'spot' Callaway. Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 1 changed file with 35 additions and 4 deletions Side-by-side Diff
drivers/scsi/qlogicpti.c
... | ... | @@ -1119,6 +1119,36 @@ |
1119 | 1119 | host->sg_tablesize = QLOGICPTI_MAX_SG(num_free); |
1120 | 1120 | } |
1121 | 1121 | |
1122 | +static unsigned int scsi_rbuf_get(struct scsi_cmnd *cmd, unsigned char **buf_out) | |
1123 | +{ | |
1124 | + unsigned char *buf; | |
1125 | + unsigned int buflen; | |
1126 | + | |
1127 | + if (cmd->use_sg) { | |
1128 | + struct scatterlist *sg; | |
1129 | + | |
1130 | + sg = (struct scatterlist *) cmd->request_buffer; | |
1131 | + buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset; | |
1132 | + buflen = sg->length; | |
1133 | + } else { | |
1134 | + buf = cmd->request_buffer; | |
1135 | + buflen = cmd->request_bufflen; | |
1136 | + } | |
1137 | + | |
1138 | + *buf_out = buf; | |
1139 | + return buflen; | |
1140 | +} | |
1141 | + | |
1142 | +static void scsi_rbuf_put(struct scsi_cmnd *cmd, unsigned char *buf) | |
1143 | +{ | |
1144 | + if (cmd->use_sg) { | |
1145 | + struct scatterlist *sg; | |
1146 | + | |
1147 | + sg = (struct scatterlist *) cmd->request_buffer; | |
1148 | + kunmap_atomic(buf - sg->offset, KM_IRQ0); | |
1149 | + } | |
1150 | +} | |
1151 | + | |
1122 | 1152 | /* |
1123 | 1153 | * Until we scan the entire bus with inquiries, go throught this fella... |
1124 | 1154 | */ |
1125 | 1155 | |
1126 | 1156 | |
... | ... | @@ -1145,12 +1175,10 @@ |
1145 | 1175 | int ok = host_byte(Cmnd->result) == DID_OK; |
1146 | 1176 | if (Cmnd->cmnd[0] == 0x12 && ok) { |
1147 | 1177 | unsigned char *iqd; |
1178 | + unsigned int iqd_len; | |
1148 | 1179 | |
1149 | - if (Cmnd->use_sg != 0) | |
1150 | - BUG(); | |
1180 | + iqd_len = scsi_rbuf_get(Cmnd, &iqd); | |
1151 | 1181 | |
1152 | - iqd = ((unsigned char *)Cmnd->buffer); | |
1153 | - | |
1154 | 1182 | /* tags handled in midlayer */ |
1155 | 1183 | /* enable sync mode? */ |
1156 | 1184 | if (iqd[7] & 0x10) { |
... | ... | @@ -1163,6 +1191,9 @@ |
1163 | 1191 | if (iqd[7] & 0x20) { |
1164 | 1192 | qpti->dev_param[tgt].device_flags |= 0x20; |
1165 | 1193 | } |
1194 | + | |
1195 | + scsi_rbuf_put(Cmnd, iqd); | |
1196 | + | |
1166 | 1197 | qpti->sbits |= (1 << tgt); |
1167 | 1198 | } else if (!ok) { |
1168 | 1199 | qpti->sbits |= (1 << tgt); |