summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2007-11-26 15:59:54 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2007-11-26 15:59:54 +0000
commit4c8ec346c37b4e89be57a88234cc8f9aaee197b7 (patch)
treeb0678cd95ee5987dd23e570e92ffa2c55e827aaa /sys/dev
parent95771ee153fc60e2025cf02b022fc75928ce33ec (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.c41
-rw-r--r--sys/dev/ata/atascsi.h3
-rw-r--r--sys/dev/ic/sili.c16
-rw-r--r--sys/dev/pci/ahci.c10
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)
{