Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Mon, 30 Jul 2007 00:22:03 +0000 (17:22 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Mon, 30 Jul 2007 00:22:03 +0000 (17:22 -0700)
* master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6: (28 commits)
  [SCSI] mpt fusion: Changes in mptctl.c for logging support
  [SCSI] mpt fusion: Changes in mptfc.c mptlan.c mptsas.c and mptspi.c for logging support
  [SCSI] mpt fusion: Changes in mptscsih.c for logging support
  [SCSI] mpt fusion: Changes in mptbase.c for logging support
  [SCSI] mpt fusion: logging support in Kconfig, Makefile, mptbase.h and addition of mptdebug.h
  [SCSI] libsas: Fix potential NULL dereference in sas_smp_get_phy_events()
  [SCSI] bsg: Fix build for CONFIG_BLOCK=n
  [SCSI] aacraid: fix Sunrise Lake reset handling
  [SCSI] aacraid: add SCSI SYNCHONIZE_CACHE range checking
  [SCSI] add easyRAID to the no report luns blacklist
  [SCSI] advansys: lindent and other large, uninteresting changes
  [SCSI] aic79xx, aic7xxx: Fix incorrect width setting
  [SCSI] qla2xxx: fix to honor ignored parameters in sysfs attributes
  [SCSI] aacraid: draw line in sand, sundry cleanup and version update
  [SCSI] iscsi_tcp: Turn off bounce buffers
  [SCSI] libiscsi: fix cmd seqeunce number checking
  [SCSI] iscsi_tcp, ib_iser Enable module refcounting for iscsi host template
  [SCSI] libiscsi: make sure session is not blocked when removing host
  [SCSI] libsas: Remove PCI dependencies
  [SCSI] simscsi: convert to use the data buffer accessors
  ...

1  2 
arch/ia64/hp/sim/simscsi.c
block/bsg.c

@@@ -101,7 -101,7 +101,7 @@@ simscsi_interrupt (unsigned long val
  {
        struct scsi_cmnd *sc;
  
 -      while ((sc = queue[rd].sc) != 0) {
 +      while ((sc = queue[rd].sc) != NULL) {
                atomic_dec(&num_reqs);
                queue[rd].sc = NULL;
                if (DBG)
@@@ -122,48 -122,22 +122,22 @@@ simscsi_biosparam (struct scsi_device *
  }
  
  static void
- simscsi_readwrite (struct scsi_cmnd *sc, int mode, unsigned long offset, unsigned long len)
- {
-       struct disk_stat stat;
-       struct disk_req req;
-       req.addr = __pa(sc->request_buffer);
-       req.len  = len;                 /* # of bytes to transfer */
-       if (sc->request_bufflen < req.len)
-               return;
-       stat.fd = desc[sc->device->id];
-       if (DBG)
-               printk("simscsi_%s @ %lx (off %lx)\n",
-                      mode == SSC_READ ? "read":"write", req.addr, offset);
-       ia64_ssc(stat.fd, 1, __pa(&req), offset, mode);
-       ia64_ssc(__pa(&stat), 0, 0, 0, SSC_WAIT_COMPLETION);
-       if (stat.count == req.len) {
-               sc->result = GOOD;
-       } else {
-               sc->result = DID_ERROR << 16;
-       }
- }
- static void
  simscsi_sg_readwrite (struct scsi_cmnd *sc, int mode, unsigned long offset)
  {
-       int list_len = sc->use_sg;
-       struct scatterlist *sl = (struct scatterlist *)sc->request_buffer;
+       int i;
+       struct scatterlist *sl;
        struct disk_stat stat;
        struct disk_req req;
  
        stat.fd = desc[sc->device->id];
  
-       while (list_len) {
+       scsi_for_each_sg(sc, sl, scsi_sg_count(sc), i) {
                req.addr = __pa(page_address(sl->page) + sl->offset);
                req.len  = sl->length;
                if (DBG)
                        printk("simscsi_sg_%s @ %lx (off %lx) use_sg=%d len=%d\n",
                               mode == SSC_READ ? "read":"write", req.addr, offset,
-                              list_len, sl->length);
+                              scsi_sg_count(sc) - i, sl->length);
                ia64_ssc(stat.fd, 1, __pa(&req), offset, mode);
                ia64_ssc(__pa(&stat), 0, 0, 0, SSC_WAIT_COMPLETION);
  
                        return;
                }
                offset +=  sl->length;
-               sl++;
-               list_len--;
        }
        sc->result = GOOD;
  }
@@@ -190,10 -162,7 +162,7 @@@ simscsi_readwrite6 (struct scsi_cmnd *s
        unsigned long offset;
  
        offset = (((sc->cmnd[1] & 0x1f) << 16) | (sc->cmnd[2] << 8) | sc->cmnd[3])*512;
-       if (sc->use_sg > 0)
-               simscsi_sg_readwrite(sc, mode, offset);
-       else
-               simscsi_readwrite(sc, mode, offset, sc->cmnd[4]*512);
+       simscsi_sg_readwrite(sc, mode, offset);
  }
  
  static size_t
@@@ -230,26 -199,21 +199,21 @@@ simscsi_readwrite10 (struct scsi_cmnd *
                | ((unsigned long)sc->cmnd[3] << 16)
                | ((unsigned long)sc->cmnd[4] <<  8) 
                | ((unsigned long)sc->cmnd[5] <<  0))*512UL;
-       if (sc->use_sg > 0)
-               simscsi_sg_readwrite(sc, mode, offset);
-       else
-               simscsi_readwrite(sc, mode, offset, ((sc->cmnd[7] << 8) | sc->cmnd[8])*512);
+       simscsi_sg_readwrite(sc, mode, offset);
  }
  
  static void simscsi_fillresult(struct scsi_cmnd *sc, char *buf, unsigned len)
  {
  
-       int scatterlen = sc->use_sg;
+       int i;
+       unsigned thislen;
        struct scatterlist *slp;
  
-       if (scatterlen == 0)
-               memcpy(sc->request_buffer, buf, len);
-       else for (slp = (struct scatterlist *)sc->request_buffer;
-                 scatterlen-- > 0 && len > 0; slp++) {
-               unsigned thislen = min(len, slp->length);
+       scsi_for_each_sg(sc, slp, scsi_sg_count(sc), i) {
+               if (!len)
+                       break;
+               thislen = min(len, slp->length);
                memcpy(page_address(slp->page) + slp->offset, buf, thislen);
-               slp++;
                len -= thislen;
        }
  }
@@@ -275,7 -239,7 +239,7 @@@ simscsi_queuecommand (struct scsi_cmnd 
        if (target_id <= 15 && sc->device->lun == 0) {
                switch (sc->cmnd[0]) {
                      case INQUIRY:
-                       if (sc->request_bufflen < 35) {
+                       if (scsi_bufflen(sc) < 35) {
                                break;
                        }
                        sprintf (fname, "%s%c", simscsi_root, 'a' + target_id);
                        break;
  
                      case READ_CAPACITY:
-                       if (desc[target_id] < 0 || sc->request_bufflen < 8) {
+                       if (desc[target_id] < 0 || scsi_bufflen(sc) < 8) {
                                break;
                        }
                        buf = localbuf;
                      case MODE_SENSE:
                      case MODE_SENSE_10:
                        /* sd.c uses this to determine whether disk does write-caching. */
-                       simscsi_fillresult(sc, (char *)empty_zero_page, sc->request_bufflen);
+                       simscsi_fillresult(sc, (char *)empty_zero_page, scsi_bufflen(sc));
                        sc->result = GOOD;
                        break;
  
diff --combined block/bsg.c
@@@ -9,13 -9,6 +9,6 @@@
   *  archive for more details.
   *
   */
- /*
-  * TODO
-  *    - Should this get merged, block/scsi_ioctl.c will be migrated into
-  *      this file. To keep maintenance down, it's easier to have them
-  *      seperated right now.
-  *
-  */
  #include <linux/module.h>
  #include <linux/init.h>
  #include <linux/file.h>
@@@ -24,6 -17,7 +17,7 @@@
  #include <linux/cdev.h>
  #include <linux/percpu.h>
  #include <linux/uio.h>
+ #include <linux/idr.h>
  #include <linux/bsg.h>
  
  #include <scsi/scsi.h>
@@@ -37,7 -31,7 +31,7 @@@
  #define BSG_VERSION   "0.4"
  
  struct bsg_device {
 -      request_queue_t *queue;
 +      struct request_queue *queue;
        spinlock_t lock;
        struct list_head busy_list;
        struct list_head done_list;
@@@ -70,13 -64,12 +64,12 @@@ enum 
  #endif
  
  static DEFINE_MUTEX(bsg_mutex);
- static int bsg_device_nr, bsg_minor_idx;
+ static DEFINE_IDR(bsg_minor_idr);
  
  #define BSG_LIST_ARRAY_SIZE   8
  static struct hlist_head bsg_device_list[BSG_LIST_ARRAY_SIZE];
  
  static struct class *bsg_class;
- static LIST_HEAD(bsg_class_list);
  static int bsg_major;
  
  static struct kmem_cache *bsg_cmd_cachep;
@@@ -92,7 -85,6 +85,6 @@@ struct bsg_command 
        struct bio *bidi_bio;
        int err;
        struct sg_io_v4 hdr;
-       struct sg_io_v4 __user *uhdr;
        char sense[SCSI_SENSE_BUFFERSIZE];
  };
  
@@@ -180,7 -172,7 +172,7 @@@ unlock
        return ret;
  }
  
 -static int blk_fill_sgv4_hdr_rq(request_queue_t *q, struct request *rq,
 +static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq,
                                struct sg_io_v4 *hdr, int has_write_perm)
  {
        memset(rq->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */
   * Check if sg_io_v4 from user is allowed and valid
   */
  static int
 -bsg_validate_sgv4_hdr(request_queue_t *q, struct sg_io_v4 *hdr, int *rw)
 +bsg_validate_sgv4_hdr(struct request_queue *q, struct sg_io_v4 *hdr, int *rw)
  {
        int ret = 0;
  
  static struct request *
  bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr)
  {
 -      request_queue_t *q = bd->queue;
 +      struct request_queue *q = bd->queue;
        struct request *rq, *next_rq = NULL;
        int ret, rw;
        unsigned int dxfer_len;
@@@ -345,7 -337,7 +337,7 @@@ static void bsg_rq_end_io(struct reques
   * do final setup of a 'bc' and submit the matching 'rq' to the block
   * layer for io
   */
 -static void bsg_add_command(struct bsg_device *bd, request_queue_t *q,
 +static void bsg_add_command(struct bsg_device *bd, struct request_queue *q,
                            struct bsg_command *bc, struct request *rq)
  {
        rq->sense = bc->sense;
@@@ -611,7 -603,7 +603,7 @@@ static int __bsg_write(struct bsg_devic
        bc = NULL;
        ret = 0;
        while (nr_commands) {
 -              request_queue_t *q = bd->queue;
 +              struct request_queue *q = bd->queue;
  
                bc = bsg_alloc_command(bd);
                if (IS_ERR(bc)) {
                        break;
                }
  
-               bc->uhdr = (struct sg_io_v4 __user *) buf;
                if (copy_from_user(&bc->hdr, buf, sizeof(bc->hdr))) {
                        ret = -EFAULT;
                        break;
@@@ -781,23 -772,18 +772,18 @@@ static struct bsg_device *__bsg_get_dev
  
  static struct bsg_device *bsg_get_device(struct inode *inode, struct file *file)
  {
-       struct bsg_device *bd = __bsg_get_device(iminor(inode));
-       struct bsg_class_device *bcd, *__bcd;
+       struct bsg_device *bd;
+       struct bsg_class_device *bcd;
  
+       bd = __bsg_get_device(iminor(inode));
        if (bd)
                return bd;
  
        /*
         * find the class device
         */
-       bcd = NULL;
        mutex_lock(&bsg_mutex);
-       list_for_each_entry(__bcd, &bsg_class_list, list) {
-               if (__bcd->minor == iminor(inode)) {
-                       bcd = __bcd;
-                       break;
-               }
-       }
+       bcd = idr_find(&bsg_minor_idr, iminor(inode));
        mutex_unlock(&bsg_mutex);
  
        if (!bcd)
@@@ -936,13 -922,12 +922,12 @@@ void bsg_unregister_queue(struct reques
                return;
  
        mutex_lock(&bsg_mutex);
+       idr_remove(&bsg_minor_idr, bcd->minor);
        sysfs_remove_link(&q->kobj, "bsg");
        class_device_unregister(bcd->class_dev);
        put_device(bcd->dev);
        bcd->class_dev = NULL;
        bcd->dev = NULL;
-       list_del_init(&bcd->list);
-       bsg_device_nr--;
        mutex_unlock(&bsg_mutex);
  }
  EXPORT_SYMBOL_GPL(bsg_unregister_queue);
  int bsg_register_queue(struct request_queue *q, struct device *gdev,
                       const char *name)
  {
-       struct bsg_class_device *bcd, *__bcd;
+       struct bsg_class_device *bcd;
        dev_t dev;
-       int ret = -EMFILE;
+       int ret, minor;
        struct class_device *class_dev = NULL;
        const char *devname;
  
  
        bcd = &q->bsg_dev;
        memset(bcd, 0, sizeof(*bcd));
-       INIT_LIST_HEAD(&bcd->list);
  
        mutex_lock(&bsg_mutex);
-       if (bsg_device_nr == BSG_MAX_DEVS) {
-               printk(KERN_ERR "bsg: too many bsg devices\n");
-               goto err;
-       }
  
- retry:
-       list_for_each_entry(__bcd, &bsg_class_list, list) {
-               if (__bcd->minor == bsg_minor_idx) {
-                       bsg_minor_idx++;
-                       if (bsg_minor_idx == BSG_MAX_DEVS)
-                               bsg_minor_idx = 0;
-                       goto retry;
-               }
+       ret = idr_pre_get(&bsg_minor_idr, GFP_KERNEL);
+       if (!ret) {
+               ret = -ENOMEM;
+               goto unlock;
        }
  
-       bcd->minor = bsg_minor_idx++;
-       if (bsg_minor_idx == BSG_MAX_DEVS)
-               bsg_minor_idx = 0;
+       ret = idr_get_new(&bsg_minor_idr, bcd, &minor);
+       if (ret < 0)
+               goto unlock;
  
+       if (minor >= BSG_MAX_DEVS) {
+               printk(KERN_ERR "bsg: too many bsg devices\n");
+               ret = -EINVAL;
+               goto remove_idr;
+       }
+       bcd->minor = minor;
        bcd->queue = q;
        bcd->dev = get_device(gdev);
        dev = MKDEV(bsg_major, bcd->minor);
                                        devname);
        if (IS_ERR(class_dev)) {
                ret = PTR_ERR(class_dev);
-               goto err_put;
+               goto put_dev;
        }
        bcd->class_dev = class_dev;
  
        if (q->kobj.sd) {
                ret = sysfs_create_link(&q->kobj, &bcd->class_dev->kobj, "bsg");
                if (ret)
-                       goto err_unregister;
+                       goto unregister_class_dev;
        }
  
        mutex_unlock(&bsg_mutex);
        return 0;
  
err_unregister:
unregister_class_dev:
        class_device_unregister(class_dev);
err_put:
put_dev:
        put_device(gdev);
- err:
+ remove_idr:
+       idr_remove(&bsg_minor_idr, minor);
+ unlock:
        mutex_unlock(&bsg_mutex);
        return ret;
  }