diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2007-11-28 13:47:10 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2007-11-28 13:47:10 +0000 |
commit | c084749f5c95ba0440adc6c76932ac3277c3f860 (patch) | |
tree | 813f43685081cdda061de6678c286af42d4da777 /sys/dev | |
parent | cab9e4984ef886485a179deef66ebafa436ba779 (diff) |
make ata controllers protect their own command lists so atascsi doesnt have
to continually go to splbio to ensure its safe to work on them. shrinks
code a little.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/ata/atascsi.c | 27 | ||||
-rw-r--r-- | sys/dev/ic/sili.c | 9 | ||||
-rw-r--r-- | sys/dev/pci/ahci.c | 9 |
3 files changed, 18 insertions, 27 deletions
diff --git a/sys/dev/ata/atascsi.c b/sys/dev/ata/atascsi.c index 226ae07a3d0..a5002ba9c72 100644 --- a/sys/dev/ata/atascsi.c +++ b/sys/dev/ata/atascsi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: atascsi.c,v 1.49 2007/11/26 20:13:53 dlg Exp $ */ +/* $OpenBSD: atascsi.c,v 1.50 2007/11/28 13:47:09 dlg Exp $ */ /* * Copyright (c) 2007 David Gwynne <dlg@openbsd.org> @@ -173,7 +173,6 @@ atascsi_probe(struct scsi_link *link) struct ata_port *ap; struct ata_xfer *xa; int port, type; - int s; /* revisit this when we do port multipliers */ if (link->lun > 0) @@ -202,9 +201,7 @@ atascsi_probe(struct scsi_link *link) as->as_ports[port] = ap; - s = splbio(); xa = ata_get_xfer(ap, 1); - splx(s); if (xa == NULL) return (EBUSY); @@ -253,21 +250,16 @@ struct ata_xfer * ata_setup_identify(struct ata_port *ap, int nosleep) { struct ata_xfer *xa; - int s; - s = splbio(); xa = ata_get_xfer(ap, nosleep); - splx(s); if (xa == NULL) return (NULL); xa->data = malloc(512, M_TEMP, nosleep ? (M_NOWAIT | M_ZERO) : (M_WAITOK | M_ZERO)); if (xa->data == NULL) { - s = splbio(); xa->state = ATA_S_ERROR; ata_put_xfer(xa); - splx(s); return (NULL); } xa->datalen = 512; @@ -338,7 +330,7 @@ atascsi_disk_cmd(struct scsi_xfer *xs) struct scsi_link *link = xs->sc_link; struct atascsi *as = link->adapter_softc; struct ata_port *ap = as->as_ports[link->target]; - int s, flags = 0; + int flags = 0; struct scsi_rw *rw; struct scsi_rw_big *rwb; struct ata_xfer *xa; @@ -375,9 +367,7 @@ atascsi_disk_cmd(struct scsi_xfer *xs) return (atascsi_stuffup(xs)); } - s = splbio(); xa = ata_get_xfer(ap, xs->flags & SCSI_NOSLEEP); - splx(s); if (xa == NULL) return (NO_CCB); @@ -637,11 +627,8 @@ atascsi_disk_sync(struct scsi_xfer *xs) struct atascsi *as = link->adapter_softc; struct ata_port *ap = as->as_ports[link->target]; struct ata_xfer *xa; - int s; - s = splbio(); xa = ata_get_xfer(ap, xs->flags & SCSI_NOSLEEP); - splx(s); if (xa == NULL) return (NO_CCB); @@ -790,13 +777,10 @@ atascsi_atapi_cmd(struct scsi_xfer *xs) struct scsi_link *link = xs->sc_link; struct atascsi *as = link->adapter_softc; struct ata_port *ap = as->as_ports[link->target]; - int s; struct ata_xfer *xa; struct ata_fis_h2d *fis; - s = splbio(); xa = ata_get_xfer(ap, xs->flags & SCSI_NOSLEEP); - splx(s); if (xa == NULL) return (NO_CCB); @@ -911,11 +895,8 @@ atascsi_ioctl_cmd(struct atascsi *as, struct ata_port *ap, atareq_t *atareq) struct ata_xfer *xa; struct ata_fis_h2d *fis; void *buf; - int s; - s = splbio(); xa = ata_get_xfer(ap, 0); - splx(s); if (xa == NULL) return (ENOMEM); @@ -953,9 +934,7 @@ atascsi_ioctl_cmd(struct atascsi *as, struct ata_port *ap, atareq_t *atareq) break; case ATA_ERROR: free(buf, M_TEMP); - s = splbio(); ata_put_xfer(xa); - splx(s); atareq->retsts = ATACMD_ERROR; return (EIO); default: @@ -981,9 +960,7 @@ atascsi_ioctl_cmd(struct atascsi *as, struct ata_port *ap, atareq_t *atareq) free(buf, M_TEMP); - s = splbio(); ata_put_xfer(xa); - splx(s); return (0); } diff --git a/sys/dev/ic/sili.c b/sys/dev/ic/sili.c index 4e544cd8ce7..8ff8ca2db70 100644 --- a/sys/dev/ic/sili.c +++ b/sys/dev/ic/sili.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sili.c,v 1.38 2007/11/26 15:59:53 dlg Exp $ */ +/* $OpenBSD: sili.c,v 1.39 2007/11/28 13:47:09 dlg Exp $ */ /* * Copyright (c) 2007 David Gwynne <dlg@openbsd.org> @@ -23,6 +23,7 @@ #include <sys/proc.h> #include <sys/malloc.h> #include <sys/kernel.h> +#include <sys/mutex.h> #include <machine/bus.h> @@ -80,6 +81,7 @@ struct sili_port { struct sili_dmamem *sp_scratch; TAILQ_HEAD(, sili_ccb) sp_free_ccbs; + struct mutex sp_free_ccb_mtx; volatile u_int32_t sp_active; TAILQ_HEAD(, sili_ccb) sp_active_ccbs; @@ -470,6 +472,7 @@ sili_ccb_alloc(struct sili_port *sp) int i; TAILQ_INIT(&sp->sp_free_ccbs); + mtx_init(&sp->sp_free_ccb_mtx, IPL_BIO); TAILQ_INIT(&sp->sp_active_ccbs); TAILQ_INIT(&sp->sp_deferred_ccbs); @@ -534,12 +537,14 @@ sili_get_ccb(struct sili_port *sp) { struct sili_ccb *ccb; + mtx_enter(&sp->sp_free_ccb_mtx); ccb = TAILQ_FIRST(&sp->sp_free_ccbs); if (ccb != NULL) { KASSERT(ccb->ccb_xa.state == ATA_S_PUT); TAILQ_REMOVE(&sp->sp_free_ccbs, ccb, ccb_entry); ccb->ccb_xa.state = ATA_S_SETUP; } + mtx_leave(&sp->sp_free_ccb_mtx); return (ccb); } @@ -560,7 +565,9 @@ sili_put_ccb(struct sili_ccb *ccb) #endif ccb->ccb_xa.state = ATA_S_PUT; + mtx_enter(&sp->sp_free_ccb_mtx); TAILQ_INSERT_TAIL(&sp->sp_free_ccbs, ccb, ccb_entry); + mtx_leave(&sp->sp_free_ccb_mtx); } struct sili_dmamem * diff --git a/sys/dev/pci/ahci.c b/sys/dev/pci/ahci.c index c9aef7bd030..aaebba7f7b0 100644 --- a/sys/dev/pci/ahci.c +++ b/sys/dev/pci/ahci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ahci.c,v 1.134 2007/11/26 15:59:53 dlg Exp $ */ +/* $OpenBSD: ahci.c,v 1.135 2007/11/28 13:47:09 dlg Exp $ */ /* * Copyright (c) 2006 David Gwynne <dlg@openbsd.org> @@ -24,6 +24,7 @@ #include <sys/device.h> #include <sys/proc.h> #include <sys/queue.h> +#include <sys/mutex.h> #include <machine/bus.h> @@ -354,6 +355,7 @@ struct ahci_port { TAILQ_HEAD(, ahci_ccb) ap_ccb_free; TAILQ_HEAD(, ahci_ccb) ap_ccb_pending; + struct mutex ap_ccb_mtx; u_int32_t ap_state; #define AP_S_NORMAL 0 @@ -890,6 +892,7 @@ ahci_port_alloc(struct ahci_softc *sc, u_int port) #endif TAILQ_INIT(&ap->ap_ccb_free); TAILQ_INIT(&ap->ap_ccb_pending); + mtx_init(&ap->ap_ccb_mtx, IPL_BIO); /* Disable port interrupts */ ahci_pwrite(ap, AHCI_PREG_IE, 0); @@ -1873,12 +1876,14 @@ ahci_get_ccb(struct ahci_port *ap) { struct ahci_ccb *ccb; + mtx_enter(&ap->ap_ccb_mtx); ccb = TAILQ_FIRST(&ap->ap_ccb_free); if (ccb != NULL) { KASSERT(ccb->ccb_xa.state == ATA_S_PUT); TAILQ_REMOVE(&ap->ap_ccb_free, ccb, ccb_entry); ccb->ccb_xa.state = ATA_S_SETUP; } + mtx_leave(&ap->ap_ccb_mtx); return (ccb); } @@ -1899,7 +1904,9 @@ ahci_put_ccb(struct ahci_ccb *ccb) #endif ccb->ccb_xa.state = ATA_S_PUT; + mtx_enter(&ap->ap_ccb_mtx); TAILQ_INSERT_TAIL(&ap->ap_ccb_free, ccb, ccb_entry); + mtx_leave(&ap->ap_ccb_mtx); } struct ahci_ccb * |