Implement reference counting for ATA adapters.

This commit is contained in:
thorpej 1998-11-20 01:22:37 +00:00
parent 6a60e078ee
commit 4ba3417429
2 changed files with 52 additions and 5 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: wdc.c,v 1.43 1998/11/19 22:50:21 kenh Exp $ */ /* $NetBSD: wdc.c,v 1.44 1998/11/20 01:22:37 thorpej Exp $ */
/* /*
@ -304,7 +304,7 @@ void
wdcattach(chp) wdcattach(chp)
struct channel_softc *chp; struct channel_softc *chp;
{ {
int channel_flags, ctrl_flags, i; int channel_flags, ctrl_flags, i, error;
struct ata_atapi_attach aa_link; struct ata_atapi_attach aa_link;
LIST_INIT(&xfer_free_list); LIST_INIT(&xfer_free_list);
@ -318,8 +318,17 @@ wdcattach(chp)
chp->ch_drive[i].drive_flags |= DRIVE_CAP32; chp->ch_drive[i].drive_flags |= DRIVE_CAP32;
} }
if (wdcprobe(chp) == 0) if ((error = wdc_addref(chp)) != 0) {
return; /* If no drives, abort attach here */ printf("%s: unable to enable controller\n",
chp->wdc->sc_dev.dv_xname);
return;
}
if (wdcprobe(chp) == 0) {
/* If no drives, abort attach here. */
wdc_delref(chp);
return;
}
TAILQ_INIT(&chp->ch_queue->sc_xfer); TAILQ_INIT(&chp->ch_queue->sc_xfer);
ctrl_flags = chp->wdc->sc_dev.dv_cfdata->cf_flags; ctrl_flags = chp->wdc->sc_dev.dv_cfdata->cf_flags;
@ -398,6 +407,7 @@ wdcattach(chp)
} }
} }
} }
wdc_delref(chp);
} }
/* /*
@ -1169,3 +1179,37 @@ wdcbit_bucket(chp, size)
if (size) if (size)
(void)bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_data); (void)bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_data);
} }
int
wdc_addref(chp)
struct channel_softc *chp;
{
struct wdc_softc *wdc = chp->wdc;
struct scsipi_adapter *adapter = &wdc->sc_atapi_adapter;
int s, error = 0;
s = splbio();
if (adapter->scsipi_refcnt++ == 0 &&
adapter->scsipi_enable != NULL) {
error = (*adapter->scsipi_enable)(wdc, 1);
if (error)
adapter->scsipi_refcnt--;
}
splx(s);
return (error);
}
void
wdc_delref(chp)
struct channel_softc *chp;
{
struct wdc_softc *wdc = chp->wdc;
struct scsipi_adapter *adapter = &wdc->sc_atapi_adapter;
int s;
s = splbio();
if (adapter->scsipi_refcnt-- == 1 &&
adapter->scsipi_enable != NULL)
(void) (*adapter->scsipi_enable)(wdc, 0);
splx(s);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: wdcvar.h,v 1.8 1998/11/19 21:53:00 thorpej Exp $ */ /* $NetBSD: wdcvar.h,v 1.9 1998/11/20 01:22:37 thorpej Exp $ */
/*- /*-
* Copyright (c) 1998 The NetBSD Foundation, Inc. * Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -169,6 +169,9 @@ void wdccommand __P((struct channel_softc *, u_int8_t, u_int8_t, u_int16_t,
void wdccommandshort __P((struct channel_softc *, int, int)); void wdccommandshort __P((struct channel_softc *, int, int));
void wdctimeout __P((void *arg)); void wdctimeout __P((void *arg));
int wdc_addref __P((struct channel_softc *));
void wdc_delref __P((struct channel_softc *));
/* /*
* ST506 spec says that if READY or SEEKCMPLT go off, then the read or write * ST506 spec says that if READY or SEEKCMPLT go off, then the read or write
* command is aborted. * command is aborted.