diff options
Diffstat (limited to 'sys/dev/ida/ida_pci.c')
-rw-r--r-- | sys/dev/ida/ida_pci.c | 150 |
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, |