On Tue, Dec 12, 2006 at 02:26:00PM +0100, Christoph Hellwig wrote: > On Tue, Dec 12, 2006 at 11:38:42AM +0100, Christoph Hellwig wrote: > > This is because the packet driver tries to send down read/write > > BLOCK_PC commands that don't use a bio and do not use sg lists. > > As part of the patch you mentioned I added strict assertations for that > > case because the scsi layer doesn't handle those anymore. > > > > The right fix is to replace all the packet_command stuff in the packet > > driver by scsi_execute() which needs to be lifted from scsi code to > > the block code for that. I'll prepare a patch this weekend unless > > someone beets me in doing that work. > > Please try the patch below to fix the bug for now. It's not the > full way to a generic execute block pc infrastcuture but should fix > the bug for the time beeing: Given that we now have a tester that confirms this fix can we please put this into 2.6.20 so we avoid a regression that makes pktcdvd entirely unusable? Signed-off-by: Christoph Hellwig <hch@xxxxxx> Index: linux-2.6/drivers/block/pktcdvd.c =================================================================== --- linux-2.6.orig/drivers/block/pktcdvd.c 2006-12-12 11:30:45.000000000 +0100 +++ linux-2.6/drivers/block/pktcdvd.c 2006-12-12 14:23:37.000000000 +0100 @@ -765,47 +765,34 @@ */ static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command *cgc) { - char sense[SCSI_SENSE_BUFFERSIZE]; - request_queue_t *q; + request_queue_t *q = bdev_get_queue(pd->bdev); struct request *rq; - DECLARE_COMPLETION_ONSTACK(wait); - int err = 0; + int ret = 0; - q = bdev_get_queue(pd->bdev); + rq = blk_get_request(q, (cgc->data_direction == CGC_DATA_WRITE) ? + WRITE : READ, __GFP_WAIT); + + if (cgc->buflen) { + if (blk_rq_map_kern(q, rq, cgc->buffer, cgc->buflen, __GFP_WAIT)) + goto out; + } + + rq->cmd_len = COMMAND_SIZE(rq->cmd[0]); + memcpy(rq->cmd, cgc->cmd, CDROM_PACKET_SIZE); + if (sizeof(rq->cmd) > CDROM_PACKET_SIZE) + memset(rq->cmd + CDROM_PACKET_SIZE, 0, sizeof(rq->cmd) - CDROM_PACKET_SIZE); - rq = blk_get_request(q, (cgc->data_direction == CGC_DATA_WRITE) ? WRITE : READ, - __GFP_WAIT); - rq->errors = 0; - rq->rq_disk = pd->bdev->bd_disk; - rq->bio = NULL; - rq->buffer = NULL; rq->timeout = 60*HZ; - rq->data = cgc->buffer; - rq->data_len = cgc->buflen; - rq->sense = sense; - memset(sense, 0, sizeof(sense)); - rq->sense_len = 0; rq->cmd_type = REQ_TYPE_BLOCK_PC; rq->cmd_flags |= REQ_HARDBARRIER; if (cgc->quiet) rq->cmd_flags |= REQ_QUIET; - memcpy(rq->cmd, cgc->cmd, CDROM_PACKET_SIZE); - if (sizeof(rq->cmd) > CDROM_PACKET_SIZE) - memset(rq->cmd + CDROM_PACKET_SIZE, 0, sizeof(rq->cmd) - CDROM_PACKET_SIZE); - rq->cmd_len = COMMAND_SIZE(rq->cmd[0]); - - rq->ref_count++; - rq->end_io_data = &wait; - rq->end_io = blk_end_sync_rq; - elv_add_request(q, rq, ELEVATOR_INSERT_BACK, 1); - generic_unplug_device(q); - wait_for_completion(&wait); - - if (rq->errors) - err = -EIO; + blk_execute_rq(rq->q, pd->bdev->bd_disk, rq, 0); + ret = rq->errors; +out: blk_put_request(rq); - return err; + return ret; } /* - To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html