- 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:
thorpej 1997-02-21 22:06:52 +00:00
parent 625d310b1b
commit 850b75414f
2 changed files with 128 additions and 26 deletions

View File

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

View File

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