diff options
Diffstat (limited to 'sys/scsi')
-rw-r--r-- | sys/scsi/scsi_base.c | 68 | ||||
-rw-r--r-- | sys/scsi/scsiconf.c | 5 | ||||
-rw-r--r-- | sys/scsi/scsiconf.h | 60 |
3 files changed, 77 insertions, 56 deletions
diff --git a/sys/scsi/scsi_base.c b/sys/scsi/scsi_base.c index 14a0195467d..17d76b6c196 100644 --- a/sys/scsi/scsi_base.c +++ b/sys/scsi/scsi_base.c @@ -1,4 +1,4 @@ -/* $OpenBSD: scsi_base.c,v 1.30 2001/08/19 15:07:34 miod Exp $ */ +/* $OpenBSD: scsi_base.c,v 1.31 2001/08/25 19:29:16 fgsch Exp $ */ /* $NetBSD: scsi_base.c,v 1.43 1997/04/02 02:29:36 mycroft Exp $ */ /* @@ -45,20 +45,38 @@ #include <sys/errno.h> #include <sys/device.h> #include <sys/proc.h> +#include <sys/pool.h> #include <scsi/scsi_all.h> #include <scsi/scsi_disk.h> #include <scsi/scsiconf.h> -LIST_HEAD(xs_free_list, scsi_xfer) xs_free_list; - static __inline struct scsi_xfer *scsi_make_xs __P((struct scsi_link *, struct scsi_generic *, int cmdlen, u_char *data_addr, int datalen, int retries, int timeout, struct buf *, int flags)); static __inline void asc2ascii __P((u_char asc, u_char ascq, char *result)); -int sc_err1 __P((struct scsi_xfer *, int)); -int scsi_interpret_sense __P((struct scsi_xfer *)); -char *scsi_decode_sense __P((void *, int)); +int sc_err1 __P((struct scsi_xfer *, int)); +int scsi_interpret_sense __P((struct scsi_xfer *)); +char *scsi_decode_sense __P((void *, int)); + +struct pool scsi_xfer_pool; + +/* + * Called when a scsibus is attached to initialize global data. + */ +void +scsi_init() +{ + static int scsi_init_done; + + if (scsi_init_done) + return; + scsi_init_done = 1; + + /* Initialize the scsi_xfer pool. */ + pool_init(&scsi_xfer_pool, sizeof(struct scsi_xfer), 0, + 0, 0, "scxspl", 0, NULL, NULL, M_DEVBUF); +} /* * Get a scsi transfer structure for the caller. Charge the structure @@ -80,35 +98,32 @@ scsi_get_xs(sc_link, flags) int s; SC_DEBUG(sc_link, SDEV_DB3, ("scsi_get_xs\n")); + s = splbio(); while (sc_link->openings <= 0) { SC_DEBUG(sc_link, SDEV_DB3, ("sleeping\n")); if ((flags & SCSI_NOSLEEP) != 0) { splx(s); - return 0; + return (NULL); } sc_link->flags |= SDEV_WAITING; (void) tsleep(sc_link, PRIBIO, "getxs", 0); } - sc_link->openings--; - if ((xs = xs_free_list.lh_first) != NULL) { - LIST_REMOVE(xs, free_list); - splx(s); + SC_DEBUG(sc_link, SDEV_DB3, ("calling pool_get\n")); + xs = pool_get(&scsi_xfer_pool, + ((flags & SCSI_NOSLEEP) != 0 ? M_NOWAIT : M_WAITOK)); + if (xs != NULL) { + sc_link->openings--; + xs->flags = flags; } else { - splx(s); - SC_DEBUG(sc_link, SDEV_DB3, ("making\n")); - xs = malloc(sizeof(*xs), M_DEVBUF, - ((flags & SCSI_NOSLEEP) != 0 ? M_NOWAIT : M_WAITOK)); - if (!xs) { - sc_print_addr(sc_link); - printf("cannot allocate scsi xs\n"); - return 0; - } + sc_print_addr(sc_link); + printf("cannot allocate scsi xs\n"); } + splx(s); SC_DEBUG(sc_link, SDEV_DB3, ("returning\n")); - xs->flags = INUSE | flags; - return xs; + + return (xs); } /* @@ -123,10 +138,10 @@ scsi_free_xs(xs, flags) { struct scsi_link *sc_link = xs->sc_link; - xs->flags &= ~INUSE; - LIST_INSERT_HEAD(&xs_free_list, xs, free_list); - SC_DEBUG(sc_link, SDEV_DB3, ("scsi_free_xs\n")); + + pool_put(&scsi_xfer_pool, xs); + /* if was 0 and someone waits, wake them up */ sc_link->openings++; if ((sc_link->flags & SDEV_WAITING) != 0) { @@ -134,7 +149,8 @@ scsi_free_xs(xs, flags) wakeup(sc_link); } else { if (sc_link->device->start) { - SC_DEBUG(sc_link, SDEV_DB2, ("calling private start()\n")); + SC_DEBUG(sc_link, SDEV_DB2, + ("calling private start()\n")); (*(sc_link->device->start)) (sc_link->device_softc); } } diff --git a/sys/scsi/scsiconf.c b/sys/scsi/scsiconf.c index ab64248015c..56719b82451 100644 --- a/sys/scsi/scsiconf.c +++ b/sys/scsi/scsiconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: scsiconf.c,v 1.59 2001/08/18 02:24:02 krw Exp $ */ +/* $OpenBSD: scsiconf.c,v 1.60 2001/08/25 19:29:16 fgsch Exp $ */ /* $NetBSD: scsiconf.c,v 1.57 1996/05/02 01:09:01 neil Exp $ */ /* @@ -167,6 +167,9 @@ scsibusattach(parent, self, aux) printf(": %d targets\n", sb->sc_buswidth); + /* Initialize shared data. */ + scsi_init(); + nbytes = sb->sc_buswidth * sizeof(struct scsi_link **); sb->sc_link = (struct scsi_link ***)malloc(nbytes, M_DEVBUF, M_NOWAIT); if (sb->sc_link == NULL) diff --git a/sys/scsi/scsiconf.h b/sys/scsi/scsiconf.h index ba2348248be..323e57efb0a 100644 --- a/sys/scsi/scsiconf.h +++ b/sys/scsi/scsiconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: scsiconf.h,v 1.28 2001/08/18 02:24:02 krw Exp $ */ +/* $OpenBSD: scsiconf.h,v 1.29 2001/08/25 19:29:16 fgsch Exp $ */ /* $NetBSD: scsiconf.h,v 1.35 1997/04/02 02:29:38 mycroft Exp $ */ /* @@ -310,34 +310,36 @@ struct scsi_xfer { #define XS_RESET 8 /* bus was reset; possible retry command */ caddr_t scsi_inqmatch __P((struct scsi_inquiry_data *, caddr_t, int, - int, int *)); - -struct scsi_xfer *scsi_get_xs __P((struct scsi_link *, int)); -void scsi_free_xs __P((struct scsi_xfer *, int)); -int scsi_execute_xs __P((struct scsi_xfer *)); -u_long scsi_size __P((struct scsi_link *, int)); -int scsi_test_unit_ready __P((struct scsi_link *, int)); -int scsi_change_def __P((struct scsi_link *, int)); -int scsi_inquire __P((struct scsi_link *, struct scsi_inquiry_data *, int)); -int scsi_prevent __P((struct scsi_link *, int, int)); -int scsi_start __P((struct scsi_link *, int, int)); -void scsi_done __P((struct scsi_xfer *)); -void scsi_user_done __P((struct scsi_xfer *)); -int scsi_scsi_cmd __P((struct scsi_link *, struct scsi_generic *, - int cmdlen, u_char *data_addr, int datalen, int retries, - int timeout, struct buf *bp, int flags)); -int scsi_do_ioctl __P((struct scsi_link *, dev_t, u_long, caddr_t, - int, struct proc *)); -int scsi_do_safeioctl __P((struct scsi_link *, dev_t, u_long, caddr_t, - int, struct proc *)); -void sc_print_addr __P((struct scsi_link *)); - -void show_scsi_xs __P((struct scsi_xfer *)); -void scsi_print_sense __P((struct scsi_xfer *, int)); -void show_scsi_cmd __P((struct scsi_xfer *)); -void show_mem __P((u_char *, int)); -int scsi_probe_busses __P((int, int, int)); -void scsi_strvis __P((u_char *, u_char *, int)); + int, int *)); + +void scsi_init __P((void)); +struct scsi_xfer * + scsi_get_xs __P((struct scsi_link *, int)); +void scsi_free_xs __P((struct scsi_xfer *, int)); +int scsi_execute_xs __P((struct scsi_xfer *)); +u_long scsi_size __P((struct scsi_link *, int)); +int scsi_test_unit_ready __P((struct scsi_link *, int)); +int scsi_change_def __P((struct scsi_link *, int)); +int scsi_inquire __P((struct scsi_link *, struct scsi_inquiry_data *, int)); +int scsi_prevent __P((struct scsi_link *, int, int)); +int scsi_start __P((struct scsi_link *, int, int)); +void scsi_done __P((struct scsi_xfer *)); +void scsi_user_done __P((struct scsi_xfer *)); +int scsi_scsi_cmd __P((struct scsi_link *, struct scsi_generic *, + int cmdlen, u_char *data_addr, int datalen, int retries, + int timeout, struct buf *bp, int flags)); +int scsi_do_ioctl __P((struct scsi_link *, dev_t, u_long, caddr_t, + int, struct proc *)); +int scsi_do_safeioctl __P((struct scsi_link *, dev_t, u_long, caddr_t, + int, struct proc *)); +void sc_print_addr __P((struct scsi_link *)); + +void show_scsi_xs __P((struct scsi_xfer *)); +void scsi_print_sense __P((struct scsi_xfer *, int)); +void show_scsi_cmd __P((struct scsi_xfer *)); +void show_mem __P((u_char *, int)); +int scsi_probe_busses __P((int, int, int)); +void scsi_strvis __P((u_char *, u_char *, int)); static __inline void _lto2b __P((u_int32_t val, u_int8_t *bytes)); static __inline void _lto3b __P((u_int32_t val, u_int8_t *bytes)); |