Commit cbfec645 authored by Jens Axboe's avatar Jens Axboe

[PATCH] scsi patches

Hi James,

Here are the changes that are good outside the other changes :-)

scsi_lib:
	o ->errors is used as the scsi status byte for REQ_BLOCK_PC
	o ->data_len is the residual byte count
	o call __scsi_end_request even for !good_sectors if status is
	  good. This legitimately can happen for REQ_BLOCK_PC commands
	  sent from a user space program, if it gets the command setup
	  wrong (or weird). Right now this will hang that queue.

scsi_merge:
	o set SCpnt->request_bufflen to ->data_len, this is the
	  authoritative io byte count for REQ_BLOCK_PC. Here we deal in
	  bytes and not sectors.

sr + sd:
	o Set transfersize and underlow correctly for REQ_BLOCK_PC

sr_ioctl
	o We want to return -EIO for command failure, not EINVAL. That
 	  is pretty stupid :-)


===== drivers/scsi/scsi_lib.c 1.35 vs edited =====
parent ecf2c214
......@@ -514,6 +514,12 @@ void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors,
}
}
if (blk_pc_request(req)) {
req->errors = result & 0xff;
if (!result)
req->data_len -= SCpnt->bufflen;
}
/*
* Zero these out. They now point to freed memory, and it is
* dangerous to hang onto the pointers.
......@@ -527,7 +533,7 @@ void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors,
* Next deal with any sectors which we were able to correctly
* handle.
*/
if (good_sectors > 0) {
if (good_sectors >= 0) {
SCSI_LOG_HLCOMPLETE(1, printk("%ld sectors total, %d sectors done.\n",
req->nr_sectors, good_sectors));
SCSI_LOG_HLCOMPLETE(1, printk("use_sg is %d\n ", SCpnt->use_sg));
......
......@@ -100,6 +100,8 @@ int scsi_init_io(Scsi_Cmnd *SCpnt)
SCpnt->request_buffer = (char *) sgpnt;
SCpnt->request_bufflen = req->nr_sectors << 9;
if (blk_pc_request(req))
SCpnt->request_bufflen = req->data_len;
req->buffer = NULL;
/*
......
......@@ -308,6 +308,8 @@ static int sd_init_command(Scsi_Cmnd * SCpnt)
if (rq->timeout)
timeout = rq->timeout;
SCpnt->transfersize = rq->data_len;
SCpnt->underflow = rq->data_len;
goto queue;
}
......@@ -431,10 +433,10 @@ static int sd_init_command(Scsi_Cmnd * SCpnt)
* host adapter, it's safe to assume that we can at least transfer
* this many bytes between each connect / disconnect.
*/
queue:
SCpnt->transfersize = sdp->sector_size;
SCpnt->underflow = this_count << 9;
queue:
SCpnt->allowed = MAX_RETRIES;
SCpnt->timeout_per_command = timeout;
......
......@@ -287,6 +287,8 @@ static int sr_init_command(Scsi_Cmnd * SCpnt)
if (rq->timeout)
timeout = rq->timeout;
SCpnt->transfersize = rq->data_len;
SCpnt->underflow = rq->data_len;
goto queue;
}
......@@ -360,10 +362,10 @@ static int sr_init_command(Scsi_Cmnd * SCpnt)
* host adapter, it's safe to assume that we can at least transfer
* this many bytes between each connect / disconnect.
*/
queue:
SCpnt->transfersize = cd->device->sector_size;
SCpnt->underflow = this_count << 9;
queue:
SCpnt->allowed = MAX_RETRIES;
SCpnt->timeout_per_command = timeout;
......
......@@ -160,13 +160,11 @@ int sr_do_ioctl(Scsi_CD *cd, struct cdrom_generic_command *cgc)
if (!cgc->quiet)
printk(KERN_ERR "%s: CDROM (ioctl) reports ILLEGAL "
"REQUEST.\n", cd->cdi.name);
err = -EIO;
if (SRpnt->sr_sense_buffer[12] == 0x20 &&
SRpnt->sr_sense_buffer[13] == 0x00) {
SRpnt->sr_sense_buffer[13] == 0x00)
/* sense: Invalid command operation code */
err = -EDRIVE_CANT_DO_THIS;
} else {
err = -EINVAL;
}
#ifdef DEBUG
print_command(cgc->cmd);
print_req_sense("sr", SRpnt);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment