Git-Url: http://git.frugalware.org/gitweb/gitweb.cgi?p=frugalware-current.git;a=commitdiff;h=a9cb21ed8d132da38d84e58e474d3506f6c75270
commit a9cb21ed8d132da38d84e58e474d3506f6c75270 Author: Miklos Vajna <[EMAIL PROTECTED]> Date: Thu Oct 25 22:39:40 2007 +0200 kernel-2.6.23-1-i686 added patch to fix suspent for aic7xxx cards from crazy diff --git a/source/base/kernel/FrugalBuild b/source/base/kernel/FrugalBuild index 2f7f7b7..fdaf9b2 100644 --- a/source/base/kernel/FrugalBuild +++ b/source/base/kernel/FrugalBuild @@ -1,4 +1,5 @@ # Compiling Time: 11.74 SBU # Maintainer: VMiklos <[EMAIL PROTECTED]> +_F_kernel_patches=('aic7xxx-suspend.patch') Finclude kernel diff --git a/source/base/kernel/aic7xxx-suspend.patch b/source/base/kernel/aic7xxx-suspend.patch new file mode 100644 index 0000000..0ba3571 --- /dev/null +++ b/source/base/kernel/aic7xxx-suspend.patch @@ -0,0 +1,691 @@ +From 2dc1cdee053846fafc98a819bdad1533ac7c2f04 Mon Sep 17 00:00:00 2001 +From: Hannes Reinecke <[EMAIL PROTECTED]> +Date: Fri, 19 Oct 2007 09:13:17 +0200 +Subject: [PATCH 1/4] aic7xxx: Add suspend/resume support + +The aic7xxx driver already contains fragments for suspend/resume +support. So we only need to update them to the current interface +and have full PCI suspend/resume. + +Signed-off-by: Hannes Reinecke <[EMAIL PROTECTED]> +Tested-by: Jens Axboe <[EMAIL PROTECTED]> +--- + drivers/scsi/aic7xxx/aic7770.c | 16 ----- + drivers/scsi/aic7xxx/aic79xx.h | 9 +++ + drivers/scsi/aic7xxx/aic79xx_core.c | 33 +--------- + drivers/scsi/aic7xxx/aic79xx_osm_pci.c | 112 ++++++++++++++++++++++++++------ + drivers/scsi/aic7xxx/aic79xx_pci.c | 24 ------- + drivers/scsi/aic7xxx/aic79xx_pci.h | 25 +++++++ + drivers/scsi/aic7xxx/aic7xxx.h | 18 +---- + drivers/scsi/aic7xxx/aic7xxx_core.c | 41 +----------- + drivers/scsi/aic7xxx/aic7xxx_osm_pci.c | 91 +++++++++++++++++++++----- + drivers/scsi/aic7xxx/aic7xxx_pci.c | 16 +---- + 10 files changed, 208 insertions(+), 177 deletions(-) + +diff --git a/drivers/scsi/aic7xxx/aic7770.c b/drivers/scsi/aic7xxx/aic7770.c +index c4d1723..6d86a9b 100644 +--- a/drivers/scsi/aic7xxx/aic7770.c ++++ b/drivers/scsi/aic7xxx/aic7770.c +@@ -60,8 +60,6 @@ + #define ID_OLV_274xD 0x04907783 /* Olivetti OEM (Differential) */ + + static int aic7770_chip_init(struct ahc_softc *ahc); +-static int aic7770_suspend(struct ahc_softc *ahc); +-static int aic7770_resume(struct ahc_softc *ahc); + static int aha2840_load_seeprom(struct ahc_softc *ahc); + static ahc_device_setup_t ahc_aic7770_VL_setup; + static ahc_device_setup_t ahc_aic7770_EISA_setup; +@@ -155,8 +153,6 @@ aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry, u_int io) + return (error); + + ahc->bus_chip_init = aic7770_chip_init; +- ahc->bus_suspend = aic7770_suspend; +- ahc->bus_resume = aic7770_resume; + + error = ahc_reset(ahc, /*reinit*/FALSE); + if (error != 0) +@@ -272,18 +268,6 @@ aic7770_chip_init(struct ahc_softc *ahc) + return (ahc_chip_init(ahc)); + } + +-static int +-aic7770_suspend(struct ahc_softc *ahc) +-{ +- return (ahc_suspend(ahc)); +-} +- +-static int +-aic7770_resume(struct ahc_softc *ahc) +-{ +- return (ahc_resume(ahc)); +-} +- + /* + * Read the 284x SEEPROM. + */ +diff --git a/drivers/scsi/aic7xxx/aic79xx.h b/drivers/scsi/aic7xxx/aic79xx.h +index 27adbb2..a96a2ff 100644 +--- a/drivers/scsi/aic7xxx/aic79xx.h ++++ b/drivers/scsi/aic7xxx/aic79xx.h +@@ -1003,8 +1003,15 @@ struct ahd_suspend_channel_state { + uint8_t seqctl; + }; + ++struct ahd_suspend_pci_state { ++ uint32_t devconfig; ++ uint8_t command; ++ uint8_t csize_lattime; ++}; ++ + struct ahd_suspend_state { + struct ahd_suspend_channel_state channel[2]; ++ struct ahd_suspend_pci_state pci_state; + uint8_t optionmode; + uint8_t dscommand0; + uint8_t dspcistatus; +@@ -1343,6 +1350,8 @@ struct ahd_softc *ahd_alloc(void *platform_arg, char *name); + int ahd_softc_init(struct ahd_softc *); + void ahd_controller_info(struct ahd_softc *ahd, char *buf); + int ahd_init(struct ahd_softc *ahd); ++void ahd_shutdown(void *arg); ++void ahd_restart(struct ahd_softc *ahd); + int ahd_default_config(struct ahd_softc *ahd); + int ahd_parse_vpddata(struct ahd_softc *ahd, + struct vpd_config *vpd); +diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c +index 05f692b..91f6f4f 100644 +--- a/drivers/scsi/aic7xxx/aic79xx_core.c ++++ b/drivers/scsi/aic7xxx/aic79xx_core.c +@@ -255,7 +255,6 @@ static void ahd_freeze_devq(struct ahd_softc *ahd, + static void ahd_handle_scb_status(struct ahd_softc *ahd, + struct scb *scb); + static struct ahd_phase_table_entry* ahd_lookup_phase_entry(int phase); +-static void ahd_shutdown(void *arg); + static void ahd_update_coalescing_values(struct ahd_softc *ahd, + u_int timer, + u_int maxcmds, +@@ -357,7 +356,7 @@ ahd_complete_scb(struct ahd_softc *ahd, struct scb *scb) + /* + * Restart the sequencer program from address zero + */ +-static void ++void + ahd_restart(struct ahd_softc *ahd) + { + +@@ -5456,7 +5455,7 @@ ahd_free(struct ahd_softc *ahd) + return; + } + +-static void ++void + ahd_shutdown(void *arg) + { + struct ahd_softc *ahd; +@@ -7175,34 +7174,6 @@ ahd_pause_and_flushwork(struct ahd_softc *ahd) + ahd->flags &= ~AHD_ALL_INTERRUPTS; + } + +-#if 0 +-int +-ahd_suspend(struct ahd_softc *ahd) +-{ +- +- ahd_pause_and_flushwork(ahd); +- +- if (LIST_FIRST(&ahd->pending_scbs) != NULL) { +- ahd_unpause(ahd); +- return (EBUSY); +- } +- ahd_shutdown(ahd); +- return (0); +-} +-#endif /* 0 */ +- +-#if 0 +-int +-ahd_resume(struct ahd_softc *ahd) +-{ +- +- ahd_reset(ahd, /*reinit*/TRUE); +- ahd_intr_enable(ahd, TRUE); +- ahd_restart(ahd); +- return (0); +-} +-#endif /* 0 */ +- + /************************** Busy Target Table *********************************/ + /* + * Set SCBPTR to the SCB that contains the busy +diff --git a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c +index c62ce41..8aa6302 100644 +--- a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c ++++ b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c +@@ -43,15 +43,6 @@ + #include "aic79xx_inline.h" + #include "aic79xx_pci.h" + +-static int ahd_linux_pci_dev_probe(struct pci_dev *pdev, +- const struct pci_device_id *ent); +-static int ahd_linux_pci_reserve_io_regions(struct ahd_softc *ahd, +- u_long *base, u_long *base2); +-static int ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd, +- u_long *bus_addr, +- uint8_t __iomem **maddr); +-static void ahd_linux_pci_dev_remove(struct pci_dev *pdev); +- + /* Define the macro locally since it's different for different class of chips. + */ + #define ID(x) \ +@@ -83,12 +74,82 @@ static struct pci_device_id ahd_linux_pci_id_table[] = { + + MODULE_DEVICE_TABLE(pci, ahd_linux_pci_id_table); + +-static struct pci_driver aic79xx_pci_driver = { +- .name = "aic79xx", +- .probe = ahd_linux_pci_dev_probe, +- .remove = ahd_linux_pci_dev_remove, +- .id_table = ahd_linux_pci_id_table +-}; ++#ifdef CONFIG_PM ++int ++ahd_linux_pci_dev_suspend(struct pci_dev *pdev, pm_message_t mesg) ++{ ++ struct ahd_softc *ahd = pci_get_drvdata(pdev); ++ ++ /* ++ * Shutdown the HBA ++ */ ++ ahd_pause_and_flushwork(ahd); ++ ++ if (LIST_FIRST(&ahd->pending_scbs) != NULL) { ++ ahd_unpause(ahd); ++ return -EBUSY; ++ } ++ ++ ahd_shutdown(ahd); ++ ++ /* ++ * Save chip register configuration data for chip resets ++ * that occur during runtime and resume events. ++ */ ++ pci_read_config_dword(ahd->dev_softc, DEVCONFIG, ++ &ahd->suspend_state.pci_state.devconfig); ++ pci_read_config_byte(ahd->dev_softc, PCIR_COMMAND, ++ &ahd->suspend_state.pci_state.command); ++ pci_read_config_byte(ahd->dev_softc, CSIZE_LATTIME, ++ &ahd->suspend_state.pci_state.csize_lattime); ++ ++ pci_save_state(pdev); ++ pci_disable_device(pdev); ++ ++ if (mesg.event == PM_EVENT_SUSPEND) ++ pci_set_power_state(pdev, PCI_D3hot); ++ ++ return 0; ++} ++ ++int ++ahd_linux_pci_dev_resume(struct pci_dev *pdev) ++{ ++ struct ahd_softc *ahd = pci_get_drvdata(pdev); ++ int rc; ++ ++ pci_set_power_state(pdev, PCI_D0); ++ pci_restore_state(pdev); ++ ++ rc = pci_enable_device(pdev); ++ if (rc) { ++ dev_printk(KERN_ERR, &pdev->dev, ++ "failed to enable device after resume (%d)\n", rc); ++ return rc; ++ } ++ ++ pci_set_master(pdev); ++ ++ /* ++ * Restore additional PCI registers ++ */ ++ pci_write_config_dword(ahd->dev_softc, DEVCONFIG, ++ ahd->suspend_state.pci_state.devconfig); ++ pci_write_config_byte(ahd->dev_softc, PCIR_COMMAND, ++ ahd->suspend_state.pci_state.command); ++ pci_write_config_byte(ahd->dev_softc, CSIZE_LATTIME, ++ ahd->suspend_state.pci_state.csize_lattime); ++ ++ /* ++ * Restart the HBA ++ */ ++ ahd_reset(ahd, /*reinit*/TRUE); ++ ahd_intr_enable(ahd, TRUE); ++ ahd_restart(ahd); ++ ++ return 0; ++} ++#endif /* CONFIG_PM */ + + static void + ahd_linux_pci_dev_remove(struct pci_dev *pdev) +@@ -97,7 +158,7 @@ ahd_linux_pci_dev_remove(struct pci_dev *pdev) + u_long s; + + if (ahd->platform_data && ahd->platform_data->host) +- scsi_remove_host(ahd->platform_data->host); ++ scsi_remove_host(ahd->platform_data->host); + + ahd_lock(ahd, &s); + ahd_intr_enable(ahd, FALSE); +@@ -195,6 +256,17 @@ ahd_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + return (0); + } + ++static struct pci_driver aic79xx_pci_driver = { ++ .name = "aic79xx", ++ .probe = ahd_linux_pci_dev_probe, ++#ifdef CONFIG_PM ++ .suspend = ahd_linux_pci_dev_suspend, ++ .resume = ahd_linux_pci_dev_resume, ++#endif ++ .remove = ahd_linux_pci_dev_remove, ++ .id_table = ahd_linux_pci_id_table ++}; ++ + int + ahd_linux_pci_init(void) + { +@@ -276,7 +348,7 @@ ahd_pci_map_registers(struct ahd_softc *ahd) + /* + * If its allowed, we prefer memory mapped access. + */ +- command = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, 4); ++ pci_read_config_dword(ahd->dev_softc, PCIR_COMMAND, &command); + command &= ~(PCIM_CMD_PORTEN|PCIM_CMD_MEMEN); + base = 0; + maddr = NULL; +@@ -287,8 +359,8 @@ ahd_pci_map_registers(struct ahd_softc *ahd) + ahd->bshs[0].maddr = maddr; + ahd->tags[1] = BUS_SPACE_MEMIO; + ahd->bshs[1].maddr = maddr + 0x100; +- ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, +- command | PCIM_CMD_MEMEN, 4); ++ pci_write_config_dword(ahd->dev_softc, PCIR_COMMAND, ++ command | PCIM_CMD_MEMEN); + + if (ahd_pci_test_register_access(ahd) != 0) { + +@@ -332,7 +404,7 @@ ahd_pci_map_registers(struct ahd_softc *ahd) + base, base2); + } + } +- ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, command, 4); ++ pci_write_config_dword(ahd->dev_softc, PCIR_COMMAND, command); + return (error); + } + +diff --git a/drivers/scsi/aic7xxx/aic79xx_pci.c b/drivers/scsi/aic7xxx/aic79xx_pci.c +index 0bada00..c8617e0 100644 +--- a/drivers/scsi/aic7xxx/aic79xx_pci.c ++++ b/drivers/scsi/aic7xxx/aic79xx_pci.c +@@ -209,12 +209,6 @@ static struct ahd_pci_identity ahd_pci_ident_table [] = + + static const u_int ahd_num_pci_devs = ARRAY_SIZE(ahd_pci_ident_table); + +-#define DEVCONFIG 0x40 +-#define PCIXINITPAT 0x0000E000ul +-#define PCIXINIT_PCI33_66 0x0000E000ul +-#define PCIXINIT_PCIX50_66 0x0000C000ul +-#define PCIXINIT_PCIX66_100 0x0000A000ul +-#define PCIXINIT_PCIX100_133 0x00008000ul + #define PCI_BUS_MODES_INDEX(devconfig) \ + (((devconfig) & PCIXINITPAT) >> 13) + static const char *pci_bus_modes[] = +@@ -229,24 +223,6 @@ static const char *pci_bus_modes[] = + "PCI 33 or 66Mhz" + }; + +-#define TESTMODE 0x00000800ul +-#define IRDY_RST 0x00000200ul +-#define FRAME_RST 0x00000100ul +-#define PCI64BIT 0x00000080ul +-#define MRDCEN 0x00000040ul +-#define ENDIANSEL 0x00000020ul +-#define MIXQWENDIANEN 0x00000008ul +-#define DACEN 0x00000004ul +-#define STPWLEVEL 0x00000002ul +-#define QWENDIANSEL 0x00000001ul +- +-#define DEVCONFIG1 0x44 +-#define PREQDIS 0x01 +- +-#define CSIZE_LATTIME 0x0c +-#define CACHESIZE 0x000000fful +-#define LATTIME 0x0000ff00ul +- + static int ahd_check_extport(struct ahd_softc *ahd); + static void ahd_configure_termination(struct ahd_softc *ahd, + u_int adapter_control); +diff --git a/drivers/scsi/aic7xxx/aic79xx_pci.h b/drivers/scsi/aic7xxx/aic79xx_pci.h +index 16b7c70..67ea5ae 100644 +--- a/drivers/scsi/aic7xxx/aic79xx_pci.h ++++ b/drivers/scsi/aic7xxx/aic79xx_pci.h +@@ -69,4 +69,29 @@ + #define ID_AHA_39320D_HP 0x8011900500AC0E11ull + #define ID_AHA_39320D_B_HP 0x801C900500AC0E11ull + ++#define DEVCONFIG 0x40 ++#define PCIXINITPAT 0x0000E000ul ++#define PCIXINIT_PCI33_66 0x0000E000ul ++#define PCIXINIT_PCIX50_66 0x0000C000ul ++#define PCIXINIT_PCIX66_100 0x0000A000ul ++#define PCIXINIT_PCIX100_133 0x00008000ul ++ ++#define TESTMODE 0x00000800ul ++#define IRDY_RST 0x00000200ul ++#define FRAME_RST 0x00000100ul ++#define PCI64BIT 0x00000080ul ++#define MRDCEN 0x00000040ul ++#define ENDIANSEL 0x00000020ul ++#define MIXQWENDIANEN 0x00000008ul ++#define DACEN 0x00000004ul ++#define STPWLEVEL 0x00000002ul ++#define QWENDIANSEL 0x00000001ul ++ ++#define DEVCONFIG1 0x44 ++#define PREQDIS 0x01 ++ ++#define CSIZE_LATTIME 0x0c ++#define CACHESIZE 0x000000fful ++#define LATTIME 0x0000ff00ul ++ + #endif /* _AIC79XX_PCI_H_ */ +diff --git a/drivers/scsi/aic7xxx/aic7xxx.h b/drivers/scsi/aic7xxx/aic7xxx.h +index e1bd57b..80ceeaf 100644 +--- a/drivers/scsi/aic7xxx/aic7xxx.h ++++ b/drivers/scsi/aic7xxx/aic7xxx.h +@@ -899,8 +899,6 @@ union ahc_bus_softc { + + typedef void (*ahc_bus_intr_t)(struct ahc_softc *); + typedef int (*ahc_bus_chip_init_t)(struct ahc_softc *); +-typedef int (*ahc_bus_suspend_t)(struct ahc_softc *); +-typedef int (*ahc_bus_resume_t)(struct ahc_softc *); + typedef void ahc_callback_t (void *); + + struct ahc_softc { +@@ -962,16 +960,6 @@ struct ahc_softc { + ahc_bus_chip_init_t bus_chip_init; + + /* +- * Bus specific suspend routine. +- */ +- ahc_bus_suspend_t bus_suspend; +- +- /* +- * Bus specific resume routine. +- */ +- ahc_bus_resume_t bus_resume; +- +- /* + * Target mode related state kept on a per enabled lun basis. + * Targets that are not enabled will have null entries. + * As an initiator, we keep one target entry for our initiator +@@ -1153,6 +1141,7 @@ struct ahc_pci_identity *ahc_find_pci_device(ahc_dev_softc_t); + int ahc_pci_config(struct ahc_softc *, + struct ahc_pci_identity *); + int ahc_pci_test_register_access(struct ahc_softc *); ++void ahc_pci_resume(struct ahc_softc *ahc); + + /*************************** EISA/VL Front End ********************************/ + struct aic7770_identity *aic7770_find_device(uint32_t); +@@ -1179,14 +1168,13 @@ int ahc_chip_init(struct ahc_softc *ahc); + int ahc_init(struct ahc_softc *ahc); + void ahc_intr_enable(struct ahc_softc *ahc, int enable); + void ahc_pause_and_flushwork(struct ahc_softc *ahc); +-int ahc_suspend(struct ahc_softc *ahc); +-int ahc_resume(struct ahc_softc *ahc); + void ahc_set_unit(struct ahc_softc *, int); + void ahc_set_name(struct ahc_softc *, char *); + void ahc_alloc_scbs(struct ahc_softc *ahc); + void ahc_free(struct ahc_softc *ahc); + int ahc_reset(struct ahc_softc *ahc, int reinit); +-void ahc_shutdown(void *arg); ++void ahc_restart(struct ahc_softc *ahc); ++void ahc_shutdown(struct ahc_softc *ahc); + + /*************************** Interrupt Services *******************************/ + void ahc_clear_intstat(struct ahc_softc *ahc); +diff --git a/drivers/scsi/aic7xxx/aic7xxx_core.c b/drivers/scsi/aic7xxx/aic7xxx_core.c +index f350b5e..40f7072 100644 +--- a/drivers/scsi/aic7xxx/aic7xxx_core.c ++++ b/drivers/scsi/aic7xxx/aic7xxx_core.c +@@ -3984,13 +3984,10 @@ ahc_free(struct ahc_softc *ahc) + } + + void +-ahc_shutdown(void *arg) ++ahc_shutdown(struct ahc_softc *ahc) + { +- struct ahc_softc *ahc; + int i; + +- ahc = (struct ahc_softc *)arg; +- + /* This will reset most registers to 0, but not all */ + ahc_reset(ahc, /*reinit*/FALSE); + ahc_outb(ahc, SCSISEQ, 0); +@@ -5078,42 +5075,6 @@ ahc_pause_and_flushwork(struct ahc_softc *ahc) + ahc->flags &= ~AHC_ALL_INTERRUPTS; + } + +-int +-ahc_suspend(struct ahc_softc *ahc) +-{ +- +- ahc_pause_and_flushwork(ahc); +- +- if (LIST_FIRST(&ahc->pending_scbs) != NULL) { +- ahc_unpause(ahc); +- return (EBUSY); +- } +- +-#ifdef AHC_TARGET_MODE +- /* +- * XXX What about ATIOs that have not yet been serviced? +- * Perhaps we should just refuse to be suspended if we +- * are acting in a target role. +- */ +- if (ahc->pending_device != NULL) { +- ahc_unpause(ahc); +- return (EBUSY); +- } +-#endif +- ahc_shutdown(ahc); +- return (0); +-} +- +-int +-ahc_resume(struct ahc_softc *ahc) +-{ +- +- ahc_reset(ahc, /*reinit*/TRUE); +- ahc_intr_enable(ahc, TRUE); +- ahc_restart(ahc); +- return (0); +-} +- + /************************** Busy Target Table *********************************/ + /* + * Return the untagged transaction id for a given target/channel lun. +diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c +index ea5687d..847485f 100644 +--- a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c ++++ b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c +@@ -41,15 +41,7 @@ + + #include "aic7xxx_osm.h" + #include "aic7xxx_pci.h" +- +-static int ahc_linux_pci_dev_probe(struct pci_dev *pdev, +- const struct pci_device_id *ent); +-static int ahc_linux_pci_reserve_io_region(struct ahc_softc *ahc, +- u_long *base); +-static int ahc_linux_pci_reserve_mem_region(struct ahc_softc *ahc, +- u_long *bus_addr, +- uint8_t __iomem **maddr); +-static void ahc_linux_pci_dev_remove(struct pci_dev *pdev); ++#include "aic7xxx_inline.h" + + /* Define the macro locally since it's different for different class of chips. + */ +@@ -130,12 +122,68 @@ static struct pci_device_id ahc_linux_pci_id_table[] = { + + MODULE_DEVICE_TABLE(pci, ahc_linux_pci_id_table); + +-static struct pci_driver aic7xxx_pci_driver = { +- .name = "aic7xxx", +- .probe = ahc_linux_pci_dev_probe, +- .remove = ahc_linux_pci_dev_remove, +- .id_table = ahc_linux_pci_id_table +-}; ++#ifdef CONFIG_PM ++static int ++ahc_linux_pci_dev_suspend(struct pci_dev *pdev, pm_message_t mesg) ++{ ++ struct ahc_softc *ahc = pci_get_drvdata(pdev); ++ ++ ahc_pause_and_flushwork(ahc); ++ ++ if (LIST_FIRST(&ahc->pending_scbs) != NULL) { ++ ahc_unpause(ahc); ++ return -EBUSY; ++ } ++ ++#ifdef AHC_TARGET_MODE ++ /* ++ * XXX What about ATIOs that have not yet been serviced? ++ * Perhaps we should just refuse to be suspended if we ++ * are acting in a target role. ++ */ ++ if (ahc->pending_device != NULL) { ++ ahc_unpause(ahc); ++ return -EBUSY; ++ } ++#endif ++ ahc_shutdown(ahc); ++ ++ pci_save_state(pdev); ++ pci_disable_device(pdev); ++ ++ if (mesg.event == PM_EVENT_SUSPEND) ++ pci_set_power_state(pdev, PCI_D3hot); ++ ++ return 0; ++} ++ ++static int ++ahc_linux_pci_dev_resume(struct pci_dev *pdev) ++{ ++ struct ahc_softc *ahc = pci_get_drvdata(pdev); ++ int rc; ++ ++ pci_set_power_state(pdev, PCI_D0); ++ pci_restore_state(pdev); ++ ++ rc = pci_enable_device(pdev); ++ if (rc) { ++ dev_printk(KERN_ERR, &pdev->dev, ++ "failed to enable device after resume (%d)\n", rc); ++ return rc; ++ } ++ ++ pci_set_master(pdev); ++ ++ ahc_pci_resume(ahc); ++ ++ ahc_reset(ahc, /*reinit*/TRUE); ++ ahc_intr_enable(ahc, TRUE); ++ ahc_restart(ahc); ++ ++ return rc; ++} ++#endif /* CONFIG_PM */ + + static void + ahc_linux_pci_dev_remove(struct pci_dev *pdev) +@@ -144,7 +192,7 @@ ahc_linux_pci_dev_remove(struct pci_dev *pdev) + u_long s; + + if (ahc->platform_data && ahc->platform_data->host) +- scsi_remove_host(ahc->platform_data->host); ++ scsi_remove_host(ahc->platform_data->host); + + ahc_lock(ahc, &s); + ahc_intr_enable(ahc, FALSE); +@@ -243,6 +291,17 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + return (0); + } + ++static struct pci_driver aic7xxx_pci_driver = { ++ .name = "aic7xxx", ++ .probe = ahc_linux_pci_dev_probe, ++#ifdef CONFIG_PM ++ .suspend = ahc_linux_pci_dev_suspend, ++ .resume = ahc_linux_pci_dev_resume, ++#endif ++ .remove = ahc_linux_pci_dev_remove, ++ .id_table = ahc_linux_pci_id_table ++}; ++ + int + ahc_linux_pci_init(void) + { +diff --git a/drivers/scsi/aic7xxx/aic7xxx_pci.c b/drivers/scsi/aic7xxx/aic7xxx_pci.c +index 09c8172..ae35937 100644 +--- a/drivers/scsi/aic7xxx/aic7xxx_pci.c ++++ b/drivers/scsi/aic7xxx/aic7xxx_pci.c +@@ -633,8 +633,6 @@ static void write_brdctl(struct ahc_softc *ahc, uint8_t value); + static uint8_t read_brdctl(struct ahc_softc *ahc); + static void ahc_pci_intr(struct ahc_softc *ahc); + static int ahc_pci_chip_init(struct ahc_softc *ahc); +-static int ahc_pci_suspend(struct ahc_softc *ahc); +-static int ahc_pci_resume(struct ahc_softc *ahc); + + static int + ahc_9005_subdevinfo_valid(uint16_t device, uint16_t vendor, +@@ -791,8 +789,6 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry) + + ahc->bus_intr = ahc_pci_intr; + ahc->bus_chip_init = ahc_pci_chip_init; +- ahc->bus_suspend = ahc_pci_suspend; +- ahc->bus_resume = ahc_pci_resume; + + /* Remeber how the card was setup in case there is no SEEPROM */ + if ((ahc_inb(ahc, HCNTRL) & POWRDN) == 0) { +@@ -2024,18 +2020,9 @@ ahc_pci_chip_init(struct ahc_softc *ahc) + return (ahc_chip_init(ahc)); + } + +-static int +-ahc_pci_suspend(struct ahc_softc *ahc) +-{ +- return (ahc_suspend(ahc)); +-} +- +-static int ++void + ahc_pci_resume(struct ahc_softc *ahc) + { +- +- pci_set_power_state(ahc->dev_softc, AHC_POWER_STATE_D0); +- + /* + * We assume that the OS has restored our register + * mappings, etc. Just update the config space registers +@@ -2063,7 +2050,6 @@ ahc_pci_resume(struct ahc_softc *ahc) + &sxfrctl1); + ahc_release_seeprom(&sd); + } +- return (ahc_resume(ahc)); + } + + static int + _______________________________________________ Frugalware-git mailing list Frugalware-git@frugalware.org http://frugalware.org/mailman/listinfo/frugalware-git