summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgibbs <gibbs@FreeBSD.org>2003-06-06 23:48:19 +0000
committergibbs <gibbs@FreeBSD.org>2003-06-06 23:48:19 +0000
commita0dd99d2907b324d198967c66253fa32d8d96241 (patch)
tree368ec8807c492474b680d3374d98c76ab05a04c4
parent8f82b3111ed84cef05772596e15511672f90e5a3 (diff)
downloadFreeBSD-src-a0dd99d2907b324d198967c66253fa32d8d96241.zip
FreeBSD-src-a0dd99d2907b324d198967c66253fa32d8d96241.tar.gz
aic7770.c:
aic79xx.c: aic79xx.h: aic79xx_pci.c: aic7xxx.c: aic7xxx.h: aic7xxx_pci.c: Switch ah?_reset() to take an additional "reinit" argument. Use this instead of init_level to determin if the chip should be fully reinitialized after a chip reset. This is required so that ah?_shutdown() can reset the chip without side-effects. aic79xx.c: Implement ahd_suspend() and ahd_resume(). aic7xxx.c: Change ahc_loadseq() to *not* restart the sequencer. This brings the loadseq behavior in line with that of the 7902 driver and also simplifies the init routine. Correct the resume routine to enable interrupts and restart the sequencer.
-rw-r--r--sys/dev/aic7xxx/aic7770.c4
-rw-r--r--sys/dev/aic7xxx/aic79xx.c150
-rw-r--r--sys/dev/aic7xxx/aic79xx.h14
-rw-r--r--sys/dev/aic7xxx/aic79xx_pci.c4
-rw-r--r--sys/dev/aic7xxx/aic7xxx.c33
-rw-r--r--sys/dev/aic7xxx/aic7xxx.h4
-rw-r--r--sys/dev/aic7xxx/aic7xxx_pci.c4
7 files changed, 58 insertions, 155 deletions
diff --git a/sys/dev/aic7xxx/aic7770.c b/sys/dev/aic7xxx/aic7770.c
index 4b2511e..7af9b8f 100644
--- a/sys/dev/aic7xxx/aic7770.c
+++ b/sys/dev/aic7xxx/aic7770.c
@@ -37,7 +37,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
- * $Id: //depot/aic7xxx/aic7xxx/aic7770.c#31 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7770.c#32 $
*
* $FreeBSD$
*/
@@ -159,7 +159,7 @@ aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry, u_int io)
ahc->bus_suspend = aic7770_suspend;
ahc->bus_resume = aic7770_resume;
- error = ahc_reset(ahc);
+ error = ahc_reset(ahc, /*reinit*/FALSE);
if (error != 0)
return (error);
diff --git a/sys/dev/aic7xxx/aic79xx.c b/sys/dev/aic7xxx/aic79xx.c
index e8b07be..9c908db 100644
--- a/sys/dev/aic7xxx/aic79xx.c
+++ b/sys/dev/aic7xxx/aic79xx.c
@@ -37,7 +37,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
- * $Id: aic79xx.c,v 1.16 2003/05/26 21:43:29 gibbs Exp $
+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#196 $
*
* $FreeBSD$
*/
@@ -5000,15 +5000,20 @@ ahd_shutdown(void *arg)
ahd_timer_stop(&ahd->stat_timer);
/* This will reset most registers to 0, but not all */
- ahd_reset(ahd);
+ ahd_reset(ahd, /*reinit*/FALSE);
}
/*
* Reset the controller and record some information about it
- * that is only available just after a reset.
+ * that is only available just after a reset. If "reinit" is
+ * non-zero, this reset occured after initial configuration
+ * and the caller requests that the chip be fully reinitialized
+ * to a runable state. Chip interrupts are *not* enabled after
+ * a reinitialization. The caller must enable interrupts via
+ * ahd_intr_enable().
*/
int
-ahd_reset(struct ahd_softc *ahd)
+ahd_reset(struct ahd_softc *ahd, int reinit)
{
u_int sxfrctl1;
int wait;
@@ -5101,7 +5106,7 @@ ahd_reset(struct ahd_softc *ahd)
* If a recovery action has forced a chip reset,
* re-initialize the chip to our liking.
*/
- if (ahd->init_level > 0)
+ if (reinit != 0)
ahd_chip_init(ahd);
return (0);
@@ -6703,141 +6708,24 @@ ahd_pause_and_flushwork(struct ahd_softc *ahd)
int
ahd_suspend(struct ahd_softc *ahd)
{
-#if 0
- uint8_t *ptr;
- int i;
ahd_pause_and_flushwork(ahd);
- if (LIST_FIRST(&ahd->pending_scbs) != NULL)
- return (EBUSY);
-
-#if AHD_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 (ahd->pending_device != NULL)
+ if (LIST_FIRST(&ahd->pending_scbs) != NULL) {
+ ahd_unpause(ahd);
return (EBUSY);
-#endif
-
- /* Save volatile registers */
- ahd->suspend_state.channel[0].scsiseq = ahd_inb(ahd, SCSISEQ0);
- ahd->suspend_state.channel[0].sxfrctl0 = ahd_inb(ahd, SXFRCTL0);
- ahd->suspend_state.channel[0].sxfrctl1 = ahd_inb(ahd, SXFRCTL1);
- ahd->suspend_state.channel[0].simode0 = ahd_inb(ahd, SIMODE0);
- ahd->suspend_state.channel[0].simode1 = ahd_inb(ahd, SIMODE1);
- ahd->suspend_state.channel[0].seltimer = ahd_inb(ahd, SELTIMER);
- ahd->suspend_state.channel[0].seqctl = ahd_inb(ahd, SEQCTL0);
- ahd->suspend_state.dscommand0 = ahd_inb(ahd, DSCOMMAND0);
- ahd->suspend_state.dspcistatus = ahd_inb(ahd, DSPCISTATUS);
-
- if ((ahd->features & AHD_DT) != 0) {
- u_int sfunct;
-
- sfunct = ahd_inb(ahd, SFUNCT) & ~ALT_MODE;
- ahd_outb(ahd, SFUNCT, sfunct | ALT_MODE);
- ahd->suspend_state.optionmode = ahd_inb(ahd, OPTIONMODE);
- ahd_outb(ahd, SFUNCT, sfunct);
- ahd->suspend_state.crccontrol1 = ahd_inb(ahd, CRCCONTROL1);
- }
-
- if ((ahd->features & AHD_MULTI_FUNC) != 0)
- ahd->suspend_state.scbbaddr = ahd_inb(ahd, SCBBADDR);
-
- if ((ahd->features & AHD_ULTRA2) != 0)
- ahd->suspend_state.dff_thrsh = ahd_inb(ahd, DFF_THRSH);
-
- ptr = ahd->suspend_state.scratch_ram;
- for (i = 0; i < 64; i++)
- *ptr++ = ahd_inb(ahd, SRAM_BASE + i);
-
- if ((ahd->features & AHD_MORE_SRAM) != 0) {
- for (i = 0; i < 16; i++)
- *ptr++ = ahd_inb(ahd, TARG_OFFSET + i);
- }
-
- ptr = ahd->suspend_state.btt;
- for (i = 0;i < AHD_NUM_TARGETS; i++) {
- int j;
-
- for (j = 0;j < AHD_NUM_LUNS_NONPKT; j++) {
- u_int tcl;
-
- tcl = BUILD_TCL_RAW(i, 'A', j);
- *ptr = ahd_find_busy_tcl(ahd, tcl);
- }
}
ahd_shutdown(ahd);
-#endif
return (0);
}
int
ahd_resume(struct ahd_softc *ahd)
{
-#if 0
- uint8_t *ptr;
- int i;
-
- ahd_reset(ahd);
- ahd_build_free_scb_list(ahd);
-
- /* Restore volatile registers */
- ahd_outb(ahd, SCSISEQ0, ahd->suspend_state.channel[0].scsiseq);
- ahd_outb(ahd, SXFRCTL0, ahd->suspend_state.channel[0].sxfrctl0);
- ahd_outb(ahd, SXFRCTL1, ahd->suspend_state.channel[0].sxfrctl1);
- ahd_outb(ahd, SIMODE0, ahd->suspend_state.channel[0].simode0);
- ahd_outb(ahd, SIMODE1, ahd->suspend_state.channel[0].simode1);
- ahd_outb(ahd, SELTIMER, ahd->suspend_state.channel[0].seltimer);
- ahd_outb(ahd, SEQCTL0, ahd->suspend_state.channel[0].seqctl);
- if ((ahd->features & AHD_ULTRA2) != 0)
- ahd_outb(ahd, SCSIID_ULTRA2, ahd->our_id);
- else
- ahd_outb(ahd, SCSIID, ahd->our_id);
-
- ahd_outb(ahd, DSCOMMAND0, ahd->suspend_state.dscommand0);
- ahd_outb(ahd, DSPCISTATUS, ahd->suspend_state.dspcistatus);
-
- if ((ahd->features & AHD_DT) != 0) {
- u_int sfunct;
-
- sfunct = ahd_inb(ahd, SFUNCT) & ~ALT_MODE;
- ahd_outb(ahd, SFUNCT, sfunct | ALT_MODE);
- ahd_outb(ahd, OPTIONMODE, ahd->suspend_state.optionmode);
- ahd_outb(ahd, SFUNCT, sfunct);
- ahd_outb(ahd, CRCCONTROL1, ahd->suspend_state.crccontrol1);
- }
-
- if ((ahd->features & AHD_MULTI_FUNC) != 0)
- ahd_outb(ahd, SCBBADDR, ahd->suspend_state.scbbaddr);
-
- if ((ahd->features & AHD_ULTRA2) != 0)
- ahd_outb(ahd, DFF_THRSH, ahd->suspend_state.dff_thrsh);
-
- ptr = ahd->suspend_state.scratch_ram;
- for (i = 0; i < 64; i++)
- ahd_outb(ahd, SRAM_BASE + i, *ptr++);
-
- if ((ahd->features & AHD_MORE_SRAM) != 0) {
- for (i = 0; i < 16; i++)
- ahd_outb(ahd, TARG_OFFSET + i, *ptr++);
- }
-
- ptr = ahd->suspend_state.btt;
- for (i = 0;i < AHD_NUM_TARGETS; i++) {
- int j;
-
- for (j = 0;j < AHD_NUM_LUNS; j++) {
- u_int tcl;
-
- tcl = BUILD_TCL(i << 4, j);
- ahd_busy_tcl(ahd, tcl, *ptr);
- }
- }
-#endif
+ ahd_reset(ahd, /*reinit*/TRUE);
+ ahd_intr_enable(ahd, TRUE);
+ ahd_restart(ahd);
return (0);
}
@@ -7490,7 +7378,7 @@ ahd_reset_current_bus(struct ahd_softc *ahd)
* we must reset the chip.
*/
ahd_delay(AHD_BUSRESET_DELAY);
- ahd_reset(ahd);
+ ahd_reset(ahd, /*reinit*/TRUE);
ahd_intr_enable(ahd, /*enable*/TRUE);
AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
}
@@ -9192,6 +9080,7 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb)
ahd->flags &= ~AHD_INITIATORROLE;
ahd_pause(ahd);
ahd_loadseq(ahd);
+ ahd_restart(ahd);
ahd_unlock(ahd, &s);
}
cel = &ccb->cel;
@@ -9425,6 +9314,11 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb)
ahd->flags |= AHD_INITIATORROLE;
ahd_pause(ahd);
ahd_loadseq(ahd);
+ ahd_restart(ahd);
+ /*
+ * Unpaused. The extra unpause
+ * that follows is harmless.
+ */
}
}
ahd_unpause(ahd);
diff --git a/sys/dev/aic7xxx/aic79xx.h b/sys/dev/aic7xxx/aic79xx.h
index 3fe4598..c40dd87 100644
--- a/sys/dev/aic7xxx/aic79xx.h
+++ b/sys/dev/aic7xxx/aic79xx.h
@@ -37,7 +37,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
- * $Id: aic79xx.h,v 1.11 2003/05/26 21:10:58 gibbs Exp $
+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#92 $
*
* $FreeBSD$
*/
@@ -1379,13 +1379,13 @@ struct scb *ahd_get_scb(struct ahd_softc *ahd, u_int col_idx);
void ahd_free_scb(struct ahd_softc *ahd, struct scb *scb);
void ahd_alloc_scbs(struct ahd_softc *ahd);
void ahd_free(struct ahd_softc *ahd);
-int ahd_reset(struct ahd_softc *ahd);
+int ahd_reset(struct ahd_softc *ahd, int reinit);
void ahd_shutdown(void *arg);
-int ahd_write_flexport(struct ahd_softc *ahd,
- u_int addr, u_int value);
-int ahd_read_flexport(struct ahd_softc *ahd, u_int addr,
- uint8_t *value);
-int ahd_wait_flexport(struct ahd_softc *ahd);
+int ahd_write_flexport(struct ahd_softc *ahd,
+ u_int addr, u_int value);
+int ahd_read_flexport(struct ahd_softc *ahd, u_int addr,
+ uint8_t *value);
+int ahd_wait_flexport(struct ahd_softc *ahd);
/*************************** Interrupt Services *******************************/
void ahd_pci_intr(struct ahd_softc *ahd);
diff --git a/sys/dev/aic7xxx/aic79xx_pci.c b/sys/dev/aic7xxx/aic79xx_pci.c
index b4da627..c7764e2 100644
--- a/sys/dev/aic7xxx/aic79xx_pci.c
+++ b/sys/dev/aic7xxx/aic79xx_pci.c
@@ -38,7 +38,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
- * $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#73 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#74 $
*
* $FreeBSD$
*/
@@ -375,7 +375,7 @@ ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry)
ahd->bus_intr = ahd_pci_intr;
- error = ahd_reset(ahd);
+ error = ahd_reset(ahd, /*reinit*/FALSE);
if (error != 0)
return (ENXIO);
diff --git a/sys/dev/aic7xxx/aic7xxx.c b/sys/dev/aic7xxx/aic7xxx.c
index dcded7e..d762979 100644
--- a/sys/dev/aic7xxx/aic7xxx.c
+++ b/sys/dev/aic7xxx/aic7xxx.c
@@ -37,7 +37,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.c#130 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.c#132 $
*
* $FreeBSD$
*/
@@ -4033,7 +4033,7 @@ ahc_shutdown(void *arg)
ahc = (struct ahc_softc *)arg;
/* This will reset most registers to 0, but not all */
- ahc_reset(ahc);
+ ahc_reset(ahc, /*reinit*/FALSE);
ahc_outb(ahc, SCSISEQ, 0);
ahc_outb(ahc, SXFRCTL0, 0);
ahc_outb(ahc, DSPCISTATUS, 0);
@@ -4044,10 +4044,15 @@ ahc_shutdown(void *arg)
/*
* Reset the controller and record some information about it
- * that is only available just after a reset.
+ * that is only available just after a reset. If "reinit" is
+ * non-zero, this reset occured after initial configuration
+ * and the caller requests that the chip be fully reinitialized
+ * to a runable state. Chip interrupts are *not* enabled after
+ * a reinitialization. The caller must enable interrupts via
+ * ahc_intr_enable().
*/
int
-ahc_reset(struct ahc_softc *ahc)
+ahc_reset(struct ahc_softc *ahc, int reinit)
{
u_int sblkctl;
u_int sxfrctl1_a, sxfrctl1_b;
@@ -4143,7 +4148,7 @@ ahc_reset(struct ahc_softc *ahc)
ahc_outb(ahc, SXFRCTL1, sxfrctl1_a);
error = 0;
- if (ahc->init_level > 0)
+ if (reinit != 0)
/*
* If a recovery action has forced a chip reset,
* re-initialize the chip to our liking.
@@ -4725,14 +4730,12 @@ ahc_chip_init(struct ahc_softc *ahc)
* never settle, so don't complain if we
* fail here.
*/
- ahc_pause(ahc);
for (wait = 5000;
(ahc_inb(ahc, SBLKCTL) & (ENAB40|ENAB20)) == 0 && wait;
wait--)
ahc_delay(100);
- ahc_unpause(ahc);
}
-
+ ahc_restart(ahc);
return (0);
}
@@ -5145,7 +5148,9 @@ int
ahc_resume(struct ahc_softc *ahc)
{
- ahc_reset(ahc);
+ ahc_reset(ahc, /*reinit*/TRUE);
+ ahc_intr_enable(ahc, TRUE);
+ ahc_restart(ahc);
return (0);
}
@@ -6407,7 +6412,6 @@ ahc_loadseq(struct ahc_softc *ahc)
memcpy(ahc->critical_sections, cs_table, cs_count);
}
ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE);
- ahc_restart(ahc);
if (bootverbose) {
printf(" %d instructions downloaded\n", downloaded);
@@ -6968,11 +6972,12 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
*/
ahc->flags = saved_flags;
(void)ahc_loadseq(ahc);
- ahc_unpause(ahc);
+ ahc_restart(ahc);
ahc_unlock(ahc, &s);
ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
return;
}
+ ahc_restart(ahc);
ahc_unlock(ahc, &s);
}
cel = &ccb->cel;
@@ -7207,12 +7212,16 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
printf("Configuring Initiator Mode\n");
ahc->flags &= ~AHC_TARGETROLE;
ahc->flags |= AHC_INITIATORROLE;
- ahc_pause(ahc);
/*
* Returning to a configuration that
* fit previously will always succeed.
*/
(void)ahc_loadseq(ahc);
+ ahc_restart(ahc);
+ /*
+ * Unpaused. The extra unpause
+ * that follows is harmless.
+ */
}
}
ahc_unpause(ahc);
diff --git a/sys/dev/aic7xxx/aic7xxx.h b/sys/dev/aic7xxx/aic7xxx.h
index 9731add..ef1214c 100644
--- a/sys/dev/aic7xxx/aic7xxx.h
+++ b/sys/dev/aic7xxx/aic7xxx.h
@@ -37,7 +37,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#78 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#79 $
*
* $FreeBSD$
*/
@@ -1205,7 +1205,7 @@ 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 ahc_reset(struct ahc_softc *ahc, int reinit);
void ahc_shutdown(void *arg);
/*************************** Interrupt Services *******************************/
diff --git a/sys/dev/aic7xxx/aic7xxx_pci.c b/sys/dev/aic7xxx/aic7xxx_pci.c
index ea98757..a36a7b6 100644
--- a/sys/dev/aic7xxx/aic7xxx_pci.c
+++ b/sys/dev/aic7xxx/aic7xxx_pci.c
@@ -39,7 +39,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#66 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#68 $
*
* $FreeBSD$
*/
@@ -877,7 +877,7 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry)
scsiseq = 0;
}
- error = ahc_reset(ahc);
+ error = ahc_reset(ahc, /*reinit*/FALSE);
if (error != 0)
return (ENXIO);
OpenPOWER on IntegriCloud