[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>
This commit is contained in:
@@ -1119,6 +1119,36 @@ static inline void update_can_queue(struct Scsi_Host *host, u_int in_ptr, u_int
|
|||||||
host->sg_tablesize = QLOGICPTI_MAX_SG(num_free);
|
host->sg_tablesize = QLOGICPTI_MAX_SG(num_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned int scsi_rbuf_get(struct scsi_cmnd *cmd, unsigned char **buf_out)
|
||||||
|
{
|
||||||
|
unsigned char *buf;
|
||||||
|
unsigned int buflen;
|
||||||
|
|
||||||
|
if (cmd->use_sg) {
|
||||||
|
struct scatterlist *sg;
|
||||||
|
|
||||||
|
sg = (struct scatterlist *) cmd->request_buffer;
|
||||||
|
buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
|
||||||
|
buflen = sg->length;
|
||||||
|
} else {
|
||||||
|
buf = cmd->request_buffer;
|
||||||
|
buflen = cmd->request_bufflen;
|
||||||
|
}
|
||||||
|
|
||||||
|
*buf_out = buf;
|
||||||
|
return buflen;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void scsi_rbuf_put(struct scsi_cmnd *cmd, unsigned char *buf)
|
||||||
|
{
|
||||||
|
if (cmd->use_sg) {
|
||||||
|
struct scatterlist *sg;
|
||||||
|
|
||||||
|
sg = (struct scatterlist *) cmd->request_buffer;
|
||||||
|
kunmap_atomic(buf - sg->offset, KM_IRQ0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Until we scan the entire bus with inquiries, go throught this fella...
|
* Until we scan the entire bus with inquiries, go throught this fella...
|
||||||
*/
|
*/
|
||||||
@@ -1145,11 +1175,9 @@ static void ourdone(struct scsi_cmnd *Cmnd)
|
|||||||
int ok = host_byte(Cmnd->result) == DID_OK;
|
int ok = host_byte(Cmnd->result) == DID_OK;
|
||||||
if (Cmnd->cmnd[0] == 0x12 && ok) {
|
if (Cmnd->cmnd[0] == 0x12 && ok) {
|
||||||
unsigned char *iqd;
|
unsigned char *iqd;
|
||||||
|
unsigned int iqd_len;
|
||||||
|
|
||||||
if (Cmnd->use_sg != 0)
|
iqd_len = scsi_rbuf_get(Cmnd, &iqd);
|
||||||
BUG();
|
|
||||||
|
|
||||||
iqd = ((unsigned char *)Cmnd->buffer);
|
|
||||||
|
|
||||||
/* tags handled in midlayer */
|
/* tags handled in midlayer */
|
||||||
/* enable sync mode? */
|
/* enable sync mode? */
|
||||||
@@ -1163,6 +1191,9 @@ static void ourdone(struct scsi_cmnd *Cmnd)
|
|||||||
if (iqd[7] & 0x20) {
|
if (iqd[7] & 0x20) {
|
||||||
qpti->dev_param[tgt].device_flags |= 0x20;
|
qpti->dev_param[tgt].device_flags |= 0x20;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scsi_rbuf_put(Cmnd, iqd);
|
||||||
|
|
||||||
qpti->sbits |= (1 << tgt);
|
qpti->sbits |= (1 << tgt);
|
||||||
} else if (!ok) {
|
} else if (!ok) {
|
||||||
qpti->sbits |= (1 << tgt);
|
qpti->sbits |= (1 << tgt);
|
||||||
|
|||||||
Reference in New Issue
Block a user