aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sg.c
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@steeleye.com>2007-08-05 14:36:11 -0400
committerJames Bottomley <jejb@mulgrave.localdomain>2007-10-12 14:50:59 -0400
commit7c07d613d22680f1caf2bd9ee49838ec7730b9da (patch)
tree61e8161d4ffefec526ad2cfbe0c676072407da4e /drivers/scsi/sg.c
parent4390e60163979621f59e3a25a260289986eacb85 (diff)
[SCSI] sg: use idr to replace static arrays
sg uses a scheme to reallocate a single contiguous array of all its pointers for lookup and management. This didn't matter too much when sg could only attach 256 nodes, but now the maximum has been bumped up to 32k we're starting to push the limits of the maximum allocatable contiguous memory. The solution to this is to eliminate the static array and do everything via idr, which this patch does. Acked-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.c253
1 files changed, 112 insertions, 141 deletions
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index fdc6618c1f61..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 = {
@@ -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;