summaryrefslogtreecommitdiff
path: root/sys/scsi
diff options
context:
space:
mode:
Diffstat (limited to 'sys/scsi')
-rw-r--r--sys/scsi/scsi_base.c68
-rw-r--r--sys/scsi/scsiconf.c5
-rw-r--r--sys/scsi/scsiconf.h60
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));