public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
From: Nathan Bryant <nbryant@optonline.net>
To: linux-scsi@vger.kernel.org
Cc: random1@o-o.yi.org, Luben Tuikov <luben_tuikov@adaptec.com>,
	pavel@ucw.cz
Subject: [patch] ACPI work on aic7xxx
Date: Tue, 20 Jul 2004 11:22:08 -0400	[thread overview]
Message-ID: <40FD38A0.3000603@optonline.net> (raw)

[-- Attachment #1: Type: text/plain, Size: 2003 bytes --]

Attached is a patch against 2.6.8-rc that supplies some more of the 
missing pieces of ACPI support for the aic7xxx driver.

--- Background and current driver status:
The 6.2.36 driver in current mainline 2.6 kernels contains the OS- and 
bus- neutral portions of the suspend/resume callbacks (ahc_resume() in 
aic7xxx_core.c and ahc_pci_resume() in aic7xxx_pci.c.) These stubs are 
mostly concerned with the card's own registers, and don't perform the 
requisite linux-specific calls to save and restore PCI config space and 
re-enable the card slot. It also appears that these callbacks were being 
developed by eyeball and were never tested. (Of course, not many people 
could test it since ACPI core wasn't in a usable state until recent 2.6)

As a consequence, after a resume the card I/O space is not visible under 
the current driver, and the driver would panic the kernel with the "Loop 
1" message. (See 
http://marc.theaimsgroup.com/?l=linux-scsi&m=102710764330862&w=2) This 
patch fixes that part. We now renable the slot and interrupts properly, 
and then call the previously-implemented resume routines (with just some 
obvious fixes) to attempt to reinitialize the card.

--- Where we are now:
It still doesn't work. The driver complains, "scsi0: Someone reset 
channel A" repeatedly. This message is coming from the driver's 
interrupt handler, so either the card registers are improperly 
reinitialized in some way, or the driver's state engine is not clearing 
the interrupt status, or we're somehow causing the reset to occur again 
and again. I'm not sure how much further I can take this without a data 
book or some help figuring out the card and driver state machines. I 
guess either the card's state machine or the driver's state machine has 
been driven insane, but I'm not sure what direction to look in.

This patch also includes a small fix for a bad merge, as suggested by 
Pavel Machec. See 
http://marc.theaimsgroup.com/?l=linux-scsi&m=108306129820558&w=2


Nathan Bryant

[-- Attachment #2: aic7xxx_acpi.patch --]
[-- Type: text/plain, Size: 6030 bytes --]

diff -urN linux-2.6.7-1.492.backup/drivers/scsi/aic7xxx/aic7xxx.h linux-2.6.7-1.492/drivers/scsi/aic7xxx/aic7xxx.h
--- linux-2.6.7-1.492.backup/drivers/scsi/aic7xxx/aic7xxx.h	2004-06-16 01:19:29.000000000 -0400
+++ linux-2.6.7-1.492/drivers/scsi/aic7xxx/aic7xxx.h	2004-07-19 23:27:51.000000000 -0400
@@ -1109,6 +1109,8 @@
 
 	uint16_t	 	  user_discenable;/* Disconnection allowed  */
 	uint16_t		  user_tagenable;/* Tagged Queuing allowed */
+
+	u32                      PciState[64]; /* save PCI state to this area */
 };
 
 TAILQ_HEAD(ahc_softc_tailq, ahc_softc);
diff -urN linux-2.6.7-1.492.backup/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c linux-2.6.7-1.492/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
--- linux-2.6.7-1.492.backup/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c	2004-07-15 14:23:17.000000000 -0400
+++ linux-2.6.7-1.492/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c	2004-07-20 00:34:30.000000000 -0400
@@ -54,6 +54,10 @@
 static int	ahc_linux_pci_reserve_mem_region(struct ahc_softc *ahc,
 						 u_long *bus_addr,
 						 uint8_t **maddr);
+#ifdef CONFIG_PM
+static int	ahc_linux_pci_suspend(struct pci_dev *dev, u32 state);
+static int	ahc_linux_pci_resume(struct pci_dev *dev);
+#endif
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 static void	ahc_linux_pci_dev_remove(struct pci_dev *pdev);
 
@@ -76,6 +80,10 @@
 	.name		= "aic7xxx",
 	.probe		= ahc_linux_pci_dev_probe,
 	.remove		= ahc_linux_pci_dev_remove,
+#ifdef CONFIG_PM
+	.suspend	= ahc_linux_pci_suspend,
+	.resume		= ahc_linux_pci_resume,
+#endif
 	.id_table	= ahc_linux_pci_id_table
 };
 
@@ -225,6 +233,72 @@
 #endif
 }
 
+#ifdef CONFIG_PM
+int ahc_linux_pci_suspend(struct pci_dev *dev, u32 state)
+{
+	int rval;
+	u32 device_state;
+	struct ahc_softc *ahc =
+		ahc_find_softc((struct ahc_softc *)pci_get_drvdata(dev));
+
+#if 0
+        switch(state)
+        {
+                case 1: /* S1 */
+                        device_state=1; /* D1 */;
+                        break;
+                case 3: /* S3 */
+                case 4: /* S4 */
+                        device_state=3; /* D3 */;
+                        break;
+                default:
+                        return -EAGAIN /*FIXME*/;
+                        break;
+        }
+#else
+	device_state = state;
+#endif
+
+        printk(KERN_INFO
+        "aic7xxx: pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
+                dev, pci_name(dev), device_state);
+
+	rval = ahc->bus_suspend(ahc);
+	if (rval != 0)
+		return rval;
+
+	pci_save_state(dev, ahc->PciState);
+	pci_disable_device(dev);
+	pci_set_power_state(dev, device_state);
+	return 0;
+}
+
+int ahc_linux_pci_resume(struct pci_dev *dev)
+{
+	int rval;
+	int device_state = dev->current_state;
+	struct ahc_softc *ahc =
+		ahc_find_softc((struct ahc_softc *)pci_get_drvdata(dev));
+
+        printk(KERN_INFO
+        "aic7xxx: pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
+                dev, pci_name(dev), device_state);
+
+        pci_set_power_state(dev, AHC_POWER_STATE_D0);
+        pci_restore_state(dev, ahc->PciState);
+        pci_enable_device(dev);
+        pci_set_master(dev);
+
+	rval = ahc->bus_resume(ahc);
+#ifdef AHC_DEBUG
+	if (ahc_debug & AHC_SHOW_MISC) {
+		ahc_dump_card_state(ahc);
+	}
+#endif
+	return rval;
+}
+#endif /* CONFIG_PM */
+
 void
 ahc_linux_pci_exit(void)
 {
diff -urN linux-2.6.7-1.492.backup/drivers/scsi/aic7xxx/aic7xxx_pci.c linux-2.6.7-1.492/drivers/scsi/aic7xxx/aic7xxx_pci.c
--- linux-2.6.7-1.492.backup/drivers/scsi/aic7xxx/aic7xxx_pci.c	2004-06-16 01:18:57.000000000 -0400
+++ linux-2.6.7-1.492/drivers/scsi/aic7xxx/aic7xxx_pci.c	2004-07-19 23:32:21.000000000 -0400
@@ -834,8 +834,8 @@
 	ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, devconfig, /*bytes*/4);
 
 	/* Ensure busmastering is enabled */
-	command = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/2);
-	command |= PCIM_CMD_BUSMASTEREN;
+        command = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/2);
+        command |= PCIM_CMD_BUSMASTEREN;
 
 	ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, command, /*bytes*/2);
 
@@ -2090,21 +2090,18 @@
 static int
 ahc_pci_resume(struct ahc_softc *ahc)
 {
-
-	ahc_power_state_change(ahc, AHC_POWER_STATE_D0);
-
 	/*
 	 * We assume that the OS has restored our register
 	 * mappings, etc.  Just update the config space registers
 	 * that the OS doesn't know about and rely on our chip
 	 * reset handler to handle the rest.
 	 */
-	ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4,
-			     ahc->bus_softc.pci_softc.devconfig);
-	ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/1,
-			     ahc->bus_softc.pci_softc.command);
-	ahc_pci_write_config(ahc->dev_softc, CSIZE_LATTIME, /*bytes*/1,
-			     ahc->bus_softc.pci_softc.csize_lattime);
+	ahc_pci_write_config(ahc->dev_softc, DEVCONFIG,
+			     ahc->bus_softc.pci_softc.devconfig, /*bytes*/4);
+	ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND,
+			     ahc->bus_softc.pci_softc.command, /*bytes*/1);
+	ahc_pci_write_config(ahc->dev_softc, CSIZE_LATTIME,
+			     ahc->bus_softc.pci_softc.csize_lattime, /*bytes*/1);
 	if ((ahc->flags & AHC_HAS_TERM_LOGIC) != 0) {
 		struct	seeprom_descriptor sd;
 		u_int	sxfrctl1;
--- linux-2.6.7-1.486/drivers/scsi/aic7xxx/aic7xxx_osm.c.orig	2004-07-14 18:45:39.695469069 -0400
+++ linux-2.6.7-1.486/drivers/scsi/aic7xxx/aic7xxx_osm.c	2004-07-14 18:46:55.160968771 -0400
@@ -2295,7 +2295,7 @@
 	sprintf(current->comm, "ahc_dv_%d", ahc->unit);
 #else
 	daemonize("ahc_dv_%d", ahc->unit);
-	current->flags |= PF_FREEZE;
+	current->flags |= PF_NOFREEZE;
 #endif
 	unlock_kernel();
 
--- linux-2.6.7-1.486/drivers/scsi/aic7xxx/aic79xx_osm.c.orig	2004-07-14 18:46:09.524239111 -0400
+++ linux-2.6.7-1.486/drivers/scsi/aic7xxx/aic79xx_osm.c	2004-07-14 18:47:09.707290430 -0400
@@ -2591,7 +2591,7 @@
 	sprintf(current->comm, "ahd_dv_%d", ahd->unit);
 #else
 	daemonize("ahd_dv_%d", ahd->unit);
-	current->flags |= PF_FREEZE;
+	current->flags |= PF_NOFREEZE;
 #endif
 	unlock_kernel();
 

             reply	other threads:[~2004-07-20 15:21 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-07-20 15:22 Nathan Bryant [this message]
2004-07-20 15:59 ` [patch] ACPI work on aic7xxx Pavel Machek
2004-07-20 16:48   ` Nathan Bryant
2004-07-20 17:46     ` device_suspend() levels [was Re: [patch] ACPI work on aic7xxx] Pavel Machek
2004-07-20 18:10       ` Nathan Bryant
2004-07-20 18:25         ` Benjamin Herrenschmidt
2004-07-20 18:34           ` Nathan Bryant
2004-07-20 19:10             ` Benjamin Herrenschmidt
2004-07-20 19:23               ` Pavel Machek
     [not found]               ` <40FD82B1.8030704@optonline.net>
     [not found]                 ` <1090356079.1993.12.camel@gaston>
     [not found]                   ` <40FD85A3.2060502@optonline.net>
     [not found]                     ` <1090357324.1993.15.camel@gaston>
     [not found]                       ` <410280E9.5040001@optonline.net>
     [not found]                         ` <1090684826.1963.6.camel@gaston>
     [not found]                           ` <41029215.1030406@optonline.net>
     [not found]                             ` <1090694118.1971.13.camel@gaston>
2004-07-25  0:19                               ` Nathan Bryant
2004-07-25 22:10                                 ` Benjamin Herrenschmidt
2004-07-26  7:32                                   ` Andre Hedrick
2004-07-28  1:18                                     ` Benjamin Herrenschmidt
2004-07-26 14:02                                   ` Nathan Bryant
2004-07-28  1:16                                     ` Benjamin Herrenschmidt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=40FD38A0.3000603@optonline.net \
    --to=nbryant@optonline.net \
    --cc=linux-scsi@vger.kernel.org \
    --cc=luben_tuikov@adaptec.com \
    --cc=pavel@ucw.cz \
    --cc=random1@o-o.yi.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox