diff options
author | Douglas Gilbert <dougg@torque.net> | 2006-10-27 17:47:49 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-11-09 00:28:01 -0500 |
commit | 7ca63cb470f23a197f187afe936d4bf806197d6e (patch) | |
tree | 530c54ec8418fff6ebd918b486eb2dfde05a1775 /drivers/scsi/sg.c | |
parent | 4039c30ef5d9189ff8dc72aaf610d1c933877e20 (diff) |
[SCSI] sg: fix incorrect last scatg length
For certain LLDs the sg driver can cause on oops
when the transfer length is large and not a
multiple of PAGE_SIZE.
ChangeLog:
- correct the length of the last scatter gather
list element.
- fix some printk()s that have the wrong function
name.
Signed-off-by: Douglas Gilbert <dougg@torque.net>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/sg.c')
-rw-r--r-- | drivers/scsi/sg.c | 25 |
1 files changed, 13 insertions, 12 deletions
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 3f8b93188567..81e3bc7b02a1 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c | |||
@@ -60,7 +60,7 @@ static int sg_version_num = 30534; /* 2 digits for each component */ | |||
60 | 60 | ||
61 | #ifdef CONFIG_SCSI_PROC_FS | 61 | #ifdef CONFIG_SCSI_PROC_FS |
62 | #include <linux/proc_fs.h> | 62 | #include <linux/proc_fs.h> |
63 | static char *sg_version_date = "20060920"; | 63 | static char *sg_version_date = "20061027"; |
64 | 64 | ||
65 | static int sg_proc_init(void); | 65 | static int sg_proc_init(void); |
66 | static void sg_proc_cleanup(void); | 66 | static void sg_proc_cleanup(void); |
@@ -710,12 +710,12 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp, | |||
710 | (int) cmnd[0], (int) hp->cmd_len)); | 710 | (int) cmnd[0], (int) hp->cmd_len)); |
711 | 711 | ||
712 | if ((k = sg_start_req(srp))) { | 712 | if ((k = sg_start_req(srp))) { |
713 | SCSI_LOG_TIMEOUT(1, printk("sg_write: start_req err=%d\n", k)); | 713 | SCSI_LOG_TIMEOUT(1, printk("sg_common_write: start_req err=%d\n", k)); |
714 | sg_finish_rem_req(srp); | 714 | sg_finish_rem_req(srp); |
715 | return k; /* probably out of space --> ENOMEM */ | 715 | return k; /* probably out of space --> ENOMEM */ |
716 | } | 716 | } |
717 | if ((k = sg_write_xfer(srp))) { | 717 | if ((k = sg_write_xfer(srp))) { |
718 | SCSI_LOG_TIMEOUT(1, printk("sg_write: write_xfer, bad address\n")); | 718 | SCSI_LOG_TIMEOUT(1, printk("sg_common_write: write_xfer, bad address\n")); |
719 | sg_finish_rem_req(srp); | 719 | sg_finish_rem_req(srp); |
720 | return k; | 720 | return k; |
721 | } | 721 | } |
@@ -746,7 +746,7 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp, | |||
746 | hp->dxfer_len, srp->data.k_use_sg, timeout, | 746 | hp->dxfer_len, srp->data.k_use_sg, timeout, |
747 | SG_DEFAULT_RETRIES, srp, sg_cmd_done, | 747 | SG_DEFAULT_RETRIES, srp, sg_cmd_done, |
748 | GFP_ATOMIC)) { | 748 | GFP_ATOMIC)) { |
749 | SCSI_LOG_TIMEOUT(1, printk("sg_write: scsi_execute_async failed\n")); | 749 | SCSI_LOG_TIMEOUT(1, printk("sg_common_write: scsi_execute_async failed\n")); |
750 | /* | 750 | /* |
751 | * most likely out of mem, but could also be a bad map | 751 | * most likely out of mem, but could also be a bad map |
752 | */ | 752 | */ |
@@ -1283,7 +1283,7 @@ sg_cmd_done(void *data, char *sense, int result, int resid) | |||
1283 | sg_finish_rem_req(srp); | 1283 | sg_finish_rem_req(srp); |
1284 | srp = NULL; | 1284 | srp = NULL; |
1285 | if (NULL == sfp->headrp) { | 1285 | if (NULL == sfp->headrp) { |
1286 | SCSI_LOG_TIMEOUT(1, printk("sg...bh: already closed, final cleanup\n")); | 1286 | SCSI_LOG_TIMEOUT(1, printk("sg_cmd_done: already closed, final cleanup\n")); |
1287 | if (0 == sg_remove_sfp(sdp, sfp)) { /* device still present */ | 1287 | if (0 == sg_remove_sfp(sdp, sfp)) { /* device still present */ |
1288 | scsi_device_put(sdp->device); | 1288 | scsi_device_put(sdp->device); |
1289 | } | 1289 | } |
@@ -1512,12 +1512,12 @@ sg_remove(struct class_device *cl_dev, struct class_interface *cl_intf) | |||
1512 | POLL_HUP); | 1512 | POLL_HUP); |
1513 | } | 1513 | } |
1514 | } | 1514 | } |
1515 | SCSI_LOG_TIMEOUT(3, printk("sg_detach: dev=%d, dirty\n", k)); | 1515 | SCSI_LOG_TIMEOUT(3, printk("sg_remove: dev=%d, dirty\n", k)); |
1516 | if (NULL == sdp->headfp) { | 1516 | if (NULL == sdp->headfp) { |
1517 | sg_dev_arr[k] = NULL; | 1517 | sg_dev_arr[k] = NULL; |
1518 | } | 1518 | } |
1519 | } else { /* nothing active, simple case */ | 1519 | } else { /* nothing active, simple case */ |
1520 | SCSI_LOG_TIMEOUT(3, printk("sg_detach: dev=%d\n", k)); | 1520 | SCSI_LOG_TIMEOUT(3, printk("sg_remove: dev=%d\n", k)); |
1521 | sg_dev_arr[k] = NULL; | 1521 | sg_dev_arr[k] = NULL; |
1522 | } | 1522 | } |
1523 | sg_nr_dev--; | 1523 | sg_nr_dev--; |
@@ -1876,14 +1876,15 @@ sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size) | |||
1876 | } | 1876 | } |
1877 | } | 1877 | } |
1878 | sg->page = p; | 1878 | sg->page = p; |
1879 | sg->length = ret_sz; | 1879 | sg->length = (ret_sz > num) ? num : ret_sz; |
1880 | 1880 | ||
1881 | SCSI_LOG_TIMEOUT(5, printk("sg_build_build: k=%d, a=0x%p, len=%d\n", | 1881 | SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k=%d, num=%d, " |
1882 | k, p, ret_sz)); | 1882 | "ret_sz=%d\n", k, num, ret_sz)); |
1883 | } /* end of for loop */ | 1883 | } /* end of for loop */ |
1884 | 1884 | ||
1885 | schp->k_use_sg = k; | 1885 | schp->k_use_sg = k; |
1886 | SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k_use_sg=%d, rem_sz=%d\n", k, rem_sz)); | 1886 | SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k_use_sg=%d, " |
1887 | "rem_sz=%d\n", k, rem_sz)); | ||
1887 | 1888 | ||
1888 | schp->bufflen = blk_size; | 1889 | schp->bufflen = blk_size; |
1889 | if (rem_sz > 0) /* must have failed */ | 1890 | if (rem_sz > 0) /* must have failed */ |
@@ -2014,7 +2015,7 @@ sg_remove_scat(Sg_scatter_hold * schp) | |||
2014 | for (k = 0; (k < schp->k_use_sg) && sg->page; | 2015 | for (k = 0; (k < schp->k_use_sg) && sg->page; |
2015 | ++k, ++sg) { | 2016 | ++k, ++sg) { |
2016 | SCSI_LOG_TIMEOUT(5, printk( | 2017 | SCSI_LOG_TIMEOUT(5, printk( |
2017 | "sg_remove_scat: k=%d, a=0x%p, len=%d\n", | 2018 | "sg_remove_scat: k=%d, pg=0x%p, len=%d\n", |
2018 | k, sg->page, sg->length)); | 2019 | k, sg->page, sg->length)); |
2019 | sg_page_free(sg->page, sg->length); | 2020 | sg_page_free(sg->page, sg->length); |
2020 | } | 2021 | } |