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:
parent
55b47b8af9
commit
ce7ac83562
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user