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 /drivers/scsi/scsi_lib.c | |
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>
Diffstat (limited to 'drivers/scsi/scsi_lib.c')
-rw-r--r-- | drivers/scsi/scsi_lib.c | 63 |
1 files changed, 25 insertions, 38 deletions
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 | ||