Enable card interrupts from the OSM.

Use "offset == 0" not "period == 0" to denote async trasnfers.

Implement TARG_IMMEDIATE_SCB non-disconnected target mode
SCB delivery scheme.

In our timeout handler, don't rely on the phase already being
set to denote an active connection.  IDENTIFY_SEEN is more
than sufficient.

Verify that the softc passed in ahc_detach is still known
to the driver before blindly using it.
This commit is contained in:
gibbs 2002-08-31 06:43:55 +00:00
parent 55b47b8af9
commit ce7ac83562

View File

@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id$ * $Id: //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.c#10 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
@ -228,14 +228,16 @@ fail:
ahc->platform_data->sim_b = sim2; ahc->platform_data->sim_b = sim2;
ahc->platform_data->path_b = path2; ahc->platform_data->path_b = path2;
} }
ahc_unlock(ahc, &s);
if (count != 0) if (count != 0) {
/* We have to wait until after any system dumps... */ /* We have to wait until after any system dumps... */
ahc->platform_data->eh = ahc->platform_data->eh =
EVENTHANDLER_REGISTER(shutdown_final, ahc_shutdown, EVENTHANDLER_REGISTER(shutdown_final, ahc_shutdown,
ahc, SHUTDOWN_PRI_DEFAULT); ahc, SHUTDOWN_PRI_DEFAULT);
ahc_intr_enable(ahc, TRUE);
}
ahc_unlock(ahc, &s);
return (count); return (count);
} }
@ -1222,7 +1224,7 @@ ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments,
if ((ccb->ccb_h.flags & CAM_NEGOTIATE) != 0 if ((ccb->ccb_h.flags & CAM_NEGOTIATE) != 0
&& (tinfo->goal.width != 0 && (tinfo->goal.width != 0
|| tinfo->goal.period != 0 || tinfo->goal.offset != 0
|| tinfo->goal.ppr_options != 0)) { || tinfo->goal.ppr_options != 0)) {
scb->flags |= SCB_NEGOTIATE; scb->flags |= SCB_NEGOTIATE;
scb->hscb->control |= MK_MESSAGE; scb->hscb->control |= MK_MESSAGE;
@ -1276,8 +1278,7 @@ ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments,
ahc_pause(ahc); ahc_pause(ahc);
if ((ahc->flags & AHC_PAGESCBS) == 0) if ((ahc->flags & AHC_PAGESCBS) == 0)
ahc_outb(ahc, SCBPTR, scb->hscb->tag); ahc_outb(ahc, SCBPTR, scb->hscb->tag);
ahc_outb(ahc, SCB_TAG, scb->hscb->tag); ahc_outb(ahc, TARG_IMMEDIATE_SCB, scb->hscb->tag);
ahc_outb(ahc, RETURN_1, CONT_MSG_LOOP);
ahc_unpause(ahc); ahc_unpause(ahc);
} else { } else {
ahc_queue_scb(ahc, scb); ahc_queue_scb(ahc, scb);
@ -1289,7 +1290,10 @@ ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments,
static void static void
ahc_poll(struct cam_sim *sim) ahc_poll(struct cam_sim *sim)
{ {
ahc_intr(cam_sim_softc(sim)); struct ahc_softc *ahc;
ahc = (struct ahc_softc *)cam_sim_softc(sim);
ahc_intr(ahc);
} }
static void static void
@ -1519,8 +1523,7 @@ bus_reset:
saved_scbptr = ahc_inb(ahc, SCBPTR); saved_scbptr = ahc_inb(ahc, SCBPTR);
active_scb_index = ahc_inb(ahc, SCB_TAG); active_scb_index = ahc_inb(ahc, SCB_TAG);
if (last_phase != P_BUSFREE if ((ahc_inb(ahc, SEQ_FLAGS) & IDENTIFY_SEEN) != 0
&& (ahc_inb(ahc, SEQ_FLAGS) & IDENTIFY_SEEN) != 0
&& (active_scb_index < ahc->scb_data->numscbs)) { && (active_scb_index < ahc->scb_data->numscbs)) {
struct scb *active_scb; struct scb *active_scb;
@ -1899,14 +1902,24 @@ int
ahc_detach(device_t dev) ahc_detach(device_t dev)
{ {
struct ahc_softc *ahc; struct ahc_softc *ahc;
u_long l;
u_long s; u_long s;
ahc_list_lock(&l);
device_printf(dev, "detaching device\n"); device_printf(dev, "detaching device\n");
ahc = device_get_softc(dev); ahc = device_get_softc(dev);
ahc = ahc_find_softc(ahc);
if (ahc == NULL) {
device_printf(dev, "aic7xxx already detached\n");
ahc_list_unlock(&l);
return (ENOENT);
}
ahc_lock(ahc, &s); ahc_lock(ahc, &s);
ahc_intr_enable(ahc, FALSE);
bus_teardown_intr(dev, ahc->platform_data->irq, ahc->platform_data->ih); bus_teardown_intr(dev, ahc->platform_data->irq, ahc->platform_data->ih);
ahc_unlock(ahc, &s); ahc_unlock(ahc, &s);
ahc_free(ahc); ahc_free(ahc);
ahc_list_unlock(&l);
return (0); return (0);
} }