aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sg.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/sg.c')
-rw-r--r--drivers/scsi/sg.c255
1 files changed, 113 insertions, 142 deletions
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 85d38940a6c9..f6f5fc7d0cee 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -43,6 +43,7 @@ static int sg_version_num = 30534; /* 2 digits for each component */
43#include <linux/poll.h> 43#include <linux/poll.h>
44#include <linux/moduleparam.h> 44#include <linux/moduleparam.h>
45#include <linux/cdev.h> 45#include <linux/cdev.h>
46#include <linux/idr.h>
46#include <linux/seq_file.h> 47#include <linux/seq_file.h>
47#include <linux/blkdev.h> 48#include <linux/blkdev.h>
48#include <linux/delay.h> 49#include <linux/delay.h>
@@ -99,12 +100,11 @@ static int scatter_elem_sz_prev = SG_SCATTER_SZ;
99#define SG_SECTOR_SZ 512 100#define SG_SECTOR_SZ 512
100#define SG_SECTOR_MSK (SG_SECTOR_SZ - 1) 101#define SG_SECTOR_MSK (SG_SECTOR_SZ - 1)
101 102
102#define SG_DEV_ARR_LUMP 32 /* amount to over allocate sg_dev_arr by */
103
104static int sg_add(struct class_device *, struct class_interface *); 103static int sg_add(struct class_device *, struct class_interface *);
105static void sg_remove(struct class_device *, struct class_interface *); 104static void sg_remove(struct class_device *, struct class_interface *);
106 105
107static DEFINE_RWLOCK(sg_dev_arr_lock); /* Also used to lock 106static DEFINE_IDR(sg_index_idr);
107static DEFINE_RWLOCK(sg_index_lock); /* Also used to lock
108 file descriptor list for device */ 108 file descriptor list for device */
109 109
110static struct class_interface sg_interface = { 110static struct class_interface sg_interface = {
@@ -114,7 +114,7 @@ static struct class_interface sg_interface = {
114 114
115typedef struct sg_scatter_hold { /* holding area for scsi scatter gather info */ 115typedef struct sg_scatter_hold { /* holding area for scsi scatter gather info */
116 unsigned short k_use_sg; /* Count of kernel scatter-gather pieces */ 116 unsigned short k_use_sg; /* Count of kernel scatter-gather pieces */
117 unsigned short sglist_len; /* size of malloc'd scatter-gather list ++ */ 117 unsigned sglist_len; /* size of malloc'd scatter-gather list ++ */
118 unsigned bufflen; /* Size of (aggregate) data buffer */ 118 unsigned bufflen; /* Size of (aggregate) data buffer */
119 unsigned b_malloc_len; /* actual len malloc'ed in buffer */ 119 unsigned b_malloc_len; /* actual len malloc'ed in buffer */
120 struct scatterlist *buffer;/* scatter list */ 120 struct scatterlist *buffer;/* scatter list */
@@ -162,6 +162,7 @@ typedef struct sg_device { /* holds the state of each scsi generic device */
162 struct scsi_device *device; 162 struct scsi_device *device;
163 wait_queue_head_t o_excl_wait; /* queue open() when O_EXCL in use */ 163 wait_queue_head_t o_excl_wait; /* queue open() when O_EXCL in use */
164 int sg_tablesize; /* adapter's max scatter-gather table size */ 164 int sg_tablesize; /* adapter's max scatter-gather table size */
165 u32 index; /* device index number */
165 Sg_fd *headfp; /* first open fd belonging to this device */ 166 Sg_fd *headfp; /* first open fd belonging to this device */
166 volatile char detached; /* 0->attached, 1->detached pending removal */ 167 volatile char detached; /* 0->attached, 1->detached pending removal */
167 volatile char exclude; /* opened for exclusive access */ 168 volatile char exclude; /* opened for exclusive access */
@@ -209,10 +210,6 @@ static Sg_device *sg_get_dev(int dev);
209static int sg_last_dev(void); 210static int sg_last_dev(void);
210#endif 211#endif
211 212
212static Sg_device **sg_dev_arr = NULL;
213static int sg_dev_max;
214static int sg_nr_dev;
215
216#define SZ_SG_HEADER sizeof(struct sg_header) 213#define SZ_SG_HEADER sizeof(struct sg_header)
217#define SZ_SG_IO_HDR sizeof(sg_io_hdr_t) 214#define SZ_SG_IO_HDR sizeof(sg_io_hdr_t)
218#define SZ_SG_IOVEC sizeof(sg_iovec_t) 215#define SZ_SG_IOVEC sizeof(sg_iovec_t)
@@ -1331,40 +1328,35 @@ static struct class *sg_sysfs_class;
1331 1328
1332static int sg_sysfs_valid = 0; 1329static int sg_sysfs_valid = 0;
1333 1330
1334static int sg_alloc(struct gendisk *disk, struct scsi_device *scsidp) 1331static Sg_device *sg_alloc(struct gendisk *disk, struct scsi_device *scsidp)
1335{ 1332{
1336 struct request_queue *q = scsidp->request_queue; 1333 struct request_queue *q = scsidp->request_queue;
1337 Sg_device *sdp; 1334 Sg_device *sdp;
1338 unsigned long iflags; 1335 unsigned long iflags;
1339 void *old_sg_dev_arr = NULL; 1336 int error;
1340 int k, error; 1337 u32 k;
1341 1338
1342 sdp = kzalloc(sizeof(Sg_device), GFP_KERNEL); 1339 sdp = kzalloc(sizeof(Sg_device), GFP_KERNEL);
1343 if (!sdp) { 1340 if (!sdp) {
1344 printk(KERN_WARNING "kmalloc Sg_device failure\n"); 1341 printk(KERN_WARNING "kmalloc Sg_device failure\n");
1345 return -ENOMEM; 1342 return ERR_PTR(-ENOMEM);
1343 }
1344 error = -ENOMEM;
1345 if (!idr_pre_get(&sg_index_idr, GFP_KERNEL)) {
1346 printk(KERN_WARNING "idr expansion Sg_device failure\n");
1347 goto out;
1346 } 1348 }
1347 1349
1348 write_lock_irqsave(&sg_dev_arr_lock, iflags); 1350 write_lock_irqsave(&sg_index_lock, iflags);
1349 if (unlikely(sg_nr_dev >= sg_dev_max)) { /* try to resize */ 1351 error = idr_get_new(&sg_index_idr, sdp, &k);
1350 Sg_device **tmp_da; 1352 write_unlock_irqrestore(&sg_index_lock, iflags);
1351 int tmp_dev_max = sg_nr_dev + SG_DEV_ARR_LUMP;
1352 write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
1353
1354 tmp_da = kzalloc(tmp_dev_max * sizeof(Sg_device *), GFP_KERNEL);
1355 if (unlikely(!tmp_da))
1356 goto expand_failed;
1357 1353
1358 write_lock_irqsave(&sg_dev_arr_lock, iflags); 1354 if (error) {
1359 memcpy(tmp_da, sg_dev_arr, sg_dev_max * sizeof(Sg_device *)); 1355 printk(KERN_WARNING "idr allocation Sg_device failure: %d\n",
1360 old_sg_dev_arr = sg_dev_arr; 1356 error);
1361 sg_dev_arr = tmp_da; 1357 goto out;
1362 sg_dev_max = tmp_dev_max;
1363 } 1358 }
1364 1359
1365 for (k = 0; k < sg_dev_max; k++)
1366 if (!sg_dev_arr[k])
1367 break;
1368 if (unlikely(k >= SG_MAX_DEVS)) 1360 if (unlikely(k >= SG_MAX_DEVS))
1369 goto overflow; 1361 goto overflow;
1370 1362
@@ -1375,25 +1367,17 @@ static int sg_alloc(struct gendisk *disk, struct scsi_device *scsidp)
1375 sdp->device = scsidp; 1367 sdp->device = scsidp;
1376 init_waitqueue_head(&sdp->o_excl_wait); 1368 init_waitqueue_head(&sdp->o_excl_wait);
1377 sdp->sg_tablesize = min(q->max_hw_segments, q->max_phys_segments); 1369 sdp->sg_tablesize = min(q->max_hw_segments, q->max_phys_segments);
1370 sdp->index = k;
1378 1371
1379 sg_nr_dev++; 1372 error = 0;
1380 sg_dev_arr[k] = sdp;
1381 write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
1382 error = k;
1383
1384 out: 1373 out:
1385 if (error < 0) 1374 if (error) {
1386 kfree(sdp); 1375 kfree(sdp);
1387 kfree(old_sg_dev_arr); 1376 return ERR_PTR(error);
1388 return error; 1377 }
1389 1378 return sdp;
1390 expand_failed:
1391 printk(KERN_WARNING "sg_alloc: device array cannot be resized\n");
1392 error = -ENOMEM;
1393 goto out;
1394 1379
1395 overflow: 1380 overflow:
1396 write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
1397 sdev_printk(KERN_WARNING, scsidp, 1381 sdev_printk(KERN_WARNING, scsidp,
1398 "Unable to attach sg device type=%d, minor " 1382 "Unable to attach sg device type=%d, minor "
1399 "number exceeds %d\n", scsidp->type, SG_MAX_DEVS - 1); 1383 "number exceeds %d\n", scsidp->type, SG_MAX_DEVS - 1);
@@ -1408,7 +1392,7 @@ sg_add(struct class_device *cl_dev, struct class_interface *cl_intf)
1408 struct gendisk *disk; 1392 struct gendisk *disk;
1409 Sg_device *sdp = NULL; 1393 Sg_device *sdp = NULL;
1410 struct cdev * cdev = NULL; 1394 struct cdev * cdev = NULL;
1411 int error, k; 1395 int error;
1412 unsigned long iflags; 1396 unsigned long iflags;
1413 1397
1414 disk = alloc_disk(1); 1398 disk = alloc_disk(1);
@@ -1427,15 +1411,15 @@ sg_add(struct class_device *cl_dev, struct class_interface *cl_intf)
1427 cdev->owner = THIS_MODULE; 1411 cdev->owner = THIS_MODULE;
1428 cdev->ops = &sg_fops; 1412 cdev->ops = &sg_fops;
1429 1413
1430 error = sg_alloc(disk, scsidp); 1414 sdp = sg_alloc(disk, scsidp);
1431 if (error < 0) { 1415 if (IS_ERR(sdp)) {
1432 printk(KERN_WARNING "sg_alloc failed\n"); 1416 printk(KERN_WARNING "sg_alloc failed\n");
1417 error = PTR_ERR(sdp);
1433 goto out; 1418 goto out;
1434 } 1419 }
1435 k = error;
1436 sdp = sg_dev_arr[k];
1437 1420
1438 error = cdev_add(cdev, MKDEV(SCSI_GENERIC_MAJOR, k), 1); 1421 class_set_devdata(cl_dev, sdp);
1422 error = cdev_add(cdev, MKDEV(SCSI_GENERIC_MAJOR, sdp->index), 1);
1439 if (error) 1423 if (error)
1440 goto cdev_add_err; 1424 goto cdev_add_err;
1441 1425
@@ -1444,8 +1428,8 @@ sg_add(struct class_device *cl_dev, struct class_interface *cl_intf)
1444 struct class_device * sg_class_member; 1428 struct class_device * sg_class_member;
1445 1429
1446 sg_class_member = class_device_create(sg_sysfs_class, NULL, 1430 sg_class_member = class_device_create(sg_sysfs_class, NULL,
1447 MKDEV(SCSI_GENERIC_MAJOR, k), 1431 MKDEV(SCSI_GENERIC_MAJOR, sdp->index),
1448 cl_dev->dev, "%s", 1432 cl_dev->dev, "%s",
1449 disk->disk_name); 1433 disk->disk_name);
1450 if (IS_ERR(sg_class_member)) 1434 if (IS_ERR(sg_class_member))
1451 printk(KERN_WARNING "sg_add: " 1435 printk(KERN_WARNING "sg_add: "
@@ -1455,21 +1439,21 @@ sg_add(struct class_device *cl_dev, struct class_interface *cl_intf)
1455 &sg_class_member->kobj, "generic"); 1439 &sg_class_member->kobj, "generic");
1456 if (error) 1440 if (error)
1457 printk(KERN_ERR "sg_add: unable to make symlink " 1441 printk(KERN_ERR "sg_add: unable to make symlink "
1458 "'generic' back to sg%d\n", k); 1442 "'generic' back to sg%d\n", sdp->index);
1459 } else 1443 } else
1460 printk(KERN_WARNING "sg_add: sg_sys INvalid\n"); 1444 printk(KERN_WARNING "sg_add: sg_sys Invalid\n");
1461 1445
1462 sdev_printk(KERN_NOTICE, scsidp, 1446 sdev_printk(KERN_NOTICE, scsidp,
1463 "Attached scsi generic sg%d type %d\n", k,scsidp->type); 1447 "Attached scsi generic sg%d type %d\n", sdp->index,
1448 scsidp->type);
1464 1449
1465 return 0; 1450 return 0;
1466 1451
1467cdev_add_err: 1452cdev_add_err:
1468 write_lock_irqsave(&sg_dev_arr_lock, iflags); 1453 write_lock_irqsave(&sg_index_lock, iflags);
1469 kfree(sg_dev_arr[k]); 1454 idr_remove(&sg_index_idr, sdp->index);
1470 sg_dev_arr[k] = NULL; 1455 write_unlock_irqrestore(&sg_index_lock, iflags);
1471 sg_nr_dev--; 1456 kfree(sdp);
1472 write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
1473 1457
1474out: 1458out:
1475 put_disk(disk); 1459 put_disk(disk);
@@ -1482,64 +1466,56 @@ static void
1482sg_remove(struct class_device *cl_dev, struct class_interface *cl_intf) 1466sg_remove(struct class_device *cl_dev, struct class_interface *cl_intf)
1483{ 1467{
1484 struct scsi_device *scsidp = to_scsi_device(cl_dev->dev); 1468 struct scsi_device *scsidp = to_scsi_device(cl_dev->dev);
1485 Sg_device *sdp = NULL; 1469 Sg_device *sdp = class_get_devdata(cl_dev);
1486 unsigned long iflags; 1470 unsigned long iflags;
1487 Sg_fd *sfp; 1471 Sg_fd *sfp;
1488 Sg_fd *tsfp; 1472 Sg_fd *tsfp;
1489 Sg_request *srp; 1473 Sg_request *srp;
1490 Sg_request *tsrp; 1474 Sg_request *tsrp;
1491 int k, delay; 1475 int delay;
1492 1476
1493 if (NULL == sg_dev_arr) 1477 if (!sdp)
1494 return; 1478 return;
1479
1495 delay = 0; 1480 delay = 0;
1496 write_lock_irqsave(&sg_dev_arr_lock, iflags); 1481 write_lock_irqsave(&sg_index_lock, iflags);
1497 for (k = 0; k < sg_dev_max; k++) { 1482 if (sdp->headfp) {
1498 sdp = sg_dev_arr[k]; 1483 sdp->detached = 1;
1499 if ((NULL == sdp) || (sdp->device != scsidp)) 1484 for (sfp = sdp->headfp; sfp; sfp = tsfp) {
1500 continue; /* dirty but lowers nesting */ 1485 tsfp = sfp->nextfp;
1501 if (sdp->headfp) { 1486 for (srp = sfp->headrp; srp; srp = tsrp) {
1502 sdp->detached = 1; 1487 tsrp = srp->nextrp;
1503 for (sfp = sdp->headfp; sfp; sfp = tsfp) { 1488 if (sfp->closed || (0 == sg_srp_done(srp, sfp)))
1504 tsfp = sfp->nextfp; 1489 sg_finish_rem_req(srp);
1505 for (srp = sfp->headrp; srp; srp = tsrp) {
1506 tsrp = srp->nextrp;
1507 if (sfp->closed || (0 == sg_srp_done(srp, sfp)))
1508 sg_finish_rem_req(srp);
1509 }
1510 if (sfp->closed) {
1511 scsi_device_put(sdp->device);
1512 __sg_remove_sfp(sdp, sfp);
1513 } else {
1514 delay = 1;
1515 wake_up_interruptible(&sfp->read_wait);
1516 kill_fasync(&sfp->async_qp, SIGPOLL,
1517 POLL_HUP);
1518 }
1519 } 1490 }
1520 SCSI_LOG_TIMEOUT(3, printk("sg_remove: dev=%d, dirty\n", k)); 1491 if (sfp->closed) {
1521 if (NULL == sdp->headfp) { 1492 scsi_device_put(sdp->device);
1522 sg_dev_arr[k] = NULL; 1493 __sg_remove_sfp(sdp, sfp);
1494 } else {
1495 delay = 1;
1496 wake_up_interruptible(&sfp->read_wait);
1497 kill_fasync(&sfp->async_qp, SIGPOLL,
1498 POLL_HUP);
1523 } 1499 }
1524 } else { /* nothing active, simple case */
1525 SCSI_LOG_TIMEOUT(3, printk("sg_remove: dev=%d\n", k));
1526 sg_dev_arr[k] = NULL;
1527 } 1500 }
1528 sg_nr_dev--; 1501 SCSI_LOG_TIMEOUT(3, printk("sg_remove: dev=%d, dirty\n", sdp->index));
1529 break; 1502 if (NULL == sdp->headfp) {
1530 } 1503 idr_remove(&sg_index_idr, sdp->index);
1531 write_unlock_irqrestore(&sg_dev_arr_lock, iflags); 1504 }
1532 1505 } else { /* nothing active, simple case */
1533 if (sdp) { 1506 SCSI_LOG_TIMEOUT(3, printk("sg_remove: dev=%d\n", sdp->index));
1534 sysfs_remove_link(&scsidp->sdev_gendev.kobj, "generic"); 1507 idr_remove(&sg_index_idr, sdp->index);
1535 class_device_destroy(sg_sysfs_class, MKDEV(SCSI_GENERIC_MAJOR, k)); 1508 }
1536 cdev_del(sdp->cdev); 1509 write_unlock_irqrestore(&sg_index_lock, iflags);
1537 sdp->cdev = NULL; 1510
1538 put_disk(sdp->disk); 1511 sysfs_remove_link(&scsidp->sdev_gendev.kobj, "generic");
1539 sdp->disk = NULL; 1512 class_device_destroy(sg_sysfs_class, MKDEV(SCSI_GENERIC_MAJOR, sdp->index));
1540 if (NULL == sdp->headfp) 1513 cdev_del(sdp->cdev);
1541 kfree((char *) sdp); 1514 sdp->cdev = NULL;
1542 } 1515 put_disk(sdp->disk);
1516 sdp->disk = NULL;
1517 if (NULL == sdp->headfp)
1518 kfree(sdp);
1543 1519
1544 if (delay) 1520 if (delay)
1545 msleep(10); /* dirty detach so delay device destruction */ 1521 msleep(10); /* dirty detach so delay device destruction */
@@ -1609,9 +1585,7 @@ exit_sg(void)
1609 sg_sysfs_valid = 0; 1585 sg_sysfs_valid = 0;
1610 unregister_chrdev_region(MKDEV(SCSI_GENERIC_MAJOR, 0), 1586 unregister_chrdev_region(MKDEV(SCSI_GENERIC_MAJOR, 0),
1611 SG_MAX_DEVS); 1587 SG_MAX_DEVS);
1612 kfree((char *)sg_dev_arr); 1588 idr_destroy(&sg_index_idr);
1613 sg_dev_arr = NULL;
1614 sg_dev_max = 0;
1615} 1589}
1616 1590
1617static int 1591static int
@@ -2331,10 +2305,10 @@ sg_get_nth_sfp(Sg_device * sdp, int nth)
2331 unsigned long iflags; 2305 unsigned long iflags;
2332 int k; 2306 int k;
2333 2307
2334 read_lock_irqsave(&sg_dev_arr_lock, iflags); 2308 read_lock_irqsave(&sg_index_lock, iflags);
2335 for (k = 0, resp = sdp->headfp; resp && (k < nth); 2309 for (k = 0, resp = sdp->headfp; resp && (k < nth);
2336 ++k, resp = resp->nextfp) ; 2310 ++k, resp = resp->nextfp) ;
2337 read_unlock_irqrestore(&sg_dev_arr_lock, iflags); 2311 read_unlock_irqrestore(&sg_index_lock, iflags);
2338 return resp; 2312 return resp;
2339} 2313}
2340#endif 2314#endif
@@ -2361,7 +2335,7 @@ sg_add_sfp(Sg_device * sdp, int dev)
2361 sfp->cmd_q = SG_DEF_COMMAND_Q; 2335 sfp->cmd_q = SG_DEF_COMMAND_Q;
2362 sfp->keep_orphan = SG_DEF_KEEP_ORPHAN; 2336 sfp->keep_orphan = SG_DEF_KEEP_ORPHAN;
2363 sfp->parentdp = sdp; 2337 sfp->parentdp = sdp;
2364 write_lock_irqsave(&sg_dev_arr_lock, iflags); 2338 write_lock_irqsave(&sg_index_lock, iflags);
2365 if (!sdp->headfp) 2339 if (!sdp->headfp)
2366 sdp->headfp = sfp; 2340 sdp->headfp = sfp;
2367 else { /* add to tail of existing list */ 2341 else { /* add to tail of existing list */
@@ -2370,7 +2344,7 @@ sg_add_sfp(Sg_device * sdp, int dev)
2370 pfp = pfp->nextfp; 2344 pfp = pfp->nextfp;
2371 pfp->nextfp = sfp; 2345 pfp->nextfp = sfp;
2372 } 2346 }
2373 write_unlock_irqrestore(&sg_dev_arr_lock, iflags); 2347 write_unlock_irqrestore(&sg_index_lock, iflags);
2374 SCSI_LOG_TIMEOUT(3, printk("sg_add_sfp: sfp=0x%p\n", sfp)); 2348 SCSI_LOG_TIMEOUT(3, printk("sg_add_sfp: sfp=0x%p\n", sfp));
2375 if (unlikely(sg_big_buff != def_reserved_size)) 2349 if (unlikely(sg_big_buff != def_reserved_size))
2376 sg_big_buff = def_reserved_size; 2350 sg_big_buff = def_reserved_size;
@@ -2431,22 +2405,14 @@ sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp)
2431 if (0 == dirty) { 2405 if (0 == dirty) {
2432 unsigned long iflags; 2406 unsigned long iflags;
2433 2407
2434 write_lock_irqsave(&sg_dev_arr_lock, iflags); 2408 write_lock_irqsave(&sg_index_lock, iflags);
2435 __sg_remove_sfp(sdp, sfp); 2409 __sg_remove_sfp(sdp, sfp);
2436 if (sdp->detached && (NULL == sdp->headfp)) { 2410 if (sdp->detached && (NULL == sdp->headfp)) {
2437 int k, maxd; 2411 idr_remove(&sg_index_idr, sdp->index);
2438 2412 kfree(sdp);
2439 maxd = sg_dev_max;
2440 for (k = 0; k < maxd; ++k) {
2441 if (sdp == sg_dev_arr[k])
2442 break;
2443 }
2444 if (k < maxd)
2445 sg_dev_arr[k] = NULL;
2446 kfree((char *) sdp);
2447 res = 1; 2413 res = 1;
2448 } 2414 }
2449 write_unlock_irqrestore(&sg_dev_arr_lock, iflags); 2415 write_unlock_irqrestore(&sg_index_lock, iflags);
2450 } else { 2416 } else {
2451 /* MOD_INC's to inhibit unloading sg and associated adapter driver */ 2417 /* MOD_INC's to inhibit unloading sg and associated adapter driver */
2452 /* only bump the access_count if we actually succeeded in 2418 /* only bump the access_count if we actually succeeded in
@@ -2546,16 +2512,25 @@ sg_allow_access(unsigned char opcode, char dev_type)
2546 2512
2547#ifdef CONFIG_SCSI_PROC_FS 2513#ifdef CONFIG_SCSI_PROC_FS
2548static int 2514static int
2515sg_idr_max_id(int id, void *p, void *data)
2516{
2517 int *k = data;
2518
2519 if (*k < id)
2520 *k = id;
2521
2522 return 0;
2523}
2524
2525static int
2549sg_last_dev(void) 2526sg_last_dev(void)
2550{ 2527{
2551 int k; 2528 int k = 0;
2552 unsigned long iflags; 2529 unsigned long iflags;
2553 2530
2554 read_lock_irqsave(&sg_dev_arr_lock, iflags); 2531 read_lock_irqsave(&sg_index_lock, iflags);
2555 for (k = sg_dev_max - 1; k >= 0; --k) 2532 idr_for_each(&sg_index_idr, sg_idr_max_id, &k);
2556 if (sg_dev_arr[k] && sg_dev_arr[k]->device) 2533 read_unlock_irqrestore(&sg_index_lock, iflags);
2557 break;
2558 read_unlock_irqrestore(&sg_dev_arr_lock, iflags);
2559 return k + 1; /* origin 1 */ 2534 return k + 1; /* origin 1 */
2560} 2535}
2561#endif 2536#endif
@@ -2563,15 +2538,13 @@ sg_last_dev(void)
2563static Sg_device * 2538static Sg_device *
2564sg_get_dev(int dev) 2539sg_get_dev(int dev)
2565{ 2540{
2566 Sg_device *sdp = NULL; 2541 Sg_device *sdp;
2567 unsigned long iflags; 2542 unsigned long iflags;
2568 2543
2569 if (sg_dev_arr && (dev >= 0)) { 2544 read_lock_irqsave(&sg_index_lock, iflags);
2570 read_lock_irqsave(&sg_dev_arr_lock, iflags); 2545 sdp = idr_find(&sg_index_idr, dev);
2571 if (dev < sg_dev_max) 2546 read_unlock_irqrestore(&sg_index_lock, iflags);
2572 sdp = sg_dev_arr[dev]; 2547
2573 read_unlock_irqrestore(&sg_dev_arr_lock, iflags);
2574 }
2575 return sdp; 2548 return sdp;
2576} 2549}
2577 2550
@@ -2805,8 +2778,6 @@ static void * dev_seq_start(struct seq_file *s, loff_t *pos)
2805 if (! it) 2778 if (! it)
2806 return NULL; 2779 return NULL;
2807 2780
2808 if (NULL == sg_dev_arr)
2809 return NULL;
2810 it->index = *pos; 2781 it->index = *pos;
2811 it->max = sg_last_dev(); 2782 it->max = sg_last_dev();
2812 if (it->index >= it->max) 2783 if (it->index >= it->max)
@@ -2942,8 +2913,8 @@ static int sg_proc_seq_show_debug(struct seq_file *s, void *v)
2942 Sg_device *sdp; 2913 Sg_device *sdp;
2943 2914
2944 if (it && (0 == it->index)) { 2915 if (it && (0 == it->index)) {
2945 seq_printf(s, "dev_max(currently)=%d max_active_device=%d " 2916 seq_printf(s, "max_active_device=%d(origin 1)\n",
2946 "(origin 1)\n", sg_dev_max, (int)it->max); 2917 (int)it->max);
2947 seq_printf(s, " def_reserved_size=%d\n", sg_big_buff); 2918 seq_printf(s, " def_reserved_size=%d\n", sg_big_buff);
2948 } 2919 }
2949 sdp = it ? sg_get_dev(it->index) : NULL; 2920 sdp = it ? sg_get_dev(it->index) : NULL;