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