cciss: factor out cciss_getbustypes
[linux-2.6-block.git] / drivers / block / cciss.c
index 3cd8397f82bdb6f311e0298c2d3b828b3ac09e57..e7b650b7f548c585c7ae8865adae533ae3554701 100644 (file)
@@ -191,17 +191,17 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time, int via_ioctl);
 static int deregister_disk(ctlr_info_t *h, int drv_index,
                           int clear_all, int via_ioctl);
 
-static void cciss_read_capacity(int ctlr, int logvol,
+static void cciss_read_capacity(ctlr_info_t *h, int logvol,
                        sector_t *total_size, unsigned int *block_size);
-static void cciss_read_capacity_16(int ctlr, int logvol,
+static void cciss_read_capacity_16(ctlr_info_t *h, int logvol,
                        sector_t *total_size, unsigned int *block_size);
-static void cciss_geometry_inquiry(int ctlr, int logvol,
+static void cciss_geometry_inquiry(ctlr_info_t *h, int logvol,
                        sector_t total_size,
                        unsigned int block_size, InquiryData_struct *inq_buff,
                                   drive_info_struct *drv);
 static void __devinit cciss_interrupt_mode(ctlr_info_t *);
 static void start_io(ctlr_info_t *h);
-static int sendcmd_withirq(__u8 cmd, int ctlr, void *buff, size_t size,
+static int sendcmd_withirq(ctlr_info_t *h, __u8 cmd, void *buff, size_t size,
                        __u8 page_code, unsigned char scsi3addr[],
                        int cmd_type);
 static int sendcmd_withirq_core(ctlr_info_t *h, CommandList_struct *c,
@@ -216,6 +216,12 @@ static void cciss_device_release(struct device *dev);
 static void cciss_free_gendisk(ctlr_info_t *h, int drv_index);
 static void cciss_free_drive_info(ctlr_info_t *h, int drv_index);
 static inline u32 next_command(ctlr_info_t *h);
+static int __devinit cciss_find_cfg_addrs(struct pci_dev *pdev,
+       void __iomem *vaddr, u32 *cfg_base_addr, u64 *cfg_base_addr_index,
+       u64 *cfg_offset);
+static int __devinit cciss_pci_find_memory_BAR(struct pci_dev *pdev,
+       unsigned long *memory_bar);
+
 
 /* performant mode helper functions */
 static void  calc_bucket_map(int *bucket, int num_buckets, int nsgs,
@@ -223,9 +229,9 @@ static void  calc_bucket_map(int *bucket, int num_buckets, int nsgs,
 static void cciss_put_controller_into_performant_mode(ctlr_info_t *h);
 
 #ifdef CONFIG_PROC_FS
-static void cciss_procinit(int i);
+static void cciss_procinit(ctlr_info_t *h);
 #else
-static void cciss_procinit(int i)
+static void cciss_procinit(ctlr_info_t *h)
 {
 }
 #endif                         /* CONFIG_PROC_FS */
@@ -373,7 +379,7 @@ static void cciss_map_sg_chain_block(ctlr_info_t *h, CommandList_struct *c,
 static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG",
        "UNKNOWN"
 };
-#define RAID_UNKNOWN (sizeof(raid_label) / sizeof(raid_label[0])-1)
+#define RAID_UNKNOWN (ARRAY_SIZE(raid_label)-1)
 
 #ifdef CONFIG_PROC_FS
 
@@ -410,26 +416,25 @@ static void cciss_seq_show_header(struct seq_file *seq)
                h->maxQsinceinit, h->max_outstanding, h->maxSG);
 
 #ifdef CONFIG_CISS_SCSI_TAPE
-       cciss_seq_tape_report(seq, h->ctlr);
+       cciss_seq_tape_report(seq, h);
 #endif /* CONFIG_CISS_SCSI_TAPE */
 }
 
 static void *cciss_seq_start(struct seq_file *seq, loff_t *pos)
 {
        ctlr_info_t *h = seq->private;
-       unsigned ctlr = h->ctlr;
        unsigned long flags;
 
        /* prevent displaying bogus info during configuration
         * or deconfiguration of a logical volume
         */
-       spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
+       spin_lock_irqsave(&h->lock, flags);
        if (h->busy_configuring) {
-               spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
+               spin_unlock_irqrestore(&h->lock, flags);
                return ERR_PTR(-EBUSY);
        }
        h->busy_configuring = 1;
-       spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
+       spin_unlock_irqrestore(&h->lock, flags);
 
        if (*pos == 0)
                cciss_seq_show_header(seq);
@@ -537,7 +542,7 @@ cciss_proc_write(struct file *file, const char __user *buf,
                struct seq_file *seq = file->private_data;
                ctlr_info_t *h = seq->private;
 
-               err = cciss_engage_scsi(h->ctlr);
+               err = cciss_engage_scsi(h);
                if (err == 0)
                        err = length;
        } else
@@ -560,7 +565,7 @@ static const struct file_operations cciss_proc_fops = {
        .write   = cciss_proc_write,
 };
 
-static void __devinit cciss_procinit(int i)
+static void __devinit cciss_procinit(ctlr_info_t *h)
 {
        struct proc_dir_entry *pde;
 
@@ -568,9 +573,9 @@ static void __devinit cciss_procinit(int i)
                proc_cciss = proc_mkdir("driver/cciss", NULL);
        if (!proc_cciss)
                return;
-       pde = proc_create_data(hba[i]->devname, S_IWUSR | S_IRUSR | S_IRGRP |
+       pde = proc_create_data(h->devname, S_IWUSR | S_IRUSR | S_IRGRP |
                                        S_IROTH, proc_cciss,
-                                       &cciss_proc_fops, hba[i]);
+                                       &cciss_proc_fops, h);
 }
 #endif                         /* CONFIG_PROC_FS */
 
@@ -603,12 +608,12 @@ static ssize_t dev_show_unique_id(struct device *dev,
        unsigned long flags;
        int ret = 0;
 
-       spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
+       spin_lock_irqsave(&h->lock, flags);
        if (h->busy_configuring)
                ret = -EBUSY;
        else
                memcpy(sn, drv->serial_no, sizeof(sn));
-       spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+       spin_unlock_irqrestore(&h->lock, flags);
 
        if (ret)
                return ret;
@@ -633,12 +638,12 @@ static ssize_t dev_show_vendor(struct device *dev,
        unsigned long flags;
        int ret = 0;
 
-       spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
+       spin_lock_irqsave(&h->lock, flags);
        if (h->busy_configuring)
                ret = -EBUSY;
        else
                memcpy(vendor, drv->vendor, VENDOR_LEN + 1);
-       spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+       spin_unlock_irqrestore(&h->lock, flags);
 
        if (ret)
                return ret;
@@ -657,12 +662,12 @@ static ssize_t dev_show_model(struct device *dev,
        unsigned long flags;
        int ret = 0;
 
-       spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
+       spin_lock_irqsave(&h->lock, flags);
        if (h->busy_configuring)
                ret = -EBUSY;
        else
                memcpy(model, drv->model, MODEL_LEN + 1);
-       spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+       spin_unlock_irqrestore(&h->lock, flags);
 
        if (ret)
                return ret;
@@ -681,12 +686,12 @@ static ssize_t dev_show_rev(struct device *dev,
        unsigned long flags;
        int ret = 0;
 
-       spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
+       spin_lock_irqsave(&h->lock, flags);
        if (h->busy_configuring)
                ret = -EBUSY;
        else
                memcpy(rev, drv->rev, REV_LEN + 1);
-       spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+       spin_unlock_irqrestore(&h->lock, flags);
 
        if (ret)
                return ret;
@@ -703,17 +708,17 @@ static ssize_t cciss_show_lunid(struct device *dev,
        unsigned long flags;
        unsigned char lunid[8];
 
-       spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
+       spin_lock_irqsave(&h->lock, flags);
        if (h->busy_configuring) {
-               spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+               spin_unlock_irqrestore(&h->lock, flags);
                return -EBUSY;
        }
        if (!drv->heads) {
-               spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+               spin_unlock_irqrestore(&h->lock, flags);
                return -ENOTTY;
        }
        memcpy(lunid, drv->LunID, sizeof(lunid));
-       spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+       spin_unlock_irqrestore(&h->lock, flags);
        return snprintf(buf, 20, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
                lunid[0], lunid[1], lunid[2], lunid[3],
                lunid[4], lunid[5], lunid[6], lunid[7]);
@@ -728,13 +733,13 @@ static ssize_t cciss_show_raid_level(struct device *dev,
        int raid;
        unsigned long flags;
 
-       spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
+       spin_lock_irqsave(&h->lock, flags);
        if (h->busy_configuring) {
-               spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+               spin_unlock_irqrestore(&h->lock, flags);
                return -EBUSY;
        }
        raid = drv->raid_level;
-       spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+       spin_unlock_irqrestore(&h->lock, flags);
        if (raid < 0 || raid > RAID_UNKNOWN)
                raid = RAID_UNKNOWN;
 
@@ -751,13 +756,13 @@ static ssize_t cciss_show_usage_count(struct device *dev,
        unsigned long flags;
        int count;
 
-       spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
+       spin_lock_irqsave(&h->lock, flags);
        if (h->busy_configuring) {
-               spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+               spin_unlock_irqrestore(&h->lock, flags);
                return -EBUSY;
        }
        count = drv->usage_count;
-       spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+       spin_unlock_irqrestore(&h->lock, flags);
        return snprintf(buf, 20, "%d\n", count);
 }
 static DEVICE_ATTR(usage_count, S_IRUGO, cciss_show_usage_count, NULL);
@@ -902,60 +907,70 @@ static void cciss_destroy_ld_sysfs_entry(struct ctlr_info *h, int drv_index,
 /*
  * For operations that cannot sleep, a command block is allocated at init,
  * and managed by cmd_alloc() and cmd_free() using a simple bitmap to track
- * which ones are free or in use.  For operations that can wait for kmalloc
- * to possible sleep, this routine can be called with get_from_pool set to 0.
- * cmd_free() MUST be called with a got_from_pool set to 0 if cmd_alloc was.
+ * which ones are free or in use.
  */
-static CommandList_struct *cmd_alloc(ctlr_info_t *h, int get_from_pool)
+static CommandList_struct *cmd_alloc(ctlr_info_t *h)
 {
        CommandList_struct *c;
        int i;
        u64bit temp64;
        dma_addr_t cmd_dma_handle, err_dma_handle;
 
-       if (!get_from_pool) {
-               c = (CommandList_struct *) pci_alloc_consistent(h->pdev,
-                       sizeof(CommandList_struct), &cmd_dma_handle);
-               if (c == NULL)
+       do {
+               i = find_first_zero_bit(h->cmd_pool_bits, h->nr_cmds);
+               if (i == h->nr_cmds)
                        return NULL;
-               memset(c, 0, sizeof(CommandList_struct));
+       } while (test_and_set_bit(i & (BITS_PER_LONG - 1),
+                 h->cmd_pool_bits + (i / BITS_PER_LONG)) != 0);
+       c = h->cmd_pool + i;
+       memset(c, 0, sizeof(CommandList_struct));
+       cmd_dma_handle = h->cmd_pool_dhandle + i * sizeof(CommandList_struct);
+       c->err_info = h->errinfo_pool + i;
+       memset(c->err_info, 0, sizeof(ErrorInfo_struct));
+       err_dma_handle = h->errinfo_pool_dhandle
+           + i * sizeof(ErrorInfo_struct);
+       h->nr_allocs++;
 
-               c->cmdindex = -1;
+       c->cmdindex = i;
 
-               c->err_info = (ErrorInfo_struct *)
-                   pci_alloc_consistent(h->pdev, sizeof(ErrorInfo_struct),
-                           &err_dma_handle);
+       INIT_HLIST_NODE(&c->list);
+       c->busaddr = (__u32) cmd_dma_handle;
+       temp64.val = (__u64) err_dma_handle;
+       c->ErrDesc.Addr.lower = temp64.val32.lower;
+       c->ErrDesc.Addr.upper = temp64.val32.upper;
+       c->ErrDesc.Len = sizeof(ErrorInfo_struct);
 
-               if (c->err_info == NULL) {
-                       pci_free_consistent(h->pdev,
-                               sizeof(CommandList_struct), c, cmd_dma_handle);
-                       return NULL;
-               }
-               memset(c->err_info, 0, sizeof(ErrorInfo_struct));
-       } else {                /* get it out of the controllers pool */
-
-               do {
-                       i = find_first_zero_bit(h->cmd_pool_bits, h->nr_cmds);
-                       if (i == h->nr_cmds)
-                               return NULL;
-               } while (test_and_set_bit
-                        (i & (BITS_PER_LONG - 1),
-                         h->cmd_pool_bits + (i / BITS_PER_LONG)) != 0);
-#ifdef CCISS_DEBUG
-               printk(KERN_DEBUG "cciss: using command buffer %d\n", i);
-#endif
-               c = h->cmd_pool + i;
-               memset(c, 0, sizeof(CommandList_struct));
-               cmd_dma_handle = h->cmd_pool_dhandle
-                   + i * sizeof(CommandList_struct);
-               c->err_info = h->errinfo_pool + i;
-               memset(c->err_info, 0, sizeof(ErrorInfo_struct));
-               err_dma_handle = h->errinfo_pool_dhandle
-                   + i * sizeof(ErrorInfo_struct);
-               h->nr_allocs++;
+       c->ctlr = h->ctlr;
+       return c;
+}
+
+/* allocate a command using pci_alloc_consistent, used for ioctls,
+ * etc., not for the main i/o path.
+ */
+static CommandList_struct *cmd_special_alloc(ctlr_info_t *h)
+{
+       CommandList_struct *c;
+       u64bit temp64;
+       dma_addr_t cmd_dma_handle, err_dma_handle;
+
+       c = (CommandList_struct *) pci_alloc_consistent(h->pdev,
+               sizeof(CommandList_struct), &cmd_dma_handle);
+       if (c == NULL)
+               return NULL;
+       memset(c, 0, sizeof(CommandList_struct));
 
-               c->cmdindex = i;
+       c->cmdindex = -1;
+
+       c->err_info = (ErrorInfo_struct *)
+           pci_alloc_consistent(h->pdev, sizeof(ErrorInfo_struct),
+                   &err_dma_handle);
+
+       if (c->err_info == NULL) {
+               pci_free_consistent(h->pdev,
+                       sizeof(CommandList_struct), c, cmd_dma_handle);
+               return NULL;
        }
+       memset(c->err_info, 0, sizeof(ErrorInfo_struct));
 
        INIT_HLIST_NODE(&c->list);
        c->busaddr = (__u32) cmd_dma_handle;
@@ -968,27 +983,26 @@ static CommandList_struct *cmd_alloc(ctlr_info_t *h, int get_from_pool)
        return c;
 }
 
-/*
- * Frees a command block that was previously allocated with cmd_alloc().
- */
-static void cmd_free(ctlr_info_t *h, CommandList_struct *c, int got_from_pool)
+static void cmd_free(ctlr_info_t *h, CommandList_struct *c)
 {
        int i;
+
+       i = c - h->cmd_pool;
+       clear_bit(i & (BITS_PER_LONG - 1),
+                 h->cmd_pool_bits + (i / BITS_PER_LONG));
+       h->nr_frees++;
+}
+
+static void cmd_special_free(ctlr_info_t *h, CommandList_struct *c)
+{
        u64bit temp64;
 
-       if (!got_from_pool) {
-               temp64.val32.lower = c->ErrDesc.Addr.lower;
-               temp64.val32.upper = c->ErrDesc.Addr.upper;
-               pci_free_consistent(h->pdev, sizeof(ErrorInfo_struct),
-                                   c->err_info, (dma_addr_t) temp64.val);
-               pci_free_consistent(h->pdev, sizeof(CommandList_struct),
-                                   c, (dma_addr_t) c->busaddr);
-       } else {
-               i = c - h->cmd_pool;
-               clear_bit(i & (BITS_PER_LONG - 1),
-                         h->cmd_pool_bits + (i / BITS_PER_LONG));
-               h->nr_frees++;
-       }
+       temp64.val32.lower = c->ErrDesc.Addr.lower;
+       temp64.val32.upper = c->ErrDesc.Addr.upper;
+       pci_free_consistent(h->pdev, sizeof(ErrorInfo_struct),
+                           c->err_info, (dma_addr_t) temp64.val);
+       pci_free_consistent(h->pdev, sizeof(CommandList_struct),
+                           c, (dma_addr_t) c->busaddr);
 }
 
 static inline ctlr_info_t *get_host(struct gendisk *disk)
@@ -1006,13 +1020,10 @@ static inline drive_info_struct *get_drv(struct gendisk *disk)
  */
 static int cciss_open(struct block_device *bdev, fmode_t mode)
 {
-       ctlr_info_t *host = get_host(bdev->bd_disk);
+       ctlr_info_t *h = get_host(bdev->bd_disk);
        drive_info_struct *drv = get_drv(bdev->bd_disk);
 
-#ifdef CCISS_DEBUG
-       printk(KERN_DEBUG "cciss_open %s\n", bdev->bd_disk->disk_name);
-#endif                         /* CCISS_DEBUG */
-
+       dev_dbg(&h->pdev->dev, "cciss_open %s\n", bdev->bd_disk->disk_name);
        if (drv->busy_configuring)
                return -EBUSY;
        /*
@@ -1038,7 +1049,7 @@ static int cciss_open(struct block_device *bdev, fmode_t mode)
                        return -EPERM;
        }
        drv->usage_count++;
-       host->usage_count++;
+       h->usage_count++;
        return 0;
 }
 
@@ -1058,19 +1069,15 @@ static int cciss_unlocked_open(struct block_device *bdev, fmode_t mode)
  */
 static int cciss_release(struct gendisk *disk, fmode_t mode)
 {
-       ctlr_info_t *host;
+       ctlr_info_t *h;
        drive_info_struct *drv;
 
        lock_kernel();
-       host = get_host(disk);
+       h = get_host(disk);
        drv = get_drv(disk);
-
-#ifdef CCISS_DEBUG
-       printk(KERN_DEBUG "cciss_release %s\n", disk->disk_name);
-#endif                         /* CCISS_DEBUG */
-
+       dev_dbg(&h->pdev->dev, "cciss_release %s\n", disk->disk_name);
        drv->usage_count--;
-       host->usage_count--;
+       h->usage_count--;
        unlock_kernel();
        return 0;
 }
@@ -1217,178 +1224,171 @@ static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo)
        return 0;
 }
 
-static void check_ioctl_unit_attention(ctlr_info_t *host, CommandList_struct *c)
+static void check_ioctl_unit_attention(ctlr_info_t *h, CommandList_struct *c)
 {
        if (c->err_info->CommandStatus == CMD_TARGET_STATUS &&
                        c->err_info->ScsiStatus != SAM_STAT_CHECK_CONDITION)
-               (void)check_for_unit_attention(host, c);
+               (void)check_for_unit_attention(h, c);
 }
-/*
- * ioctl
- */
-static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
-                      unsigned int cmd, unsigned long arg)
+
+static int cciss_getpciinfo(ctlr_info_t *h, void __user *argp)
 {
-       struct gendisk *disk = bdev->bd_disk;
-       ctlr_info_t *host = get_host(disk);
-       drive_info_struct *drv = get_drv(disk);
-       int ctlr = host->ctlr;
-       void __user *argp = (void __user *)arg;
+       cciss_pci_info_struct pciinfo;
 
-#ifdef CCISS_DEBUG
-       printk(KERN_DEBUG "cciss_ioctl: Called with cmd=%x %lx\n", cmd, arg);
-#endif                         /* CCISS_DEBUG */
+       if (!argp)
+               return -EINVAL;
+       pciinfo.domain = pci_domain_nr(h->pdev->bus);
+       pciinfo.bus = h->pdev->bus->number;
+       pciinfo.dev_fn = h->pdev->devfn;
+       pciinfo.board_id = h->board_id;
+       if (copy_to_user(argp, &pciinfo, sizeof(cciss_pci_info_struct)))
+               return -EFAULT;
+       return 0;
+}
 
-       switch (cmd) {
-       case CCISS_GETPCIINFO:
-               {
-                       cciss_pci_info_struct pciinfo;
+static int cciss_getintinfo(ctlr_info_t *h, void __user *argp)
+{
+       cciss_coalint_struct intinfo;
 
-                       if (!arg)
-                               return -EINVAL;
-                       pciinfo.domain = pci_domain_nr(host->pdev->bus);
-                       pciinfo.bus = host->pdev->bus->number;
-                       pciinfo.dev_fn = host->pdev->devfn;
-                       pciinfo.board_id = host->board_id;
-                       if (copy_to_user
-                           (argp, &pciinfo, sizeof(cciss_pci_info_struct)))
-                               return -EFAULT;
-                       return 0;
-               }
-       case CCISS_GETINTINFO:
-               {
-                       cciss_coalint_struct intinfo;
-                       if (!arg)
-                               return -EINVAL;
-                       intinfo.delay =
-                           readl(&host->cfgtable->HostWrite.CoalIntDelay);
-                       intinfo.count =
-                           readl(&host->cfgtable->HostWrite.CoalIntCount);
-                       if (copy_to_user
-                           (argp, &intinfo, sizeof(cciss_coalint_struct)))
-                               return -EFAULT;
-                       return 0;
-               }
-       case CCISS_SETINTINFO:
-               {
-                       cciss_coalint_struct intinfo;
-                       unsigned long flags;
-                       int i;
+       if (!argp)
+               return -EINVAL;
+       intinfo.delay = readl(&h->cfgtable->HostWrite.CoalIntDelay);
+       intinfo.count = readl(&h->cfgtable->HostWrite.CoalIntCount);
+       if (copy_to_user
+           (argp, &intinfo, sizeof(cciss_coalint_struct)))
+               return -EFAULT;
+       return 0;
+}
 
-                       if (!arg)
-                               return -EINVAL;
-                       if (!capable(CAP_SYS_ADMIN))
-                               return -EPERM;
-                       if (copy_from_user
-                           (&intinfo, argp, sizeof(cciss_coalint_struct)))
-                               return -EFAULT;
-                       if ((intinfo.delay == 0) && (intinfo.count == 0))
-                       {
-//                      printk("cciss_ioctl: delay and count cannot be 0\n");
-                               return -EINVAL;
-                       }
-                       spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
-                       /* Update the field, and then ring the doorbell */
-                       writel(intinfo.delay,
-                              &(host->cfgtable->HostWrite.CoalIntDelay));
-                       writel(intinfo.count,
-                              &(host->cfgtable->HostWrite.CoalIntCount));
-                       writel(CFGTBL_ChangeReq, host->vaddr + SA5_DOORBELL);
-
-                       for (i = 0; i < MAX_IOCTL_CONFIG_WAIT; i++) {
-                               if (!(readl(host->vaddr + SA5_DOORBELL)
-                                     & CFGTBL_ChangeReq))
-                                       break;
-                               /* delay and try again */
-                               udelay(1000);
-                       }
-                       spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
-                       if (i >= MAX_IOCTL_CONFIG_WAIT)
-                               return -EAGAIN;
-                       return 0;
-               }
-       case CCISS_GETNODENAME:
-               {
-                       NodeName_type NodeName;
-                       int i;
+static int cciss_setintinfo(ctlr_info_t *h, void __user *argp)
+{
+       cciss_coalint_struct intinfo;
+       unsigned long flags;
+       int i;
 
-                       if (!arg)
-                               return -EINVAL;
-                       for (i = 0; i < 16; i++)
-                               NodeName[i] =
-                                   readb(&host->cfgtable->ServerName[i]);
-                       if (copy_to_user(argp, NodeName, sizeof(NodeName_type)))
-                               return -EFAULT;
-                       return 0;
-               }
-       case CCISS_SETNODENAME:
-               {
-                       NodeName_type NodeName;
-                       unsigned long flags;
-                       int i;
+       if (!argp)
+               return -EINVAL;
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+       if (copy_from_user(&intinfo, argp, sizeof(intinfo)))
+               return -EFAULT;
+       if ((intinfo.delay == 0) && (intinfo.count == 0))
+               return -EINVAL;
+       spin_lock_irqsave(&h->lock, flags);
+       /* Update the field, and then ring the doorbell */
+       writel(intinfo.delay, &(h->cfgtable->HostWrite.CoalIntDelay));
+       writel(intinfo.count, &(h->cfgtable->HostWrite.CoalIntCount));
+       writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);
 
-                       if (!arg)
-                               return -EINVAL;
-                       if (!capable(CAP_SYS_ADMIN))
-                               return -EPERM;
+       for (i = 0; i < MAX_IOCTL_CONFIG_WAIT; i++) {
+               if (!(readl(h->vaddr + SA5_DOORBELL) & CFGTBL_ChangeReq))
+                       break;
+               udelay(1000); /* delay and try again */
+       }
+       spin_unlock_irqrestore(&h->lock, flags);
+       if (i >= MAX_IOCTL_CONFIG_WAIT)
+               return -EAGAIN;
+       return 0;
+}
 
-                       if (copy_from_user
-                           (NodeName, argp, sizeof(NodeName_type)))
-                               return -EFAULT;
+static int cciss_getnodename(ctlr_info_t *h, void __user *argp)
+{
+       NodeName_type NodeName;
+       int i;
 
-                       spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
+       if (!argp)
+               return -EINVAL;
+       for (i = 0; i < 16; i++)
+               NodeName[i] = readb(&h->cfgtable->ServerName[i]);
+       if (copy_to_user(argp, NodeName, sizeof(NodeName_type)))
+               return -EFAULT;
+       return 0;
+}
 
-                       /* Update the field, and then ring the doorbell */
-                       for (i = 0; i < 16; i++)
-                               writeb(NodeName[i],
-                                      &host->cfgtable->ServerName[i]);
+static int cciss_setnodename(ctlr_info_t *h, void __user *argp)
+{
+       NodeName_type NodeName;
+       unsigned long flags;
+       int i;
 
-                       writel(CFGTBL_ChangeReq, host->vaddr + SA5_DOORBELL);
+       if (!argp)
+               return -EINVAL;
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+       if (copy_from_user(NodeName, argp, sizeof(NodeName_type)))
+               return -EFAULT;
+       spin_lock_irqsave(&h->lock, flags);
+       /* Update the field, and then ring the doorbell */
+       for (i = 0; i < 16; i++)
+               writeb(NodeName[i], &h->cfgtable->ServerName[i]);
+       writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);
+       for (i = 0; i < MAX_IOCTL_CONFIG_WAIT; i++) {
+               if (!(readl(h->vaddr + SA5_DOORBELL) & CFGTBL_ChangeReq))
+                       break;
+               udelay(1000); /* delay and try again */
+       }
+       spin_unlock_irqrestore(&h->lock, flags);
+       if (i >= MAX_IOCTL_CONFIG_WAIT)
+               return -EAGAIN;
+       return 0;
+}
 
-                       for (i = 0; i < MAX_IOCTL_CONFIG_WAIT; i++) {
-                               if (!(readl(host->vaddr + SA5_DOORBELL)
-                                     & CFGTBL_ChangeReq))
-                                       break;
-                               /* delay and try again */
-                               udelay(1000);
-                       }
-                       spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
-                       if (i >= MAX_IOCTL_CONFIG_WAIT)
-                               return -EAGAIN;
-                       return 0;
-               }
+static int cciss_getheartbeat(ctlr_info_t *h, void __user *argp)
+{
+       Heartbeat_type heartbeat;
 
-       case CCISS_GETHEARTBEAT:
-               {
-                       Heartbeat_type heartbeat;
+       if (!argp)
+               return -EINVAL;
+       heartbeat = readl(&h->cfgtable->HeartBeat);
+       if (copy_to_user(argp, &heartbeat, sizeof(Heartbeat_type)))
+               return -EFAULT;
+       return 0;
+}
 
-                       if (!arg)
-                               return -EINVAL;
-                       heartbeat = readl(&host->cfgtable->HeartBeat);
-                       if (copy_to_user
-                           (argp, &heartbeat, sizeof(Heartbeat_type)))
-                               return -EFAULT;
-                       return 0;
-               }
-       case CCISS_GETBUSTYPES:
-               {
-                       BusTypes_type BusTypes;
+static int cciss_getbustypes(ctlr_info_t *h, void __user *argp)
+{
+       BusTypes_type BusTypes;
 
-                       if (!arg)
-                               return -EINVAL;
-                       BusTypes = readl(&host->cfgtable->BusTypes);
-                       if (copy_to_user
-                           (argp, &BusTypes, sizeof(BusTypes_type)))
-                               return -EFAULT;
-                       return 0;
-               }
+       if (!argp)
+               return -EINVAL;
+       BusTypes = readl(&h->cfgtable->BusTypes);
+       if (copy_to_user(argp, &BusTypes, sizeof(BusTypes_type)))
+               return -EFAULT;
+       return 0;
+}
+
+static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
+                      unsigned int cmd, unsigned long arg)
+{
+       struct gendisk *disk = bdev->bd_disk;
+       ctlr_info_t *h = get_host(disk);
+       drive_info_struct *drv = get_drv(disk);
+       void __user *argp = (void __user *)arg;
+
+       dev_dbg(&h->pdev->dev, "cciss_ioctl: Called with cmd=%x %lx\n",
+               cmd, arg);
+       switch (cmd) {
+       case CCISS_GETPCIINFO:
+               return cciss_getpciinfo(h, argp);
+       case CCISS_GETINTINFO:
+               return cciss_getintinfo(h, argp);
+       case CCISS_SETINTINFO:
+               return cciss_setintinfo(h, argp);
+       case CCISS_GETNODENAME:
+               return cciss_getnodename(h, argp);
+       case CCISS_SETNODENAME:
+               return cciss_setnodename(h, argp);
+       case CCISS_GETHEARTBEAT:
+               return cciss_getheartbeat(h, argp);
+       case CCISS_GETBUSTYPES:
+               return cciss_getbustypes(h, argp);
        case CCISS_GETFIRMVER:
                {
                        FirmwareVer_type firmware;
 
                        if (!arg)
                                return -EINVAL;
-                       memcpy(firmware, host->firm_ver, 4);
+                       memcpy(firmware, h->firm_ver, 4);
 
                        if (copy_to_user
                            (argp, firmware, sizeof(FirmwareVer_type)))
@@ -1411,7 +1411,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
        case CCISS_DEREGDISK:
        case CCISS_REGNEWD:
        case CCISS_REVALIDVOLS:
-               return rebuild_lun_table(host, 0, 1);
+               return rebuild_lun_table(h, 0, 1);
 
        case CCISS_GETLUNINFO:{
                        LogvolInfo_struct luninfo;
@@ -1466,7 +1466,8 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
                        } else {
                                memset(buff, 0, iocommand.buf_size);
                        }
-                       if ((c = cmd_alloc(host, 0)) == NULL) {
+                       c = cmd_special_alloc(h);
+                       if (!c) {
                                kfree(buff);
                                return -ENOMEM;
                        }
@@ -1492,7 +1493,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
 
                        /* Fill in the scatter gather information */
                        if (iocommand.buf_size > 0) {
-                               temp64.val = pci_map_single(host->pdev, buff,
+                               temp64.val = pci_map_single(h->pdev, buff,
                                        iocommand.buf_size,
                                        PCI_DMA_BIDIRECTIONAL);
                                c->SG[0].Addr.lower = temp64.val32.lower;
@@ -1502,24 +1503,24 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
                        }
                        c->waiting = &wait;
 
-                       enqueue_cmd_and_start_io(host, c);
+                       enqueue_cmd_and_start_io(h, c);
                        wait_for_completion(&wait);
 
                        /* unlock the buffers from DMA */
                        temp64.val32.lower = c->SG[0].Addr.lower;
                        temp64.val32.upper = c->SG[0].Addr.upper;
-                       pci_unmap_single(host->pdev, (dma_addr_t) temp64.val,
+                       pci_unmap_single(h->pdev, (dma_addr_t) temp64.val,
                                         iocommand.buf_size,
                                         PCI_DMA_BIDIRECTIONAL);
 
-                       check_ioctl_unit_attention(host, c);
+                       check_ioctl_unit_attention(h, c);
 
                        /* Copy the error information out */
                        iocommand.error_info = *(c->err_info);
                        if (copy_to_user
                            (argp, &iocommand, sizeof(IOCTL_Command_struct))) {
                                kfree(buff);
-                               cmd_free(host, c, 0);
+                               cmd_special_free(h, c);
                                return -EFAULT;
                        }
 
@@ -1528,12 +1529,12 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
                                if (copy_to_user
                                    (iocommand.buf, buff, iocommand.buf_size)) {
                                        kfree(buff);
-                                       cmd_free(host, c, 0);
+                                       cmd_special_free(h, c);
                                        return -EFAULT;
                                }
                        }
                        kfree(buff);
-                       cmd_free(host, c, 0);
+                       cmd_special_free(h, c);
                        return 0;
                }
        case CCISS_BIG_PASSTHRU:{
@@ -1615,7 +1616,8 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
                                data_ptr += sz;
                                sg_used++;
                        }
-                       if ((c = cmd_alloc(host, 0)) == NULL) {
+                       c = cmd_special_alloc(h);
+                       if (!c) {
                                status = -ENOMEM;
                                goto cleanup1;
                        }
@@ -1636,7 +1638,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
                        if (ioc->buf_size > 0) {
                                for (i = 0; i < sg_used; i++) {
                                        temp64.val =
-                                           pci_map_single(host->pdev, buff[i],
+                                           pci_map_single(h->pdev, buff[i],
                                                    buff_size[i],
                                                    PCI_DMA_BIDIRECTIONAL);
                                        c->SG[i].Addr.lower =
@@ -1648,21 +1650,21 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
                                }
                        }
                        c->waiting = &wait;
-                       enqueue_cmd_and_start_io(host, c);
+                       enqueue_cmd_and_start_io(h, c);
                        wait_for_completion(&wait);
                        /* unlock the buffers from DMA */
                        for (i = 0; i < sg_used; i++) {
                                temp64.val32.lower = c->SG[i].Addr.lower;
                                temp64.val32.upper = c->SG[i].Addr.upper;
-                               pci_unmap_single(host->pdev,
+                               pci_unmap_single(h->pdev,
                                        (dma_addr_t) temp64.val, buff_size[i],
                                        PCI_DMA_BIDIRECTIONAL);
                        }
-                       check_ioctl_unit_attention(host, c);
+                       check_ioctl_unit_attention(h, c);
                        /* Copy the error information out */
                        ioc->error_info = *(c->err_info);
                        if (copy_to_user(argp, ioc, sizeof(*ioc))) {
-                               cmd_free(host, c, 0);
+                               cmd_special_free(h, c);
                                status = -EFAULT;
                                goto cleanup1;
                        }
@@ -1672,14 +1674,14 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
                                for (i = 0; i < sg_used; i++) {
                                        if (copy_to_user
                                            (ptr, buff[i], buff_size[i])) {
-                                               cmd_free(host, c, 0);
+                                               cmd_special_free(h, c);
                                                status = -EFAULT;
                                                goto cleanup1;
                                        }
                                        ptr += buff_size[i];
                                }
                        }
-                       cmd_free(host, c, 0);
+                       cmd_special_free(h, c);
                        status = 0;
                      cleanup1:
                        if (buff) {
@@ -1767,26 +1769,26 @@ static void cciss_check_queues(ctlr_info_t *h)
 
 static void cciss_softirq_done(struct request *rq)
 {
-       CommandList_struct *cmd = rq->completion_data;
-       ctlr_info_t *h = hba[cmd->ctlr];
-       SGDescriptor_struct *curr_sg = cmd->SG;
+       CommandList_struct *c = rq->completion_data;
+       ctlr_info_t *h = hba[c->ctlr];
+       SGDescriptor_struct *curr_sg = c->SG;
        u64bit temp64;
        unsigned long flags;
        int i, ddir;
        int sg_index = 0;
 
-       if (cmd->Request.Type.Direction == XFER_READ)
+       if (c->Request.Type.Direction == XFER_READ)
                ddir = PCI_DMA_FROMDEVICE;
        else
                ddir = PCI_DMA_TODEVICE;
 
        /* command did not need to be retried */
        /* unmap the DMA mapping for all the scatter gather elements */
-       for (i = 0; i < cmd->Header.SGList; i++) {
+       for (i = 0; i < c->Header.SGList; i++) {
                if (curr_sg[sg_index].Ext == CCISS_SG_CHAIN) {
-                       cciss_unmap_sg_chain_block(h, cmd);
+                       cciss_unmap_sg_chain_block(h, c);
                        /* Point to the next block */
-                       curr_sg = h->cmd_sg_list[cmd->cmdindex];
+                       curr_sg = h->cmd_sg_list[c->cmdindex];
                        sg_index = 0;
                }
                temp64.val32.lower = curr_sg[sg_index].Addr.lower;
@@ -1796,18 +1798,16 @@ static void cciss_softirq_done(struct request *rq)
                ++sg_index;
        }
 
-#ifdef CCISS_DEBUG
-       printk("Done with %p\n", rq);
-#endif                         /* CCISS_DEBUG */
+       dev_dbg(&h->pdev->dev, "Done with %p\n", rq);
 
        /* set the residual count for pc requests */
        if (rq->cmd_type == REQ_TYPE_BLOCK_PC)
-               rq->resid_len = cmd->err_info->ResidualCnt;
+               rq->resid_len = c->err_info->ResidualCnt;
 
        blk_end_request_all(rq, (rq->errors == 0) ? 0 : -EIO);
 
        spin_lock_irqsave(&h->lock, flags);
-       cmd_free(h, cmd, 1);
+       cmd_free(h, c);
        cciss_check_queues(h);
        spin_unlock_irqrestore(&h->lock, flags);
 }
@@ -1823,7 +1823,7 @@ static inline void log_unit_to_scsi3addr(ctlr_info_t *h,
  * via the inquiry page 0.  Model, vendor, and rev are set to empty strings if
  * they cannot be read.
  */
-static void cciss_get_device_descr(int ctlr, int logvol,
+static void cciss_get_device_descr(ctlr_info_t *h, int logvol,
                                   char *vendor, char *model, char *rev)
 {
        int rc;
@@ -1838,8 +1838,8 @@ static void cciss_get_device_descr(int ctlr, int logvol,
        if (!inq_buf)
                return;
 
-       log_unit_to_scsi3addr(hba[ctlr], scsi3addr, logvol);
-       rc = sendcmd_withirq(CISS_INQUIRY, ctlr, inq_buf, sizeof(*inq_buf), 0,
+       log_unit_to_scsi3addr(h, scsi3addr, logvol);
+       rc = sendcmd_withirq(h, CISS_INQUIRY, inq_buf, sizeof(*inq_buf), 0,
                        scsi3addr, TYPE_CMD);
        if (rc == IO_OK) {
                memcpy(vendor, &inq_buf->data_byte[8], VENDOR_LEN);
@@ -1859,7 +1859,7 @@ static void cciss_get_device_descr(int ctlr, int logvol,
  * number cannot be had, for whatever reason, 16 bytes of 0xff
  * are returned instead.
  */
-static void cciss_get_serial_no(int ctlr, int logvol,
+static void cciss_get_serial_no(ctlr_info_t *h, int logvol,
                                unsigned char *serial_no, int buflen)
 {
 #define PAGE_83_INQ_BYTES 64
@@ -1874,8 +1874,8 @@ static void cciss_get_serial_no(int ctlr, int logvol,
        if (!buf)
                return;
        memset(serial_no, 0, buflen);
-       log_unit_to_scsi3addr(hba[ctlr], scsi3addr, logvol);
-       rc = sendcmd_withirq(CISS_INQUIRY, ctlr, buf,
+       log_unit_to_scsi3addr(h, scsi3addr, logvol);
+       rc = sendcmd_withirq(h, CISS_INQUIRY, buf,
                PAGE_83_INQ_BYTES, 0x83, scsi3addr, TYPE_CMD);
        if (rc == IO_OK)
                memcpy(serial_no, &buf[8], buflen);
@@ -1941,10 +1941,9 @@ init_queue_failure:
  * is also the controller node.  Any changes to disk 0 will show up on
  * the next reboot.
  */
-static void cciss_update_drive_info(int ctlr, int drv_index, int first_time,
-       int via_ioctl)
+static void cciss_update_drive_info(ctlr_info_t *h, int drv_index,
+       int first_time, int via_ioctl)
 {
-       ctlr_info_t *h = hba[ctlr];
        struct gendisk *disk;
        InquiryData_struct *inq_buff = NULL;
        unsigned int block_size;
@@ -1961,16 +1960,16 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time,
 
        /* testing to see if 16-byte CDBs are already being used */
        if (h->cciss_read == CCISS_READ_16) {
-               cciss_read_capacity_16(h->ctlr, drv_index,
+               cciss_read_capacity_16(h, drv_index,
                        &total_size, &block_size);
 
        } else {
-               cciss_read_capacity(ctlr, drv_index, &total_size, &block_size);
+               cciss_read_capacity(h, drv_index, &total_size, &block_size);
                /* if read_capacity returns all F's this volume is >2TB */
                /* in size so we switch to 16-byte CDB's for all */
                /* read/write ops */
                if (total_size == 0xFFFFFFFFULL) {
-                       cciss_read_capacity_16(ctlr, drv_index,
+                       cciss_read_capacity_16(h, drv_index,
                        &total_size, &block_size);
                        h->cciss_read = CCISS_READ_16;
                        h->cciss_write = CCISS_WRITE_16;
@@ -1980,14 +1979,14 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time,
                }
        }
 
-       cciss_geometry_inquiry(ctlr, drv_index, total_size, block_size,
+       cciss_geometry_inquiry(h, drv_index, total_size, block_size,
                               inq_buff, drvinfo);
        drvinfo->block_size = block_size;
        drvinfo->nr_blocks = total_size + 1;
 
-       cciss_get_device_descr(ctlr, drv_index, drvinfo->vendor,
+       cciss_get_device_descr(h, drv_index, drvinfo->vendor,
                                drvinfo->model, drvinfo->rev);
-       cciss_get_serial_no(ctlr, drv_index, drvinfo->serial_no,
+       cciss_get_serial_no(h, drv_index, drvinfo->serial_no,
                        sizeof(drvinfo->serial_no));
        /* Save the lunid in case we deregister the disk, below. */
        memcpy(drvinfo->LunID, h->drv[drv_index]->LunID,
@@ -2012,10 +2011,10 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time,
         * (unless it's the first disk (for the controller node).
         */
        if (h->drv[drv_index]->raid_level != -1 && drv_index != 0) {
-               printk(KERN_WARNING "disk %d has changed.\n", drv_index);
-               spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
+               dev_warn(&h->pdev->dev, "disk %d has changed.\n", drv_index);
+               spin_lock_irqsave(&h->lock, flags);
                h->drv[drv_index]->busy_configuring = 1;
-               spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+               spin_unlock_irqrestore(&h->lock, flags);
 
                /* deregister_disk sets h->drv[drv_index]->queue = NULL
                 * which keeps the interrupt handler from starting
@@ -2065,8 +2064,8 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time,
                if (cciss_add_disk(h, disk, drv_index) != 0) {
                        cciss_free_gendisk(h, drv_index);
                        cciss_free_drive_info(h, drv_index);
-                       printk(KERN_WARNING "cciss:%d could not update "
-                               "disk %d\n", h->ctlr, drv_index);
+                       dev_warn(&h->pdev->dev, "could not update disk %d\n",
+                               drv_index);
                        --h->num_luns;
                }
        }
@@ -2076,7 +2075,7 @@ freeret:
        kfree(drvinfo);
        return;
 mem_msg:
-       printk(KERN_ERR "cciss: out of memory\n");
+       dev_err(&h->pdev->dev, "out of memory\n");
        goto freeret;
 }
 
@@ -2168,9 +2167,9 @@ static int cciss_add_gendisk(ctlr_info_t *h, unsigned char lunid[],
                h->gendisk[drv_index] =
                        alloc_disk(1 << NWD_SHIFT);
                if (!h->gendisk[drv_index]) {
-                       printk(KERN_ERR "cciss%d: could not "
-                               "allocate a new disk %d\n",
-                               h->ctlr, drv_index);
+                       dev_err(&h->pdev->dev,
+                               "could not allocate a new disk %d\n",
+                               drv_index);
                        goto err_free_drive_info;
                }
        }
@@ -2221,8 +2220,7 @@ static void cciss_add_controller_node(ctlr_info_t *h)
        cciss_free_gendisk(h, drv_index);
        cciss_free_drive_info(h, drv_index);
 error:
-       printk(KERN_WARNING "cciss%d: could not "
-               "add disk 0.\n", h->ctlr);
+       dev_warn(&h->pdev->dev, "could not add disk 0.\n");
        return;
 }
 
@@ -2237,7 +2235,6 @@ error:
 static int rebuild_lun_table(ctlr_info_t *h, int first_time,
        int via_ioctl)
 {
-       int ctlr = h->ctlr;
        int num_luns;
        ReportLunData_struct *ld_buff = NULL;
        int return_code;
@@ -2252,27 +2249,27 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time,
                return -EPERM;
 
        /* Set busy_configuring flag for this operation */
-       spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
+       spin_lock_irqsave(&h->lock, flags);
        if (h->busy_configuring) {
-               spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+               spin_unlock_irqrestore(&h->lock, flags);
                return -EBUSY;
        }
        h->busy_configuring = 1;
-       spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+       spin_unlock_irqrestore(&h->lock, flags);
 
        ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL);
        if (ld_buff == NULL)
                goto mem_msg;
 
-       return_code = sendcmd_withirq(CISS_REPORT_LOG, ctlr, ld_buff,
+       return_code = sendcmd_withirq(h, CISS_REPORT_LOG, ld_buff,
                                      sizeof(ReportLunData_struct),
                                      0, CTLR_LUNID, TYPE_CMD);
 
        if (return_code == IO_OK)
                listlength = be32_to_cpu(*(__be32 *) ld_buff->LUNListLength);
        else {  /* reading number of logical volumes failed */
-               printk(KERN_WARNING "cciss: report logical volume"
-                      " command failed\n");
+               dev_warn(&h->pdev->dev,
+                       "report logical volume command failed\n");
                listlength = 0;
                goto freeret;
        }
@@ -2280,7 +2277,7 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time,
        num_luns = listlength / 8;      /* 8 bytes per entry */
        if (num_luns > CISS_MAX_LUN) {
                num_luns = CISS_MAX_LUN;
-               printk(KERN_WARNING "cciss: more luns configured"
+               dev_warn(&h->pdev->dev, "more luns configured"
                       " on controller than can be handled by"
                       " this driver.\n");
        }
@@ -2311,9 +2308,9 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time,
                }
                if (!drv_found) {
                        /* Deregister it from the OS, it's gone. */
-                       spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
+                       spin_lock_irqsave(&h->lock, flags);
                        h->drv[i]->busy_configuring = 1;
-                       spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+                       spin_unlock_irqrestore(&h->lock, flags);
                        return_code = deregister_disk(h, i, 1, via_ioctl);
                        if (h->drv[i] != NULL)
                                h->drv[i]->busy_configuring = 0;
@@ -2352,8 +2349,7 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time,
                        if (drv_index == -1)
                                goto freeret;
                }
-               cciss_update_drive_info(ctlr, drv_index, first_time,
-                       via_ioctl);
+               cciss_update_drive_info(h, drv_index, first_time, via_ioctl);
        }               /* end for */
 
 freeret:
@@ -2365,7 +2361,7 @@ freeret:
         */
        return -1;
 mem_msg:
-       printk(KERN_ERR "cciss: out of memory\n");
+       dev_err(&h->pdev->dev, "out of memory\n");
        h->busy_configuring = 0;
        goto freeret;
 }
@@ -2485,11 +2481,10 @@ static int deregister_disk(ctlr_info_t *h, int drv_index,
        return 0;
 }
 
-static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff,
+static int fill_cmd(ctlr_info_t *h, CommandList_struct *c, __u8 cmd, void *buff,
                size_t size, __u8 page_code, unsigned char *scsi3addr,
                int cmd_type)
 {
-       ctlr_info_t *h = hba[ctlr];
        u64bit buff_dma_handle;
        int status = IO_OK;
 
@@ -2573,8 +2568,7 @@ static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff,
                        c->Request.Timeout = 0;
                        break;
                default:
-                       printk(KERN_WARNING
-                              "cciss%d:  Unknown Command 0x%c\n", ctlr, cmd);
+                       dev_warn(&h->pdev->dev, "Unknown Command 0x%c\n", cmd);
                        return IO_ERROR;
                }
        } else if (cmd_type == TYPE_MSG) {
@@ -2606,13 +2600,12 @@ static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff,
                        c->Request.CDB[0] = cmd;
                        break;
                default:
-                       printk(KERN_WARNING
-                              "cciss%d: unknown message type %d\n", ctlr, cmd);
+                       dev_warn(&h->pdev->dev,
+                               "unknown message type %d\n", cmd);
                        return IO_ERROR;
                }
        } else {
-               printk(KERN_WARNING
-                      "cciss%d: unknown command type %d\n", ctlr, cmd_type);
+               dev_warn(&h->pdev->dev, "unknown command type %d\n", cmd_type);
                return IO_ERROR;
        }
        /* Fill in the scatter gather information */
@@ -2640,15 +2633,14 @@ static int check_target_status(ctlr_info_t *h, CommandList_struct *c)
                default:
                        if (check_for_unit_attention(h, c))
                                return IO_NEEDS_RETRY;
-                       printk(KERN_WARNING "cciss%d: cmd 0x%02x "
+                       dev_warn(&h->pdev->dev, "cmd 0x%02x "
                                "check condition, sense key = 0x%02x\n",
-                               h->ctlr, c->Request.CDB[0],
-                               c->err_info->SenseInfo[2]);
+                               c->Request.CDB[0], c->err_info->SenseInfo[2]);
                }
                break;
        default:
-               printk(KERN_WARNING "cciss%d: cmd 0x%02x"
-                       "scsi status = 0x%02x\n", h->ctlr,
+               dev_warn(&h->pdev->dev, "cmd 0x%02x"
+                       "scsi status = 0x%02x\n",
                        c->Request.CDB[0], c->err_info->ScsiStatus);
                break;
        }
@@ -2671,43 +2663,42 @@ static int process_sendcmd_error(ctlr_info_t *h, CommandList_struct *c)
                /* expected for inquiry and report lun commands */
                break;
        case CMD_INVALID:
-               printk(KERN_WARNING "cciss: cmd 0x%02x is "
+               dev_warn(&h->pdev->dev, "cmd 0x%02x is "
                       "reported invalid\n", c->Request.CDB[0]);
                return_status = IO_ERROR;
                break;
        case CMD_PROTOCOL_ERR:
-               printk(KERN_WARNING "cciss: cmd 0x%02x has "
-                      "protocol error \n", c->Request.CDB[0]);
+               dev_warn(&h->pdev->dev, "cmd 0x%02x has "
+                      "protocol error\n", c->Request.CDB[0]);
                return_status = IO_ERROR;
                break;
        case CMD_HARDWARE_ERR:
-               printk(KERN_WARNING "cciss: cmd 0x%02x had "
+               dev_warn(&h->pdev->dev, "cmd 0x%02x had "
                       " hardware error\n", c->Request.CDB[0]);
                return_status = IO_ERROR;
                break;
        case CMD_CONNECTION_LOST:
-               printk(KERN_WARNING "cciss: cmd 0x%02x had "
+               dev_warn(&h->pdev->dev, "cmd 0x%02x had "
                       "connection lost\n", c->Request.CDB[0]);
                return_status = IO_ERROR;
                break;
        case CMD_ABORTED:
-               printk(KERN_WARNING "cciss: cmd 0x%02x was "
+               dev_warn(&h->pdev->dev, "cmd 0x%02x was "
                       "aborted\n", c->Request.CDB[0]);
                return_status = IO_ERROR;
                break;
        case CMD_ABORT_FAILED:
-               printk(KERN_WARNING "cciss: cmd 0x%02x reports "
+               dev_warn(&h->pdev->dev, "cmd 0x%02x reports "
                       "abort failed\n", c->Request.CDB[0]);
                return_status = IO_ERROR;
                break;
        case CMD_UNSOLICITED_ABORT:
-               printk(KERN_WARNING
-                      "cciss%d: unsolicited abort 0x%02x\n", h->ctlr,
+               dev_warn(&h->pdev->dev, "unsolicited abort 0x%02x\n",
                        c->Request.CDB[0]);
                return_status = IO_NEEDS_RETRY;
                break;
        default:
-               printk(KERN_WARNING "cciss: cmd 0x%02x returned "
+               dev_warn(&h->pdev->dev, "cmd 0x%02x returned "
                       "unknown status %x\n", c->Request.CDB[0],
                       c->err_info->CommandStatus);
                return_status = IO_ERROR;
@@ -2735,7 +2726,7 @@ resend_cmd2:
 
        if (return_status == IO_NEEDS_RETRY &&
                c->retry_count < MAX_CMD_RETRIES) {
-               printk(KERN_WARNING "cciss%d: retrying 0x%02x\n", h->ctlr,
+               dev_warn(&h->pdev->dev, "retrying 0x%02x\n",
                        c->Request.CDB[0]);
                c->retry_count++;
                /* erase the old error information */
@@ -2754,27 +2745,26 @@ command_done:
        return return_status;
 }
 
-static int sendcmd_withirq(__u8 cmd, int ctlr, void *buff, size_t size,
+static int sendcmd_withirq(ctlr_info_t *h, __u8 cmd, void *buff, size_t size,
                           __u8 page_code, unsigned char scsi3addr[],
                        int cmd_type)
 {
-       ctlr_info_t *h = hba[ctlr];
        CommandList_struct *c;
        int return_status;
 
-       c = cmd_alloc(h, 0);
+       c = cmd_special_alloc(h);
        if (!c)
                return -ENOMEM;
-       return_status = fill_cmd(c, cmd, ctlr, buff, size, page_code,
+       return_status = fill_cmd(h, c, cmd, buff, size, page_code,
                scsi3addr, cmd_type);
        if (return_status == IO_OK)
                return_status = sendcmd_withirq_core(h, c, 1);
 
-       cmd_free(h, c, 0);
+       cmd_special_free(h, c);
        return return_status;
 }
 
-static void cciss_geometry_inquiry(int ctlr, int logvol,
+static void cciss_geometry_inquiry(ctlr_info_t *h, int logvol,
                                   sector_t total_size,
                                   unsigned int block_size,
                                   InquiryData_struct *inq_buff,
@@ -2785,13 +2775,13 @@ static void cciss_geometry_inquiry(int ctlr, int logvol,
        unsigned char scsi3addr[8];
 
        memset(inq_buff, 0, sizeof(InquiryData_struct));
-       log_unit_to_scsi3addr(hba[ctlr], scsi3addr, logvol);
-       return_code = sendcmd_withirq(CISS_INQUIRY, ctlr, inq_buff,
+       log_unit_to_scsi3addr(h, scsi3addr, logvol);
+       return_code = sendcmd_withirq(h, CISS_INQUIRY, inq_buff,
                        sizeof(*inq_buff), 0xC1, scsi3addr, TYPE_CMD);
        if (return_code == IO_OK) {
                if (inq_buff->data_byte[8] == 0xFF) {
-                       printk(KERN_WARNING
-                              "cciss: reading geometry failed, volume "
+                       dev_warn(&h->pdev->dev,
+                              "reading geometry failed, volume "
                               "does not support reading geometry\n");
                        drv->heads = 255;
                        drv->sectors = 32;      /* Sectors per track */
@@ -2815,12 +2805,12 @@ static void cciss_geometry_inquiry(int ctlr, int logvol,
                        drv->cylinders = real_size;
                }
        } else {                /* Get geometry failed */
-               printk(KERN_WARNING "cciss: reading geometry failed\n");
+               dev_warn(&h->pdev->dev, "reading geometry failed\n");
        }
 }
 
 static void
-cciss_read_capacity(int ctlr, int logvol, sector_t *total_size,
+cciss_read_capacity(ctlr_info_t *h, int logvol, sector_t *total_size,
                    unsigned int *block_size)
 {
        ReadCapdata_struct *buf;
@@ -2829,25 +2819,25 @@ cciss_read_capacity(int ctlr, int logvol, sector_t *total_size,
 
        buf = kzalloc(sizeof(ReadCapdata_struct), GFP_KERNEL);
        if (!buf) {
-               printk(KERN_WARNING "cciss: out of memory\n");
+               dev_warn(&h->pdev->dev, "out of memory\n");
                return;
        }
 
-       log_unit_to_scsi3addr(hba[ctlr], scsi3addr, logvol);
-       return_code = sendcmd_withirq(CCISS_READ_CAPACITY, ctlr, buf,
+       log_unit_to_scsi3addr(h, scsi3addr, logvol);
+       return_code = sendcmd_withirq(h, CCISS_READ_CAPACITY, buf,
                sizeof(ReadCapdata_struct), 0, scsi3addr, TYPE_CMD);
        if (return_code == IO_OK) {
                *total_size = be32_to_cpu(*(__be32 *) buf->total_size);
                *block_size = be32_to_cpu(*(__be32 *) buf->block_size);
        } else {                /* read capacity command failed */
-               printk(KERN_WARNING "cciss: read capacity failed\n");
+               dev_warn(&h->pdev->dev, "read capacity failed\n");
                *total_size = 0;
                *block_size = BLOCK_SIZE;
        }
        kfree(buf);
 }
 
-static void cciss_read_capacity_16(int ctlr, int logvol,
+static void cciss_read_capacity_16(ctlr_info_t *h, int logvol,
        sector_t *total_size, unsigned int *block_size)
 {
        ReadCapdata_struct_16 *buf;
@@ -2856,23 +2846,23 @@ static void cciss_read_capacity_16(int ctlr, int logvol,
 
        buf = kzalloc(sizeof(ReadCapdata_struct_16), GFP_KERNEL);
        if (!buf) {
-               printk(KERN_WARNING "cciss: out of memory\n");
+               dev_warn(&h->pdev->dev, "out of memory\n");
                return;
        }
 
-       log_unit_to_scsi3addr(hba[ctlr], scsi3addr, logvol);
-       return_code = sendcmd_withirq(CCISS_READ_CAPACITY_16,
-               ctlr, buf, sizeof(ReadCapdata_struct_16),
+       log_unit_to_scsi3addr(h, scsi3addr, logvol);
+       return_code = sendcmd_withirq(h, CCISS_READ_CAPACITY_16,
+               buf, sizeof(ReadCapdata_struct_16),
                        0, scsi3addr, TYPE_CMD);
        if (return_code == IO_OK) {
                *total_size = be64_to_cpu(*(__be64 *) buf->total_size);
                *block_size = be32_to_cpu(*(__be32 *) buf->block_size);
        } else {                /* read capacity command failed */
-               printk(KERN_WARNING "cciss: read capacity failed\n");
+               dev_warn(&h->pdev->dev, "read capacity failed\n");
                *total_size = 0;
                *block_size = BLOCK_SIZE;
        }
-       printk(KERN_INFO "      blocks= %llu block_size= %d\n",
+       dev_info(&h->pdev->dev, "      blocks= %llu block_size= %d\n",
               (unsigned long long)*total_size+1, *block_size);
        kfree(buf);
 }
@@ -2900,17 +2890,17 @@ static int cciss_revalidate(struct gendisk *disk)
 
        inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL);
        if (inq_buff == NULL) {
-               printk(KERN_WARNING "cciss: out of memory\n");
+               dev_warn(&h->pdev->dev, "out of memory\n");
                return 1;
        }
        if (h->cciss_read == CCISS_READ_10) {
-               cciss_read_capacity(h->ctlr, logvol,
+               cciss_read_capacity(h, logvol,
                                        &total_size, &block_size);
        } else {
-               cciss_read_capacity_16(h->ctlr, logvol,
+               cciss_read_capacity_16(h, logvol,
                                        &total_size, &block_size);
        }
-       cciss_geometry_inquiry(h->ctlr, logvol, total_size, block_size,
+       cciss_geometry_inquiry(h, logvol, total_size, block_size,
                               inq_buff, drv);
 
        blk_queue_logical_block_size(drv->queue, drv->block_size);
@@ -2944,7 +2934,7 @@ static void start_io(ctlr_info_t *h)
                c = hlist_entry(h->reqQ.first, CommandList_struct, list);
                /* can't do anything if fifo is full */
                if ((h->access.fifo_full(h))) {
-                       printk(KERN_WARNING "cciss: fifo full\n");
+                       dev_warn(&h->pdev->dev, "fifo full\n");
                        break;
                }
 
@@ -2960,7 +2950,7 @@ static void start_io(ctlr_info_t *h)
        }
 }
 
-/* Assumes that CCISS_LOCK(h->ctlr) is held. */
+/* Assumes that h->lock is held. */
 /* Zeros out the error record and then resends the command back */
 /* to the controller */
 static inline void resend_cciss_cmd(ctlr_info_t *h, CommandList_struct *c)
@@ -3011,7 +3001,7 @@ static inline int evaluate_target_status(ctlr_info_t *h,
 
        if (cmd->err_info->ScsiStatus != SAM_STAT_CHECK_CONDITION) {
                if (cmd->rq->cmd_type != REQ_TYPE_BLOCK_PC)
-                       printk(KERN_WARNING "cciss: cmd %p "
+                       dev_warn(&h->pdev->dev, "cmd %p "
                               "has SCSI Status 0x%x\n",
                               cmd, cmd->err_info->ScsiStatus);
                return error_value;
@@ -3032,7 +3022,7 @@ static inline int evaluate_target_status(ctlr_info_t *h,
        /* Not SG_IO or similar? */
        if (cmd->rq->cmd_type != REQ_TYPE_BLOCK_PC) {
                if (error_value != 0)
-                       printk(KERN_WARNING "cciss: cmd %p has CHECK CONDITION"
+                       dev_warn(&h->pdev->dev, "cmd %p has CHECK CONDITION"
                               " sense key = 0x%x\n", cmd, sense_key);
                return error_value;
        }
@@ -3073,7 +3063,7 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd,
                break;
        case CMD_DATA_UNDERRUN:
                if (cmd->rq->cmd_type == REQ_TYPE_FS) {
-                       printk(KERN_WARNING "cciss: cmd %p has"
+                       dev_warn(&h->pdev->dev, "cmd %p has"
                               " completed with data underrun "
                               "reported\n", cmd);
                        cmd->rq->resid_len = cmd->err_info->ResidualCnt;
@@ -3081,12 +3071,12 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd,
                break;
        case CMD_DATA_OVERRUN:
                if (cmd->rq->cmd_type == REQ_TYPE_FS)
-                       printk(KERN_WARNING "cciss: cmd %p has"
+                       dev_warn(&h->pdev->dev, "cciss: cmd %p has"
                               " completed with data overrun "
                               "reported\n", cmd);
                break;
        case CMD_INVALID:
-               printk(KERN_WARNING "cciss: cmd %p is "
+               dev_warn(&h->pdev->dev, "cciss: cmd %p is "
                       "reported invalid\n", cmd);
                rq->errors = make_status_bytes(SAM_STAT_GOOD,
                        cmd->err_info->CommandStatus, DRIVER_OK,
@@ -3094,15 +3084,15 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd,
                                DID_PASSTHROUGH : DID_ERROR);
                break;
        case CMD_PROTOCOL_ERR:
-               printk(KERN_WARNING "cciss: cmd %p has "
-                      "protocol error \n", cmd);
+               dev_warn(&h->pdev->dev, "cciss: cmd %p has "
+                      "protocol error\n", cmd);
                rq->errors = make_status_bytes(SAM_STAT_GOOD,
                        cmd->err_info->CommandStatus, DRIVER_OK,
                        (cmd->rq->cmd_type == REQ_TYPE_BLOCK_PC) ?
                                DID_PASSTHROUGH : DID_ERROR);
                break;
        case CMD_HARDWARE_ERR:
-               printk(KERN_WARNING "cciss: cmd %p had "
+               dev_warn(&h->pdev->dev, "cciss: cmd %p had "
                       " hardware error\n", cmd);
                rq->errors = make_status_bytes(SAM_STAT_GOOD,
                        cmd->err_info->CommandStatus, DRIVER_OK,
@@ -3110,7 +3100,7 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd,
                                DID_PASSTHROUGH : DID_ERROR);
                break;
        case CMD_CONNECTION_LOST:
-               printk(KERN_WARNING "cciss: cmd %p had "
+               dev_warn(&h->pdev->dev, "cciss: cmd %p had "
                       "connection lost\n", cmd);
                rq->errors = make_status_bytes(SAM_STAT_GOOD,
                        cmd->err_info->CommandStatus, DRIVER_OK,
@@ -3118,7 +3108,7 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd,
                                DID_PASSTHROUGH : DID_ERROR);
                break;
        case CMD_ABORTED:
-               printk(KERN_WARNING "cciss: cmd %p was "
+               dev_warn(&h->pdev->dev, "cciss: cmd %p was "
                       "aborted\n", cmd);
                rq->errors = make_status_bytes(SAM_STAT_GOOD,
                        cmd->err_info->CommandStatus, DRIVER_OK,
@@ -3126,7 +3116,7 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd,
                                DID_PASSTHROUGH : DID_ABORT);
                break;
        case CMD_ABORT_FAILED:
-               printk(KERN_WARNING "cciss: cmd %p reports "
+               dev_warn(&h->pdev->dev, "cciss: cmd %p reports "
                       "abort failed\n", cmd);
                rq->errors = make_status_bytes(SAM_STAT_GOOD,
                        cmd->err_info->CommandStatus, DRIVER_OK,
@@ -3134,31 +3124,29 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd,
                                DID_PASSTHROUGH : DID_ERROR);
                break;
        case CMD_UNSOLICITED_ABORT:
-               printk(KERN_WARNING "cciss%d: unsolicited "
+               dev_warn(&h->pdev->dev, "cciss%d: unsolicited "
                       "abort %p\n", h->ctlr, cmd);
                if (cmd->retry_count < MAX_CMD_RETRIES) {
                        retry_cmd = 1;
-                       printk(KERN_WARNING
-                              "cciss%d: retrying %p\n", h->ctlr, cmd);
+                       dev_warn(&h->pdev->dev, "retrying %p\n", cmd);
                        cmd->retry_count++;
                } else
-                       printk(KERN_WARNING
-                              "cciss%d: %p retried too "
-                              "many times\n", h->ctlr, cmd);
+                       dev_warn(&h->pdev->dev,
+                               "%p retried too many times\n", cmd);
                rq->errors = make_status_bytes(SAM_STAT_GOOD,
                        cmd->err_info->CommandStatus, DRIVER_OK,
                        (cmd->rq->cmd_type == REQ_TYPE_BLOCK_PC) ?
                                DID_PASSTHROUGH : DID_ABORT);
                break;
        case CMD_TIMEOUT:
-               printk(KERN_WARNING "cciss: cmd %p timedout\n", cmd);
+               dev_warn(&h->pdev->dev, "cmd %p timedout\n", cmd);
                rq->errors = make_status_bytes(SAM_STAT_GOOD,
                        cmd->err_info->CommandStatus, DRIVER_OK,
                        (cmd->rq->cmd_type == REQ_TYPE_BLOCK_PC) ?
                                DID_PASSTHROUGH : DID_ERROR);
                break;
        default:
-               printk(KERN_WARNING "cciss: cmd %p returned "
+               dev_warn(&h->pdev->dev, "cmd %p returned "
                       "unknown status %x\n", cmd,
                       cmd->err_info->CommandStatus);
                rq->errors = make_status_bytes(SAM_STAT_GOOD,
@@ -3237,7 +3225,8 @@ static void do_cciss_request(struct request_queue *q)
 
        BUG_ON(creq->nr_phys_segments > h->maxsgentries);
 
-       if ((c = cmd_alloc(h, 1)) == NULL)
+       c = cmd_alloc(h);
+       if (!c)
                goto full;
 
        blk_start_request(creq);
@@ -3266,11 +3255,8 @@ static void do_cciss_request(struct request_queue *q)
        c->Request.CDB[0] =
            (rq_data_dir(creq) == READ) ? h->cciss_read : h->cciss_write;
        start_blk = blk_rq_pos(creq);
-#ifdef CCISS_DEBUG
-       printk(KERN_DEBUG "ciss: sector =%d nr_sectors=%d\n",
+       dev_dbg(&h->pdev->dev, "sector =%d nr_sectors=%d\n",
               (int)blk_rq_pos(creq), (int)blk_rq_sectors(creq));
-#endif                         /* CCISS_DEBUG */
-
        sg_init_table(tmp_sg, h->maxsgentries);
        seg = blk_rq_map_sg(q, creq, tmp_sg);
 
@@ -3310,11 +3296,9 @@ static void do_cciss_request(struct request_queue *q)
        if (seg > h->maxSG)
                h->maxSG = seg;
 
-#ifdef CCISS_DEBUG
-       printk(KERN_DEBUG "cciss: Submitting %ld sectors in %d segments "
+       dev_dbg(&h->pdev->dev, "Submitting %u sectors in %d segments "
                        "chained[%d]\n",
                        blk_rq_sectors(creq), seg, chained);
-#endif                         /* CCISS_DEBUG */
 
        c->Header.SGTotal = seg + chained;
        if (seg <= h->max_cmd_sgentries)
@@ -3357,7 +3341,8 @@ static void do_cciss_request(struct request_queue *q)
                c->Request.CDBLen = creq->cmd_len;
                memcpy(c->Request.CDB, creq->cmd, BLK_MAX_CDB);
        } else {
-               printk(KERN_WARNING "cciss%d: bad request type %d\n", h->ctlr, creq->cmd_type);
+               dev_warn(&h->pdev->dev, "bad request type %d\n",
+                       creq->cmd_type);
                BUG();
        }
 
@@ -3390,8 +3375,7 @@ static inline int interrupt_pending(ctlr_info_t *h)
 
 static inline long interrupt_not_for_us(ctlr_info_t *h)
 {
-       return !(h->msi_vector || h->msix_vector) &&
-               ((h->access.intr_pending(h) == 0) ||
+       return ((h->access.intr_pending(h) == 0) ||
                (h->interrupts_enabled == 0));
 }
 
@@ -3484,11 +3468,7 @@ static irqreturn_t do_cciss_intx(int irq, void *dev_id)
 
        if (interrupt_not_for_us(h))
                return IRQ_NONE;
-       /*
-        * If there are completed commands in the completion queue,
-        * we had better do something about it.
-        */
-       spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
+       spin_lock_irqsave(&h->lock, flags);
        while (interrupt_pending(h)) {
                raw_tag = get_next_completion(h);
                while (raw_tag != FIFO_EMPTY) {
@@ -3498,8 +3478,7 @@ static irqreturn_t do_cciss_intx(int irq, void *dev_id)
                                raw_tag = process_nonindexed_cmd(h, raw_tag);
                }
        }
-
-       spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+       spin_unlock_irqrestore(&h->lock, flags);
        return IRQ_HANDLED;
 }
 
@@ -3512,13 +3491,7 @@ static irqreturn_t do_cciss_msix_intr(int irq, void *dev_id)
        unsigned long flags;
        u32 raw_tag;
 
-       if (interrupt_not_for_us(h))
-               return IRQ_NONE;
-       /*
-        * If there are completed commands in the completion queue,
-        * we had better do something about it.
-        */
-       spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
+       spin_lock_irqsave(&h->lock, flags);
        raw_tag = get_next_completion(h);
        while (raw_tag != FIFO_EMPTY) {
                if (cciss_tag_contains_index(raw_tag))
@@ -3526,8 +3499,7 @@ static irqreturn_t do_cciss_msix_intr(int irq, void *dev_id)
                else
                        raw_tag = process_nonindexed_cmd(h, raw_tag);
        }
-
-       spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+       spin_unlock_irqrestore(&h->lock, flags);
        return IRQ_HANDLED;
 }
 
@@ -3659,18 +3631,17 @@ static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c)
 
        switch (c->err_info->SenseInfo[12]) {
        case STATE_CHANGED:
-               printk(KERN_WARNING "cciss%d: a state change "
-                       "detected, command retried\n", h->ctlr);
+               dev_warn(&h->pdev->dev, "a state change "
+                       "detected, command retried\n");
                return 1;
        break;
        case LUN_FAILED:
-               printk(KERN_WARNING "cciss%d: LUN failure "
-                       "detected, action required\n", h->ctlr);
+               dev_warn(&h->pdev->dev, "LUN failure "
+                       "detected, action required\n");
                return 1;
        break;
        case REPORT_LUNS_CHANGED:
-               printk(KERN_WARNING "cciss%d: report LUN data "
-                       "changed\n", h->ctlr);
+               dev_warn(&h->pdev->dev, "report LUN data changed\n");
        /*
         * Here, we could call add_to_scan_list and wake up the scan thread,
         * except that it's quite likely that we will get more than one
@@ -3690,19 +3661,18 @@ static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c)
                return 1;
        break;
        case POWER_OR_RESET:
-               printk(KERN_WARNING "cciss%d: a power on "
-                       "or device reset detected\n", h->ctlr);
+               dev_warn(&h->pdev->dev,
+                       "a power on or device reset detected\n");
                return 1;
        break;
        case UNIT_ATTENTION_CLEARED:
-               printk(KERN_WARNING "cciss%d: unit attention "
-                   "cleared by another initiator\n", h->ctlr);
+               dev_warn(&h->pdev->dev,
+                       "unit attention cleared by another initiator\n");
                return 1;
        break;
        default:
-               printk(KERN_WARNING "cciss%d: unknown "
-                       "unit attention detected\n", h->ctlr);
-                               return 1;
+               dev_warn(&h->pdev->dev, "unknown unit attention detected\n");
+               return 1;
        }
 }
 
@@ -3711,38 +3681,40 @@ static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c)
  *   the io functions.
  *   This is for debug only.
  */
-static void print_cfg_table(CfgTable_struct *tb)
+static void print_cfg_table(ctlr_info_t *h)
 {
-#ifdef CCISS_DEBUG
        int i;
        char temp_name[17];
+       CfgTable_struct *tb = h->cfgtable;
 
-       printk("Controller Configuration information\n");
-       printk("------------------------------------\n");
+       dev_dbg(&h->pdev->dev, "Controller Configuration information\n");
+       dev_dbg(&h->pdev->dev, "------------------------------------\n");
        for (i = 0; i < 4; i++)
                temp_name[i] = readb(&(tb->Signature[i]));
        temp_name[4] = '\0';
-       printk("   Signature = %s\n", temp_name);
-       printk("   Spec Number = %d\n", readl(&(tb->SpecValence)));
-       printk("   Transport methods supported = 0x%x\n",
+       dev_dbg(&h->pdev->dev, "   Signature = %s\n", temp_name);
+       dev_dbg(&h->pdev->dev, "   Spec Number = %d\n",
+               readl(&(tb->SpecValence)));
+       dev_dbg(&h->pdev->dev, "   Transport methods supported = 0x%x\n",
               readl(&(tb->TransportSupport)));
-       printk("   Transport methods active = 0x%x\n",
+       dev_dbg(&h->pdev->dev, "   Transport methods active = 0x%x\n",
               readl(&(tb->TransportActive)));
-       printk("   Requested transport Method = 0x%x\n",
+       dev_dbg(&h->pdev->dev, "   Requested transport Method = 0x%x\n",
               readl(&(tb->HostWrite.TransportRequest)));
-       printk("   Coalesce Interrupt Delay = 0x%x\n",
+       dev_dbg(&h->pdev->dev, "   Coalesce Interrupt Delay = 0x%x\n",
               readl(&(tb->HostWrite.CoalIntDelay)));
-       printk("   Coalesce Interrupt Count = 0x%x\n",
+       dev_dbg(&h->pdev->dev, "   Coalesce Interrupt Count = 0x%x\n",
               readl(&(tb->HostWrite.CoalIntCount)));
-       printk("   Max outstanding commands = 0x%d\n",
+       dev_dbg(&h->pdev->dev, "   Max outstanding commands = 0x%d\n",
               readl(&(tb->CmdsOutMax)));
-       printk("   Bus Types = 0x%x\n", readl(&(tb->BusTypes)));
+       dev_dbg(&h->pdev->dev, "   Bus Types = 0x%x\n",
+               readl(&(tb->BusTypes)));
        for (i = 0; i < 16; i++)
                temp_name[i] = readb(&(tb->ServerName[i]));
        temp_name[16] = '\0';
-       printk("   Server Name = %s\n", temp_name);
-       printk("   Heartbeat Counter = 0x%x\n\n\n", readl(&(tb->HeartBeat)));
-#endif                         /* CCISS_DEBUG */
+       dev_dbg(&h->pdev->dev, "   Server Name = %s\n", temp_name);
+       dev_dbg(&h->pdev->dev, "   Heartbeat Counter = 0x%x\n\n\n",
+               readl(&(tb->HeartBeat)));
 }
 
 static int find_PCI_BAR_index(struct pci_dev *pdev, unsigned long pci_bar_addr)
@@ -3767,7 +3739,7 @@ static int find_PCI_BAR_index(struct pci_dev *pdev, unsigned long pci_bar_addr)
                                offset += 8;
                                break;
                        default:        /* reserved in PCI 2.2 */
-                               printk(KERN_WARNING
+                               dev_warn(&pdev->dev,
                                       "Base address is invalid\n");
                                return -1;
                                break;
@@ -3892,7 +3864,7 @@ static __devinit void cciss_enter_performant_mode(ctlr_info_t *h)
        cciss_wait_for_mode_change_ack(h);
        register_value = readl(&(h->cfgtable->TransportActive));
        if (!(register_value & CFGTBL_Trans_Performant))
-               printk(KERN_WARNING "cciss: unable to get board into"
+               dev_warn(&h->pdev->dev, "cciss: unable to get board into"
                                        " performant mode\n");
 }
 
@@ -3907,14 +3879,13 @@ static void __devinit cciss_put_controller_into_performant_mode(ctlr_info_t *h)
        if (!(trans_support & PERFORMANT_MODE))
                return;
 
-       printk(KERN_WARNING "cciss%d: Placing controller into "
-                               "performant mode\n", h->ctlr);
+       dev_dbg(&h->pdev->dev, "Placing controller into performant mode\n");
        /* Performant mode demands commands on a 32 byte boundary
         * pci_alloc_consistent aligns on page boundarys already.
         * Just need to check if divisible by 32
         */
        if ((sizeof(CommandList_struct) % 32) != 0) {
-               printk(KERN_WARNING "%s %d %s\n",
+               dev_warn(&h->pdev->dev, "%s %d %s\n",
                        "cciss info: command size[",
                        (int)sizeof(CommandList_struct),
                        "] not divisible by 32, no performant mode..\n");
@@ -3955,7 +3926,7 @@ clean_up:
  * controllers that are capable. If not, we use IO-APIC mode.
  */
 
-static void __devinit cciss_interrupt_mode(ctlr_info_t *c)
+static void __devinit cciss_interrupt_mode(ctlr_info_t *h)
 {
 #ifdef CONFIG_PCI_MSI
        int err;
@@ -3964,41 +3935,40 @@ static void __devinit cciss_interrupt_mode(ctlr_info_t *c)
        };
 
        /* Some boards advertise MSI but don't really support it */
-       if ((c->board_id == 0x40700E11) || (c->board_id == 0x40800E11) ||
-           (c->board_id == 0x40820E11) || (c->board_id == 0x40830E11))
+       if ((h->board_id == 0x40700E11) || (h->board_id == 0x40800E11) ||
+           (h->board_id == 0x40820E11) || (h->board_id == 0x40830E11))
                goto default_int_mode;
 
-       if (pci_find_capability(c->pdev, PCI_CAP_ID_MSIX)) {
-               err = pci_enable_msix(c->pdev, cciss_msix_entries, 4);
+       if (pci_find_capability(h->pdev, PCI_CAP_ID_MSIX)) {
+               err = pci_enable_msix(h->pdev, cciss_msix_entries, 4);
                if (!err) {
-                       c->intr[0] = cciss_msix_entries[0].vector;
-                       c->intr[1] = cciss_msix_entries[1].vector;
-                       c->intr[2] = cciss_msix_entries[2].vector;
-                       c->intr[3] = cciss_msix_entries[3].vector;
-                       c->msix_vector = 1;
+                       h->intr[0] = cciss_msix_entries[0].vector;
+                       h->intr[1] = cciss_msix_entries[1].vector;
+                       h->intr[2] = cciss_msix_entries[2].vector;
+                       h->intr[3] = cciss_msix_entries[3].vector;
+                       h->msix_vector = 1;
                        return;
                }
                if (err > 0) {
-                       printk(KERN_WARNING "cciss: only %d MSI-X vectors "
-                              "available\n", err);
+                       dev_warn(&h->pdev->dev,
+                               "only %d MSI-X vectors available\n", err);
                        goto default_int_mode;
                } else {
-                       printk(KERN_WARNING "cciss: MSI-X init failed %d\n",
-                              err);
+                       dev_warn(&h->pdev->dev,
+                               "MSI-X init failed %d\n", err);
                        goto default_int_mode;
                }
        }
-       if (pci_find_capability(c->pdev, PCI_CAP_ID_MSI)) {
-               if (!pci_enable_msi(c->pdev)) {
-                       c->msi_vector = 1;
-               } else {
-                       printk(KERN_WARNING "cciss: MSI init failed\n");
-               }
+       if (pci_find_capability(h->pdev, PCI_CAP_ID_MSI)) {
+               if (!pci_enable_msi(h->pdev))
+                       h->msi_vector = 1;
+               else
+                       dev_warn(&h->pdev->dev, "MSI init failed\n");
        }
 default_int_mode:
 #endif                         /* CONFIG_PCI_MSI */
        /* if we get here we're going to use the default interrupt mode */
-       c->intr[PERF_MODE_INT] = c->pdev->irq;
+       h->intr[PERF_MODE_INT] = h->pdev->irq;
        return;
 }
 
@@ -4106,13 +4076,25 @@ static int __devinit cciss_find_cfgtables(ctlr_info_t *h)
        return 0;
 }
 
+static void __devinit cciss_get_max_perf_mode_cmds(struct ctlr_info *h)
+{
+       h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands));
+       if (h->max_commands < 16) {
+               dev_warn(&h->pdev->dev, "Controller reports "
+                       "max supported commands of %d, an obvious lie. "
+                       "Using 16.  Ensure that firmware is up to date.\n",
+                       h->max_commands);
+               h->max_commands = 16;
+       }
+}
+
 /* Interrogate the hardware for some limits:
  * max commands, max SG elements without chaining, and with chaining,
  * SG chain block size, etc.
  */
 static void __devinit cciss_find_board_params(ctlr_info_t *h)
 {
-       h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands));
+       cciss_get_max_perf_mode_cmds(h);
        h->nr_cmds = h->max_commands - 4; /* Allow room for some ioctls */
        h->maxsgentries = readl(&(h->cfgtable->MaxSGElements));
        /*
@@ -4172,68 +4154,64 @@ static inline void cciss_p600_dma_prefetch_quirk(ctlr_info_t *h)
        pci_write_config_dword(h->pdev, PCI_COMMAND_PARITY, dma_refetch);
 }
 
-static int __devinit cciss_pci_init(ctlr_info_t *c)
+static int __devinit cciss_pci_init(ctlr_info_t *h)
 {
        int prod_index, err;
 
-       prod_index = cciss_lookup_board_id(c->pdev, &c->board_id);
+       prod_index = cciss_lookup_board_id(h->pdev, &h->board_id);
        if (prod_index < 0)
                return -ENODEV;
-       c->product_name = products[prod_index].product_name;
-       c->access = *(products[prod_index].access);
+       h->product_name = products[prod_index].product_name;
+       h->access = *(products[prod_index].access);
 
-       if (cciss_board_disabled(c)) {
-               printk(KERN_WARNING
-                      "cciss: controller appears to be disabled\n");
+       if (cciss_board_disabled(h)) {
+               dev_warn(&h->pdev->dev, "controller appears to be disabled\n");
                return -ENODEV;
        }
-       err = pci_enable_device(c->pdev);
+       err = pci_enable_device(h->pdev);
        if (err) {
-               printk(KERN_ERR "cciss: Unable to Enable PCI device\n");
+               dev_warn(&h->pdev->dev, "Unable to Enable PCI device\n");
                return err;
        }
 
-       err = pci_request_regions(c->pdev, "cciss");
+       err = pci_request_regions(h->pdev, "cciss");
        if (err) {
-               printk(KERN_ERR "cciss: Cannot obtain PCI resources, "
-                      "aborting\n");
+               dev_warn(&h->pdev->dev,
+                       "Cannot obtain PCI resources, aborting\n");
                return err;
        }
 
-#ifdef CCISS_DEBUG
-       printk(KERN_INFO "command = %x\n", command);
-       printk(KERN_INFO "irq = %x\n", c->pdev->irq);
-       printk(KERN_INFO "board_id = %x\n", c->board_id);
-#endif                         /* CCISS_DEBUG */
+       dev_dbg(&h->pdev->dev, "irq = %x\n", h->pdev->irq);
+       dev_dbg(&h->pdev->dev, "board_id = %x\n", h->board_id);
 
 /* If the kernel supports MSI/MSI-X we will try to enable that functionality,
  * else we use the IO-APIC interrupt assigned to us by system ROM.
  */
-       cciss_interrupt_mode(c);
-       err = cciss_pci_find_memory_BAR(c->pdev, &c->paddr);
+       cciss_interrupt_mode(h);
+       err = cciss_pci_find_memory_BAR(h->pdev, &h->paddr);
        if (err)
                goto err_out_free_res;
-       c->vaddr = remap_pci_mem(c->paddr, 0x250);
-       if (!c->vaddr) {
+       h->vaddr = remap_pci_mem(h->paddr, 0x250);
+       if (!h->vaddr) {
                err = -ENOMEM;
                goto err_out_free_res;
        }
-       err = cciss_wait_for_board_ready(c);
+       err = cciss_wait_for_board_ready(h);
        if (err)
                goto err_out_free_res;
-       err = cciss_find_cfgtables(c);
+       err = cciss_find_cfgtables(h);
        if (err)
                goto err_out_free_res;
-       print_cfg_table(c->cfgtable);
-       cciss_find_board_params(c);
+       print_cfg_table(h);
+       cciss_find_board_params(h);
 
-       if (!CISS_signature_present(c)) {
+       if (!CISS_signature_present(h)) {
                err = -ENODEV;
                goto err_out_free_res;
        }
-       cciss_enable_scsi_prefetch(c);
-       cciss_p600_dma_prefetch_quirk(c);
-       cciss_put_controller_into_performant_mode(c);
+       cciss_enable_scsi_prefetch(h);
+       cciss_p600_dma_prefetch_quirk(h);
+       cciss_put_controller_into_performant_mode(h);
        return 0;
 
 err_out_free_res:
@@ -4241,48 +4219,47 @@ err_out_free_res:
         * Deliberately omit pci_disable_device(): it does something nasty to
         * Smart Array controllers that pci_enable_device does not undo
         */
-       if (c->transtable)
-               iounmap(c->transtable);
-       if (c->cfgtable)
-               iounmap(c->cfgtable);
-       if (c->vaddr)
-               iounmap(c->vaddr);
-       pci_release_regions(c->pdev);
+       if (h->transtable)
+               iounmap(h->transtable);
+       if (h->cfgtable)
+               iounmap(h->cfgtable);
+       if (h->vaddr)
+               iounmap(h->vaddr);
+       pci_release_regions(h->pdev);
        return err;
 }
 
 /* Function to find the first free pointer into our hba[] array
  * Returns -1 if no free entries are left.
  */
-static int alloc_cciss_hba(void)
+static int alloc_cciss_hba(struct pci_dev *pdev)
 {
        int i;
 
        for (i = 0; i < MAX_CTLR; i++) {
                if (!hba[i]) {
-                       ctlr_info_t *p;
+                       ctlr_info_t *h;
 
-                       p = kzalloc(sizeof(ctlr_info_t), GFP_KERNEL);
-                       if (!p)
+                       h = kzalloc(sizeof(ctlr_info_t), GFP_KERNEL);
+                       if (!h)
                                goto Enomem;
-                       hba[i] = p;
+                       hba[i] = h;
                        return i;
                }
        }
-       printk(KERN_WARNING "cciss: This driver supports a maximum"
+       dev_warn(&pdev->dev, "This driver supports a maximum"
               " of %d controllers.\n", MAX_CTLR);
        return -1;
 Enomem:
-       printk(KERN_ERR "cciss: out of memory.\n");
+       dev_warn(&pdev->dev, "out of memory.\n");
        return -1;
 }
 
-static void free_hba(int n)
+static void free_hba(ctlr_info_t *h)
 {
-       ctlr_info_t *h = hba[n];
        int i;
 
-       hba[n] = NULL;
+       hba[h->ctlr] = NULL;
        for (i = 0; i < h->highest_lun + 1; i++)
                if (h->gendisk[i] != NULL)
                        put_disk(h->gendisk[i]);
@@ -4362,7 +4339,8 @@ static __devinit int cciss_message(struct pci_dev *pdev, unsigned char opcode, u
        /* we leak the DMA buffer here ... no choice since the controller could
           still complete the command. */
        if (i == 10) {
-               printk(KERN_ERR "cciss: controller message %02x:%02x timed out\n",
+               dev_err(&pdev->dev,
+                       "controller message %02x:%02x timed out\n",
                        opcode, type);
                return -ETIMEDOUT;
        }
@@ -4370,12 +4348,12 @@ static __devinit int cciss_message(struct pci_dev *pdev, unsigned char opcode, u
        pci_free_consistent(pdev, cmd_sz, cmd, paddr64);
 
        if (tag & 2) {
-               printk(KERN_ERR "cciss: controller message %02x:%02x failed\n",
+               dev_err(&pdev->dev, "controller message %02x:%02x failed\n",
                        opcode, type);
                return -EIO;
        }
 
-       printk(KERN_INFO "cciss: controller message %02x:%02x succeeded\n",
+       dev_info(&pdev->dev, "controller message %02x:%02x succeeded\n",
                opcode, type);
        return 0;
 }
@@ -4396,7 +4374,7 @@ static __devinit int cciss_reset_msi(struct pci_dev *pdev)
        if (pos) {
                pci_read_config_word(pdev, msi_control_reg(pos), &control);
                if (control & PCI_MSI_FLAGS_ENABLE) {
-                       printk(KERN_INFO "cciss: resetting MSI\n");
+                       dev_info(&pdev->dev, "resetting MSI\n");
                        pci_write_config_word(pdev, msi_control_reg(pos), control & ~PCI_MSI_FLAGS_ENABLE);
                }
        }
@@ -4405,7 +4383,7 @@ static __devinit int cciss_reset_msi(struct pci_dev *pdev)
        if (pos) {
                pci_read_config_word(pdev, msi_control_reg(pos), &control);
                if (control & PCI_MSIX_FLAGS_ENABLE) {
-                       printk(KERN_INFO "cciss: resetting MSI-X\n");
+                       dev_info(&pdev->dev, "resetting MSI-X\n");
                        pci_write_config_word(pdev, msi_control_reg(pos), control & ~PCI_MSIX_FLAGS_ENABLE);
                }
        }
@@ -4413,68 +4391,144 @@ static __devinit int cciss_reset_msi(struct pci_dev *pdev)
        return 0;
 }
 
-/* This does a hard reset of the controller using PCI power management
- * states. */
-static __devinit int cciss_hard_reset_controller(struct pci_dev *pdev)
+static int cciss_controller_hard_reset(struct pci_dev *pdev,
+       void * __iomem vaddr, bool use_doorbell)
 {
-       u16 pmcsr, saved_config_space[32];
-       int i, pos;
+       u16 pmcsr;
+       int pos;
 
-       printk(KERN_INFO "cciss: using PCI PM to reset controller\n");
+       if (use_doorbell) {
+               /* For everything after the P600, the PCI power state method
+                * of resetting the controller doesn't work, so we have this
+                * other way using the doorbell register.
+                */
+               dev_info(&pdev->dev, "using doorbell to reset controller\n");
+               writel(DOORBELL_CTLR_RESET, vaddr + SA5_DOORBELL);
+               msleep(1000);
+       } else { /* Try to do it the PCI power state way */
+
+               /* Quoting from the Open CISS Specification: "The Power
+                * Management Control/Status Register (CSR) controls the power
+                * state of the device.  The normal operating state is D0,
+                * CSR=00h.  The software off state is D3, CSR=03h.  To reset
+                * the controller, place the interface device in D3 then to D0,
+                * this causes a secondary PCI reset which will reset the
+                * controller." */
+
+               pos = pci_find_capability(pdev, PCI_CAP_ID_PM);
+               if (pos == 0) {
+                       dev_err(&pdev->dev,
+                               "cciss_controller_hard_reset: "
+                               "PCI PM not supported\n");
+                       return -ENODEV;
+               }
+               dev_info(&pdev->dev, "using PCI PM to reset controller\n");
+               /* enter the D3hot power management state */
+               pci_read_config_word(pdev, pos + PCI_PM_CTRL, &pmcsr);
+               pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
+               pmcsr |= PCI_D3hot;
+               pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr);
 
-       /* This is very nearly the same thing as
+               msleep(500);
 
-          pci_save_state(pci_dev);
-          pci_set_power_state(pci_dev, PCI_D3hot);
-          pci_set_power_state(pci_dev, PCI_D0);
-          pci_restore_state(pci_dev);
+               /* enter the D0 power management state */
+               pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
+               pmcsr |= PCI_D0;
+               pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr);
 
-          but we can't use these nice canned kernel routines on
-          kexec, because they also check the MSI/MSI-X state in PCI
-          configuration space and do the wrong thing when it is
-          set/cleared.  Also, the pci_save/restore_state functions
-          violate the ordering requirements for restoring the
-          configuration space from the CCISS document (see the
-          comment below).  So we roll our own .... */
+               msleep(500);
+       }
+       return 0;
+}
 
-       for (i = 0; i < 32; i++)
-               pci_read_config_word(pdev, 2*i, &saved_config_space[i]);
+/* This does a hard reset of the controller using PCI power management
+ * states or using the doorbell register. */
+static __devinit int cciss_kdump_hard_reset_controller(struct pci_dev *pdev)
+{
+       u16 saved_config_space[32];
+       u64 cfg_offset;
+       u32 cfg_base_addr;
+       u64 cfg_base_addr_index;
+       void __iomem *vaddr;
+       unsigned long paddr;
+       u32 misc_fw_support, active_transport;
+       int rc, i;
+       CfgTable_struct __iomem *cfgtable;
+       bool use_doorbell;
+       u32 board_id;
+
+       /* For controllers as old a the p600, this is very nearly
+        * the same thing as
+        *
+        * pci_save_state(pci_dev);
+        * pci_set_power_state(pci_dev, PCI_D3hot);
+        * pci_set_power_state(pci_dev, PCI_D0);
+        * pci_restore_state(pci_dev);
+        *
+        * but we can't use these nice canned kernel routines on
+        * kexec, because they also check the MSI/MSI-X state in PCI
+        * configuration space and do the wrong thing when it is
+        * set/cleared.  Also, the pci_save/restore_state functions
+        * violate the ordering requirements for restoring the
+        * configuration space from the CCISS document (see the
+        * comment below).  So we roll our own ....
+        *
+        * For controllers newer than the P600, the pci power state
+        * method of resetting doesn't work so we have another way
+        * using the doorbell register.
+        */
 
-       pos = pci_find_capability(pdev, PCI_CAP_ID_PM);
-       if (pos == 0) {
-               printk(KERN_ERR "cciss_reset_controller: PCI PM not supported\n");
+       /* Exclude 640x boards.  These are two pci devices in one slot
+        * which share a battery backed cache module.  One controls the
+        * cache, the other accesses the cache through the one that controls
+        * it.  If we reset the one controlling the cache, the other will
+        * likely not be happy.  Just forbid resetting this conjoined mess.
+        */
+       cciss_lookup_board_id(pdev, &board_id);
+       if (board_id == 0x409C0E11 || board_id == 0x409D0E11) {
+               dev_warn(&pdev->dev, "Cannot reset Smart Array 640x "
+                               "due to shared cache module.");
                return -ENODEV;
        }
 
-       /* Quoting from the Open CISS Specification: "The Power
-        * Management Control/Status Register (CSR) controls the power
-        * state of the device.  The normal operating state is D0,
-        * CSR=00h.  The software off state is D3, CSR=03h.  To reset
-        * the controller, place the interface device in D3 then to
-        * D0, this causes a secondary PCI reset which will reset the
-        * controller." */
+       for (i = 0; i < 32; i++)
+               pci_read_config_word(pdev, 2*i, &saved_config_space[i]);
 
-       /* enter the D3hot power management state */
-       pci_read_config_word(pdev, pos + PCI_PM_CTRL, &pmcsr);
-       pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
-       pmcsr |= PCI_D3hot;
-       pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr);
+       /* find the first memory BAR, so we can find the cfg table */
+       rc = cciss_pci_find_memory_BAR(pdev, &paddr);
+       if (rc)
+               return rc;
+       vaddr = remap_pci_mem(paddr, 0x250);
+       if (!vaddr)
+               return -ENOMEM;
 
-       schedule_timeout_uninterruptible(HZ >> 1);
+       /* find cfgtable in order to check if reset via doorbell is supported */
+       rc = cciss_find_cfg_addrs(pdev, vaddr, &cfg_base_addr,
+                                       &cfg_base_addr_index, &cfg_offset);
+       if (rc)
+               goto unmap_vaddr;
+       cfgtable = remap_pci_mem(pci_resource_start(pdev,
+                      cfg_base_addr_index) + cfg_offset, sizeof(*cfgtable));
+       if (!cfgtable) {
+               rc = -ENOMEM;
+               goto unmap_vaddr;
+       }
 
-       /* enter the D0 power management state */
-       pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
-       pmcsr |= PCI_D0;
-       pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr);
+       /* If reset via doorbell register is supported, use that. */
+       misc_fw_support = readl(&cfgtable->misc_fw_support);
+       use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET;
 
-       schedule_timeout_uninterruptible(HZ >> 1);
+       rc = cciss_controller_hard_reset(pdev, vaddr, use_doorbell);
+       if (rc)
+               goto unmap_cfgtable;
 
        /* Restore the PCI configuration space.  The Open CISS
         * Specification says, "Restore the PCI Configuration
         * Registers, offsets 00h through 60h. It is important to
         * restore the command register, 16-bits at offset 04h,
         * last. Do not restore the configuration status register,
-        * 16-bits at offset 06h."  Note that the offset is 2*i. */
+        * 16-bits at offset 06h."  Note that the offset is 2*i.
+        */
        for (i = 0; i < 32; i++) {
                if (i == 2 || i == 3)
                        continue;
@@ -4483,6 +4537,63 @@ static __devinit int cciss_hard_reset_controller(struct pci_dev *pdev)
        wmb();
        pci_write_config_word(pdev, 4, saved_config_space[2]);
 
+       /* Some devices (notably the HP Smart Array 5i Controller)
+          need a little pause here */
+       msleep(CCISS_POST_RESET_PAUSE_MSECS);
+
+       /* Controller should be in simple mode at this point.  If it's not,
+        * It means we're on one of those controllers which doesn't support
+        * the doorbell reset method and on which the PCI power management reset
+        * method doesn't work (P800, for example.)
+        * In those cases, don't try to proceed, as it generally doesn't work.
+        */
+       active_transport = readl(&cfgtable->TransportActive);
+       if (active_transport & PERFORMANT_MODE) {
+               dev_warn(&pdev->dev, "Unable to successfully reset controller,"
+                       " Ignoring controller.\n");
+               rc = -ENODEV;
+       }
+
+unmap_cfgtable:
+       iounmap(cfgtable);
+
+unmap_vaddr:
+       iounmap(vaddr);
+       return rc;
+}
+
+static __devinit int cciss_init_reset_devices(struct pci_dev *pdev)
+{
+       int rc, i;
+
+       if (!reset_devices)
+               return 0;
+
+       /* Reset the controller with a PCI power-cycle or via doorbell */
+       rc = cciss_kdump_hard_reset_controller(pdev);
+
+       /* -ENOTSUPP here means we cannot reset the controller
+        * but it's already (and still) up and running in
+        * "performant mode".  Or, it might be 640x, which can't reset
+        * due to concerns about shared bbwc between 6402/6404 pair.
+        */
+       if (rc == -ENOTSUPP)
+               return 0; /* just try to do the kdump anyhow. */
+       if (rc)
+               return -ENODEV;
+       if (cciss_reset_msi(pdev))
+               return -ENODEV;
+
+       /* Now try to get the controller to respond to a no-op */
+       for (i = 0; i < CCISS_POST_RESET_NOOP_RETRIES; i++) {
+               if (cciss_noop(pdev) == 0)
+                       break;
+               else
+                       dev_warn(&pdev->dev, "no-op failed%s\n",
+                               (i < CCISS_POST_RESET_NOOP_RETRIES - 1 ?
+                                       "; re-trying" : ""));
+               msleep(CCISS_POST_RESET_NOOP_INTERVAL_MSECS);
+       }
        return 0;
 }
 
@@ -4500,46 +4611,31 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
        int rc;
        int dac, return_code;
        InquiryData_struct *inq_buff;
+       ctlr_info_t *h;
 
-       if (reset_devices) {
-               /* Reset the controller with a PCI power-cycle */
-               if (cciss_hard_reset_controller(pdev) || cciss_reset_msi(pdev))
-                       return -ENODEV;
-
-               /* Now try to get the controller to respond to a no-op. Some
-                  devices (notably the HP Smart Array 5i Controller) need
-                  up to 30 seconds to respond. */
-               for (i=0; i<30; i++) {
-                       if (cciss_noop(pdev) == 0)
-                               break;
-
-                       schedule_timeout_uninterruptible(HZ);
-               }
-               if (i == 30) {
-                       printk(KERN_ERR "cciss: controller seems dead\n");
-                       return -EBUSY;
-               }
-       }
-
-       i = alloc_cciss_hba();
+       rc = cciss_init_reset_devices(pdev);
+       if (rc)
+               return rc;
+       i = alloc_cciss_hba(pdev);
        if (i < 0)
                return -1;
 
-       hba[i]->pdev = pdev;
-       hba[i]->busy_initializing = 1;
-       INIT_HLIST_HEAD(&hba[i]->cmpQ);
-       INIT_HLIST_HEAD(&hba[i]->reqQ);
-       mutex_init(&hba[i]->busy_shutting_down);
+       h = hba[i];
+       h->pdev = pdev;
+       h->busy_initializing = 1;
+       INIT_HLIST_HEAD(&h->cmpQ);
+       INIT_HLIST_HEAD(&h->reqQ);
+       mutex_init(&h->busy_shutting_down);
 
-       if (cciss_pci_init(hba[i]) != 0)
+       if (cciss_pci_init(h) != 0)
                goto clean_no_release_regions;
 
-       sprintf(hba[i]->devname, "cciss%d", i);
-       hba[i]->ctlr = i;
+       sprintf(h->devname, "cciss%d", i);
+       h->ctlr = i;
 
-       init_completion(&hba[i]->scan_wait);
+       init_completion(&h->scan_wait);
 
-       if (cciss_create_hba_sysfs_entry(hba[i]))
+       if (cciss_create_hba_sysfs_entry(h))
                goto clean0;
 
        /* configure PCI DMA stuff */
@@ -4548,7 +4644,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
        else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))
                dac = 0;
        else {
-               printk(KERN_ERR "cciss: no suitable DMA available\n");
+               dev_err(&h->pdev->dev, "no suitable DMA available\n");
                goto clean1;
        }
 
@@ -4558,161 +4654,161 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
         * 8 controller support.
         */
        if (i < MAX_CTLR_ORIG)
-               hba[i]->major = COMPAQ_CISS_MAJOR + i;
-       rc = register_blkdev(hba[i]->major, hba[i]->devname);
+               h->major = COMPAQ_CISS_MAJOR + i;
+       rc = register_blkdev(h->major, h->devname);
        if (rc == -EBUSY || rc == -EINVAL) {
-               printk(KERN_ERR
-                      "cciss:  Unable to get major number %d for %s "
-                      "on hba %d\n", hba[i]->major, hba[i]->devname, i);
+               dev_err(&h->pdev->dev,
+                      "Unable to get major number %d for %s "
+                      "on hba %d\n", h->major, h->devname, i);
                goto clean1;
        } else {
                if (i >= MAX_CTLR_ORIG)
-                       hba[i]->major = rc;
+                       h->major = rc;
        }
 
        /* make sure the board interrupts are off */
-       hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_OFF);
-       if (hba[i]->msi_vector || hba[i]->msix_vector) {
-               if (request_irq(hba[i]->intr[PERF_MODE_INT],
+       h->access.set_intr_mask(h, CCISS_INTR_OFF);
+       if (h->msi_vector || h->msix_vector) {
+               if (request_irq(h->intr[PERF_MODE_INT],
                                do_cciss_msix_intr,
-                               IRQF_DISABLED, hba[i]->devname, hba[i])) {
-                       printk(KERN_ERR "cciss: Unable to get irq %d for %s\n",
-                              hba[i]->intr[PERF_MODE_INT], hba[i]->devname);
+                               IRQF_DISABLED, h->devname, h)) {
+                       dev_err(&h->pdev->dev, "Unable to get irq %d for %s\n",
+                              h->intr[PERF_MODE_INT], h->devname);
                        goto clean2;
                }
        } else {
-               if (request_irq(hba[i]->intr[PERF_MODE_INT], do_cciss_intx,
-                               IRQF_DISABLED, hba[i]->devname, hba[i])) {
-                       printk(KERN_ERR "cciss: Unable to get irq %d for %s\n",
-                              hba[i]->intr[PERF_MODE_INT], hba[i]->devname);
+               if (request_irq(h->intr[PERF_MODE_INT], do_cciss_intx,
+                               IRQF_DISABLED, h->devname, h)) {
+                       dev_err(&h->pdev->dev, "Unable to get irq %d for %s\n",
+                              h->intr[PERF_MODE_INT], h->devname);
                        goto clean2;
                }
        }
 
-       printk(KERN_INFO "%s: <0x%x> at PCI %s IRQ %d%s using DAC\n",
-              hba[i]->devname, pdev->device, pci_name(pdev),
-              hba[i]->intr[PERF_MODE_INT], dac ? "" : " not");
+       dev_info(&h->pdev->dev, "%s: <0x%x> at PCI %s IRQ %d%s using DAC\n",
+              h->devname, pdev->device, pci_name(pdev),
+              h->intr[PERF_MODE_INT], dac ? "" : " not");
 
-       hba[i]->cmd_pool_bits =
-           kmalloc(DIV_ROUND_UP(hba[i]->nr_cmds, BITS_PER_LONG)
+       h->cmd_pool_bits =
+           kmalloc(DIV_ROUND_UP(h->nr_cmds, BITS_PER_LONG)
                        * sizeof(unsigned long), GFP_KERNEL);
-       hba[i]->cmd_pool = (CommandList_struct *)
-           pci_alloc_consistent(hba[i]->pdev,
-                   hba[i]->nr_cmds * sizeof(CommandList_struct),
-                   &(hba[i]->cmd_pool_dhandle));
-       hba[i]->errinfo_pool = (ErrorInfo_struct *)
-           pci_alloc_consistent(hba[i]->pdev,
-                   hba[i]->nr_cmds * sizeof(ErrorInfo_struct),
-                   &(hba[i]->errinfo_pool_dhandle));
-       if ((hba[i]->cmd_pool_bits == NULL)
-           || (hba[i]->cmd_pool == NULL)
-           || (hba[i]->errinfo_pool == NULL)) {
-               printk(KERN_ERR "cciss: out of memory");
+       h->cmd_pool = (CommandList_struct *)
+           pci_alloc_consistent(h->pdev,
+                   h->nr_cmds * sizeof(CommandList_struct),
+                   &(h->cmd_pool_dhandle));
+       h->errinfo_pool = (ErrorInfo_struct *)
+           pci_alloc_consistent(h->pdev,
+                   h->nr_cmds * sizeof(ErrorInfo_struct),
+                   &(h->errinfo_pool_dhandle));
+       if ((h->cmd_pool_bits == NULL)
+           || (h->cmd_pool == NULL)
+           || (h->errinfo_pool == NULL)) {
+               dev_err(&h->pdev->dev, "out of memory");
                goto clean4;
        }
 
        /* Need space for temp scatter list */
-       hba[i]->scatter_list = kmalloc(hba[i]->max_commands *
+       h->scatter_list = kmalloc(h->max_commands *
                                                sizeof(struct scatterlist *),
                                                GFP_KERNEL);
-       for (k = 0; k < hba[i]->nr_cmds; k++) {
-               hba[i]->scatter_list[k] = kmalloc(sizeof(struct scatterlist) *
-                                                       hba[i]->maxsgentries,
+       for (k = 0; k < h->nr_cmds; k++) {
+               h->scatter_list[k] = kmalloc(sizeof(struct scatterlist) *
+                                                       h->maxsgentries,
                                                        GFP_KERNEL);
-               if (hba[i]->scatter_list[k] == NULL) {
-                       printk(KERN_ERR "cciss%d: could not allocate "
-                               "s/g lists\n", i);
+               if (h->scatter_list[k] == NULL) {
+                       dev_err(&h->pdev->dev,
+                               "could not allocate s/g lists\n");
                        goto clean4;
                }
        }
-       hba[i]->cmd_sg_list = cciss_allocate_sg_chain_blocks(hba[i],
-               hba[i]->chainsize, hba[i]->nr_cmds);
-       if (!hba[i]->cmd_sg_list && hba[i]->chainsize > 0)
+       h->cmd_sg_list = cciss_allocate_sg_chain_blocks(h,
+               h->chainsize, h->nr_cmds);
+       if (!h->cmd_sg_list && h->chainsize > 0)
                goto clean4;
 
-       spin_lock_init(&hba[i]->lock);
+       spin_lock_init(&h->lock);
 
        /* Initialize the pdev driver private data.
-          have it point to hba[i].  */
-       pci_set_drvdata(pdev, hba[i]);
+          have it point to h.  */
+       pci_set_drvdata(pdev, h);
        /* command and error info recs zeroed out before
           they are used */
-       memset(hba[i]->cmd_pool_bits, 0,
-              DIV_ROUND_UP(hba[i]->nr_cmds, BITS_PER_LONG)
+       memset(h->cmd_pool_bits, 0,
+              DIV_ROUND_UP(h->nr_cmds, BITS_PER_LONG)
                        * sizeof(unsigned long));
 
-       hba[i]->num_luns = 0;
-       hba[i]->highest_lun = -1;
+       h->num_luns = 0;
+       h->highest_lun = -1;
        for (j = 0; j < CISS_MAX_LUN; j++) {
-               hba[i]->drv[j] = NULL;
-               hba[i]->gendisk[j] = NULL;
+               h->drv[j] = NULL;
+               h->gendisk[j] = NULL;
        }
 
-       cciss_scsi_setup(i);
+       cciss_scsi_setup(h);
 
        /* Turn the interrupts on so we can service requests */
-       hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_ON);
+       h->access.set_intr_mask(h, CCISS_INTR_ON);
 
        /* Get the firmware version */
        inq_buff = kzalloc(sizeof(InquiryData_struct), GFP_KERNEL);
        if (inq_buff == NULL) {
-               printk(KERN_ERR "cciss: out of memory\n");
+               dev_err(&h->pdev->dev, "out of memory\n");
                goto clean4;
        }
 
-       return_code = sendcmd_withirq(CISS_INQUIRY, i, inq_buff,
+       return_code = sendcmd_withirq(h, CISS_INQUIRY, inq_buff,
                sizeof(InquiryData_struct), 0, CTLR_LUNID, TYPE_CMD);
        if (return_code == IO_OK) {
-               hba[i]->firm_ver[0] = inq_buff->data_byte[32];
-               hba[i]->firm_ver[1] = inq_buff->data_byte[33];
-               hba[i]->firm_ver[2] = inq_buff->data_byte[34];
-               hba[i]->firm_ver[3] = inq_buff->data_byte[35];
+               h->firm_ver[0] = inq_buff->data_byte[32];
+               h->firm_ver[1] = inq_buff->data_byte[33];
+               h->firm_ver[2] = inq_buff->data_byte[34];
+               h->firm_ver[3] = inq_buff->data_byte[35];
        } else {         /* send command failed */
-               printk(KERN_WARNING "cciss: unable to determine firmware"
+               dev_warn(&h->pdev->dev, "unable to determine firmware"
                        " version of controller\n");
        }
        kfree(inq_buff);
 
-       cciss_procinit(i);
+       cciss_procinit(h);
 
-       hba[i]->cciss_max_sectors = 8192;
+       h->cciss_max_sectors = 8192;
 
-       rebuild_lun_table(hba[i], 1, 0);
-       hba[i]->busy_initializing = 0;
+       rebuild_lun_table(h, 1, 0);
+       h->busy_initializing = 0;
        return 1;
 
 clean4:
-       kfree(hba[i]->cmd_pool_bits);
+       kfree(h->cmd_pool_bits);
        /* Free up sg elements */
-       for (k = 0; k < hba[i]->nr_cmds; k++)
-               kfree(hba[i]->scatter_list[k]);
-       kfree(hba[i]->scatter_list);
-       cciss_free_sg_chain_blocks(hba[i]->cmd_sg_list, hba[i]->nr_cmds);
-       if (hba[i]->cmd_pool)
-               pci_free_consistent(hba[i]->pdev,
-                                   hba[i]->nr_cmds * sizeof(CommandList_struct),
-                                   hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle);
-       if (hba[i]->errinfo_pool)
-               pci_free_consistent(hba[i]->pdev,
-                                   hba[i]->nr_cmds * sizeof(ErrorInfo_struct),
-                                   hba[i]->errinfo_pool,
-                                   hba[i]->errinfo_pool_dhandle);
-       free_irq(hba[i]->intr[PERF_MODE_INT], hba[i]);
+       for (k = 0; k < h->nr_cmds; k++)
+               kfree(h->scatter_list[k]);
+       kfree(h->scatter_list);
+       cciss_free_sg_chain_blocks(h->cmd_sg_list, h->nr_cmds);
+       if (h->cmd_pool)
+               pci_free_consistent(h->pdev,
+                                   h->nr_cmds * sizeof(CommandList_struct),
+                                   h->cmd_pool, h->cmd_pool_dhandle);
+       if (h->errinfo_pool)
+               pci_free_consistent(h->pdev,
+                                   h->nr_cmds * sizeof(ErrorInfo_struct),
+                                   h->errinfo_pool,
+                                   h->errinfo_pool_dhandle);
+       free_irq(h->intr[PERF_MODE_INT], h);
 clean2:
-       unregister_blkdev(hba[i]->major, hba[i]->devname);
+       unregister_blkdev(h->major, h->devname);
 clean1:
-       cciss_destroy_hba_sysfs_entry(hba[i]);
+       cciss_destroy_hba_sysfs_entry(h);
 clean0:
        pci_release_regions(pdev);
 clean_no_release_regions:
-       hba[i]->busy_initializing = 0;
+       h->busy_initializing = 0;
 
        /*
         * Deliberately omit pci_disable_device(): it does something nasty to
         * Smart Array controllers that pci_enable_device does not undo
         */
        pci_set_drvdata(pdev, NULL);
-       free_hba(i);
+       free_hba(h);
        return -1;
 }
 
@@ -4725,55 +4821,51 @@ static void cciss_shutdown(struct pci_dev *pdev)
        h = pci_get_drvdata(pdev);
        flush_buf = kzalloc(4, GFP_KERNEL);
        if (!flush_buf) {
-               printk(KERN_WARNING
-                       "cciss:%d cache not flushed, out of memory.\n",
-                       h->ctlr);
+               dev_warn(&h->pdev->dev, "cache not flushed, out of memory.\n");
                return;
        }
        /* write all data in the battery backed cache to disk */
        memset(flush_buf, 0, 4);
-       return_code = sendcmd_withirq(CCISS_CACHE_FLUSH, h->ctlr, flush_buf,
+       return_code = sendcmd_withirq(h, CCISS_CACHE_FLUSH, flush_buf,
                4, 0, CTLR_LUNID, TYPE_CMD);
        kfree(flush_buf);
        if (return_code != IO_OK)
-               printk(KERN_WARNING "cciss%d: Error flushing cache\n",
-                       h->ctlr);
+               dev_warn(&h->pdev->dev, "Error flushing cache\n");
        h->access.set_intr_mask(h, CCISS_INTR_OFF);
        free_irq(h->intr[PERF_MODE_INT], h);
 }
 
 static void __devexit cciss_remove_one(struct pci_dev *pdev)
 {
-       ctlr_info_t *tmp_ptr;
+       ctlr_info_t *h;
        int i, j;
 
        if (pci_get_drvdata(pdev) == NULL) {
-               printk(KERN_ERR "cciss: Unable to remove device \n");
+               dev_err(&pdev->dev, "Unable to remove device\n");
                return;
        }
 
-       tmp_ptr = pci_get_drvdata(pdev);
-       i = tmp_ptr->ctlr;
+       h = pci_get_drvdata(pdev);
+       i = h->ctlr;
        if (hba[i] == NULL) {
-               printk(KERN_ERR "cciss: device appears to "
-                      "already be removed \n");
+               dev_err(&pdev->dev, "device appears to already be removed\n");
                return;
        }
 
-       mutex_lock(&hba[i]->busy_shutting_down);
+       mutex_lock(&h->busy_shutting_down);
 
-       remove_from_scan_list(hba[i]);
-       remove_proc_entry(hba[i]->devname, proc_cciss);
-       unregister_blkdev(hba[i]->major, hba[i]->devname);
+       remove_from_scan_list(h);
+       remove_proc_entry(h->devname, proc_cciss);
+       unregister_blkdev(h->major, h->devname);
 
        /* remove it from the disk list */
        for (j = 0; j < CISS_MAX_LUN; j++) {
-               struct gendisk *disk = hba[i]->gendisk[j];
+               struct gendisk *disk = h->gendisk[j];
                if (disk) {
                        struct request_queue *q = disk->queue;
 
                        if (disk->flags & GENHD_FL_UP) {
-                               cciss_destroy_ld_sysfs_entry(hba[i], j, 1);
+                               cciss_destroy_ld_sysfs_entry(h, j, 1);
                                del_gendisk(disk);
                        }
                        if (q)
@@ -4782,41 +4874,41 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev)
        }
 
 #ifdef CONFIG_CISS_SCSI_TAPE
-       cciss_unregister_scsi(i);       /* unhook from SCSI subsystem */
+       cciss_unregister_scsi(h);       /* unhook from SCSI subsystem */
 #endif
 
        cciss_shutdown(pdev);
 
 #ifdef CONFIG_PCI_MSI
-       if (hba[i]->msix_vector)
-               pci_disable_msix(hba[i]->pdev);
-       else if (hba[i]->msi_vector)
-               pci_disable_msi(hba[i]->pdev);
+       if (h->msix_vector)
+               pci_disable_msix(h->pdev);
+       else if (h->msi_vector)
+               pci_disable_msi(h->pdev);
 #endif                         /* CONFIG_PCI_MSI */
 
-       iounmap(hba[i]->transtable);
-       iounmap(hba[i]->cfgtable);
-       iounmap(hba[i]->vaddr);
+       iounmap(h->transtable);
+       iounmap(h->cfgtable);
+       iounmap(h->vaddr);
 
-       pci_free_consistent(hba[i]->pdev, hba[i]->nr_cmds * sizeof(CommandList_struct),
-                           hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle);
-       pci_free_consistent(hba[i]->pdev, hba[i]->nr_cmds * sizeof(ErrorInfo_struct),
-                           hba[i]->errinfo_pool, hba[i]->errinfo_pool_dhandle);
-       kfree(hba[i]->cmd_pool_bits);
+       pci_free_consistent(h->pdev, h->nr_cmds * sizeof(CommandList_struct),
+                           h->cmd_pool, h->cmd_pool_dhandle);
+       pci_free_consistent(h->pdev, h->nr_cmds * sizeof(ErrorInfo_struct),
+                           h->errinfo_pool, h->errinfo_pool_dhandle);
+       kfree(h->cmd_pool_bits);
        /* Free up sg elements */
-       for (j = 0; j < hba[i]->nr_cmds; j++)
-               kfree(hba[i]->scatter_list[j]);
-       kfree(hba[i]->scatter_list);
-       cciss_free_sg_chain_blocks(hba[i]->cmd_sg_list, hba[i]->nr_cmds);
+       for (j = 0; j < h->nr_cmds; j++)
+               kfree(h->scatter_list[j]);
+       kfree(h->scatter_list);
+       cciss_free_sg_chain_blocks(h->cmd_sg_list, h->nr_cmds);
        /*
         * Deliberately omit pci_disable_device(): it does something nasty to
         * Smart Array controllers that pci_enable_device does not undo
         */
        pci_release_regions(pdev);
        pci_set_drvdata(pdev, NULL);
-       cciss_destroy_hba_sysfs_entry(hba[i]);
-       mutex_unlock(&hba[i]->busy_shutting_down);
-       free_hba(i);
+       cciss_destroy_hba_sysfs_entry(h);
+       mutex_unlock(&h->busy_shutting_down);
+       free_hba(h);
 }
 
 static struct pci_driver cciss_pci_driver = {
@@ -4877,8 +4969,8 @@ static void __exit cciss_cleanup(void)
        /* double check that all controller entrys have been removed */
        for (i = 0; i < MAX_CTLR; i++) {
                if (hba[i] != NULL) {
-                       printk(KERN_WARNING "cciss: had to remove"
-                              " controller %d\n", i);
+                       dev_warn(&hba[i]->pdev->dev,
+                               "had to remove controller\n");
                        cciss_remove_one(hba[i]->pdev);
                }
        }