diff options
author | marius <marius@FreeBSD.org> | 2011-03-06 12:48:15 +0000 |
---|---|---|
committer | marius <marius@FreeBSD.org> | 2011-03-06 12:48:15 +0000 |
commit | efdc3bab88588b25e0abec1cccd8e57479614115 (patch) | |
tree | b455dec8b7bcc6253e8b45411570d43399b7fe1f | |
parent | 229ca25a4ffd260489a46b13f6931d9f37543be0 (diff) | |
download | FreeBSD-src-efdc3bab88588b25e0abec1cccd8e57479614115.zip FreeBSD-src-efdc3bab88588b25e0abec1cccd8e57479614115.tar.gz |
- Allocate the DMA memory shared between the host and the controller as
coherent.
- Add some missing bus_dmamap_sync() calls. This includes putting such
calls before calling reply handlers instead of calling bus_dmamap_sync()
for the request queue from individual reply handlers as these handlers
generally read back updates by the controller.
Tested on amd64 and sparc64.
MFC after: 2 weeks
-rw-r--r-- | sys/dev/mpt/mpt.c | 42 | ||||
-rw-r--r-- | sys/dev/mpt/mpt_cam.c | 9 | ||||
-rw-r--r-- | sys/dev/mpt/mpt_user.c | 21 |
3 files changed, 41 insertions, 31 deletions
diff --git a/sys/dev/mpt/mpt.c b/sys/dev/mpt/mpt.c index 12f0949..c42be81 100644 --- a/sys/dev/mpt/mpt.c +++ b/sys/dev/mpt/mpt.c @@ -718,15 +718,16 @@ mpt_intr(void *arg) uint32_t ctxt_idx; u_int cb_index; u_int req_index; + u_int offset; int free_rf; req = NULL; reply_frame = NULL; reply_baddr = 0; + offset = 0; if ((reply_desc & MPI_ADDRESS_REPLY_A_BIT) != 0) { - u_int offset; /* - * Insure that the reply frame is coherent. + * Ensure that the reply frame is coherent. */ reply_baddr = MPT_REPLY_BADDR(reply_desc); offset = reply_baddr - (mpt->reply_phys & 0xFFFFFFFF); @@ -808,10 +809,15 @@ mpt_intr(void *arg) " 0x%x)\n", req_index, reply_desc); } + bus_dmamap_sync(mpt->request_dmat, mpt->request_dmap, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); free_rf = mpt_reply_handlers[cb_index](mpt, req, reply_desc, reply_frame); if (reply_frame != NULL && free_rf) { + bus_dmamap_sync_range(mpt->reply_dmat, + mpt->reply_dmap, offset, MPT_REPLY_SIZE, + BUS_DMASYNC_PREREAD); mpt_free_reply(mpt, reply_baddr); } @@ -844,6 +850,8 @@ mpt_complete_request_chain(struct mpt_softc *mpt, struct req_queue *chain, MSG_REQUEST_HEADER *msg_hdr; u_int cb_index; + bus_dmamap_sync(mpt->request_dmat, mpt->request_dmap, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); msg_hdr = (MSG_REQUEST_HEADER *)req->req_vbuf; ioc_status_frame.Function = msg_hdr->Function; ioc_status_frame.MsgContext = msg_hdr->MsgContext; @@ -1167,7 +1175,7 @@ mpt_free_request(struct mpt_softc *mpt, request_t *req) { request_t *nxt; struct mpt_evtf_record *record; - uint32_t reply_baddr; + uint32_t offset, reply_baddr; if (req == NULL || req != &mpt->request_pool[req->index]) { panic("mpt_free_request bad req ptr\n"); @@ -1216,8 +1224,10 @@ mpt_free_request(struct mpt_softc *mpt, request_t *req) req->state = REQ_STATE_ALLOCATED; mpt_assign_serno(mpt, req); mpt_send_event_ack(mpt, req, &record->reply, record->context); - reply_baddr = (uint32_t)((uint8_t *)record - mpt->reply) - + (mpt->reply_phys & 0xFFFFFFFF); + offset = (uint32_t)((uint8_t *)record - mpt->reply); + reply_baddr = offset + (mpt->reply_phys & 0xFFFFFFFF); + bus_dmamap_sync_range(mpt->reply_dmat, mpt->reply_dmap, offset, + MPT_REPLY_SIZE, BUS_DMASYNC_PREREAD); mpt_free_reply(mpt, reply_baddr); } @@ -1257,7 +1267,7 @@ mpt_send_cmd(struct mpt_softc *mpt, request_t *req) mpt_dump_request(mpt, req); } bus_dmamap_sync(mpt->request_dmat, mpt->request_dmap, - BUS_DMASYNC_PREWRITE); + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); req->state |= REQ_STATE_QUEUED; KASSERT(mpt_req_on_free_list(mpt, req) == 0, ("req %p:%u func %x on freelist list in mpt_send_cmd", @@ -1696,8 +1706,6 @@ mpt_read_extcfg_page(struct mpt_softc *mpt, int Action, uint32_t PageAddress, mpt_free_request(mpt, req); return (-1); } - bus_dmamap_sync(mpt->request_dmat, mpt->request_dmap, - BUS_DMASYNC_POSTREAD); memcpy(buf, ((uint8_t *)req->req_vbuf)+MPT_RQSL(mpt), len); mpt_free_request(mpt, req); return (0); @@ -1795,8 +1803,6 @@ mpt_read_cfg_page(struct mpt_softc *mpt, int Action, uint32_t PageAddress, mpt_free_request(mpt, req); return (-1); } - bus_dmamap_sync(mpt->request_dmat, mpt->request_dmap, - BUS_DMASYNC_POSTREAD); memcpy(hdr, ((uint8_t *)req->req_vbuf)+MPT_RQSL(mpt), len); mpt_free_request(mpt, req); return (0); @@ -2383,10 +2389,12 @@ mpt_upload_fw(struct mpt_softc *mpt) flags <<= MPI_SGE_FLAGS_SHIFT; sge->FlagsLength = htole32(flags | mpt->fw_image_size); sge->Address = htole32(mpt->fw_phys); + bus_dmamap_sync(mpt->fw_dmat, mpt->fw_dmap, BUS_DMASYNC_PREREAD); error = mpt_send_handshake_cmd(mpt, sizeof(fw_req_buf), &fw_req_buf); if (error) return(error); error = mpt_recv_handshake_reply(mpt, sizeof(fw_reply), &fw_reply); + bus_dmamap_sync(mpt->fw_dmat, mpt->fw_dmap, BUS_DMASYNC_POSTREAD); return (error); } @@ -2431,8 +2439,10 @@ mpt_download_fw(struct mpt_softc *mpt) MPI_DIAG_RW_ENABLE|MPI_DIAG_DISABLE_ARM); fw_hdr = (MpiFwHeader_t *)mpt->fw_image; + bus_dmamap_sync(mpt->fw_dmat, mpt->fw_dmap, BUS_DMASYNC_PREWRITE); mpt_diag_outsl(mpt, fw_hdr->LoadStartAddress, (uint32_t*)fw_hdr, fw_hdr->ImageSize); + bus_dmamap_sync(mpt->fw_dmat, mpt->fw_dmap, BUS_DMASYNC_POSTWRITE); ext_offset = fw_hdr->NextImageHeaderOffset; while (ext_offset != 0) { @@ -2440,9 +2450,12 @@ mpt_download_fw(struct mpt_softc *mpt) ext = (MpiExtImageHeader_t *)((uintptr_t)fw_hdr + ext_offset); ext_offset = ext->NextImageHeaderOffset; - + bus_dmamap_sync(mpt->fw_dmat, mpt->fw_dmap, + BUS_DMASYNC_PREWRITE); mpt_diag_outsl(mpt, ext->LoadStartAddress, (uint32_t*)ext, ext->ImageSize); + bus_dmamap_sync(mpt->fw_dmat, mpt->fw_dmap, + BUS_DMASYNC_POSTWRITE); } if (mpt->is_sas) { @@ -2506,7 +2519,7 @@ mpt_dma_buf_alloc(struct mpt_softc *mpt) /* Allocate some DMA accessable memory for requests */ if (bus_dmamem_alloc(mpt->request_dmat, (void **)&mpt->request, - BUS_DMA_NOWAIT, &mpt->request_dmap) != 0) { + BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &mpt->request_dmap) != 0) { mpt_prt(mpt, "cannot allocate %d bytes of request memory\n", MPT_REQ_MEM_SIZE(mpt)); return (1); @@ -2714,11 +2727,12 @@ mpt_configure_ioc(struct mpt_softc *mpt, int tn, int needreset) mpt->fw_image_size, 1, mpt->fw_image_size, 0, &mpt->fw_dmat); if (error != 0) { - mpt_prt(mpt, "cannot create firmwarew dma tag\n"); + mpt_prt(mpt, "cannot create firmware dma tag\n"); return (ENOMEM); } error = bus_dmamem_alloc(mpt->fw_dmat, - (void **)&mpt->fw_image, BUS_DMA_NOWAIT, &mpt->fw_dmap); + (void **)&mpt->fw_image, BUS_DMA_NOWAIT | + BUS_DMA_COHERENT, &mpt->fw_dmap); if (error != 0) { mpt_prt(mpt, "cannot allocate firmware memory\n"); bus_dma_tag_destroy(mpt->fw_dmat); diff --git a/sys/dev/mpt/mpt_cam.c b/sys/dev/mpt/mpt_cam.c index c3aca53..30c56b1 100644 --- a/sys/dev/mpt/mpt_cam.c +++ b/sys/dev/mpt/mpt_cam.c @@ -5023,15 +5023,6 @@ mpt_scsi_tgt_atio(struct mpt_softc *mpt, request_t *req, uint32_t reply_desc) uint8_t *cdbp; /* - * First, DMA sync the received command- - * which is in the *request* * phys area. - * - * XXX: We could optimize this for a range - */ - bus_dmamap_sync(mpt->request_dmat, mpt->request_dmap, - BUS_DMASYNC_POSTREAD); - - /* * Stash info for the current command where we can get at it later. */ vbuf = req->req_vbuf; diff --git a/sys/dev/mpt/mpt_user.c b/sys/dev/mpt/mpt_user.c index 6e3b32f..e6a9d1f 100644 --- a/sys/dev/mpt/mpt_user.c +++ b/sys/dev/mpt/mpt_user.c @@ -204,7 +204,7 @@ mpt_alloc_buffer(struct mpt_softc *mpt, struct mpt_page_memory *page_mem, if (error) return (error); error = bus_dmamem_alloc(page_mem->tag, &page_mem->vaddr, - BUS_DMA_NOWAIT, &page_mem->map); + BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &page_mem->map); if (error) { bus_dma_tag_destroy(page_mem->tag); return (error); @@ -302,6 +302,8 @@ mpt_user_read_cfg_page(struct mpt_softc *mpt, struct mpt_cfg_page_req *page_req, params.PageNumber = hdr->PageNumber; params.PageType = hdr->PageType & MPI_CONFIG_PAGETYPE_MASK; params.PageAddress = le32toh(page_req->page_address); + bus_dmamap_sync(mpt_page->tag, mpt_page->map, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); error = mpt_issue_cfg_req(mpt, req, ¶ms, mpt_page->paddr, le32toh(page_req->len), TRUE, 5000); if (error != 0) { @@ -312,7 +314,7 @@ mpt_user_read_cfg_page(struct mpt_softc *mpt, struct mpt_cfg_page_req *page_req, page_req->ioc_status = htole16(req->IOCStatus); if ((req->IOCStatus & MPI_IOCSTATUS_MASK) == MPI_IOCSTATUS_SUCCESS) bus_dmamap_sync(mpt_page->tag, mpt_page->map, - BUS_DMASYNC_POSTREAD); + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); mpt_free_request(mpt, req); return (0); } @@ -390,6 +392,8 @@ mpt_user_read_extcfg_page(struct mpt_softc *mpt, params.PageAddress = le32toh(ext_page_req->page_address); params.ExtPageType = hdr->ExtPageType; params.ExtPageLength = hdr->ExtPageLength; + bus_dmamap_sync(mpt_page->tag, mpt_page->map, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); error = mpt_issue_cfg_req(mpt, req, ¶ms, mpt_page->paddr, le32toh(ext_page_req->len), TRUE, 5000); if (error != 0) { @@ -400,7 +404,7 @@ mpt_user_read_extcfg_page(struct mpt_softc *mpt, ext_page_req->ioc_status = htole16(req->IOCStatus); if ((req->IOCStatus & MPI_IOCSTATUS_MASK) == MPI_IOCSTATUS_SUCCESS) bus_dmamap_sync(mpt_page->tag, mpt_page->map, - BUS_DMASYNC_POSTREAD); + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); mpt_free_request(mpt, req); return (0); } @@ -435,7 +439,8 @@ mpt_user_write_cfg_page(struct mpt_softc *mpt, if (req == NULL) return (ENOMEM); - bus_dmamap_sync(mpt_page->tag, mpt_page->map, BUS_DMASYNC_PREWRITE); + bus_dmamap_sync(mpt_page->tag, mpt_page->map, BUS_DMASYNC_PREREAD | + BUS_DMASYNC_PREWRITE); /* * There isn't any point in restoring stripped out attributes @@ -462,6 +467,8 @@ mpt_user_write_cfg_page(struct mpt_softc *mpt, } page_req->ioc_status = htole16(req->IOCStatus); + bus_dmamap_sync(mpt_page->tag, mpt_page->map, BUS_DMASYNC_POSTREAD | + BUS_DMASYNC_POSTWRITE); mpt_free_request(mpt, req); return (0); } @@ -477,8 +484,6 @@ mpt_user_reply_handler(struct mpt_softc *mpt, request_t *req, return (TRUE); if (reply_frame != NULL) { - bus_dmamap_sync(mpt->request_dmat, mpt->request_dmap, - BUS_DMASYNC_POSTREAD); reply = (MSG_RAID_ACTION_REPLY *)reply_frame; req->IOCStatus = le16toh(reply->IOCStatus); res = (struct mpt_user_raid_action_result *) @@ -535,7 +540,7 @@ mpt_user_raid_action(struct mpt_softc *mpt, struct mpt_raid_action *raid_act, se = (SGE_SIMPLE32 *)&rap->ActionDataSGE; if (mpt_page->vaddr != NULL && raid_act->len != 0) { bus_dmamap_sync(mpt_page->tag, mpt_page->map, - BUS_DMASYNC_PREWRITE); + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); se->Address = htole32(mpt_page->paddr); MPI_pSGE_SET_LENGTH(se, le32toh(raid_act->len)); MPI_pSGE_SET_FLAGS(se, (MPI_SGE_FLAGS_SIMPLE_ELEMENT | @@ -574,7 +579,7 @@ mpt_user_raid_action(struct mpt_softc *mpt, struct mpt_raid_action *raid_act, sizeof(res->action_data)); if (mpt_page->vaddr != NULL) bus_dmamap_sync(mpt_page->tag, mpt_page->map, - BUS_DMASYNC_POSTREAD); + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); mpt_free_request(mpt, req); return (0); } |