aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDouglas Gilbert <dougg@torque.net>2006-10-27 17:47:49 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-11-09 00:28:01 -0500
commit7ca63cb470f23a197f187afe936d4bf806197d6e (patch)
tree530c54ec8418fff6ebd918b486eb2dfde05a1775
parent4039c30ef5d9189ff8dc72aaf610d1c933877e20 (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>
-rw-r--r--drivers/scsi/sg.c25
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>
63static char *sg_version_date = "20060920"; 63static char *sg_version_date = "20061027";
64 64
65static int sg_proc_init(void); 65static int sg_proc_init(void);
66static void sg_proc_cleanup(void); 66static 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 }