diff options
| -rw-r--r-- | drivers/scsi/3w-9xxx.c | 101 | ||||
| -rw-r--r-- | drivers/scsi/3w-9xxx.h | 2 |
2 files changed, 100 insertions, 3 deletions
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index 5311317c2e4c..a12783ebb42d 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | Written By: Adam Radford <linuxraid@amcc.com> | 4 | Written By: Adam Radford <linuxraid@amcc.com> |
| 5 | Modifications By: Tom Couch <linuxraid@amcc.com> | 5 | Modifications By: Tom Couch <linuxraid@amcc.com> |
| 6 | 6 | ||
| 7 | Copyright (C) 2004-2008 Applied Micro Circuits Corporation. | 7 | Copyright (C) 2004-2009 Applied Micro Circuits Corporation. |
| 8 | 8 | ||
| 9 | This program is free software; you can redistribute it and/or modify | 9 | This program is free software; you can redistribute it and/or modify |
| 10 | it under the terms of the GNU General Public License as published by | 10 | it under the terms of the GNU General Public License as published by |
| @@ -75,6 +75,7 @@ | |||
| 75 | Add MSI support and "use_msi" module parameter. | 75 | Add MSI support and "use_msi" module parameter. |
| 76 | Fix bug in twa_get_param() on 4GB+. | 76 | Fix bug in twa_get_param() on 4GB+. |
| 77 | Use pci_resource_len() for ioremap(). | 77 | Use pci_resource_len() for ioremap(). |
| 78 | 2.26.02.012 - Add power management support. | ||
| 78 | */ | 79 | */ |
| 79 | 80 | ||
| 80 | #include <linux/module.h> | 81 | #include <linux/module.h> |
| @@ -99,7 +100,7 @@ | |||
| 99 | #include "3w-9xxx.h" | 100 | #include "3w-9xxx.h" |
| 100 | 101 | ||
| 101 | /* Globals */ | 102 | /* Globals */ |
| 102 | #define TW_DRIVER_VERSION "2.26.02.011" | 103 | #define TW_DRIVER_VERSION "2.26.02.012" |
| 103 | static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT]; | 104 | static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT]; |
| 104 | static unsigned int twa_device_extension_count; | 105 | static unsigned int twa_device_extension_count; |
| 105 | static int twa_major = -1; | 106 | static int twa_major = -1; |
| @@ -2182,6 +2183,98 @@ static void twa_remove(struct pci_dev *pdev) | |||
| 2182 | twa_device_extension_count--; | 2183 | twa_device_extension_count--; |
| 2183 | } /* End twa_remove() */ | 2184 | } /* End twa_remove() */ |
| 2184 | 2185 | ||
| 2186 | #ifdef CONFIG_PM | ||
| 2187 | /* This function is called on PCI suspend */ | ||
| 2188 | static int twa_suspend(struct pci_dev *pdev, pm_message_t state) | ||
| 2189 | { | ||
| 2190 | struct Scsi_Host *host = pci_get_drvdata(pdev); | ||
| 2191 | TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata; | ||
| 2192 | |||
| 2193 | printk(KERN_WARNING "3w-9xxx: Suspending host %d.\n", tw_dev->host->host_no); | ||
| 2194 | |||
| 2195 | TW_DISABLE_INTERRUPTS(tw_dev); | ||
| 2196 | free_irq(tw_dev->tw_pci_dev->irq, tw_dev); | ||
| 2197 | |||
| 2198 | if (test_bit(TW_USING_MSI, &tw_dev->flags)) | ||
| 2199 | pci_disable_msi(pdev); | ||
| 2200 | |||
| 2201 | /* Tell the card we are shutting down */ | ||
| 2202 | if (twa_initconnection(tw_dev, 1, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL)) { | ||
| 2203 | TW_PRINTK(tw_dev->host, TW_DRIVER, 0x38, "Connection shutdown failed during suspend"); | ||
| 2204 | } else { | ||
| 2205 | printk(KERN_WARNING "3w-9xxx: Suspend complete.\n"); | ||
| 2206 | } | ||
| 2207 | TW_CLEAR_ALL_INTERRUPTS(tw_dev); | ||
| 2208 | |||
| 2209 | pci_save_state(pdev); | ||
| 2210 | pci_disable_device(pdev); | ||
| 2211 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
| 2212 | |||
| 2213 | return 0; | ||
| 2214 | } /* End twa_suspend() */ | ||
| 2215 | |||
| 2216 | /* This function is called on PCI resume */ | ||
| 2217 | static int twa_resume(struct pci_dev *pdev) | ||
| 2218 | { | ||
| 2219 | int retval = 0; | ||
| 2220 | struct Scsi_Host *host = pci_get_drvdata(pdev); | ||
| 2221 | TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata; | ||
| 2222 | |||
| 2223 | printk(KERN_WARNING "3w-9xxx: Resuming host %d.\n", tw_dev->host->host_no); | ||
| 2224 | pci_set_power_state(pdev, PCI_D0); | ||
| 2225 | pci_enable_wake(pdev, PCI_D0, 0); | ||
| 2226 | pci_restore_state(pdev); | ||
| 2227 | |||
| 2228 | retval = pci_enable_device(pdev); | ||
| 2229 | if (retval) { | ||
| 2230 | TW_PRINTK(tw_dev->host, TW_DRIVER, 0x39, "Enable device failed during resume"); | ||
| 2231 | return retval; | ||
| 2232 | } | ||
| 2233 | |||
| 2234 | pci_set_master(pdev); | ||
| 2235 | pci_try_set_mwi(pdev); | ||
| 2236 | |||
| 2237 | if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) | ||
| 2238 | || pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) | ||
| 2239 | if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) | ||
| 2240 | || pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) { | ||
| 2241 | TW_PRINTK(host, TW_DRIVER, 0x40, "Failed to set dma mask during resume"); | ||
| 2242 | retval = -ENODEV; | ||
| 2243 | goto out_disable_device; | ||
| 2244 | } | ||
| 2245 | |||
| 2246 | /* Initialize the card */ | ||
| 2247 | if (twa_reset_sequence(tw_dev, 0)) { | ||
| 2248 | retval = -ENODEV; | ||
| 2249 | goto out_disable_device; | ||
| 2250 | } | ||
| 2251 | |||
| 2252 | /* Now setup the interrupt handler */ | ||
| 2253 | retval = request_irq(pdev->irq, twa_interrupt, IRQF_SHARED, "3w-9xxx", tw_dev); | ||
| 2254 | if (retval) { | ||
| 2255 | TW_PRINTK(tw_dev->host, TW_DRIVER, 0x42, "Error requesting IRQ during resume"); | ||
| 2256 | retval = -ENODEV; | ||
| 2257 | goto out_disable_device; | ||
| 2258 | } | ||
| 2259 | |||
| 2260 | /* Now enable MSI if enabled */ | ||
| 2261 | if (test_bit(TW_USING_MSI, &tw_dev->flags)) | ||
| 2262 | pci_enable_msi(pdev); | ||
| 2263 | |||
| 2264 | /* Re-enable interrupts on the card */ | ||
| 2265 | TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev); | ||
| 2266 | |||
| 2267 | printk(KERN_WARNING "3w-9xxx: Resume complete.\n"); | ||
| 2268 | return 0; | ||
| 2269 | |||
| 2270 | out_disable_device: | ||
| 2271 | scsi_remove_host(host); | ||
| 2272 | pci_disable_device(pdev); | ||
| 2273 | |||
| 2274 | return retval; | ||
| 2275 | } /* End twa_resume() */ | ||
| 2276 | #endif | ||
| 2277 | |||
| 2185 | /* PCI Devices supported by this driver */ | 2278 | /* PCI Devices supported by this driver */ |
| 2186 | static struct pci_device_id twa_pci_tbl[] __devinitdata = { | 2279 | static struct pci_device_id twa_pci_tbl[] __devinitdata = { |
| 2187 | { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9000, | 2280 | { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9000, |
| @@ -2202,6 +2295,10 @@ static struct pci_driver twa_driver = { | |||
| 2202 | .id_table = twa_pci_tbl, | 2295 | .id_table = twa_pci_tbl, |
| 2203 | .probe = twa_probe, | 2296 | .probe = twa_probe, |
| 2204 | .remove = twa_remove, | 2297 | .remove = twa_remove, |
| 2298 | #ifdef CONFIG_PM | ||
| 2299 | .suspend = twa_suspend, | ||
| 2300 | .resume = twa_resume, | ||
| 2301 | #endif | ||
| 2205 | .shutdown = twa_shutdown | 2302 | .shutdown = twa_shutdown |
| 2206 | }; | 2303 | }; |
| 2207 | 2304 | ||
diff --git a/drivers/scsi/3w-9xxx.h b/drivers/scsi/3w-9xxx.h index 1729a8785fea..2893eec78ed2 100644 --- a/drivers/scsi/3w-9xxx.h +++ b/drivers/scsi/3w-9xxx.h | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | Written By: Adam Radford <linuxraid@amcc.com> | 4 | Written By: Adam Radford <linuxraid@amcc.com> |
| 5 | Modifications By: Tom Couch <linuxraid@amcc.com> | 5 | Modifications By: Tom Couch <linuxraid@amcc.com> |
| 6 | 6 | ||
| 7 | Copyright (C) 2004-2008 Applied Micro Circuits Corporation. | 7 | Copyright (C) 2004-2009 Applied Micro Circuits Corporation. |
| 8 | 8 | ||
| 9 | This program is free software; you can redistribute it and/or modify | 9 | This program is free software; you can redistribute it and/or modify |
| 10 | it under the terms of the GNU General Public License as published by | 10 | it under the terms of the GNU General Public License as published by |
