[Frugalware-git] kernel-rt: kernel-rt-2.6.23-1-i686

crazy crazy at frugalware.org
Sat Nov 3 18:16:48 CET 2007


Git-Url: http://git.frugalware.org/gitweb/gitweb.cgi?p=kernel-rt.git;a=commitdiff;h=327dbc297d263f9eebc23e02f381b57f534d9ebc

commit 327dbc297d263f9eebc23e02f381b57f534d9ebc
Author: crazy <crazy at frugalware.org>
Date:   Sat Nov 3 18:16:30 2007 +0100

kernel-rt-2.6.23-1-i686
* Upss fogrot the patch

diff --git a/source/base-extra/kernel-rt/aic7xxx-suspend.patch b/source/base-extra/kernel-rt/aic7xxx-suspend.patch
new file mode 100644
index 0000000..0ba3571
--- /dev/null
+++ b/source/base-extra/kernel-rt/aic7xxx-suspend.patch
@@ -0,0 +1,691 @@
+From 2dc1cdee053846fafc98a819bdad1533ac7c2f04 Mon Sep 17 00:00:00 2001
+From: Hannes Reinecke <hare at suse.de>
+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 <hare at suse.de>
+Tested-by: Jens Axboe <jens.axboe at oracle.com>
+---
+ 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
+


More information about the Frugalware-git mailing list