diff options
author | Boaz Harrosh <bharrosh@panasas.com> | 2007-12-13 06:47:40 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-01-30 14:03:40 -0500 |
commit | 30b0c37b27485a9cb897bfe3824f6f517b8c80d6 (patch) | |
tree | 22643da8e175ff7badf2413dc8c84b2e99613a6f | |
parent | bb52d82f45df3a2661d88befba7c79a7db8be496 (diff) |
[SCSI] implement scsi_data_buffer
In preparation for bidi we abstract all IO members of scsi_cmnd,
that will need to duplicate, into a substructure.
- Group all IO members of scsi_cmnd into a scsi_data_buffer
structure.
- Adjust accessors to new members.
- scsi_{alloc,free}_sgtable receive a scsi_data_buffer instead of
scsi_cmnd. And work on it.
- Adjust scsi_init_io() and scsi_release_buffers() for above
change.
- Fix other parts of scsi_lib/scsi.c to members migration. Use
accessors where appropriate.
- fix Documentation about scsi_cmnd in scsi_host.h
- scsi_error.c
* Changed needed members of struct scsi_eh_save.
* Careful considerations in scsi_eh_prep/restore_cmnd.
- sd.c and sr.c
* sd and sr would adjust IO size to align on device's block
size so code needs to change once we move to scsi_data_buff
implementation.
* Convert code to use scsi_for_each_sg
* Use data accessors where appropriate.
- tgt: convert libsrp to use scsi_data_buffer
- isd200: This driver still bangs on scsi_cmnd IO members,
so need changing
[jejb: rebased on top of sg_table patches fixed up conflicts
and used the synergy to eliminate use_sg and sg_count]
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r-- | drivers/scsi/libsrp.c | 4 | ||||
-rw-r--r-- | drivers/scsi/scsi.c | 2 | ||||
-rw-r--r-- | drivers/scsi/scsi_error.c | 30 | ||||
-rw-r--r-- | drivers/scsi/scsi_lib.c | 63 | ||||
-rw-r--r-- | drivers/scsi/sd.c | 4 | ||||
-rw-r--r-- | drivers/scsi/sr.c | 25 | ||||
-rw-r--r-- | drivers/usb/storage/isd200.c | 8 | ||||
-rw-r--r-- | include/scsi/scsi_cmnd.h | 36 | ||||
-rw-r--r-- | include/scsi/scsi_eh.h | 8 | ||||
-rw-r--r-- | include/scsi/scsi_host.h | 4 |
10 files changed, 85 insertions, 99 deletions
diff --git a/drivers/scsi/libsrp.c b/drivers/scsi/libsrp.c index 5cff0204227d..6d6a76e65a6c 100644 --- a/drivers/scsi/libsrp.c +++ b/drivers/scsi/libsrp.c | |||
@@ -426,8 +426,8 @@ int srp_cmd_queue(struct Scsi_Host *shost, struct srp_cmd *cmd, void *info, | |||
426 | 426 | ||
427 | sc->SCp.ptr = info; | 427 | sc->SCp.ptr = info; |
428 | memcpy(sc->cmnd, cmd->cdb, MAX_COMMAND_SIZE); | 428 | memcpy(sc->cmnd, cmd->cdb, MAX_COMMAND_SIZE); |
429 | sc->request_bufflen = len; | 429 | sc->sdb.length = len; |
430 | sc->request_buffer = (void *) (unsigned long) addr; | 430 | sc->sdb.table.sgl = (void *) (unsigned long) addr; |
431 | sc->tag = tag; | 431 | sc->tag = tag; |
432 | err = scsi_tgt_queue_command(sc, itn_id, (struct scsi_lun *)&cmd->lun, | 432 | err = scsi_tgt_queue_command(sc, itn_id, (struct scsi_lun *)&cmd->lun, |
433 | cmd->tag); | 433 | cmd->tag); |
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 1a9fba6a9f92..b35d19472caa 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c | |||
@@ -757,7 +757,7 @@ void scsi_finish_command(struct scsi_cmnd *cmd) | |||
757 | "Notifying upper driver of completion " | 757 | "Notifying upper driver of completion " |
758 | "(result %x)\n", cmd->result)); | 758 | "(result %x)\n", cmd->result)); |
759 | 759 | ||
760 | good_bytes = cmd->request_bufflen; | 760 | good_bytes = scsi_bufflen(cmd); |
761 | if (cmd->request->cmd_type != REQ_TYPE_BLOCK_PC) { | 761 | if (cmd->request->cmd_type != REQ_TYPE_BLOCK_PC) { |
762 | drv = scsi_cmd_to_driver(cmd); | 762 | drv = scsi_cmd_to_driver(cmd); |
763 | if (drv->done) | 763 | if (drv->done) |
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 547e85aa414f..4f4edc388c07 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -617,29 +617,25 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses, | |||
617 | ses->cmd_len = scmd->cmd_len; | 617 | ses->cmd_len = scmd->cmd_len; |
618 | memcpy(ses->cmnd, scmd->cmnd, sizeof(scmd->cmnd)); | 618 | memcpy(ses->cmnd, scmd->cmnd, sizeof(scmd->cmnd)); |
619 | ses->data_direction = scmd->sc_data_direction; | 619 | ses->data_direction = scmd->sc_data_direction; |
620 | ses->bufflen = scmd->request_bufflen; | 620 | ses->sdb = scmd->sdb; |
621 | ses->buffer = scmd->request_buffer; | ||
622 | ses->use_sg = scmd->use_sg; | ||
623 | ses->resid = scmd->resid; | ||
624 | ses->result = scmd->result; | 621 | ses->result = scmd->result; |
625 | 622 | ||
623 | memset(&scmd->sdb, 0, sizeof(scmd->sdb)); | ||
624 | |||
626 | if (sense_bytes) { | 625 | if (sense_bytes) { |
627 | scmd->request_bufflen = min_t(unsigned, | 626 | scmd->sdb.length = min_t(unsigned, SCSI_SENSE_BUFFERSIZE, |
628 | SCSI_SENSE_BUFFERSIZE, sense_bytes); | 627 | sense_bytes); |
629 | sg_init_one(&ses->sense_sgl, scmd->sense_buffer, | 628 | sg_init_one(&ses->sense_sgl, scmd->sense_buffer, |
630 | scmd->request_bufflen); | 629 | scmd->sdb.length); |
631 | scmd->request_buffer = &ses->sense_sgl; | 630 | scmd->sdb.table.sgl = &ses->sense_sgl; |
632 | scmd->sc_data_direction = DMA_FROM_DEVICE; | 631 | scmd->sc_data_direction = DMA_FROM_DEVICE; |
633 | scmd->use_sg = 1; | 632 | scmd->sdb.table.nents = 1; |
634 | memset(scmd->cmnd, 0, sizeof(scmd->cmnd)); | 633 | memset(scmd->cmnd, 0, sizeof(scmd->cmnd)); |
635 | scmd->cmnd[0] = REQUEST_SENSE; | 634 | scmd->cmnd[0] = REQUEST_SENSE; |
636 | scmd->cmnd[4] = scmd->request_bufflen; | 635 | scmd->cmnd[4] = scmd->sdb.length; |
637 | scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); | 636 | scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); |
638 | } else { | 637 | } else { |
639 | scmd->request_buffer = NULL; | ||
640 | scmd->request_bufflen = 0; | ||
641 | scmd->sc_data_direction = DMA_NONE; | 638 | scmd->sc_data_direction = DMA_NONE; |
642 | scmd->use_sg = 0; | ||
643 | if (cmnd) { | 639 | if (cmnd) { |
644 | memset(scmd->cmnd, 0, sizeof(scmd->cmnd)); | 640 | memset(scmd->cmnd, 0, sizeof(scmd->cmnd)); |
645 | memcpy(scmd->cmnd, cmnd, cmnd_size); | 641 | memcpy(scmd->cmnd, cmnd, cmnd_size); |
@@ -676,10 +672,7 @@ void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd, struct scsi_eh_save *ses) | |||
676 | scmd->cmd_len = ses->cmd_len; | 672 | scmd->cmd_len = ses->cmd_len; |
677 | memcpy(scmd->cmnd, ses->cmnd, sizeof(scmd->cmnd)); | 673 | memcpy(scmd->cmnd, ses->cmnd, sizeof(scmd->cmnd)); |
678 | scmd->sc_data_direction = ses->data_direction; | 674 | scmd->sc_data_direction = ses->data_direction; |
679 | scmd->request_bufflen = ses->bufflen; | 675 | scmd->sdb = ses->sdb; |
680 | scmd->request_buffer = ses->buffer; | ||
681 | scmd->use_sg = ses->use_sg; | ||
682 | scmd->resid = ses->resid; | ||
683 | scmd->result = ses->result; | 676 | scmd->result = ses->result; |
684 | } | 677 | } |
685 | EXPORT_SYMBOL(scsi_eh_restore_cmnd); | 678 | EXPORT_SYMBOL(scsi_eh_restore_cmnd); |
@@ -1700,8 +1693,7 @@ scsi_reset_provider(struct scsi_device *dev, int flag) | |||
1700 | memset(&scmd->cmnd, '\0', sizeof(scmd->cmnd)); | 1693 | memset(&scmd->cmnd, '\0', sizeof(scmd->cmnd)); |
1701 | 1694 | ||
1702 | scmd->scsi_done = scsi_reset_provider_done_command; | 1695 | scmd->scsi_done = scsi_reset_provider_done_command; |
1703 | scmd->request_buffer = NULL; | 1696 | memset(&scmd->sdb, 0, sizeof(scmd->sdb)); |
1704 | scmd->request_bufflen = 0; | ||
1705 | 1697 | ||
1706 | scmd->cmd_len = 0; | 1698 | scmd->cmd_len = 0; |
1707 | 1699 | ||
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 69fd62183bab..d5e77e9b3a9c 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -440,7 +440,7 @@ EXPORT_SYMBOL_GPL(scsi_execute_async); | |||
440 | static void scsi_init_cmd_errh(struct scsi_cmnd *cmd) | 440 | static void scsi_init_cmd_errh(struct scsi_cmnd *cmd) |
441 | { | 441 | { |
442 | cmd->serial_number = 0; | 442 | cmd->serial_number = 0; |
443 | cmd->resid = 0; | 443 | scsi_set_resid(cmd, 0); |
444 | memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); | 444 | memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); |
445 | if (cmd->cmd_len == 0) | 445 | if (cmd->cmd_len == 0) |
446 | cmd->cmd_len = COMMAND_SIZE(cmd->cmnd[0]); | 446 | cmd->cmd_len = COMMAND_SIZE(cmd->cmnd[0]); |
@@ -746,25 +746,25 @@ static struct scatterlist *scsi_sg_alloc(unsigned int nents, gfp_t gfp_mask) | |||
746 | return mempool_alloc(sgp->pool, gfp_mask); | 746 | return mempool_alloc(sgp->pool, gfp_mask); |
747 | } | 747 | } |
748 | 748 | ||
749 | static int scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask) | 749 | static int scsi_alloc_sgtable(struct scsi_data_buffer *sdb, int nents, |
750 | gfp_t gfp_mask) | ||
750 | { | 751 | { |
751 | int ret; | 752 | int ret; |
752 | 753 | ||
753 | BUG_ON(!cmd->use_sg); | 754 | BUG_ON(!nents); |
754 | 755 | ||
755 | ret = __sg_alloc_table(&cmd->sg_table, cmd->use_sg, | 756 | ret = __sg_alloc_table(&sdb->table, nents, SCSI_MAX_SG_SEGMENTS, |
756 | SCSI_MAX_SG_SEGMENTS, gfp_mask, scsi_sg_alloc); | 757 | gfp_mask, scsi_sg_alloc); |
757 | if (unlikely(ret)) | 758 | if (unlikely(ret)) |
758 | __sg_free_table(&cmd->sg_table, SCSI_MAX_SG_SEGMENTS, | 759 | __sg_free_table(&sdb->table, SCSI_MAX_SG_SEGMENTS, |
759 | scsi_sg_free); | 760 | scsi_sg_free); |
760 | 761 | ||
761 | cmd->request_buffer = cmd->sg_table.sgl; | ||
762 | return ret; | 762 | return ret; |
763 | } | 763 | } |
764 | 764 | ||
765 | static void scsi_free_sgtable(struct scsi_cmnd *cmd) | 765 | static void scsi_free_sgtable(struct scsi_data_buffer *sdb) |
766 | { | 766 | { |
767 | __sg_free_table(&cmd->sg_table, SCSI_MAX_SG_SEGMENTS, scsi_sg_free); | 767 | __sg_free_table(&sdb->table, SCSI_MAX_SG_SEGMENTS, scsi_sg_free); |
768 | } | 768 | } |
769 | 769 | ||
770 | /* | 770 | /* |
@@ -786,15 +786,10 @@ static void scsi_free_sgtable(struct scsi_cmnd *cmd) | |||
786 | */ | 786 | */ |
787 | void scsi_release_buffers(struct scsi_cmnd *cmd) | 787 | void scsi_release_buffers(struct scsi_cmnd *cmd) |
788 | { | 788 | { |
789 | if (cmd->use_sg) | 789 | if (cmd->sdb.table.nents) |
790 | scsi_free_sgtable(cmd); | 790 | scsi_free_sgtable(&cmd->sdb); |
791 | 791 | ||
792 | /* | 792 | memset(&cmd->sdb, 0, sizeof(cmd->sdb)); |
793 | * Zero these out. They now point to freed memory, and it is | ||
794 | * dangerous to hang onto the pointers. | ||
795 | */ | ||
796 | cmd->request_buffer = NULL; | ||
797 | cmd->request_bufflen = 0; | ||
798 | } | 793 | } |
799 | EXPORT_SYMBOL(scsi_release_buffers); | 794 | EXPORT_SYMBOL(scsi_release_buffers); |
800 | 795 | ||
@@ -829,7 +824,7 @@ EXPORT_SYMBOL(scsi_release_buffers); | |||
829 | void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | 824 | void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) |
830 | { | 825 | { |
831 | int result = cmd->result; | 826 | int result = cmd->result; |
832 | int this_count = cmd->request_bufflen; | 827 | int this_count = scsi_bufflen(cmd); |
833 | struct request_queue *q = cmd->device->request_queue; | 828 | struct request_queue *q = cmd->device->request_queue; |
834 | struct request *req = cmd->request; | 829 | struct request *req = cmd->request; |
835 | int clear_errors = 1; | 830 | int clear_errors = 1; |
@@ -837,8 +832,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
837 | int sense_valid = 0; | 832 | int sense_valid = 0; |
838 | int sense_deferred = 0; | 833 | int sense_deferred = 0; |
839 | 834 | ||
840 | scsi_release_buffers(cmd); | ||
841 | |||
842 | if (result) { | 835 | if (result) { |
843 | sense_valid = scsi_command_normalize_sense(cmd, &sshdr); | 836 | sense_valid = scsi_command_normalize_sense(cmd, &sshdr); |
844 | if (sense_valid) | 837 | if (sense_valid) |
@@ -861,9 +854,11 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
861 | req->sense_len = len; | 854 | req->sense_len = len; |
862 | } | 855 | } |
863 | } | 856 | } |
864 | req->data_len = cmd->resid; | 857 | req->data_len = scsi_get_resid(cmd); |
865 | } | 858 | } |
866 | 859 | ||
860 | scsi_release_buffers(cmd); | ||
861 | |||
867 | /* | 862 | /* |
868 | * Next deal with any sectors which we were able to correctly | 863 | * Next deal with any sectors which we were able to correctly |
869 | * handle. | 864 | * handle. |
@@ -871,7 +866,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
871 | SCSI_LOG_HLCOMPLETE(1, printk("%ld sectors total, " | 866 | SCSI_LOG_HLCOMPLETE(1, printk("%ld sectors total, " |
872 | "%d bytes done.\n", | 867 | "%d bytes done.\n", |
873 | req->nr_sectors, good_bytes)); | 868 | req->nr_sectors, good_bytes)); |
874 | SCSI_LOG_HLCOMPLETE(1, printk("use_sg is %d\n", cmd->use_sg)); | ||
875 | 869 | ||
876 | if (clear_errors) | 870 | if (clear_errors) |
877 | req->errors = 0; | 871 | req->errors = 0; |
@@ -1002,35 +996,30 @@ int scsi_init_io(struct scsi_cmnd *cmd, gfp_t gfp_mask) | |||
1002 | { | 996 | { |
1003 | struct request *req = cmd->request; | 997 | struct request *req = cmd->request; |
1004 | int count; | 998 | int count; |
1005 | 999 | struct scsi_data_buffer *sdb = &cmd->sdb; | |
1006 | /* | ||
1007 | * We used to not use scatter-gather for single segment request, | ||
1008 | * but now we do (it makes highmem I/O easier to support without | ||
1009 | * kmapping pages) | ||
1010 | */ | ||
1011 | cmd->use_sg = req->nr_phys_segments; | ||
1012 | 1000 | ||
1013 | /* | 1001 | /* |
1014 | * If sg table allocation fails, requeue request later. | 1002 | * If sg table allocation fails, requeue request later. |
1015 | */ | 1003 | */ |
1016 | if (unlikely(scsi_alloc_sgtable(cmd, gfp_mask))) { | 1004 | if (unlikely(scsi_alloc_sgtable(sdb, req->nr_phys_segments, |
1005 | gfp_mask))) { | ||
1017 | scsi_unprep_request(req); | 1006 | scsi_unprep_request(req); |
1018 | return BLKPREP_DEFER; | 1007 | return BLKPREP_DEFER; |
1019 | } | 1008 | } |
1020 | 1009 | ||
1021 | req->buffer = NULL; | 1010 | req->buffer = NULL; |
1022 | if (blk_pc_request(req)) | 1011 | if (blk_pc_request(req)) |
1023 | cmd->request_bufflen = req->data_len; | 1012 | sdb->length = req->data_len; |
1024 | else | 1013 | else |
1025 | cmd->request_bufflen = req->nr_sectors << 9; | 1014 | sdb->length = req->nr_sectors << 9; |
1026 | 1015 | ||
1027 | /* | 1016 | /* |
1028 | * Next, walk the list, and fill in the addresses and sizes of | 1017 | * Next, walk the list, and fill in the addresses and sizes of |
1029 | * each segment. | 1018 | * each segment. |
1030 | */ | 1019 | */ |
1031 | count = blk_rq_map_sg(req->q, req, cmd->request_buffer); | 1020 | count = blk_rq_map_sg(req->q, req, sdb->table.sgl); |
1032 | BUG_ON(count > cmd->use_sg); | 1021 | BUG_ON(count > sdb->table.nents); |
1033 | cmd->use_sg = count; | 1022 | sdb->table.nents = count; |
1034 | return BLKPREP_OK; | 1023 | return BLKPREP_OK; |
1035 | } | 1024 | } |
1036 | EXPORT_SYMBOL(scsi_init_io); | 1025 | EXPORT_SYMBOL(scsi_init_io); |
@@ -1086,9 +1075,7 @@ int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req) | |||
1086 | BUG_ON(req->data_len); | 1075 | BUG_ON(req->data_len); |
1087 | BUG_ON(req->data); | 1076 | BUG_ON(req->data); |
1088 | 1077 | ||
1089 | cmd->request_bufflen = 0; | 1078 | memset(&cmd->sdb, 0, sizeof(cmd->sdb)); |
1090 | cmd->request_buffer = NULL; | ||
1091 | cmd->use_sg = 0; | ||
1092 | req->buffer = NULL; | 1079 | req->buffer = NULL; |
1093 | } | 1080 | } |
1094 | 1081 | ||
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 24eba3118b5a..51a5557f42dd 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -519,7 +519,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) | |||
519 | SCpnt->cmnd[4] = (unsigned char) this_count; | 519 | SCpnt->cmnd[4] = (unsigned char) this_count; |
520 | SCpnt->cmnd[5] = 0; | 520 | SCpnt->cmnd[5] = 0; |
521 | } | 521 | } |
522 | SCpnt->request_bufflen = this_count * sdp->sector_size; | 522 | SCpnt->sdb.length = this_count * sdp->sector_size; |
523 | 523 | ||
524 | /* | 524 | /* |
525 | * We shouldn't disconnect in the middle of a sector, so with a dumb | 525 | * We shouldn't disconnect in the middle of a sector, so with a dumb |
@@ -926,7 +926,7 @@ static struct block_device_operations sd_fops = { | |||
926 | static int sd_done(struct scsi_cmnd *SCpnt) | 926 | static int sd_done(struct scsi_cmnd *SCpnt) |
927 | { | 927 | { |
928 | int result = SCpnt->result; | 928 | int result = SCpnt->result; |
929 | unsigned int xfer_size = SCpnt->request_bufflen; | 929 | unsigned int xfer_size = scsi_bufflen(SCpnt); |
930 | unsigned int good_bytes = result ? 0 : xfer_size; | 930 | unsigned int good_bytes = result ? 0 : xfer_size; |
931 | u64 start_lba = SCpnt->request->sector; | 931 | u64 start_lba = SCpnt->request->sector; |
932 | u64 bad_lba; | 932 | u64 bad_lba; |
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 1fcee16fa36d..50ba49250203 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c | |||
@@ -231,7 +231,7 @@ out: | |||
231 | static int sr_done(struct scsi_cmnd *SCpnt) | 231 | static int sr_done(struct scsi_cmnd *SCpnt) |
232 | { | 232 | { |
233 | int result = SCpnt->result; | 233 | int result = SCpnt->result; |
234 | int this_count = SCpnt->request_bufflen; | 234 | int this_count = scsi_bufflen(SCpnt); |
235 | int good_bytes = (result == 0 ? this_count : 0); | 235 | int good_bytes = (result == 0 ? this_count : 0); |
236 | int block_sectors = 0; | 236 | int block_sectors = 0; |
237 | long error_sector; | 237 | long error_sector; |
@@ -379,17 +379,18 @@ static int sr_prep_fn(struct request_queue *q, struct request *rq) | |||
379 | } | 379 | } |
380 | 380 | ||
381 | { | 381 | { |
382 | struct scatterlist *sg = SCpnt->request_buffer; | 382 | struct scatterlist *sg; |
383 | int i, size = 0; | 383 | int i, size = 0, sg_count = scsi_sg_count(SCpnt); |
384 | for (i = 0; i < SCpnt->use_sg; i++) | ||
385 | size += sg[i].length; | ||
386 | 384 | ||
387 | if (size != SCpnt->request_bufflen && SCpnt->use_sg) { | 385 | scsi_for_each_sg(SCpnt, sg, sg_count, i) |
386 | size += sg->length; | ||
387 | |||
388 | if (size != scsi_bufflen(SCpnt)) { | ||
388 | scmd_printk(KERN_ERR, SCpnt, | 389 | scmd_printk(KERN_ERR, SCpnt, |
389 | "mismatch count %d, bytes %d\n", | 390 | "mismatch count %d, bytes %d\n", |
390 | size, SCpnt->request_bufflen); | 391 | size, scsi_bufflen(SCpnt)); |
391 | if (SCpnt->request_bufflen > size) | 392 | if (scsi_bufflen(SCpnt) > size) |
392 | SCpnt->request_bufflen = size; | 393 | SCpnt->sdb.length = size; |
393 | } | 394 | } |
394 | } | 395 | } |
395 | 396 | ||
@@ -397,12 +398,12 @@ static int sr_prep_fn(struct request_queue *q, struct request *rq) | |||
397 | * request doesn't start on hw block boundary, add scatter pads | 398 | * request doesn't start on hw block boundary, add scatter pads |
398 | */ | 399 | */ |
399 | if (((unsigned int)rq->sector % (s_size >> 9)) || | 400 | if (((unsigned int)rq->sector % (s_size >> 9)) || |
400 | (SCpnt->request_bufflen % s_size)) { | 401 | (scsi_bufflen(SCpnt) % s_size)) { |
401 | scmd_printk(KERN_NOTICE, SCpnt, "unaligned transfer\n"); | 402 | scmd_printk(KERN_NOTICE, SCpnt, "unaligned transfer\n"); |
402 | goto out; | 403 | goto out; |
403 | } | 404 | } |
404 | 405 | ||
405 | this_count = (SCpnt->request_bufflen >> 9) / (s_size >> 9); | 406 | this_count = (scsi_bufflen(SCpnt) >> 9) / (s_size >> 9); |
406 | 407 | ||
407 | 408 | ||
408 | SCSI_LOG_HLQUEUE(2, printk("%s : %s %d/%ld 512 byte blocks.\n", | 409 | SCSI_LOG_HLQUEUE(2, printk("%s : %s %d/%ld 512 byte blocks.\n", |
@@ -416,7 +417,7 @@ static int sr_prep_fn(struct request_queue *q, struct request *rq) | |||
416 | 417 | ||
417 | if (this_count > 0xffff) { | 418 | if (this_count > 0xffff) { |
418 | this_count = 0xffff; | 419 | this_count = 0xffff; |
419 | SCpnt->request_bufflen = this_count * s_size; | 420 | SCpnt->sdb.length = this_count * s_size; |
420 | } | 421 | } |
421 | 422 | ||
422 | SCpnt->cmnd[2] = (unsigned char) (block >> 24) & 0xff; | 423 | SCpnt->cmnd[2] = (unsigned char) (block >> 24) & 0xff; |
diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c index 178e8c2a8a2f..0db488624ab1 100644 --- a/drivers/usb/storage/isd200.c +++ b/drivers/usb/storage/isd200.c | |||
@@ -415,14 +415,14 @@ static void isd200_set_srb(struct isd200_info *info, | |||
415 | sg_init_one(&info->sg, buff, bufflen); | 415 | sg_init_one(&info->sg, buff, bufflen); |
416 | 416 | ||
417 | srb->sc_data_direction = dir; | 417 | srb->sc_data_direction = dir; |
418 | srb->request_buffer = buff ? &info->sg : NULL; | 418 | srb->sdb.table.sgl = buff ? &info->sg : NULL; |
419 | srb->request_bufflen = bufflen; | 419 | srb->sdb.length = bufflen; |
420 | srb->use_sg = buff ? 1 : 0; | 420 | srb->sdb.table.nents = buff ? 1 : 0; |
421 | } | 421 | } |
422 | 422 | ||
423 | static void isd200_srb_set_bufflen(struct scsi_cmnd *srb, unsigned bufflen) | 423 | static void isd200_srb_set_bufflen(struct scsi_cmnd *srb, unsigned bufflen) |
424 | { | 424 | { |
425 | srb->request_bufflen = bufflen; | 425 | srb->sdb.length = bufflen; |
426 | } | 426 | } |
427 | 427 | ||
428 | 428 | ||
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index 09d44f91dbdb..c6478bb6f963 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h | |||
@@ -11,6 +11,11 @@ struct request; | |||
11 | struct Scsi_Host; | 11 | struct Scsi_Host; |
12 | struct scsi_device; | 12 | struct scsi_device; |
13 | 13 | ||
14 | struct scsi_data_buffer { | ||
15 | struct sg_table table; | ||
16 | unsigned length; | ||
17 | int resid; | ||
18 | }; | ||
14 | 19 | ||
15 | /* embedded in scsi_cmnd */ | 20 | /* embedded in scsi_cmnd */ |
16 | struct scsi_pointer { | 21 | struct scsi_pointer { |
@@ -61,15 +66,11 @@ struct scsi_cmnd { | |||
61 | /* These elements define the operation we are about to perform */ | 66 | /* These elements define the operation we are about to perform */ |
62 | #define MAX_COMMAND_SIZE 16 | 67 | #define MAX_COMMAND_SIZE 16 |
63 | unsigned char cmnd[MAX_COMMAND_SIZE]; | 68 | unsigned char cmnd[MAX_COMMAND_SIZE]; |
64 | unsigned request_bufflen; /* Actual request size */ | ||
65 | 69 | ||
66 | struct timer_list eh_timeout; /* Used to time out the command. */ | 70 | struct timer_list eh_timeout; /* Used to time out the command. */ |
67 | void *request_buffer; /* Actual requested buffer */ | ||
68 | 71 | ||
69 | /* These elements define the operation we ultimately want to perform */ | 72 | /* These elements define the operation we ultimately want to perform */ |
70 | struct sg_table sg_table; | 73 | struct scsi_data_buffer sdb; |
71 | unsigned short use_sg; /* Number of pieces of scatter-gather */ | ||
72 | |||
73 | unsigned underflow; /* Return error if less than | 74 | unsigned underflow; /* Return error if less than |
74 | this amount is transferred */ | 75 | this amount is transferred */ |
75 | 76 | ||
@@ -79,10 +80,6 @@ struct scsi_cmnd { | |||
79 | reconnects. Probably == sector | 80 | reconnects. Probably == sector |
80 | size */ | 81 | size */ |
81 | 82 | ||
82 | int resid; /* Number of bytes requested to be | ||
83 | transferred less actual number | ||
84 | transferred (0 if not supported) */ | ||
85 | |||
86 | struct request *request; /* The command we are | 83 | struct request *request; /* The command we are |
87 | working on */ | 84 | working on */ |
88 | 85 | ||
@@ -133,18 +130,29 @@ extern void scsi_release_buffers(struct scsi_cmnd *cmd); | |||
133 | extern int scsi_dma_map(struct scsi_cmnd *cmd); | 130 | extern int scsi_dma_map(struct scsi_cmnd *cmd); |
134 | extern void scsi_dma_unmap(struct scsi_cmnd *cmd); | 131 | extern void scsi_dma_unmap(struct scsi_cmnd *cmd); |
135 | 132 | ||
136 | #define scsi_sg_count(cmd) ((cmd)->use_sg) | 133 | static inline unsigned scsi_sg_count(struct scsi_cmnd *cmd) |
137 | #define scsi_sglist(cmd) ((cmd)->sg_table.sgl) | 134 | { |
138 | #define scsi_bufflen(cmd) ((cmd)->request_bufflen) | 135 | return cmd->sdb.table.nents; |
136 | } | ||
137 | |||
138 | static inline struct scatterlist *scsi_sglist(struct scsi_cmnd *cmd) | ||
139 | { | ||
140 | return cmd->sdb.table.sgl; | ||
141 | } | ||
142 | |||
143 | static inline unsigned scsi_bufflen(struct scsi_cmnd *cmd) | ||
144 | { | ||
145 | return cmd->sdb.length; | ||
146 | } | ||
139 | 147 | ||
140 | static inline void scsi_set_resid(struct scsi_cmnd *cmd, int resid) | 148 | static inline void scsi_set_resid(struct scsi_cmnd *cmd, int resid) |
141 | { | 149 | { |
142 | cmd->resid = resid; | 150 | cmd->sdb.resid = resid; |
143 | } | 151 | } |
144 | 152 | ||
145 | static inline int scsi_get_resid(struct scsi_cmnd *cmd) | 153 | static inline int scsi_get_resid(struct scsi_cmnd *cmd) |
146 | { | 154 | { |
147 | return cmd->resid; | 155 | return cmd->sdb.resid; |
148 | } | 156 | } |
149 | 157 | ||
150 | #define scsi_for_each_sg(cmd, sg, nseg, __i) \ | 158 | #define scsi_for_each_sg(cmd, sg, nseg, __i) \ |
diff --git a/include/scsi/scsi_eh.h b/include/scsi/scsi_eh.h index d21b8913ceb3..1e08be1466ee 100644 --- a/include/scsi/scsi_eh.h +++ b/include/scsi/scsi_eh.h | |||
@@ -68,16 +68,14 @@ extern int scsi_get_sense_info_fld(const u8 * sense_buffer, int sb_len, | |||
68 | extern int scsi_reset_provider(struct scsi_device *, int); | 68 | extern int scsi_reset_provider(struct scsi_device *, int); |
69 | 69 | ||
70 | struct scsi_eh_save { | 70 | struct scsi_eh_save { |
71 | /* saved state */ | ||
71 | int result; | 72 | int result; |
72 | enum dma_data_direction data_direction; | 73 | enum dma_data_direction data_direction; |
73 | unsigned char cmd_len; | 74 | unsigned char cmd_len; |
74 | unsigned char cmnd[MAX_COMMAND_SIZE]; | 75 | unsigned char cmnd[MAX_COMMAND_SIZE]; |
76 | struct scsi_data_buffer sdb; | ||
75 | 77 | ||
76 | void *buffer; | 78 | /* new command support */ |
77 | unsigned bufflen; | ||
78 | unsigned short use_sg; | ||
79 | int resid; | ||
80 | |||
81 | struct scatterlist sense_sgl; | 79 | struct scatterlist sense_sgl; |
82 | }; | 80 | }; |
83 | 81 | ||
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 0fd4746ee39d..cb2bcab41dfb 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h | |||
@@ -136,9 +136,9 @@ struct scsi_host_template { | |||
136 | * the done callback is invoked. | 136 | * the done callback is invoked. |
137 | * | 137 | * |
138 | * This is called to inform the LLD to transfer | 138 | * This is called to inform the LLD to transfer |
139 | * cmd->request_bufflen bytes. The cmd->use_sg speciefies the | 139 | * scsi_bufflen(cmd) bytes. scsi_sg_count(cmd) speciefies the |
140 | * number of scatterlist entried in the command and | 140 | * number of scatterlist entried in the command and |
141 | * cmd->request_buffer contains the scatterlist. | 141 | * scsi_sglist(cmd) returns the scatterlist. |
142 | * | 142 | * |
143 | * return values: see queuecommand | 143 | * return values: see queuecommand |
144 | * | 144 | * |