summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorscottl <scottl@FreeBSD.org>2006-02-04 08:45:19 +0000
committerscottl <scottl@FreeBSD.org>2006-02-04 08:45:19 +0000
commit056a4092f0a74a545c794e05730abfc7fbba1716 (patch)
tree3e591a1e7b255abec898bd0056f001eb9ac80f88 /sys
parentcf93cd9ef8504e4355b07bc18bd285dd035f1edd (diff)
downloadFreeBSD-src-056a4092f0a74a545c794e05730abfc7fbba1716.zip
FreeBSD-src-056a4092f0a74a545c794e05730abfc7fbba1716.tar.gz
Add the start of busdma infrastructure to this driver. Convert the
ASR_resetIOPR function to use it.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/asr/asr.c121
1 files changed, 111 insertions, 10 deletions
diff --git a/sys/dev/asr/asr.c b/sys/dev/asr/asr.c
index 2b761af..dd0d5ab 100644
--- a/sys/dev/asr/asr.c
+++ b/sys/dev/asr/asr.c
@@ -123,6 +123,7 @@
#include <machine/bus.h>
#include <sys/rman.h>
#include <sys/stat.h>
+#include <sys/bus_dma.h>
#include <cam/cam.h>
#include <cam/cam_ccb.h>
@@ -156,13 +157,13 @@
#define osdSwap4(x) ((u_long)ntohl((u_long)(x)))
#define KVTOPHYS(x) vtophys(x)
-#include "dev/asr/dptalign.h"
-#include "dev/asr/i2oexec.h"
-#include "dev/asr/i2obscsi.h"
-#include "dev/asr/i2odpt.h"
-#include "dev/asr/i2oadptr.h"
+#include <dev/asr/dptalign.h>
+#include <dev/asr/i2oexec.h>
+#include <dev/asr/i2obscsi.h>
+#include <dev/asr/i2odpt.h>
+#include <dev/asr/i2oadptr.h>
-#include "dev/asr/sys_info.h"
+#include <dev/asr/sys_info.h>
__FBSDID("$FreeBSD$");
@@ -322,6 +323,7 @@ union asr_ccb {
***************************************************************************/
typedef struct Asr_softc {
+ device_t ha_dev;
u_int16_t ha_irq;
u_long ha_Base; /* base port for each board */
bus_size_t ha_blinkLED;
@@ -331,6 +333,12 @@ typedef struct Asr_softc {
bus_space_tag_t ha_frame_btag;
I2O_IOP_ENTRY ha_SystemTable;
LIST_HEAD(,ccb_hdr) ha_ccb; /* ccbs in use */
+
+ bus_dma_tag_t ha_parent_dmat;
+ bus_dma_tag_t ha_status_dmat;
+ bus_dmamap_t ha_status_dmamap;
+ u_int32_t * ha_status;
+ u_int32_t ha_status_phys;
struct cam_path * ha_path[MAX_CHANNEL+1];
struct cam_sim * ha_sim[MAX_CHANNEL+1];
struct resource * ha_mem_res;
@@ -561,7 +569,7 @@ ASR_resetIOP(Asr_softc_t *sc)
U32 R;
} Message;
PI2O_EXEC_IOP_RESET_MESSAGE Message_Ptr;
- U32 * volatile Reply_Ptr;
+ U32 * Reply_Ptr;
U32 Old;
/*
@@ -573,10 +581,10 @@ ASR_resetIOP(Asr_softc_t *sc)
/*
* Reset the Reply Status
*/
- *(Reply_Ptr = (U32 *)((char *)Message_Ptr
- + sizeof(I2O_EXEC_IOP_RESET_MESSAGE))) = 0;
+ Reply_Ptr = sc->ha_status;
+ *Reply_Ptr = 0;
I2O_EXEC_IOP_RESET_MESSAGE_setStatusWordLowAddress(Message_Ptr,
- KVTOPHYS((void *)Reply_Ptr));
+ sc->ha_status_phys);
/*
* Send the Message out
*/
@@ -2291,6 +2299,89 @@ asr_pci_map_int(device_t dev, Asr_softc_t *sc)
return (1);
} /* asr_pci_map_int */
+static void
+asr_status_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
+{
+ Asr_softc_t *sc;
+
+ if (error)
+ return;
+
+ sc = (Asr_softc_t *)arg;
+
+ /* XXX
+ * The status word can be at a 64-bit address, but the existing
+ * accessor macros simply cannot manipulate 64-bit addresses.
+ */
+ sc->ha_status_phys = (u_int32_t)segs[0].ds_addr;
+}
+
+static int
+asr_alloc_dma(Asr_softc_t *sc)
+{
+ device_t dev;
+
+ dev = sc->ha_dev;
+
+ if (bus_dma_tag_create(NULL, /* parent */
+ 1, 0, /* algnmnt, boundary */
+ BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ BUS_SPACE_MAXSIZE_32BIT, /* maxsize */
+ BUS_SPACE_UNRESTRICTED, /* nsegments */
+ BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
+ 0, /* flags */
+ NULL, NULL, /* lockfunc, lockarg */
+ &sc->ha_parent_dmat)) {
+ device_printf(dev, "Cannot allocate parent DMA tag\n");
+ return (ENOMEM);
+ }
+
+ if (bus_dma_tag_create(sc->ha_parent_dmat, /* parent */
+ 1, 0, /* algnmnt, boundary */
+ BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ sizeof(uint32_t), /* maxsize */
+ 1, /* nsegments */
+ sizeof(uint32_t), /* maxsegsize */
+ 0, /* flags */
+ NULL, NULL, /* lockfunc, lockarg */
+ &sc->ha_status_dmat)) {
+ device_printf(dev, "Cannot allocate status DMA tag\n");
+ bus_dma_tag_destroy(sc->ha_parent_dmat);
+ return (ENOMEM);
+ }
+
+ if (bus_dmamem_alloc(sc->ha_status_dmat, (void **)&sc->ha_status,
+ BUS_DMA_NOWAIT, &sc->ha_status_dmamap)) {
+ device_printf(dev, "Cannot allocate status memory\n");
+ bus_dma_tag_destroy(sc->ha_status_dmat);
+ bus_dma_tag_destroy(sc->ha_parent_dmat);
+ return (ENOMEM);
+ }
+ (void)bus_dmamap_load(sc->ha_status_dmat, sc->ha_status_dmamap,
+ sc->ha_status, sizeof(sc->ha_status), asr_status_cb, sc, 0);
+
+ return (0);
+}
+
+static void
+asr_release_dma(Asr_softc_t *sc)
+{
+
+ if (sc->ha_status_phys != 0)
+ bus_dmamap_unload(sc->ha_status_dmat, sc->ha_status_dmamap);
+ if (sc->ha_status != NULL)
+ bus_dmamem_free(sc->ha_status_dmat, sc->ha_status,
+ sc->ha_status_dmamap);
+ if (sc->ha_status_dmat != NULL)
+ bus_dma_tag_destroy(sc->ha_status_dmat);
+ if (sc->ha_parent_dmat != NULL)
+ bus_dma_tag_destroy(sc->ha_parent_dmat);
+}
+
/*
* Attach the devices, and virtual devices to the driver list.
*/
@@ -2302,9 +2393,11 @@ asr_attach(device_t dev)
Asr_softc_t *sc, **ha;
struct scsi_inquiry_data *iq;
int bus, size, unit;
+ int error;
sc = device_get_softc(dev);
unit = device_get_unit(dev);
+ sc->ha_dev = dev;
if (Asr_softc == NULL) {
/*
@@ -2336,19 +2429,25 @@ asr_attach(device_t dev)
sc->ha_pciBusNum = pci_get_bus(dev);
sc->ha_pciDeviceNum = (pci_get_slot(dev) << 3) | pci_get_function(dev);
+ if ((error = asr_alloc_dma(sc)) != 0)
+ return (error);
+
/* Check if the device is there? */
if (ASR_resetIOP(sc) == 0) {
device_printf(dev, "Cannot reset adapter\n");
+ asr_release_dma(sc);
return (EIO);
}
if ((status = (PI2O_EXEC_STATUS_GET_REPLY)malloc(
sizeof(I2O_EXEC_STATUS_GET_REPLY), M_TEMP, M_NOWAIT)) == NULL) {
device_printf(dev, "Cannot allocate memory\n");
+ asr_release_dma(sc);
return (ENOMEM);
}
if (ASR_getStatus(sc, status) == NULL) {
device_printf(dev, "could not initialize hardware\n");
free(status, M_TEMP);
+ asr_release_dma(sc);
return(ENODEV);
}
sc->ha_SystemTable.OrganizationID = status->OrganizationID;
@@ -2362,6 +2461,7 @@ asr_attach(device_t dev)
if (!asr_pci_map_int(dev, (void *)sc)) {
device_printf(dev, "could not map interrupt\n");
+ asr_release_dma(sc);
return(ENXIO);
}
@@ -2415,6 +2515,7 @@ asr_attach(device_t dev)
}
} else {
device_printf(dev, "failed to initialize\n");
+ asr_release_dma(sc);
return(ENXIO);
}
/*
OpenPOWER on IntegriCloud