diff options
Diffstat (limited to 'drivers/block/cciss.c')
-rw-r--r-- | drivers/block/cciss.c | 196 |
1 files changed, 141 insertions, 55 deletions
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index d2815b7a9150..e4e9f255bd1f 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Disk Array driver for HP SA 5xxx and 6xxx Controllers | 2 | * Disk Array driver for HP SA 5xxx and 6xxx Controllers |
3 | * Copyright 2000, 2005 Hewlett-Packard Development Company, L.P. | 3 | * Copyright 2000, 2006 Hewlett-Packard Development Company, L.P. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify | 5 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License as published by | 6 | * it under the terms of the GNU General Public License as published by |
@@ -47,12 +47,12 @@ | |||
47 | #include <linux/completion.h> | 47 | #include <linux/completion.h> |
48 | 48 | ||
49 | #define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin)) | 49 | #define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin)) |
50 | #define DRIVER_NAME "HP CISS Driver (v 2.6.8)" | 50 | #define DRIVER_NAME "HP CISS Driver (v 2.6.10)" |
51 | #define DRIVER_VERSION CCISS_DRIVER_VERSION(2,6,8) | 51 | #define DRIVER_VERSION CCISS_DRIVER_VERSION(2,6,10) |
52 | 52 | ||
53 | /* Embedded module documentation macros - see modules.h */ | 53 | /* Embedded module documentation macros - see modules.h */ |
54 | MODULE_AUTHOR("Hewlett-Packard Company"); | 54 | MODULE_AUTHOR("Hewlett-Packard Company"); |
55 | MODULE_DESCRIPTION("Driver for HP Controller SA5xxx SA6xxx version 2.6.8"); | 55 | MODULE_DESCRIPTION("Driver for HP Controller SA5xxx SA6xxx version 2.6.10"); |
56 | MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400" | 56 | MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400" |
57 | " SA6i P600 P800 P400 P400i E200 E200i"); | 57 | " SA6i P600 P800 P400 P400i E200 E200i"); |
58 | MODULE_LICENSE("GPL"); | 58 | MODULE_LICENSE("GPL"); |
@@ -103,7 +103,7 @@ static const struct pci_device_id cciss_pci_device_id[] = { | |||
103 | }; | 103 | }; |
104 | MODULE_DEVICE_TABLE(pci, cciss_pci_device_id); | 104 | MODULE_DEVICE_TABLE(pci, cciss_pci_device_id); |
105 | 105 | ||
106 | #define NR_PRODUCTS (sizeof(products)/sizeof(struct board_type)) | 106 | #define NR_PRODUCTS ARRAY_SIZE(products) |
107 | 107 | ||
108 | /* board_id = Subsystem Device ID & Vendor ID | 108 | /* board_id = Subsystem Device ID & Vendor ID |
109 | * product = Marketing Name for the board | 109 | * product = Marketing Name for the board |
@@ -153,6 +153,7 @@ static int cciss_open(struct inode *inode, struct file *filep); | |||
153 | static int cciss_release(struct inode *inode, struct file *filep); | 153 | static int cciss_release(struct inode *inode, struct file *filep); |
154 | static int cciss_ioctl(struct inode *inode, struct file *filep, | 154 | static int cciss_ioctl(struct inode *inode, struct file *filep, |
155 | unsigned int cmd, unsigned long arg); | 155 | unsigned int cmd, unsigned long arg); |
156 | static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo); | ||
156 | 157 | ||
157 | static int revalidate_allvol(ctlr_info_t *host); | 158 | static int revalidate_allvol(ctlr_info_t *host); |
158 | static int cciss_revalidate(struct gendisk *disk); | 159 | static int cciss_revalidate(struct gendisk *disk); |
@@ -166,7 +167,7 @@ static void cciss_geometry_inquiry(int ctlr, int logvol, | |||
166 | unsigned int block_size, InquiryData_struct *inq_buff, | 167 | unsigned int block_size, InquiryData_struct *inq_buff, |
167 | drive_info_struct *drv); | 168 | drive_info_struct *drv); |
168 | static void cciss_getgeometry(int cntl_num); | 169 | static void cciss_getgeometry(int cntl_num); |
169 | 170 | static void __devinit cciss_interrupt_mode(ctlr_info_t *, struct pci_dev *, __u32); | |
170 | static void start_io( ctlr_info_t *h); | 171 | static void start_io( ctlr_info_t *h); |
171 | static int sendcmd( __u8 cmd, int ctlr, void *buff, size_t size, | 172 | static int sendcmd( __u8 cmd, int ctlr, void *buff, size_t size, |
172 | unsigned int use_unit_num, unsigned int log_unit, __u8 page_code, | 173 | unsigned int use_unit_num, unsigned int log_unit, __u8 page_code, |
@@ -194,6 +195,7 @@ static struct block_device_operations cciss_fops = { | |||
194 | .open = cciss_open, | 195 | .open = cciss_open, |
195 | .release = cciss_release, | 196 | .release = cciss_release, |
196 | .ioctl = cciss_ioctl, | 197 | .ioctl = cciss_ioctl, |
198 | .getgeo = cciss_getgeo, | ||
197 | #ifdef CONFIG_COMPAT | 199 | #ifdef CONFIG_COMPAT |
198 | .compat_ioctl = cciss_compat_ioctl, | 200 | .compat_ioctl = cciss_compat_ioctl, |
199 | #endif | 201 | #endif |
@@ -282,7 +284,7 @@ static int cciss_proc_get_info(char *buffer, char **start, off_t offset, | |||
282 | h->product_name, | 284 | h->product_name, |
283 | (unsigned long)h->board_id, | 285 | (unsigned long)h->board_id, |
284 | h->firm_ver[0], h->firm_ver[1], h->firm_ver[2], h->firm_ver[3], | 286 | h->firm_ver[0], h->firm_ver[1], h->firm_ver[2], h->firm_ver[3], |
285 | (unsigned int)h->intr, | 287 | (unsigned int)h->intr[SIMPLE_MODE_INT], |
286 | h->num_luns, | 288 | h->num_luns, |
287 | h->Qdepth, h->commands_outstanding, | 289 | h->Qdepth, h->commands_outstanding, |
288 | h->maxQsinceinit, h->max_outstanding, h->maxSG); | 290 | h->maxQsinceinit, h->max_outstanding, h->maxSG); |
@@ -633,6 +635,20 @@ static int cciss_ioctl32_big_passthru(struct file *file, unsigned cmd, unsigned | |||
633 | return err; | 635 | return err; |
634 | } | 636 | } |
635 | #endif | 637 | #endif |
638 | |||
639 | static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo) | ||
640 | { | ||
641 | drive_info_struct *drv = get_drv(bdev->bd_disk); | ||
642 | |||
643 | if (!drv->cylinders) | ||
644 | return -ENXIO; | ||
645 | |||
646 | geo->heads = drv->heads; | ||
647 | geo->sectors = drv->sectors; | ||
648 | geo->cylinders = drv->cylinders; | ||
649 | return 0; | ||
650 | } | ||
651 | |||
636 | /* | 652 | /* |
637 | * ioctl | 653 | * ioctl |
638 | */ | 654 | */ |
@@ -651,21 +667,6 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, | |||
651 | #endif /* CCISS_DEBUG */ | 667 | #endif /* CCISS_DEBUG */ |
652 | 668 | ||
653 | switch(cmd) { | 669 | switch(cmd) { |
654 | case HDIO_GETGEO: | ||
655 | { | ||
656 | struct hd_geometry driver_geo; | ||
657 | if (drv->cylinders) { | ||
658 | driver_geo.heads = drv->heads; | ||
659 | driver_geo.sectors = drv->sectors; | ||
660 | driver_geo.cylinders = drv->cylinders; | ||
661 | } else | ||
662 | return -ENXIO; | ||
663 | driver_geo.start= get_start_sect(inode->i_bdev); | ||
664 | if (copy_to_user(argp, &driver_geo, sizeof(struct hd_geometry))) | ||
665 | return -EFAULT; | ||
666 | return(0); | ||
667 | } | ||
668 | |||
669 | case CCISS_GETPCIINFO: | 670 | case CCISS_GETPCIINFO: |
670 | { | 671 | { |
671 | cciss_pci_info_struct pciinfo; | 672 | cciss_pci_info_struct pciinfo; |
@@ -2177,16 +2178,48 @@ static inline void resend_cciss_cmd( ctlr_info_t *h, CommandList_struct *c) | |||
2177 | 2178 | ||
2178 | start_io(h); | 2179 | start_io(h); |
2179 | } | 2180 | } |
2181 | |||
2182 | static void cciss_softirq_done(struct request *rq) | ||
2183 | { | ||
2184 | CommandList_struct *cmd = rq->completion_data; | ||
2185 | ctlr_info_t *h = hba[cmd->ctlr]; | ||
2186 | u64bit temp64; | ||
2187 | int i, ddir; | ||
2188 | |||
2189 | if (cmd->Request.Type.Direction == XFER_READ) | ||
2190 | ddir = PCI_DMA_FROMDEVICE; | ||
2191 | else | ||
2192 | ddir = PCI_DMA_TODEVICE; | ||
2193 | |||
2194 | /* command did not need to be retried */ | ||
2195 | /* unmap the DMA mapping for all the scatter gather elements */ | ||
2196 | for(i=0; i<cmd->Header.SGList; i++) { | ||
2197 | temp64.val32.lower = cmd->SG[i].Addr.lower; | ||
2198 | temp64.val32.upper = cmd->SG[i].Addr.upper; | ||
2199 | pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir); | ||
2200 | } | ||
2201 | |||
2202 | complete_buffers(rq->bio, rq->errors); | ||
2203 | |||
2204 | #ifdef CCISS_DEBUG | ||
2205 | printk("Done with %p\n", rq); | ||
2206 | #endif /* CCISS_DEBUG */ | ||
2207 | |||
2208 | spin_lock_irq(&h->lock); | ||
2209 | end_that_request_last(rq, rq->errors); | ||
2210 | cmd_free(h, cmd,1); | ||
2211 | spin_unlock_irq(&h->lock); | ||
2212 | } | ||
2213 | |||
2180 | /* checks the status of the job and calls complete buffers to mark all | 2214 | /* checks the status of the job and calls complete buffers to mark all |
2181 | * buffers for the completed job. | 2215 | * buffers for the completed job. Note that this function does not need |
2216 | * to hold the hba/queue lock. | ||
2182 | */ | 2217 | */ |
2183 | static inline void complete_command( ctlr_info_t *h, CommandList_struct *cmd, | 2218 | static inline void complete_command( ctlr_info_t *h, CommandList_struct *cmd, |
2184 | int timeout) | 2219 | int timeout) |
2185 | { | 2220 | { |
2186 | int status = 1; | 2221 | int status = 1; |
2187 | int i; | ||
2188 | int retry_cmd = 0; | 2222 | int retry_cmd = 0; |
2189 | u64bit temp64; | ||
2190 | 2223 | ||
2191 | if (timeout) | 2224 | if (timeout) |
2192 | status = 0; | 2225 | status = 0; |
@@ -2294,24 +2327,10 @@ static inline void complete_command( ctlr_info_t *h, CommandList_struct *cmd, | |||
2294 | resend_cciss_cmd(h,cmd); | 2327 | resend_cciss_cmd(h,cmd); |
2295 | return; | 2328 | return; |
2296 | } | 2329 | } |
2297 | /* command did not need to be retried */ | ||
2298 | /* unmap the DMA mapping for all the scatter gather elements */ | ||
2299 | for(i=0; i<cmd->Header.SGList; i++) { | ||
2300 | temp64.val32.lower = cmd->SG[i].Addr.lower; | ||
2301 | temp64.val32.upper = cmd->SG[i].Addr.upper; | ||
2302 | pci_unmap_page(hba[cmd->ctlr]->pdev, | ||
2303 | temp64.val, cmd->SG[i].Len, | ||
2304 | (cmd->Request.Type.Direction == XFER_READ) ? | ||
2305 | PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE); | ||
2306 | } | ||
2307 | complete_buffers(cmd->rq->bio, status); | ||
2308 | 2330 | ||
2309 | #ifdef CCISS_DEBUG | 2331 | cmd->rq->completion_data = cmd; |
2310 | printk("Done with %p\n", cmd->rq); | 2332 | cmd->rq->errors = status; |
2311 | #endif /* CCISS_DEBUG */ | 2333 | blk_complete_request(cmd->rq); |
2312 | |||
2313 | end_that_request_last(cmd->rq, status ? 1 : -EIO); | ||
2314 | cmd_free(h,cmd,1); | ||
2315 | } | 2334 | } |
2316 | 2335 | ||
2317 | /* | 2336 | /* |
@@ -2661,6 +2680,60 @@ static int find_PCI_BAR_index(struct pci_dev *pdev, | |||
2661 | return -1; | 2680 | return -1; |
2662 | } | 2681 | } |
2663 | 2682 | ||
2683 | /* If MSI/MSI-X is supported by the kernel we will try to enable it on | ||
2684 | * controllers that are capable. If not, we use IO-APIC mode. | ||
2685 | */ | ||
2686 | |||
2687 | static void __devinit cciss_interrupt_mode(ctlr_info_t *c, struct pci_dev *pdev, __u32 board_id) | ||
2688 | { | ||
2689 | #ifdef CONFIG_PCI_MSI | ||
2690 | int err; | ||
2691 | struct msix_entry cciss_msix_entries[4] = {{0,0}, {0,1}, | ||
2692 | {0,2}, {0,3}}; | ||
2693 | |||
2694 | /* Some boards advertise MSI but don't really support it */ | ||
2695 | if ((board_id == 0x40700E11) || | ||
2696 | (board_id == 0x40800E11) || | ||
2697 | (board_id == 0x40820E11) || | ||
2698 | (board_id == 0x40830E11)) | ||
2699 | goto default_int_mode; | ||
2700 | |||
2701 | if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) { | ||
2702 | err = pci_enable_msix(pdev, cciss_msix_entries, 4); | ||
2703 | if (!err) { | ||
2704 | c->intr[0] = cciss_msix_entries[0].vector; | ||
2705 | c->intr[1] = cciss_msix_entries[1].vector; | ||
2706 | c->intr[2] = cciss_msix_entries[2].vector; | ||
2707 | c->intr[3] = cciss_msix_entries[3].vector; | ||
2708 | c->msix_vector = 1; | ||
2709 | return; | ||
2710 | } | ||
2711 | if (err > 0) { | ||
2712 | printk(KERN_WARNING "cciss: only %d MSI-X vectors " | ||
2713 | "available\n", err); | ||
2714 | } else { | ||
2715 | printk(KERN_WARNING "cciss: MSI-X init failed %d\n", | ||
2716 | err); | ||
2717 | } | ||
2718 | } | ||
2719 | if (pci_find_capability(pdev, PCI_CAP_ID_MSI)) { | ||
2720 | if (!pci_enable_msi(pdev)) { | ||
2721 | c->intr[SIMPLE_MODE_INT] = pdev->irq; | ||
2722 | c->msi_vector = 1; | ||
2723 | return; | ||
2724 | } else { | ||
2725 | printk(KERN_WARNING "cciss: MSI init failed\n"); | ||
2726 | c->intr[SIMPLE_MODE_INT] = pdev->irq; | ||
2727 | return; | ||
2728 | } | ||
2729 | } | ||
2730 | #endif /* CONFIG_PCI_MSI */ | ||
2731 | /* if we get here we're going to use the default interrupt mode */ | ||
2732 | default_int_mode: | ||
2733 | c->intr[SIMPLE_MODE_INT] = pdev->irq; | ||
2734 | return; | ||
2735 | } | ||
2736 | |||
2664 | static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) | 2737 | static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) |
2665 | { | 2738 | { |
2666 | ushort subsystem_vendor_id, subsystem_device_id, command; | 2739 | ushort subsystem_vendor_id, subsystem_device_id, command; |
@@ -2721,7 +2794,10 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) | |||
2721 | printk("board_id = %x\n", board_id); | 2794 | printk("board_id = %x\n", board_id); |
2722 | #endif /* CCISS_DEBUG */ | 2795 | #endif /* CCISS_DEBUG */ |
2723 | 2796 | ||
2724 | c->intr = pdev->irq; | 2797 | /* If the kernel supports MSI/MSI-X we will try to enable that functionality, |
2798 | * else we use the IO-APIC interrupt assigned to us by system ROM. | ||
2799 | */ | ||
2800 | cciss_interrupt_mode(c, pdev, board_id); | ||
2725 | 2801 | ||
2726 | /* | 2802 | /* |
2727 | * Memory base addr is first addr , the second points to the config | 2803 | * Memory base addr is first addr , the second points to the config |
@@ -2775,7 +2851,7 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) | |||
2775 | c->board_id = board_id; | 2851 | c->board_id = board_id; |
2776 | 2852 | ||
2777 | #ifdef CCISS_DEBUG | 2853 | #ifdef CCISS_DEBUG |
2778 | print_cfg_table(c->cfgtable); | 2854 | print_cfg_table(c->cfgtable); |
2779 | #endif /* CCISS_DEBUG */ | 2855 | #endif /* CCISS_DEBUG */ |
2780 | 2856 | ||
2781 | for(i=0; i<NR_PRODUCTS; i++) { | 2857 | for(i=0; i<NR_PRODUCTS; i++) { |
@@ -3060,7 +3136,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
3060 | * 8 controller support. | 3136 | * 8 controller support. |
3061 | */ | 3137 | */ |
3062 | if (i < MAX_CTLR_ORIG) | 3138 | if (i < MAX_CTLR_ORIG) |
3063 | hba[i]->major = MAJOR_NR + i; | 3139 | hba[i]->major = COMPAQ_CISS_MAJOR + i; |
3064 | rc = register_blkdev(hba[i]->major, hba[i]->devname); | 3140 | rc = register_blkdev(hba[i]->major, hba[i]->devname); |
3065 | if(rc == -EBUSY || rc == -EINVAL) { | 3141 | if(rc == -EBUSY || rc == -EINVAL) { |
3066 | printk(KERN_ERR | 3142 | printk(KERN_ERR |
@@ -3075,11 +3151,11 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
3075 | 3151 | ||
3076 | /* make sure the board interrupts are off */ | 3152 | /* make sure the board interrupts are off */ |
3077 | hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_OFF); | 3153 | hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_OFF); |
3078 | if( request_irq(hba[i]->intr, do_cciss_intr, | 3154 | if( request_irq(hba[i]->intr[SIMPLE_MODE_INT], do_cciss_intr, |
3079 | SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, | 3155 | SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, |
3080 | hba[i]->devname, hba[i])) { | 3156 | hba[i]->devname, hba[i])) { |
3081 | printk(KERN_ERR "cciss: Unable to get irq %d for %s\n", | 3157 | printk(KERN_ERR "cciss: Unable to get irq %d for %s\n", |
3082 | hba[i]->intr, hba[i]->devname); | 3158 | hba[i]->intr[SIMPLE_MODE_INT], hba[i]->devname); |
3083 | goto clean2; | 3159 | goto clean2; |
3084 | } | 3160 | } |
3085 | hba[i]->cmd_pool_bits = kmalloc(((NR_CMDS+BITS_PER_LONG-1)/BITS_PER_LONG)*sizeof(unsigned long), GFP_KERNEL); | 3161 | hba[i]->cmd_pool_bits = kmalloc(((NR_CMDS+BITS_PER_LONG-1)/BITS_PER_LONG)*sizeof(unsigned long), GFP_KERNEL); |
@@ -3141,15 +3217,17 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
3141 | drv->queue = q; | 3217 | drv->queue = q; |
3142 | 3218 | ||
3143 | q->backing_dev_info.ra_pages = READ_AHEAD; | 3219 | q->backing_dev_info.ra_pages = READ_AHEAD; |
3144 | blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask); | 3220 | blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask); |
3145 | 3221 | ||
3146 | /* This is a hardware imposed limit. */ | 3222 | /* This is a hardware imposed limit. */ |
3147 | blk_queue_max_hw_segments(q, MAXSGENTRIES); | 3223 | blk_queue_max_hw_segments(q, MAXSGENTRIES); |
3148 | 3224 | ||
3149 | /* This is a limit in the driver and could be eliminated. */ | 3225 | /* This is a limit in the driver and could be eliminated. */ |
3150 | blk_queue_max_phys_segments(q, MAXSGENTRIES); | 3226 | blk_queue_max_phys_segments(q, MAXSGENTRIES); |
3151 | 3227 | ||
3152 | blk_queue_max_sectors(q, 512); | 3228 | blk_queue_max_sectors(q, 512); |
3229 | |||
3230 | blk_queue_softirq_done(q, cciss_softirq_done); | ||
3153 | 3231 | ||
3154 | q->queuedata = hba[i]; | 3232 | q->queuedata = hba[i]; |
3155 | sprintf(disk->disk_name, "cciss/c%dd%d", i, j); | 3233 | sprintf(disk->disk_name, "cciss/c%dd%d", i, j); |
@@ -3185,7 +3263,7 @@ clean4: | |||
3185 | NR_CMDS * sizeof( ErrorInfo_struct), | 3263 | NR_CMDS * sizeof( ErrorInfo_struct), |
3186 | hba[i]->errinfo_pool, | 3264 | hba[i]->errinfo_pool, |
3187 | hba[i]->errinfo_pool_dhandle); | 3265 | hba[i]->errinfo_pool_dhandle); |
3188 | free_irq(hba[i]->intr, hba[i]); | 3266 | free_irq(hba[i]->intr[SIMPLE_MODE_INT], hba[i]); |
3189 | clean2: | 3267 | clean2: |
3190 | unregister_blkdev(hba[i]->major, hba[i]->devname); | 3268 | unregister_blkdev(hba[i]->major, hba[i]->devname); |
3191 | clean1: | 3269 | clean1: |
@@ -3226,7 +3304,15 @@ static void __devexit cciss_remove_one (struct pci_dev *pdev) | |||
3226 | printk(KERN_WARNING "Error Flushing cache on controller %d\n", | 3304 | printk(KERN_WARNING "Error Flushing cache on controller %d\n", |
3227 | i); | 3305 | i); |
3228 | } | 3306 | } |
3229 | free_irq(hba[i]->intr, hba[i]); | 3307 | free_irq(hba[i]->intr[2], hba[i]); |
3308 | |||
3309 | #ifdef CONFIG_PCI_MSI | ||
3310 | if (hba[i]->msix_vector) | ||
3311 | pci_disable_msix(hba[i]->pdev); | ||
3312 | else if (hba[i]->msi_vector) | ||
3313 | pci_disable_msi(hba[i]->pdev); | ||
3314 | #endif /* CONFIG_PCI_MSI */ | ||
3315 | |||
3230 | pci_set_drvdata(pdev, NULL); | 3316 | pci_set_drvdata(pdev, NULL); |
3231 | iounmap(hba[i]->vaddr); | 3317 | iounmap(hba[i]->vaddr); |
3232 | cciss_unregister_scsi(i); /* unhook from SCSI subsystem */ | 3318 | cciss_unregister_scsi(i); /* unhook from SCSI subsystem */ |