- Tidy up some printf code in chattach().
- Implement a simple quirks framework for changers. - Add a quirk for the Spectra 9000 8mm tape library; it requires a slightly-longer-than-1-minute delay to take tape inventory. Many thanks to David Webster at Cygnus Solutions for testing this for me.
This commit is contained in:
parent
625d310b1b
commit
850b75414f
|
@ -1,7 +1,7 @@
|
|||
/* $NetBSD: ch.c,v 1.25 1996/12/05 01:06:40 cgd Exp $ */
|
||||
/* $NetBSD: ch.c,v 1.26 1997/02/21 22:06:52 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 Jason R. Thorpe <thorpej@and.com>
|
||||
* Copyright (c) 1996, 1997 Jason R. Thorpe <thorpej@and.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Partially based on an autochanger driver written by Stefan Grefen
|
||||
|
@ -81,6 +81,12 @@ struct ch_softc {
|
|||
u_int8_t sc_exchangemask[4];
|
||||
|
||||
int flags; /* misc. info */
|
||||
|
||||
/*
|
||||
* Quirks; see below.
|
||||
*/
|
||||
int sc_settledelay; /* delay for settle */
|
||||
|
||||
};
|
||||
|
||||
/* sc_flags */
|
||||
|
@ -118,6 +124,21 @@ int ch_position __P((struct ch_softc *, struct changer_position *));
|
|||
int ch_usergetelemstatus __P((struct ch_softc *, int, u_int8_t *));
|
||||
int ch_getelemstatus __P((struct ch_softc *, int, int, caddr_t, size_t));
|
||||
int ch_get_params __P((struct ch_softc *, int));
|
||||
void ch_get_quirks __P((struct ch_softc *, struct scsi_inquiry_data *));
|
||||
|
||||
/*
|
||||
* SCSI changer quirks.
|
||||
*/
|
||||
struct chquirk {
|
||||
struct scsi_inquiry_pattern cq_match; /* device id pattern */
|
||||
int cq_settledelay; /* settle delay, in seconds */
|
||||
};
|
||||
|
||||
struct chquirk chquirks[] = {
|
||||
{{T_CHANGER, T_REMOV,
|
||||
"SPECTRA", "9000", "0200"},
|
||||
75},
|
||||
};
|
||||
|
||||
int
|
||||
chmatch(parent, match, aux)
|
||||
|
@ -156,6 +177,21 @@ chattach(parent, self, aux)
|
|||
|
||||
printf("\n");
|
||||
|
||||
/*
|
||||
* Find out our device's quirks.
|
||||
*/
|
||||
ch_get_quirks(sc, sa->sa_inqbuf);
|
||||
|
||||
/*
|
||||
* Some changers require a long time to settle out, to do
|
||||
* tape inventory, for instance.
|
||||
*/
|
||||
if (sc->sc_settledelay) {
|
||||
printf("%s: waiting %d seconds for changer to settle...\n",
|
||||
sc->sc_dev.dv_xname, sc->sc_settledelay);
|
||||
delay(1000000 * sc->sc_settledelay);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get information about the device. Note we can't use
|
||||
* interrupts yet.
|
||||
|
@ -163,18 +199,14 @@ chattach(parent, self, aux)
|
|||
if (ch_get_params(sc, SCSI_AUTOCONF))
|
||||
printf("%s: offline\n", sc->sc_dev.dv_xname);
|
||||
else {
|
||||
printf("%s: %d slot%s, %d drive%s, %d picker%s",
|
||||
#define PLURAL(c) (c) == 1 ? "" : "s"
|
||||
printf("%s: %d slot%s, %d drive%s, %d picker%s, %d portal%s\n",
|
||||
sc->sc_dev.dv_xname,
|
||||
sc->sc_counts[CHET_ST], (sc->sc_counts[CHET_ST] > 1) ?
|
||||
"s" : "",
|
||||
sc->sc_counts[CHET_DT], (sc->sc_counts[CHET_DT] > 1) ?
|
||||
"s" : "",
|
||||
sc->sc_counts[CHET_MT], (sc->sc_counts[CHET_MT] > 1) ?
|
||||
"s" : "");
|
||||
if (sc->sc_counts[CHET_IE])
|
||||
printf(", %d portal%s", sc->sc_counts[CHET_IE],
|
||||
(sc->sc_counts[CHET_IE] > 1) ? "s" : "");
|
||||
printf("\n");
|
||||
sc->sc_counts[CHET_ST], PLURAL(sc->sc_counts[CHET_ST]),
|
||||
sc->sc_counts[CHET_DT], PLURAL(sc->sc_counts[CHET_DT]),
|
||||
sc->sc_counts[CHET_MT], PLURAL(sc->sc_counts[CHET_MT]),
|
||||
sc->sc_counts[CHET_IE], PLURAL(sc->sc_counts[CHET_IE]));
|
||||
#undef PLURAL
|
||||
#ifdef CHANGER_DEBUG
|
||||
printf("%s: move mask: 0x%x 0x%x 0x%x 0x%x\n",
|
||||
sc->sc_dev.dv_xname,
|
||||
|
@ -660,3 +692,22 @@ ch_get_params(sc, scsiflags)
|
|||
sc->sc_link->flags |= SDEV_MEDIA_LOADED;
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
ch_get_quirks(sc, inqbuf)
|
||||
struct ch_softc *sc;
|
||||
struct scsi_inquiry_data *inqbuf;
|
||||
{
|
||||
struct chquirk *match;
|
||||
int priority;
|
||||
|
||||
sc->sc_settledelay = 0;
|
||||
|
||||
match = (struct chquirk *)scsi_inqmatch(inqbuf,
|
||||
(caddr_t)chquirks,
|
||||
sizeof(chquirks) / sizeof(chquirks[0]),
|
||||
sizeof(chquirks[0]), &priority);
|
||||
if (priority != 0) {
|
||||
sc->sc_settledelay = match->cq_settledelay;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* $NetBSD: ch.c,v 1.25 1996/12/05 01:06:40 cgd Exp $ */
|
||||
/* $NetBSD: ch.c,v 1.26 1997/02/21 22:06:52 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 Jason R. Thorpe <thorpej@and.com>
|
||||
* Copyright (c) 1996, 1997 Jason R. Thorpe <thorpej@and.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Partially based on an autochanger driver written by Stefan Grefen
|
||||
|
@ -81,6 +81,12 @@ struct ch_softc {
|
|||
u_int8_t sc_exchangemask[4];
|
||||
|
||||
int flags; /* misc. info */
|
||||
|
||||
/*
|
||||
* Quirks; see below.
|
||||
*/
|
||||
int sc_settledelay; /* delay for settle */
|
||||
|
||||
};
|
||||
|
||||
/* sc_flags */
|
||||
|
@ -118,6 +124,21 @@ int ch_position __P((struct ch_softc *, struct changer_position *));
|
|||
int ch_usergetelemstatus __P((struct ch_softc *, int, u_int8_t *));
|
||||
int ch_getelemstatus __P((struct ch_softc *, int, int, caddr_t, size_t));
|
||||
int ch_get_params __P((struct ch_softc *, int));
|
||||
void ch_get_quirks __P((struct ch_softc *, struct scsi_inquiry_data *));
|
||||
|
||||
/*
|
||||
* SCSI changer quirks.
|
||||
*/
|
||||
struct chquirk {
|
||||
struct scsi_inquiry_pattern cq_match; /* device id pattern */
|
||||
int cq_settledelay; /* settle delay, in seconds */
|
||||
};
|
||||
|
||||
struct chquirk chquirks[] = {
|
||||
{{T_CHANGER, T_REMOV,
|
||||
"SPECTRA", "9000", "0200"},
|
||||
75},
|
||||
};
|
||||
|
||||
int
|
||||
chmatch(parent, match, aux)
|
||||
|
@ -156,6 +177,21 @@ chattach(parent, self, aux)
|
|||
|
||||
printf("\n");
|
||||
|
||||
/*
|
||||
* Find out our device's quirks.
|
||||
*/
|
||||
ch_get_quirks(sc, sa->sa_inqbuf);
|
||||
|
||||
/*
|
||||
* Some changers require a long time to settle out, to do
|
||||
* tape inventory, for instance.
|
||||
*/
|
||||
if (sc->sc_settledelay) {
|
||||
printf("%s: waiting %d seconds for changer to settle...\n",
|
||||
sc->sc_dev.dv_xname, sc->sc_settledelay);
|
||||
delay(1000000 * sc->sc_settledelay);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get information about the device. Note we can't use
|
||||
* interrupts yet.
|
||||
|
@ -163,18 +199,14 @@ chattach(parent, self, aux)
|
|||
if (ch_get_params(sc, SCSI_AUTOCONF))
|
||||
printf("%s: offline\n", sc->sc_dev.dv_xname);
|
||||
else {
|
||||
printf("%s: %d slot%s, %d drive%s, %d picker%s",
|
||||
#define PLURAL(c) (c) == 1 ? "" : "s"
|
||||
printf("%s: %d slot%s, %d drive%s, %d picker%s, %d portal%s\n",
|
||||
sc->sc_dev.dv_xname,
|
||||
sc->sc_counts[CHET_ST], (sc->sc_counts[CHET_ST] > 1) ?
|
||||
"s" : "",
|
||||
sc->sc_counts[CHET_DT], (sc->sc_counts[CHET_DT] > 1) ?
|
||||
"s" : "",
|
||||
sc->sc_counts[CHET_MT], (sc->sc_counts[CHET_MT] > 1) ?
|
||||
"s" : "");
|
||||
if (sc->sc_counts[CHET_IE])
|
||||
printf(", %d portal%s", sc->sc_counts[CHET_IE],
|
||||
(sc->sc_counts[CHET_IE] > 1) ? "s" : "");
|
||||
printf("\n");
|
||||
sc->sc_counts[CHET_ST], PLURAL(sc->sc_counts[CHET_ST]),
|
||||
sc->sc_counts[CHET_DT], PLURAL(sc->sc_counts[CHET_DT]),
|
||||
sc->sc_counts[CHET_MT], PLURAL(sc->sc_counts[CHET_MT]),
|
||||
sc->sc_counts[CHET_IE], PLURAL(sc->sc_counts[CHET_IE]));
|
||||
#undef PLURAL
|
||||
#ifdef CHANGER_DEBUG
|
||||
printf("%s: move mask: 0x%x 0x%x 0x%x 0x%x\n",
|
||||
sc->sc_dev.dv_xname,
|
||||
|
@ -660,3 +692,22 @@ ch_get_params(sc, scsiflags)
|
|||
sc->sc_link->flags |= SDEV_MEDIA_LOADED;
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
ch_get_quirks(sc, inqbuf)
|
||||
struct ch_softc *sc;
|
||||
struct scsi_inquiry_data *inqbuf;
|
||||
{
|
||||
struct chquirk *match;
|
||||
int priority;
|
||||
|
||||
sc->sc_settledelay = 0;
|
||||
|
||||
match = (struct chquirk *)scsi_inqmatch(inqbuf,
|
||||
(caddr_t)chquirks,
|
||||
sizeof(chquirks) / sizeof(chquirks[0]),
|
||||
sizeof(chquirks[0]), &priority);
|
||||
if (priority != 0) {
|
||||
sc->sc_settledelay = match->cq_settledelay;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue