Skip to contentSkip to conversation

aic7xxx: Add suspend/resume support

PATCH In review Hannes Reinecke 2 participants 5 messages Oct 19, 2007

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

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.

---
 drivers/scsi/aic7xxx/aic7770.c         |   16 ----------
 drivers/scsi/aic7xxx/aic79xx.h         |   11 +++++++
 drivers/scsi/aic7xxx/aic79xx_core.c    |    7 +----
 drivers/scsi/aic7xxx/aic79xx_osm_pci.c |   50 ++++++++++++++++++++++++++++++++
 drivers/scsi/aic7xxx/aic79xx_pci.c     |   27 +++++++++++++++++
 drivers/scsi/aic7xxx/aic7xxx.h         |   11 +------
 drivers/scsi/aic7xxx/aic7xxx_osm_pci.c |   46 +++++++++++++++++++++++++++++
 drivers/scsi/aic7xxx/aic7xxx_pci.c     |   16 +---------
 8 files changed, 137 insertions(+), 47 deletions(-)
drivers/scsi/aic7xxx/aic7770.c +0 -16
index c4d1723..6d86a9b 100644
@@ -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.
  */
drivers/scsi/aic7xxx/aic79xx.h +11 -0
index 27adbb2..ce638aa 100644
@@ -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;
@@ -1333,6 +1340,8 @@ struct	ahd_pci_identity *ahd_find_pci_device(ahd_dev_softc_t);
 int			  ahd_pci_config(struct ahd_softc *,
 					 struct ahd_pci_identity *);
 int	ahd_pci_test_register_access(struct ahd_softc *);
+void	ahd_pci_suspend(struct ahd_softc *);
+void	ahd_pci_resume(struct ahd_softc *);
 
 /************************** SCB and SCB queue management **********************/
 void		ahd_qinfifo_requeue_tail(struct ahd_softc *ahd,
@@ -1343,6 +1352,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);
+int			 ahd_suspend(struct ahd_softc *ahd);
+void			 ahd_resume(struct ahd_softc *ahd);
 int			 ahd_default_config(struct ahd_softc *ahd);
 int			 ahd_parse_vpddata(struct ahd_softc *ahd,
 					   struct vpd_config *vpd);
drivers/scsi/aic7xxx/aic79xx_core.c +1 -6
index 05f692b..a7dd8cd 100644
@@ -7175,7 +7175,6 @@ ahd_pause_and_flushwork(struct ahd_softc *ahd)
 	ahd->flags &= ~AHD_ALL_INTERRUPTS;
 }
 
-#if 0
 int
 ahd_suspend(struct ahd_softc *ahd)
 {
@@ -7189,19 +7188,15 @@ ahd_suspend(struct ahd_softc *ahd)
 	ahd_shutdown(ahd);
 	return (0);
 }
-#endif  /*  0  */
 
-#if 0
-int
+void
 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 *********************************/
 /*
drivers/scsi/aic7xxx/aic79xx_osm_pci.c +50 -0

66 lines not on this page · raw message

drivers/scsi/aic7xxx/aic79xx_pci.c +27 -0
index 0bada00..7a203a9 100644
@@ -389,6 +389,33 @@ ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry)
 	return error;
 }
 
+void
+ahd_pci_suspend(struct ahd_softc *ahd)
+{
+	/*
+	 * Save chip register configuration data for chip resets
+	 * that occur during runtime and resume events.
+	 */
+	ahd->suspend_state.pci_state.devconfig =
+	    ahd_pci_read_config(ahd->dev_softc, DEVCONFIG, /*bytes*/4);
+	ahd->suspend_state.pci_state.command =
+	    ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/1);
+	ahd->suspend_state.pci_state.csize_lattime =
+	    ahd_pci_read_config(ahd->dev_softc, CSIZE_LATTIME, /*bytes*/1);
+
+}
+
+void
+ahd_pci_resume(struct ahd_softc *ahd)
+{
+	ahd_pci_write_config(ahd->dev_softc, DEVCONFIG,
+			     ahd->suspend_state.pci_state.devconfig, /*bytes*/4);
+	ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND,
+			     ahd->suspend_state.pci_state.command, /*bytes*/1);
+	ahd_pci_write_config(ahd->dev_softc, CSIZE_LATTIME,
+			     ahd->suspend_state.pci_state.csize_lattime, /*bytes*/1);
+}
+
 /*
  * Perform some simple tests that should catch situations where
  * our registers are invalidly mapped.
drivers/scsi/aic7xxx/aic7xxx.h +1 -10
index e1bd57b..3d4e42d 100644
@@ -962,16 +962,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 +1143,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);
drivers/scsi/aic7xxx/aic7xxx_osm_pci.c +46 -0

62 lines not on this page · raw message

drivers/scsi/aic7xxx/aic7xxx_pci.c +1 -15
index 09c8172..ae35937 100644
@@ -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
Signature · 1 line
1.5.2.4
#1 lore raw

I think this needs a little restructuring. ahd_pci_suspend/ahd_pci_resume should be merged into their callers and use the normal Linux pci accessors, and ahd_suspend/ahd_resume are tiny enough to merged into the caller aswell.

drivers/scsi/aic7xxx/aic79xx_osm_pci.c MODULE_DEVICE_TABLE(pci, ahd_linux_pci_id_table); · line 100

Quoted 10 lines
drivers/scsi/aic7xxx/aic79xx_osm_pci.c +6 -0
+#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
 };
 
+static int
+ahd_linux_pci_dev_suspend(struct pci_dev *pdev, pm_message_t mesg)

I think this needsa #ifdef CONFIG_PM aswell. Also any chance you could implement functions before their use so we can avoid forward declarations.

drivers/scsi/aic7xxx/aic79xx_osm_pci.c MODULE_DEVICE_TABLE(pci, ahd_linux_pci_id_table); · line 106

Quoted 6 lines
drivers/scsi/aic7xxx/aic79xx_osm_pci.c +6 -0
+{
+	struct ahd_softc *ahd = pci_get_drvdata(pdev);
+	int rc;
+
+	if ((rc = ahd_suspend(ahd)))
+		return rc;
	rc = ahd_suspend(ahd)
	if (rc)
		return rc;

but as I mentioned above better just inline the content of ahd_suspend into this function. That would also catch that ahd_suspend returns positive errno values and we'd have to invert them here.

Same comments apply to the aic7xxx portion.

author Tested-by Jens Axboe
#2 lore raw
Quoted 4 lines · Christoph Hellwig

I think this needs a little restructuring. ahd_pci_suspend/ahd_pci_resume should be merged into their callers and use the normal Linux pci accessors, and ahd_suspend/ahd_resume are tiny enough to merged into the caller aswell.

Yes, partially. ahc_pci_resume() has to stay there as it uses quite some functions from aic7xxx_pci.c. And I'd rather keep the overall structure (ie split between linux-specific and generic pci access) for now. In the long run it should be restructured as we don't do cross-compilation with ***BSD anymore.

Quoted 8 lines
Quoted 8 lines
(quoted diff) +4 -0
+#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
 };
Quoted 7 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+static int
+ahd_linux_pci_dev_suspend(struct pci_dev *pdev, pm_message_t mesg)

I think this needsa #ifdef CONFIG_PM aswell. Also any chance you could implement functions before their use so we can avoid forward declarations.

Yes, no problem.

Quoted 11 lines

Review

Quoted 6 lines
(quoted diff) +6 -0
+{
+	struct ahd_softc *ahd = pci_get_drvdata(pdev);
+	int rc;
+
+	if ((rc = ahd_suspend(ahd)))
+		return rc;
	rc = ahd_suspend(ahd)
	if (rc)
		return rc;
Quoted 4 lines

but as I mentioned above better just inline the content of ahd_suspend into this function. That would also catch that ahd_suspend returns positive errno values and we'd have to invert them here.

Ok. Done.
Updated patch attached.
More to your liking?

Cheers,

Hannes

Signature · 4 lines
Dr. Hannes Reinecke		      zSeries & Storage
[email protected]			      +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Markus Rex, HRB 16746 (AG Nürnberg)
Quoted 1 line

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.

---
 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 |  109 ++++++++++++++++++++++++++------
 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 |   88 +++++++++++++++++++++-----
 drivers/scsi/aic7xxx/aic7xxx_pci.c     |   16 +-----
 10 files changed, 204 insertions(+), 175 deletions(-)
drivers/scsi/aic7xxx/aic7770.c +0 -16
index c4d1723..6d86a9b 100644
@@ -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.
  */
drivers/scsi/aic7xxx/aic79xx.h +9 -0
index 27adbb2..a96a2ff 100644
@@ -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);
drivers/scsi/aic7xxx/aic79xx_core.c +2 -31
index 05f692b..91f6f4f 100644
@@ -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
drivers/scsi/aic7xxx/aic79xx_osm_pci.c +90 -19

145 lines not on this page · raw message

drivers/scsi/aic7xxx/aic79xx_pci.c +0 -24
index 0bada00..c8617e0 100644
@@ -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);
drivers/scsi/aic7xxx/aic79xx_pci.h +25 -0
index 16b7c70..67ea5ae 100644
@@ -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_ */
drivers/scsi/aic7xxx/aic7xxx.h +3 -15
index e1bd57b..80ceeaf 100644
@@ -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);
drivers/scsi/aic7xxx/aic7xxx_core.c +1 -40

56 lines not on this page · raw message

drivers/scsi/aic7xxx/aic7xxx_osm_pci.c +73 -15

106 lines not on this page · raw message

drivers/scsi/aic7xxx/aic7xxx_pci.c +1 -15
index 09c8172..ae35937 100644
@@ -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
#3 lore raw
Quoted 10 lines · Hannes Reinecke
Quoted 4 lines · Christoph Hellwig

I think this needs a little restructuring. ahd_pci_suspend/ahd_pci_resume should be merged into their callers and use the normal Linux pci accessors, and ahd_suspend/ahd_resume are tiny enough to merged into the caller aswell.

Yes, partially. ahc_pci_resume() has to stay there as it uses quite some functions from aic7xxx_pci.c. And I'd rather keep the overall structure (ie split between linux-specific and generic pci access) for now. In the long run it should be restructured as we don't do cross-compilation with ***BSD anymore.

Ok..

Quoted 3 lines

Ok. Done.
Updated patch attached.
More to your liking?

Much better. There's still some if ((rc = fo())) left, but it's probably not worth to delay the patch further because of that. Just clean it up in a followon patch.

author Tested-by Jens Axboe
#4 lore raw
Quoted 1 line · Christoph Hellwig

On Fri, Oct 19, 2007 at 02:35:35PM +0200, Hannes Reinecke wrote:

[ .. ]

Quoted 8 lines
Quoted 3 lines

Ok. Done.
Updated patch attached.
More to your liking?

Much better. There's still some if ((rc = fo())) left, but it's probably not worth to delay the patch further because of that. Just clean it up in a followon patch.

Might as well do it now. Fixed patch attached.

Cheers,

Hannes

Signature · 4 lines
Dr. Hannes Reinecke		      zSeries & Storage
[email protected]			      +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Markus Rex, HRB 16746 (AG Nürnberg)
Quoted 1 line

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.

---
 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(-)
drivers/scsi/aic7xxx/aic7770.c +0 -16
index c4d1723..6d86a9b 100644
@@ -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.
  */
drivers/scsi/aic7xxx/aic79xx.h +9 -0
index 27adbb2..a96a2ff 100644
@@ -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);
drivers/scsi/aic7xxx/aic79xx_core.c +2 -31
index 05f692b..91f6f4f 100644
@@ -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
drivers/scsi/aic7xxx/aic79xx_osm_pci.c +92 -20

154 lines not on this page · raw message

drivers/scsi/aic7xxx/aic79xx_pci.c +0 -24
index 0bada00..c8617e0 100644
@@ -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);
drivers/scsi/aic7xxx/aic79xx_pci.h +25 -0
index 16b7c70..67ea5ae 100644
@@ -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_ */
drivers/scsi/aic7xxx/aic7xxx.h +3 -15
index e1bd57b..80ceeaf 100644
@@ -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);
drivers/scsi/aic7xxx/aic7xxx_core.c +1 -40

56 lines not on this page · raw message

drivers/scsi/aic7xxx/aic7xxx_osm_pci.c +75 -16

115 lines not on this page · raw message

drivers/scsi/aic7xxx/aic7xxx_pci.c +1 -15
index 09c8172..ae35937 100644
@@ -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