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.
This commit is contained in:
Justin T. Gibbs 2003-06-06 23:48:19 +00:00
parent 0785ee125b
commit 1d528d6792
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=115917
7 changed files with 58 additions and 155 deletions

View File

@ -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);

View File

@ -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)
if (LIST_FIRST(&ahd->pending_scbs) != NULL) {
ahd_unpause(ahd);
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)
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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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 *******************************/

View File

@ -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);