summaryrefslogtreecommitdiffstats
path: root/sys/dev/ida/ida_pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/ida/ida_pci.c')
-rw-r--r--sys/dev/ida/ida_pci.c150
1 files changed, 119 insertions, 31 deletions
diff --git a/sys/dev/ida/ida_pci.c b/sys/dev/ida/ida_pci.c
index 4e97181..d43a157 100644
--- a/sys/dev/ida/ida_pci.c
+++ b/sys/dev/ida/ida_pci.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1999 Jonathan Lemon
+ * Copyright (c) 1999,2000 Jonathan Lemon
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -34,6 +34,7 @@
#include <sys/buf.h>
#include <sys/bus.h>
#include <sys/devicestat.h>
+#include <sys/disk.h>
#include <machine/bus_memio.h>
#include <machine/bus_pio.h>
@@ -45,6 +46,7 @@
#include <pci/pcivar.h>
#include <dev/ida/idavar.h>
+#include <dev/ida/idareg.h>
#define IDA_PCI_MAX_DMA_ADDR 0xFFFFFFFF
#define IDA_PCI_MAX_DMA_COUNT 0xFFFFFFFF
@@ -53,17 +55,101 @@
#define IDA_DEVICEID_SMART 0xAE100E11
-static struct {
- u_long board;
- char *desc;
-} board_id[] = {
- { 0x4030, "Compaq SMART-2/P array controller" },
- { 0x4031, "Compaq SMART-2SL array controller" },
- { 0x4032, "Compaq Smart Array 3200 controller" },
- { 0x4033, "Compaq Smart Array 3100ES controller" },
- { 0x4034, "Compaq Smart Array 221 controller" },
-
- { 0, "" },
+static int
+ida_v3_fifo_full(struct ida_softc *ida)
+{
+ return (ida_inl(ida, R_CMD_FIFO) == 0);
+}
+
+static void
+ida_v3_submit(struct ida_softc *ida, struct ida_qcb *qcb)
+{
+ ida_outl(ida, R_CMD_FIFO, qcb->hwqcb_busaddr);
+}
+
+static bus_addr_t
+ida_v3_done(struct ida_softc *ida)
+{
+ return (ida_inl(ida, R_DONE_FIFO));
+}
+
+static int
+ida_v3_int_pending(struct ida_softc *ida)
+{
+ return (ida_inl(ida, R_INT_PENDING));
+}
+
+static void
+ida_v3_int_enable(struct ida_softc *ida, int enable)
+{
+ ida_outl(ida, R_INT_MASK, enable ? INT_ENABLE : INT_DISABLE);
+}
+
+static int
+ida_v4_fifo_full(struct ida_softc *ida)
+{
+ return (ida_inl(ida, R_42XX_REQUEST) != 0);
+}
+
+static void
+ida_v4_submit(struct ida_softc *ida, struct ida_qcb *qcb)
+{
+ ida_outl(ida, R_42XX_REQUEST, qcb->hwqcb_busaddr);
+}
+
+static bus_addr_t
+ida_v4_done(struct ida_softc *ida)
+{
+ bus_addr_t completed;
+
+ completed = ida_inl(ida, R_42XX_REPLY);
+ if (completed == -1)
+ return (0); /* fifo is empty */
+ ida_outl(ida, R_42XX_REPLY, 0); /* confirm read */
+ return (completed);
+}
+
+static int
+ida_v4_int_pending(struct ida_softc *ida)
+{
+ return (ida_inl(ida, R_42XX_STATUS) & STATUS_42XX_INT_PENDING);
+}
+
+static void
+ida_v4_int_enable(struct ida_softc *ida, int enable)
+{
+ ida_outl(ida, R_42XX_INT_MASK,
+ enable ? INT_ENABLE_42XX : INT_DISABLE_42XX);
+}
+
+static struct ida_access ida_v3_access = {
+ ida_v3_fifo_full,
+ ida_v3_submit,
+ ida_v3_done,
+ ida_v3_int_pending,
+ ida_v3_int_enable,
+};
+
+static struct ida_access ida_v4_access = {
+ ida_v4_fifo_full,
+ ida_v4_submit,
+ ida_v4_done,
+ ida_v4_int_pending,
+ ida_v4_int_enable,
+};
+
+static struct ida_board board_id[] = {
+ { 0x4030, "Compaq SMART-2/P array controller", &ida_v3_access },
+ { 0x4031, "Compaq SMART-2SL array controller", &ida_v3_access },
+ { 0x4032, "Compaq Smart Array 3200 controller", &ida_v3_access },
+ { 0x4033, "Compaq Smart Array 3100ES controller", &ida_v3_access },
+ { 0x4034, "Compaq Smart Array 221 controller", &ida_v3_access },
+
+ { 0x4040, "Compaq Integrated Array controller", &ida_v4_access },
+ { 0x4050, "Compaq Smart Array 4200 controller", &ida_v4_access },
+ { 0x4051, "Compaq Smart Array 4250ES controller", &ida_v4_access },
+
+ { 0, "", 0 },
};
static int ida_pci_probe(device_t dev);
@@ -72,6 +158,7 @@ static int ida_pci_attach(device_t dev);
static device_method_t ida_pci_methods[] = {
DEVMETHOD(device_probe, ida_pci_probe),
DEVMETHOD(device_attach, ida_pci_attach),
+ DEVMETHOD(device_detach, ida_detach),
DEVMETHOD(bus_print_child, bus_generic_print_child),
@@ -86,26 +173,28 @@ static driver_t ida_pci_driver = {
static devclass_t ida_devclass;
+static struct ida_board *
+ida_pci_match(u_int32_t id)
+{
+ int i;
+
+ for (i = 0; board_id[i].board; i++)
+ if (board_id[i].board == id)
+ return (&board_id[i]);
+ return (NULL);
+}
+
static int
ida_pci_probe(device_t dev)
{
- u_long board;
- int i;
+ struct ida_board *board;
if (pci_get_devid(dev) == IDA_DEVICEID_SMART) {
- board = pci_get_subdevice(dev);
- for (i = 0; board_id[i].board; i++) {
- if (board_id[i].board == board) {
- device_set_desc(dev, board_id[i].desc);
- return (0);
- }
+ board = ida_pci_match(pci_get_subdevice(dev));
+ if (board != NULL) {
+ device_set_desc(dev, board->desc);
+ return (0);
}
- /*
- * It's an unknown Compaq SMART device, but assume we
- * can support it.
- */
- device_set_desc(dev, "Unknown Compaq Smart Array controller");
- return (0);
}
return (ENXIO);
}
@@ -113,6 +202,7 @@ ida_pci_probe(device_t dev)
static int
ida_pci_attach(device_t dev)
{
+ struct ida_board *board;
struct ida_softc *ida;
u_int command;
int error, rid;
@@ -120,11 +210,6 @@ ida_pci_attach(device_t dev)
command = pci_read_config(dev, PCIR_COMMAND, 1);
/*
- * for multiple card types, need to re-determine which type is
- * being attached here
- */
-
- /*
* it appears that this board only does MEMIO access.
*/
if ((command & PCIM_CMD_MEMEN) == 0) {
@@ -135,6 +220,9 @@ ida_pci_attach(device_t dev)
ida = (struct ida_softc *)device_get_softc(dev);
ida->dev = dev;
+ board = ida_pci_match(pci_get_subdevice(dev));
+ ida->cmd = *board->accessor;
+
ida->regs_res_type = SYS_RES_MEMORY;
ida->regs_res_id = IDA_PCI_MEMADDR;
ida->regs = bus_alloc_resource(dev, ida->regs_res_type,
OpenPOWER on IntegriCloud