diff options
Diffstat (limited to 'drivers/scsi/sg.c')
-rw-r--r-- | drivers/scsi/sg.c | 55 |
1 files changed, 8 insertions, 47 deletions
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 5a0a19322d01..7405d0df95db 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c | |||
@@ -44,7 +44,6 @@ static int sg_version_num = 30533; /* 2 digits for each component */ | |||
44 | #include <linux/poll.h> | 44 | #include <linux/poll.h> |
45 | #include <linux/smp_lock.h> | 45 | #include <linux/smp_lock.h> |
46 | #include <linux/moduleparam.h> | 46 | #include <linux/moduleparam.h> |
47 | #include <linux/devfs_fs_kernel.h> | ||
48 | #include <linux/cdev.h> | 47 | #include <linux/cdev.h> |
49 | #include <linux/seq_file.h> | 48 | #include <linux/seq_file.h> |
50 | #include <linux/blkdev.h> | 49 | #include <linux/blkdev.h> |
@@ -1140,32 +1139,6 @@ sg_fasync(int fd, struct file *filp, int mode) | |||
1140 | return (retval < 0) ? retval : 0; | 1139 | return (retval < 0) ? retval : 0; |
1141 | } | 1140 | } |
1142 | 1141 | ||
1143 | /* When startFinish==1 increments page counts for pages other than the | ||
1144 | first of scatter gather elements obtained from alloc_pages(). | ||
1145 | When startFinish==0 decrements ... */ | ||
1146 | static void | ||
1147 | sg_rb_correct4mmap(Sg_scatter_hold * rsv_schp, int startFinish) | ||
1148 | { | ||
1149 | struct scatterlist *sg = rsv_schp->buffer; | ||
1150 | struct page *page; | ||
1151 | int k, m; | ||
1152 | |||
1153 | SCSI_LOG_TIMEOUT(3, printk("sg_rb_correct4mmap: startFinish=%d, scatg=%d\n", | ||
1154 | startFinish, rsv_schp->k_use_sg)); | ||
1155 | /* N.B. correction _not_ applied to base page of each allocation */ | ||
1156 | for (k = 0; k < rsv_schp->k_use_sg; ++k, ++sg) { | ||
1157 | for (m = PAGE_SIZE; m < sg->length; m += PAGE_SIZE) { | ||
1158 | page = sg->page; | ||
1159 | if (startFinish) | ||
1160 | get_page(page); | ||
1161 | else { | ||
1162 | if (page_count(page) > 0) | ||
1163 | __put_page(page); | ||
1164 | } | ||
1165 | } | ||
1166 | } | ||
1167 | } | ||
1168 | |||
1169 | static struct page * | 1142 | static struct page * |
1170 | sg_vma_nopage(struct vm_area_struct *vma, unsigned long addr, int *type) | 1143 | sg_vma_nopage(struct vm_area_struct *vma, unsigned long addr, int *type) |
1171 | { | 1144 | { |
@@ -1237,10 +1210,7 @@ sg_mmap(struct file *filp, struct vm_area_struct *vma) | |||
1237 | sa += len; | 1210 | sa += len; |
1238 | } | 1211 | } |
1239 | 1212 | ||
1240 | if (0 == sfp->mmap_called) { | 1213 | sfp->mmap_called = 1; |
1241 | sg_rb_correct4mmap(rsv_schp, 1); /* do only once per fd lifetime */ | ||
1242 | sfp->mmap_called = 1; | ||
1243 | } | ||
1244 | vma->vm_flags |= VM_RESERVED; | 1214 | vma->vm_flags |= VM_RESERVED; |
1245 | vma->vm_private_data = sfp; | 1215 | vma->vm_private_data = sfp; |
1246 | vma->vm_ops = &sg_mmap_vm_ops; | 1216 | vma->vm_ops = &sg_mmap_vm_ops; |
@@ -1361,7 +1331,7 @@ static int sg_alloc(struct gendisk *disk, struct scsi_device *scsidp) | |||
1361 | void *old_sg_dev_arr = NULL; | 1331 | void *old_sg_dev_arr = NULL; |
1362 | int k, error; | 1332 | int k, error; |
1363 | 1333 | ||
1364 | sdp = kmalloc(sizeof(Sg_device), GFP_KERNEL); | 1334 | sdp = kzalloc(sizeof(Sg_device), GFP_KERNEL); |
1365 | if (!sdp) { | 1335 | if (!sdp) { |
1366 | printk(KERN_WARNING "kmalloc Sg_device failure\n"); | 1336 | printk(KERN_WARNING "kmalloc Sg_device failure\n"); |
1367 | return -ENOMEM; | 1337 | return -ENOMEM; |
@@ -1373,12 +1343,11 @@ static int sg_alloc(struct gendisk *disk, struct scsi_device *scsidp) | |||
1373 | int tmp_dev_max = sg_nr_dev + SG_DEV_ARR_LUMP; | 1343 | int tmp_dev_max = sg_nr_dev + SG_DEV_ARR_LUMP; |
1374 | write_unlock_irqrestore(&sg_dev_arr_lock, iflags); | 1344 | write_unlock_irqrestore(&sg_dev_arr_lock, iflags); |
1375 | 1345 | ||
1376 | tmp_da = kmalloc(tmp_dev_max * sizeof(Sg_device *), GFP_KERNEL); | 1346 | tmp_da = kzalloc(tmp_dev_max * sizeof(Sg_device *), GFP_KERNEL); |
1377 | if (unlikely(!tmp_da)) | 1347 | if (unlikely(!tmp_da)) |
1378 | goto expand_failed; | 1348 | goto expand_failed; |
1379 | 1349 | ||
1380 | write_lock_irqsave(&sg_dev_arr_lock, iflags); | 1350 | write_lock_irqsave(&sg_dev_arr_lock, iflags); |
1381 | memset(tmp_da, 0, tmp_dev_max * sizeof(Sg_device *)); | ||
1382 | memcpy(tmp_da, sg_dev_arr, sg_dev_max * sizeof(Sg_device *)); | 1351 | memcpy(tmp_da, sg_dev_arr, sg_dev_max * sizeof(Sg_device *)); |
1383 | old_sg_dev_arr = sg_dev_arr; | 1352 | old_sg_dev_arr = sg_dev_arr; |
1384 | sg_dev_arr = tmp_da; | 1353 | sg_dev_arr = tmp_da; |
@@ -1391,7 +1360,6 @@ static int sg_alloc(struct gendisk *disk, struct scsi_device *scsidp) | |||
1391 | if (unlikely(k >= SG_MAX_DEVS)) | 1360 | if (unlikely(k >= SG_MAX_DEVS)) |
1392 | goto overflow; | 1361 | goto overflow; |
1393 | 1362 | ||
1394 | memset(sdp, 0, sizeof(*sdp)); | ||
1395 | SCSI_LOG_TIMEOUT(3, printk("sg_alloc: dev=%d \n", k)); | 1363 | SCSI_LOG_TIMEOUT(3, printk("sg_alloc: dev=%d \n", k)); |
1396 | sprintf(disk->disk_name, "sg%d", k); | 1364 | sprintf(disk->disk_name, "sg%d", k); |
1397 | disk->first_minor = k; | 1365 | disk->first_minor = k; |
@@ -1458,14 +1426,10 @@ sg_add(struct class_device *cl_dev, struct class_interface *cl_intf) | |||
1458 | k = error; | 1426 | k = error; |
1459 | sdp = sg_dev_arr[k]; | 1427 | sdp = sg_dev_arr[k]; |
1460 | 1428 | ||
1461 | devfs_mk_cdev(MKDEV(SCSI_GENERIC_MAJOR, k), | ||
1462 | S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, | ||
1463 | "%s/generic", scsidp->devfs_name); | ||
1464 | error = cdev_add(cdev, MKDEV(SCSI_GENERIC_MAJOR, k), 1); | 1429 | error = cdev_add(cdev, MKDEV(SCSI_GENERIC_MAJOR, k), 1); |
1465 | if (error) { | 1430 | if (error) |
1466 | devfs_remove("%s/generic", scsidp->devfs_name); | ||
1467 | goto out; | 1431 | goto out; |
1468 | } | 1432 | |
1469 | sdp->cdev = cdev; | 1433 | sdp->cdev = cdev; |
1470 | if (sg_sysfs_valid) { | 1434 | if (sg_sysfs_valid) { |
1471 | struct class_device * sg_class_member; | 1435 | struct class_device * sg_class_member; |
@@ -1555,7 +1519,6 @@ sg_remove(struct class_device *cl_dev, struct class_interface *cl_intf) | |||
1555 | class_device_destroy(sg_sysfs_class, MKDEV(SCSI_GENERIC_MAJOR, k)); | 1519 | class_device_destroy(sg_sysfs_class, MKDEV(SCSI_GENERIC_MAJOR, k)); |
1556 | cdev_del(sdp->cdev); | 1520 | cdev_del(sdp->cdev); |
1557 | sdp->cdev = NULL; | 1521 | sdp->cdev = NULL; |
1558 | devfs_remove("%s/generic", scsidp->devfs_name); | ||
1559 | put_disk(sdp->disk); | 1522 | put_disk(sdp->disk); |
1560 | sdp->disk = NULL; | 1523 | sdp->disk = NULL; |
1561 | if (NULL == sdp->headfp) | 1524 | if (NULL == sdp->headfp) |
@@ -1577,6 +1540,7 @@ MODULE_AUTHOR("Douglas Gilbert"); | |||
1577 | MODULE_DESCRIPTION("SCSI generic (sg) driver"); | 1540 | MODULE_DESCRIPTION("SCSI generic (sg) driver"); |
1578 | MODULE_LICENSE("GPL"); | 1541 | MODULE_LICENSE("GPL"); |
1579 | MODULE_VERSION(SG_VERSION_STR); | 1542 | MODULE_VERSION(SG_VERSION_STR); |
1543 | MODULE_ALIAS_CHARDEV_MAJOR(SCSI_GENERIC_MAJOR); | ||
1580 | 1544 | ||
1581 | MODULE_PARM_DESC(def_reserved_size, "size of buffer reserved for each fd"); | 1545 | MODULE_PARM_DESC(def_reserved_size, "size of buffer reserved for each fd"); |
1582 | MODULE_PARM_DESC(allow_dio, "allow direct I/O (default: 0 (disallow))"); | 1546 | MODULE_PARM_DESC(allow_dio, "allow direct I/O (default: 0 (disallow))"); |
@@ -2395,8 +2359,6 @@ __sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp) | |||
2395 | SCSI_LOG_TIMEOUT(6, | 2359 | SCSI_LOG_TIMEOUT(6, |
2396 | printk("__sg_remove_sfp: bufflen=%d, k_use_sg=%d\n", | 2360 | printk("__sg_remove_sfp: bufflen=%d, k_use_sg=%d\n", |
2397 | (int) sfp->reserve.bufflen, (int) sfp->reserve.k_use_sg)); | 2361 | (int) sfp->reserve.bufflen, (int) sfp->reserve.k_use_sg)); |
2398 | if (sfp->mmap_called) | ||
2399 | sg_rb_correct4mmap(&sfp->reserve, 0); /* undo correction */ | ||
2400 | sg_remove_scat(&sfp->reserve); | 2362 | sg_remove_scat(&sfp->reserve); |
2401 | } | 2363 | } |
2402 | sfp->parentdp = NULL; | 2364 | sfp->parentdp = NULL; |
@@ -2478,9 +2440,9 @@ sg_page_malloc(int rqSz, int lowDma, int *retSzp) | |||
2478 | return resp; | 2440 | return resp; |
2479 | 2441 | ||
2480 | if (lowDma) | 2442 | if (lowDma) |
2481 | page_mask = GFP_ATOMIC | GFP_DMA | __GFP_NOWARN; | 2443 | page_mask = GFP_ATOMIC | GFP_DMA | __GFP_COMP | __GFP_NOWARN; |
2482 | else | 2444 | else |
2483 | page_mask = GFP_ATOMIC | __GFP_NOWARN; | 2445 | page_mask = GFP_ATOMIC | __GFP_COMP | __GFP_NOWARN; |
2484 | 2446 | ||
2485 | for (order = 0, a_size = PAGE_SIZE; a_size < rqSz; | 2447 | for (order = 0, a_size = PAGE_SIZE; a_size < rqSz; |
2486 | order++, a_size <<= 1) ; | 2448 | order++, a_size <<= 1) ; |
@@ -2974,4 +2936,3 @@ static int sg_proc_seq_show_debug(struct seq_file *s, void *v) | |||
2974 | 2936 | ||
2975 | module_init(init_sg); | 2937 | module_init(init_sg); |
2976 | module_exit(exit_sg); | 2938 | module_exit(exit_sg); |
2977 | MODULE_ALIAS_CHARDEV_MAJOR(SCSI_GENERIC_MAJOR); | ||