Remove the silly statically allocated array, and simply malloc the data

structures as needed.  Also, put the buf in the malloc()ed area.  Remove a
duplicate si_free() (though this was harmless before).
This commit is contained in:
mycroft 1994-12-01 11:53:56 +00:00
parent 8fd1f92ae7
commit a10cbd7179
2 changed files with 94 additions and 142 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: scsipi_ioctl.c,v 1.10 1994/10/30 21:49:21 cgd Exp $ */ /* $NetBSD: scsipi_ioctl.c,v 1.11 1994/12/01 11:53:56 mycroft Exp $ */
/* /*
* Copyright (c) 1994 Charles Hannum. All rights reserved. * Copyright (c) 1994 Charles Hannum. All rights reserved.
@ -50,69 +50,56 @@
void scsierr __P((struct buf *, int)); void scsierr __P((struct buf *, int));
/*
* We need to maintain an assocation between the buf and the SCSI request
* structure. We do this with a simple array of scsi_ioctl structures below.
* XXX The free structures should probably be in a linked list.
*/
#define NIOCTL 16
struct scsi_ioctl { struct scsi_ioctl {
struct buf *si_bp; LIST_ENTRY(scsi_ioctl) si_list;
scsireq_t si_screq; struct buf si_bp;
struct scsi_link *si_sc_link;
struct uio si_uio; struct uio si_uio;
struct iovec si_iov; struct iovec si_iov;
} scsi_ioctl[NIOCTL]; scsireq_t si_screq;
struct scsi_link *si_sc_link;
};
LIST_HEAD(, scsi_ioctl) si_head;
struct scsi_ioctl * struct scsi_ioctl *
si_get(bp) si_get()
struct buf *bp;
{ {
int s = splbio();
struct scsi_ioctl *si; struct scsi_ioctl *si;
int error; int s;
for (;;) { si = malloc(sizeof(struct scsi_ioctl), M_TEMP, M_WAITOK);
for (si = scsi_ioctl; si < &scsi_ioctl[NIOCTL]; si++) bzero(si, sizeof(struct scsi_ioctl));
if (si->si_bp == 0) { s = splbio();
si->si_bp = bp; LIST_INSERT_HEAD(&si_head, si, si_list);
splx(s); splx(s);
return si; return (si);
}
error = tsleep(scsi_ioctl, PRIBIO | PCATCH, "siget", 0);
if (error) {
splx(s);
return 0;
}
}
} }
void void
si_free(si) si_free(si)
struct scsi_ioctl *si; struct scsi_ioctl *si;
{ {
int s = splbio(); int s;
si->si_bp = 0; s = splbio();
wakeup(scsi_ioctl); LIST_REMOVE(si, si_list);
splx(s); splx(s);
free(si, M_TEMP);
} }
struct scsi_ioctl * struct scsi_ioctl *
si_find(bp) si_find(bp)
struct buf *bp; struct buf *bp;
{ {
int s = splbio();
struct scsi_ioctl *si; struct scsi_ioctl *si;
int s;
for (si = scsi_ioctl; si < &scsi_ioctl[NIOCTL]; si++) s = splbio();
if (si->si_bp == bp) { for (si = si_head.lh_first; si != 0; si = si->si_list.le_next)
splx(s); if (bp == &si->si_bp)
return si; break;
}
splx(s); splx(s);
return 0; return (si);
} }
/* /*
@ -204,7 +191,7 @@ void
scsistrategy(bp) scsistrategy(bp)
struct buf *bp; struct buf *bp;
{ {
int err; int error;
struct scsi_ioctl *si; struct scsi_ioctl *si;
scsireq_t *screq; scsireq_t *screq;
struct scsi_link *sc_link; struct scsi_link *sc_link;
@ -223,7 +210,7 @@ scsistrategy(bp)
if (!sc_link) { if (!sc_link) {
printf("user_strat: No link pointer\n"); printf("user_strat: No link pointer\n");
scsierr(bp, EINVAL); scsierr(bp, EINVAL);
goto out; return;
} }
SC_DEBUG(sc_link, SDEV_DB2, ("user_strategy\n")); SC_DEBUG(sc_link, SDEV_DB2, ("user_strategy\n"));
@ -234,19 +221,19 @@ scsistrategy(bp)
sc_print_addr(sc_link); sc_print_addr(sc_link);
printf("physio split the request.. cannot proceed\n"); printf("physio split the request.. cannot proceed\n");
scsierr(bp, EIO); scsierr(bp, EIO);
goto out; return;
} }
if (screq->timeout == 0) { if (screq->timeout == 0) {
scsierr(bp, EINVAL); scsierr(bp, EINVAL);
goto out; return;
} }
if (screq->cmdlen > sizeof(struct scsi_generic)) { if (screq->cmdlen > sizeof(struct scsi_generic)) {
sc_print_addr(sc_link); sc_print_addr(sc_link);
printf("cmdlen too big\n"); printf("cmdlen too big\n");
scsierr(bp, EFAULT); scsierr(bp, EFAULT);
goto out; return;
} }
if (screq->flags & SCCMD_READ) if (screq->flags & SCCMD_READ)
@ -258,25 +245,22 @@ scsistrategy(bp)
if (screq->flags & SCCMD_ESCAPE) if (screq->flags & SCCMD_ESCAPE)
flags |= SCSI_ESCAPE; flags |= SCSI_ESCAPE;
err = scsi_scsi_cmd(sc_link, (struct scsi_generic *)screq->cmd, error = scsi_scsi_cmd(sc_link, (struct scsi_generic *)screq->cmd,
screq->cmdlen, (u_char *)bp->b_data, screq->datalen, screq->cmdlen, (u_char *)bp->b_data, screq->datalen,
0, /* user must do the retries *//* ignored */ 0, /* user must do the retries *//* ignored */
screq->timeout, bp, flags | SCSI_USER); screq->timeout, bp, flags | SCSI_USER);
/* because there is a bp, scsi_scsi_cmd will return immediatly */ /* because there is a bp, scsi_scsi_cmd will return immediatly */
if (err) { if (error) {
scsierr(bp, err); scsierr(bp, error);
goto out; return;
} }
SC_DEBUG(sc_link, SDEV_DB3, ("about to sleep\n")); SC_DEBUG(sc_link, SDEV_DB3, ("about to sleep\n"));
s = splbio(); s = splbio();
while (!(bp->b_flags & B_DONE)) while (!(bp->b_flags & B_DONE))
tsleep(bp, PRIBIO, "scistr", 0); tsleep(bp, PRIBIO, "scistr", 0);
splx(s); splx(s);
SC_DEBUG(sc_link, SDEV_DB3, ("back from sleep\n")); SC_DEBUG(sc_link, SDEV_DB3, ("back from sleep\n"));
out:
si_free(si);
} }
/* /*
@ -297,6 +281,7 @@ scsi_do_ioctl(sc_link, dev, cmd, addr, f)
int error; int error;
SC_DEBUG(sc_link, SDEV_DB2, ("scsi_do_ioctl(0x%lx)\n", cmd)); SC_DEBUG(sc_link, SDEV_DB2, ("scsi_do_ioctl(0x%lx)\n", cmd));
switch(cmd) { switch(cmd) {
case SCIOCCOMMAND: { case SCIOCCOMMAND: {
/* /*
@ -308,24 +293,15 @@ scsi_do_ioctl(sc_link, dev, cmd, addr, f)
* Make a static copy using malloc! * Make a static copy using malloc!
*/ */
scsireq_t *screq = (scsireq_t *)addr; scsireq_t *screq = (scsireq_t *)addr;
struct buf *bp;
struct scsi_ioctl *si; struct scsi_ioctl *si;
caddr_t daddr;
int len; int len;
bp = malloc(sizeof(struct buf), M_TEMP, M_WAITOK); si = si_get();
bzero(bp, sizeof(struct buf));
daddr = screq->databuf;
bp->b_bcount = len = screq->datalen;
si = si_get(bp);
if (!si) {
scsierr(bp, EINTR);
return EINTR;
}
si->si_screq = *screq; si->si_screq = *screq;
si->si_sc_link = sc_link; si->si_sc_link = sc_link;
si->si_bp.b_bcount = len = screq->datalen;
if (len) { if (len) {
si->si_iov.iov_base = daddr; si->si_iov.iov_base = screq->databuf;
si->si_iov.iov_len = len; si->si_iov.iov_len = len;
si->si_uio.uio_iov = &si->si_iov; si->si_uio.uio_iov = &si->si_iov;
si->si_uio.uio_iovcnt = 1; si->si_uio.uio_iovcnt = 1;
@ -334,18 +310,18 @@ scsi_do_ioctl(sc_link, dev, cmd, addr, f)
si->si_uio.uio_rw = si->si_uio.uio_rw =
(screq->flags & SCCMD_READ) ? UIO_READ : UIO_WRITE; (screq->flags & SCCMD_READ) ? UIO_READ : UIO_WRITE;
si->si_uio.uio_procp = curproc; /* XXX */ si->si_uio.uio_procp = curproc; /* XXX */
error = physio(scsistrategy, bp, dev, error = physio(scsistrategy, &si->si_bp, dev,
(screq->flags & SCCMD_READ) ? B_READ : B_WRITE, (screq->flags & SCCMD_READ) ? B_READ : B_WRITE,
sc_link->adapter->scsi_minphys, &si->si_uio); sc_link->adapter->scsi_minphys, &si->si_uio);
} else { } else {
/* if no data, no need to translate it.. */ /* if no data, no need to translate it.. */
bp->b_data = 0; si->si_bp.b_data = 0;
bp->b_dev = -1; /* irrelevant info */ si->si_bp.b_dev = -1; /* irrelevant info */
bp->b_flags = 0; si->si_bp.b_flags = 0;
scsistrategy(bp); scsistrategy(&si->si_bp);
error = bp->b_error; error = si->si_bp.b_error;
} }
free(bp, M_TEMP); si_free(si);
return error; return error;
} }
case SCIOCDEBUG: { case SCIOCDEBUG: {

View File

@ -1,4 +1,4 @@
/* $NetBSD: scsi_ioctl.c,v 1.10 1994/10/30 21:49:21 cgd Exp $ */ /* $NetBSD: scsi_ioctl.c,v 1.11 1994/12/01 11:53:56 mycroft Exp $ */
/* /*
* Copyright (c) 1994 Charles Hannum. All rights reserved. * Copyright (c) 1994 Charles Hannum. All rights reserved.
@ -50,69 +50,56 @@
void scsierr __P((struct buf *, int)); void scsierr __P((struct buf *, int));
/*
* We need to maintain an assocation between the buf and the SCSI request
* structure. We do this with a simple array of scsi_ioctl structures below.
* XXX The free structures should probably be in a linked list.
*/
#define NIOCTL 16
struct scsi_ioctl { struct scsi_ioctl {
struct buf *si_bp; LIST_ENTRY(scsi_ioctl) si_list;
scsireq_t si_screq; struct buf si_bp;
struct scsi_link *si_sc_link;
struct uio si_uio; struct uio si_uio;
struct iovec si_iov; struct iovec si_iov;
} scsi_ioctl[NIOCTL]; scsireq_t si_screq;
struct scsi_link *si_sc_link;
};
LIST_HEAD(, scsi_ioctl) si_head;
struct scsi_ioctl * struct scsi_ioctl *
si_get(bp) si_get()
struct buf *bp;
{ {
int s = splbio();
struct scsi_ioctl *si; struct scsi_ioctl *si;
int error; int s;
for (;;) { si = malloc(sizeof(struct scsi_ioctl), M_TEMP, M_WAITOK);
for (si = scsi_ioctl; si < &scsi_ioctl[NIOCTL]; si++) bzero(si, sizeof(struct scsi_ioctl));
if (si->si_bp == 0) { s = splbio();
si->si_bp = bp; LIST_INSERT_HEAD(&si_head, si, si_list);
splx(s); splx(s);
return si; return (si);
}
error = tsleep(scsi_ioctl, PRIBIO | PCATCH, "siget", 0);
if (error) {
splx(s);
return 0;
}
}
} }
void void
si_free(si) si_free(si)
struct scsi_ioctl *si; struct scsi_ioctl *si;
{ {
int s = splbio(); int s;
si->si_bp = 0; s = splbio();
wakeup(scsi_ioctl); LIST_REMOVE(si, si_list);
splx(s); splx(s);
free(si, M_TEMP);
} }
struct scsi_ioctl * struct scsi_ioctl *
si_find(bp) si_find(bp)
struct buf *bp; struct buf *bp;
{ {
int s = splbio();
struct scsi_ioctl *si; struct scsi_ioctl *si;
int s;
for (si = scsi_ioctl; si < &scsi_ioctl[NIOCTL]; si++) s = splbio();
if (si->si_bp == bp) { for (si = si_head.lh_first; si != 0; si = si->si_list.le_next)
splx(s); if (bp == &si->si_bp)
return si; break;
}
splx(s); splx(s);
return 0; return (si);
} }
/* /*
@ -204,7 +191,7 @@ void
scsistrategy(bp) scsistrategy(bp)
struct buf *bp; struct buf *bp;
{ {
int err; int error;
struct scsi_ioctl *si; struct scsi_ioctl *si;
scsireq_t *screq; scsireq_t *screq;
struct scsi_link *sc_link; struct scsi_link *sc_link;
@ -223,7 +210,7 @@ scsistrategy(bp)
if (!sc_link) { if (!sc_link) {
printf("user_strat: No link pointer\n"); printf("user_strat: No link pointer\n");
scsierr(bp, EINVAL); scsierr(bp, EINVAL);
goto out; return;
} }
SC_DEBUG(sc_link, SDEV_DB2, ("user_strategy\n")); SC_DEBUG(sc_link, SDEV_DB2, ("user_strategy\n"));
@ -234,19 +221,19 @@ scsistrategy(bp)
sc_print_addr(sc_link); sc_print_addr(sc_link);
printf("physio split the request.. cannot proceed\n"); printf("physio split the request.. cannot proceed\n");
scsierr(bp, EIO); scsierr(bp, EIO);
goto out; return;
} }
if (screq->timeout == 0) { if (screq->timeout == 0) {
scsierr(bp, EINVAL); scsierr(bp, EINVAL);
goto out; return;
} }
if (screq->cmdlen > sizeof(struct scsi_generic)) { if (screq->cmdlen > sizeof(struct scsi_generic)) {
sc_print_addr(sc_link); sc_print_addr(sc_link);
printf("cmdlen too big\n"); printf("cmdlen too big\n");
scsierr(bp, EFAULT); scsierr(bp, EFAULT);
goto out; return;
} }
if (screq->flags & SCCMD_READ) if (screq->flags & SCCMD_READ)
@ -258,25 +245,22 @@ scsistrategy(bp)
if (screq->flags & SCCMD_ESCAPE) if (screq->flags & SCCMD_ESCAPE)
flags |= SCSI_ESCAPE; flags |= SCSI_ESCAPE;
err = scsi_scsi_cmd(sc_link, (struct scsi_generic *)screq->cmd, error = scsi_scsi_cmd(sc_link, (struct scsi_generic *)screq->cmd,
screq->cmdlen, (u_char *)bp->b_data, screq->datalen, screq->cmdlen, (u_char *)bp->b_data, screq->datalen,
0, /* user must do the retries *//* ignored */ 0, /* user must do the retries *//* ignored */
screq->timeout, bp, flags | SCSI_USER); screq->timeout, bp, flags | SCSI_USER);
/* because there is a bp, scsi_scsi_cmd will return immediatly */ /* because there is a bp, scsi_scsi_cmd will return immediatly */
if (err) { if (error) {
scsierr(bp, err); scsierr(bp, error);
goto out; return;
} }
SC_DEBUG(sc_link, SDEV_DB3, ("about to sleep\n")); SC_DEBUG(sc_link, SDEV_DB3, ("about to sleep\n"));
s = splbio(); s = splbio();
while (!(bp->b_flags & B_DONE)) while (!(bp->b_flags & B_DONE))
tsleep(bp, PRIBIO, "scistr", 0); tsleep(bp, PRIBIO, "scistr", 0);
splx(s); splx(s);
SC_DEBUG(sc_link, SDEV_DB3, ("back from sleep\n")); SC_DEBUG(sc_link, SDEV_DB3, ("back from sleep\n"));
out:
si_free(si);
} }
/* /*
@ -297,6 +281,7 @@ scsi_do_ioctl(sc_link, dev, cmd, addr, f)
int error; int error;
SC_DEBUG(sc_link, SDEV_DB2, ("scsi_do_ioctl(0x%lx)\n", cmd)); SC_DEBUG(sc_link, SDEV_DB2, ("scsi_do_ioctl(0x%lx)\n", cmd));
switch(cmd) { switch(cmd) {
case SCIOCCOMMAND: { case SCIOCCOMMAND: {
/* /*
@ -308,24 +293,15 @@ scsi_do_ioctl(sc_link, dev, cmd, addr, f)
* Make a static copy using malloc! * Make a static copy using malloc!
*/ */
scsireq_t *screq = (scsireq_t *)addr; scsireq_t *screq = (scsireq_t *)addr;
struct buf *bp;
struct scsi_ioctl *si; struct scsi_ioctl *si;
caddr_t daddr;
int len; int len;
bp = malloc(sizeof(struct buf), M_TEMP, M_WAITOK); si = si_get();
bzero(bp, sizeof(struct buf));
daddr = screq->databuf;
bp->b_bcount = len = screq->datalen;
si = si_get(bp);
if (!si) {
scsierr(bp, EINTR);
return EINTR;
}
si->si_screq = *screq; si->si_screq = *screq;
si->si_sc_link = sc_link; si->si_sc_link = sc_link;
si->si_bp.b_bcount = len = screq->datalen;
if (len) { if (len) {
si->si_iov.iov_base = daddr; si->si_iov.iov_base = screq->databuf;
si->si_iov.iov_len = len; si->si_iov.iov_len = len;
si->si_uio.uio_iov = &si->si_iov; si->si_uio.uio_iov = &si->si_iov;
si->si_uio.uio_iovcnt = 1; si->si_uio.uio_iovcnt = 1;
@ -334,18 +310,18 @@ scsi_do_ioctl(sc_link, dev, cmd, addr, f)
si->si_uio.uio_rw = si->si_uio.uio_rw =
(screq->flags & SCCMD_READ) ? UIO_READ : UIO_WRITE; (screq->flags & SCCMD_READ) ? UIO_READ : UIO_WRITE;
si->si_uio.uio_procp = curproc; /* XXX */ si->si_uio.uio_procp = curproc; /* XXX */
error = physio(scsistrategy, bp, dev, error = physio(scsistrategy, &si->si_bp, dev,
(screq->flags & SCCMD_READ) ? B_READ : B_WRITE, (screq->flags & SCCMD_READ) ? B_READ : B_WRITE,
sc_link->adapter->scsi_minphys, &si->si_uio); sc_link->adapter->scsi_minphys, &si->si_uio);
} else { } else {
/* if no data, no need to translate it.. */ /* if no data, no need to translate it.. */
bp->b_data = 0; si->si_bp.b_data = 0;
bp->b_dev = -1; /* irrelevant info */ si->si_bp.b_dev = -1; /* irrelevant info */
bp->b_flags = 0; si->si_bp.b_flags = 0;
scsistrategy(bp); scsistrategy(&si->si_bp);
error = bp->b_error; error = si->si_bp.b_error;
} }
free(bp, M_TEMP); si_free(si);
return error; return error;
} }
case SCIOCDEBUG: { case SCIOCDEBUG: {