diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2007-11-26 15:59:54 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2007-11-26 15:59:54 +0000 |
commit | 4c8ec346c37b4e89be57a88234cc8f9aaee197b7 (patch) | |
tree | b0678cd95ee5987dd23e570e92ffa2c55e827aaa /sys/dev | |
parent | 95771ee153fc60e2025cf02b022fc75928ce33ec (diff) |
drive port probes from the scsi midlayer now that it will ask the adapter
if a device is there before doing any scsi commands. also implement a free
path for when devices are detached. software hotplug has been tested on
sili, and ahci is still working according to claudio@
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/ata/atascsi.c | 41 | ||||
-rw-r--r-- | sys/dev/ata/atascsi.h | 3 | ||||
-rw-r--r-- | sys/dev/ic/sili.c | 16 | ||||
-rw-r--r-- | sys/dev/pci/ahci.c | 10 |
4 files changed, 50 insertions, 20 deletions
diff --git a/sys/dev/ata/atascsi.c b/sys/dev/ata/atascsi.c index c7875568060..e37eeb71668 100644 --- a/sys/dev/ata/atascsi.c +++ b/sys/dev/ata/atascsi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: atascsi.c,v 1.47 2007/11/23 18:21:55 dlg Exp $ */ +/* $OpenBSD: atascsi.c,v 1.48 2007/11/26 15:59:53 dlg Exp $ */ /* * Copyright (c) 2007 David Gwynne <dlg@openbsd.org> @@ -50,6 +50,8 @@ struct atascsi { int atascsi_cmd(struct scsi_xfer *); int atascsi_ioctl(struct scsi_link *, u_long, caddr_t, int, struct proc *); +int atascsi_probe(struct scsi_link *); +void atascsi_free(struct scsi_link *); /* template */ struct scsi_adapter atascsi_switch = { @@ -57,16 +59,15 @@ struct scsi_adapter atascsi_switch = { minphys, /* scsi_minphys */ NULL, NULL, - atascsi_ioctl /* ioctl */ + atascsi_ioctl, /* ioctl */ + atascsi_probe, /* dev_probe */ + atascsi_free /* dev_free */ }; struct scsi_device atascsi_device = { NULL, NULL, NULL, NULL }; -int atascsi_probe(struct atascsi *, int); -void atascsi_unprobe(struct atascsi *, int); - struct ata_xfer *ata_setup_identify(struct ata_port *, int); void ata_free_identify(struct ata_xfer *); void ata_complete_identify(struct ata_xfer *, @@ -103,7 +104,6 @@ atascsi_attach(struct device *self, struct atascsi_attach_args *aaa) { struct scsibus_attach_args saa; struct atascsi *as; - int i; as = malloc(sizeof(*as), M_DEVBUF, M_WAITOK | M_ZERO); @@ -130,10 +130,6 @@ atascsi_attach(struct device *self, struct atascsi_attach_args *aaa) as->as_ports = malloc(sizeof(struct ata_port *) * aaa->aaa_nports, M_DEVBUF, M_WAITOK | M_ZERO); - /* fill in the port array with the type of devices there */ - for (i = 0; i < as->as_link.adapter_buswidth; i++) - atascsi_probe(as, i); - bzero(&saa, sizeof(saa)); saa.saa_sc_link = &as->as_link; @@ -148,27 +144,30 @@ int atascsi_detach(struct atascsi *as, int flags) { int rv; - int i; rv = config_detach((struct device *)as->as_scsibus, flags); if (rv != 0) return (rv); - for (i = 0; i < as->as_link.adapter_buswidth; i++) - atascsi_unprobe(as, i); - free(as, M_DEVBUF); return (0); } int -atascsi_probe(struct atascsi *as, int port) +atascsi_probe(struct scsi_link *link) { + struct atascsi *as = link->adapter_softc; struct ata_port *ap; struct ata_xfer *xa; - int type, s; + int port, type; + int s; + /* revisit this when we do port multipliers */ + if (link->lun > 0) + return (ENXIO); + + port = link->target; if (port > as->as_link.adapter_buswidth) return (ENXIO); @@ -215,10 +214,16 @@ atascsi_probe(struct atascsi *as, int port) } void -atascsi_unprobe(struct atascsi *as, int port) +atascsi_free(struct scsi_link *link) { + struct atascsi *as = link->adapter_softc; struct ata_port *ap; + int port; + if (link->lun > 0) + return; + + port = link->target; if (port > as->as_link.adapter_buswidth) return; @@ -228,6 +233,8 @@ atascsi_unprobe(struct atascsi *as, int port) free(ap, M_DEVBUF); as->as_ports[port] = NULL; + + as->as_methods->free(as->as_cookie, port); } struct ata_xfer * diff --git a/sys/dev/ata/atascsi.h b/sys/dev/ata/atascsi.h index 5245029ff23..37833225e43 100644 --- a/sys/dev/ata/atascsi.h +++ b/sys/dev/ata/atascsi.h @@ -1,4 +1,4 @@ -/* $OpenBSD: atascsi.h,v 1.26 2007/11/23 18:21:55 dlg Exp $ */ +/* $OpenBSD: atascsi.h,v 1.27 2007/11/26 15:59:53 dlg Exp $ */ /* * Copyright (c) 2007 David Gwynne <dlg@openbsd.org> @@ -291,6 +291,7 @@ struct ata_xfer { struct atascsi_methods { int (*probe)(void *, int); + void (*free)(void *, int); struct ata_xfer * (*ata_get_xfer)(void *, int ); int (*ata_cmd)(struct ata_xfer *); }; diff --git a/sys/dev/ic/sili.c b/sys/dev/ic/sili.c index 0d309d1239b..4e544cd8ce7 100644 --- a/sys/dev/ic/sili.c +++ b/sys/dev/ic/sili.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sili.c,v 1.37 2007/11/23 18:26:03 kettenis Exp $ */ +/* $OpenBSD: sili.c,v 1.38 2007/11/26 15:59:53 dlg Exp $ */ /* * Copyright (c) 2007 David Gwynne <dlg@openbsd.org> @@ -159,12 +159,14 @@ u_int32_t sili_port_intr(struct sili_port *, int); /* atascsi interface */ int sili_ata_probe(void *, int); +void sili_ata_free(void *, int); struct ata_xfer *sili_ata_get_xfer(void *, int); void sili_ata_put_xfer(struct ata_xfer *); int sili_ata_cmd(struct ata_xfer *); struct atascsi_methods sili_atascsi_methods = { sili_ata_probe, + sili_ata_free, sili_ata_get_xfer, sili_ata_cmd }; @@ -794,6 +796,18 @@ sili_ata_probe(void *xsc, int port) return (port_type); } +void +sili_ata_free(void *xsc, int port) +{ + struct sili_softc *sc = xsc; + struct sili_port *sp = &sc->sc_ports[port]; + + if (sp->sp_ccbs != NULL) + sili_ccb_free(sp); + + /* XXX we should do more here */ +} + int sili_ata_cmd(struct ata_xfer *xa) { diff --git a/sys/dev/pci/ahci.c b/sys/dev/pci/ahci.c index 7b75c0ec7c8..c9aef7bd030 100644 --- a/sys/dev/pci/ahci.c +++ b/sys/dev/pci/ahci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ahci.c,v 1.133 2007/11/19 01:18:48 pascoe Exp $ */ +/* $OpenBSD: ahci.c,v 1.134 2007/11/26 15:59:53 dlg Exp $ */ /* * Copyright (c) 2006 David Gwynne <dlg@openbsd.org> @@ -508,12 +508,14 @@ int ahci_pwait_eq(struct ahci_port *, bus_size_t, /* provide methods for atascsi to call */ int ahci_ata_probe(void *, int); +void ahci_ata_free(void *, int); struct ata_xfer * ahci_ata_get_xfer(void *, int); void ahci_ata_put_xfer(struct ata_xfer *); int ahci_ata_cmd(struct ata_xfer *); struct atascsi_methods ahci_atascsi_methods = { ahci_ata_probe, + ahci_ata_free, ahci_ata_get_xfer, ahci_ata_cmd }; @@ -2195,6 +2197,12 @@ ahci_ata_probe(void *xsc, int port) return (ATA_PORT_T_DISK); } +void +ahci_ata_free(void *xsc, int port) +{ + +} + struct ata_xfer * ahci_ata_get_xfer(void *aaa_cookie, int port) { |