aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2007-01-05 19:36:26 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2007-01-06 02:55:22 -0500
commit406c9b605cbc45151c03ac9a3f95e9acf050808c (patch)
treefd7d1d60065edf85c456b1643e73c83a3d3fbc9a /drivers
parentd73e3cd73c058ce792ad276f979680aa331f4f8e (diff)
[PATCH] Fix BUG at drivers/scsi/scsi_lib.c:1118 caused by "pktsetup dvd /dev/sr0"
Fix http://bugzilla.kernel.org/show_bug.cgi?id=7667 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. 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. Fix the bug for now. It's not the full way to a generic execute block pc infrastcuture but fixes the bug for the time being. Signed-off-by: Christoph Hellwig <hch@lst.de> Acked-by: Peter Osterlund <petero2@telia.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/pktcdvd.c49
1 files changed, 18 insertions, 31 deletions
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 7c95c762950f..62462190e07e 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -765,47 +765,34 @@ static inline struct bio *pkt_get_list_first(struct bio **list_head, struct bio
765 */ 765 */
766static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command *cgc) 766static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command *cgc)
767{ 767{
768 char sense[SCSI_SENSE_BUFFERSIZE]; 768 request_queue_t *q = bdev_get_queue(pd->bdev);
769 request_queue_t *q;
770 struct request *rq; 769 struct request *rq;
771 DECLARE_COMPLETION_ONSTACK(wait); 770 int ret = 0;
772 int err = 0;
773 771
774 q = bdev_get_queue(pd->bdev); 772 rq = blk_get_request(q, (cgc->data_direction == CGC_DATA_WRITE) ?
773 WRITE : READ, __GFP_WAIT);
774
775 if (cgc->buflen) {
776 if (blk_rq_map_kern(q, rq, cgc->buffer, cgc->buflen, __GFP_WAIT))
777 goto out;
778 }
779
780 rq->cmd_len = COMMAND_SIZE(rq->cmd[0]);
781 memcpy(rq->cmd, cgc->cmd, CDROM_PACKET_SIZE);
782 if (sizeof(rq->cmd) > CDROM_PACKET_SIZE)
783 memset(rq->cmd + CDROM_PACKET_SIZE, 0, sizeof(rq->cmd) - CDROM_PACKET_SIZE);
775 784
776 rq = blk_get_request(q, (cgc->data_direction == CGC_DATA_WRITE) ? WRITE : READ,
777 __GFP_WAIT);
778 rq->errors = 0;
779 rq->rq_disk = pd->bdev->bd_disk;
780 rq->bio = NULL;
781 rq->buffer = NULL;
782 rq->timeout = 60*HZ; 785 rq->timeout = 60*HZ;
783 rq->data = cgc->buffer;
784 rq->data_len = cgc->buflen;
785 rq->sense = sense;
786 memset(sense, 0, sizeof(sense));
787 rq->sense_len = 0;
788 rq->cmd_type = REQ_TYPE_BLOCK_PC; 786 rq->cmd_type = REQ_TYPE_BLOCK_PC;
789 rq->cmd_flags |= REQ_HARDBARRIER; 787 rq->cmd_flags |= REQ_HARDBARRIER;
790 if (cgc->quiet) 788 if (cgc->quiet)
791 rq->cmd_flags |= REQ_QUIET; 789 rq->cmd_flags |= REQ_QUIET;
792 memcpy(rq->cmd, cgc->cmd, CDROM_PACKET_SIZE);
793 if (sizeof(rq->cmd) > CDROM_PACKET_SIZE)
794 memset(rq->cmd + CDROM_PACKET_SIZE, 0, sizeof(rq->cmd) - CDROM_PACKET_SIZE);
795 rq->cmd_len = COMMAND_SIZE(rq->cmd[0]);
796
797 rq->ref_count++;
798 rq->end_io_data = &wait;
799 rq->end_io = blk_end_sync_rq;
800 elv_add_request(q, rq, ELEVATOR_INSERT_BACK, 1);
801 generic_unplug_device(q);
802 wait_for_completion(&wait);
803
804 if (rq->errors)
805 err = -EIO;
806 790
791 blk_execute_rq(rq->q, pd->bdev->bd_disk, rq, 0);
792 ret = rq->errors;
793out:
807 blk_put_request(rq); 794 blk_put_request(rq);
808 return err; 795 return ret;
809} 796}
810 797
811/* 798/*