mfi.c (162118) | mfi.c (162458) |
---|---|
1/*- 2 * Copyright (c) 2006 IronPort Systems 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2006 IronPort Systems 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> |
28__FBSDID("$FreeBSD: head/sys/dev/mfi/mfi.c 162118 2006-09-07 18:40:49Z ambrisko $"); | 28__FBSDID("$FreeBSD: head/sys/dev/mfi/mfi.c 162458 2006-09-20 06:58:02Z scottl $"); |
29 30#include "opt_mfi.h" 31 32#include <sys/param.h> 33#include <sys/systm.h> 34#include <sys/sysctl.h> 35#include <sys/malloc.h> 36#include <sys/kernel.h> --- 137 unchanged lines hidden (view full) --- 174 *addr = segs[0].ds_addr; 175} 176 177int 178mfi_attach(struct mfi_softc *sc) 179{ 180 uint32_t status; 181 int error, commsz, framessz, sensesz; | 29 30#include "opt_mfi.h" 31 32#include <sys/param.h> 33#include <sys/systm.h> 34#include <sys/sysctl.h> 35#include <sys/malloc.h> 36#include <sys/kernel.h> --- 137 unchanged lines hidden (view full) --- 174 *addr = segs[0].ds_addr; 175} 176 177int 178mfi_attach(struct mfi_softc *sc) 179{ 180 uint32_t status; 181 int error, commsz, framessz, sensesz; |
182 int frames, unit; | 182 int frames, unit, max_fw_sge; |
183 184 mtx_init(&sc->mfi_io_lock, "MFI I/O lock", NULL, MTX_DEF); 185 TAILQ_INIT(&sc->mfi_ld_tqh); 186 TAILQ_INIT(&sc->mfi_aen_pids); 187 188 mfi_initq_free(sc); 189 mfi_initq_ready(sc); 190 mfi_initq_busy(sc); --- 10 unchanged lines hidden (view full) --- 201 * Get information needed for sizing the contiguous memory for the 202 * frame pool. Size down the sgl parameter since we know that 203 * we will never need more than what's required for MAXPHYS. 204 * It would be nice if these constants were available at runtime 205 * instead of compile time. 206 */ 207 status = MFI_READ4(sc, MFI_OMSG0); 208 sc->mfi_max_fw_cmds = status & MFI_FWSTATE_MAXCMD_MASK; | 183 184 mtx_init(&sc->mfi_io_lock, "MFI I/O lock", NULL, MTX_DEF); 185 TAILQ_INIT(&sc->mfi_ld_tqh); 186 TAILQ_INIT(&sc->mfi_aen_pids); 187 188 mfi_initq_free(sc); 189 mfi_initq_ready(sc); 190 mfi_initq_busy(sc); --- 10 unchanged lines hidden (view full) --- 201 * Get information needed for sizing the contiguous memory for the 202 * frame pool. Size down the sgl parameter since we know that 203 * we will never need more than what's required for MAXPHYS. 204 * It would be nice if these constants were available at runtime 205 * instead of compile time. 206 */ 207 status = MFI_READ4(sc, MFI_OMSG0); 208 sc->mfi_max_fw_cmds = status & MFI_FWSTATE_MAXCMD_MASK; |
209 sc->mfi_max_fw_sgl = (status & MFI_FWSTATE_MAXSGL_MASK) >> 16; 210 sc->mfi_total_sgl = min(sc->mfi_max_fw_sgl, ((MAXPHYS / PAGE_SIZE) +1)); | 209 max_fw_sge = (status & MFI_FWSTATE_MAXSGL_MASK) >> 16; 210 sc->mfi_max_sge = min(max_fw_sge, ((MAXPHYS / PAGE_SIZE) + 1)); |
211 212 /* 213 * Create the dma tag for data buffers. Used both for block I/O 214 * and for various internal data queries. 215 */ 216 if (bus_dma_tag_create( sc->mfi_parent_dmat, /* parent */ 217 1, 0, /* algnmnt, boundary */ 218 BUS_SPACE_MAXADDR, /* lowaddr */ 219 BUS_SPACE_MAXADDR, /* highaddr */ 220 NULL, NULL, /* filter, filterarg */ 221 BUS_SPACE_MAXSIZE_32BIT,/* maxsize */ | 211 212 /* 213 * Create the dma tag for data buffers. Used both for block I/O 214 * and for various internal data queries. 215 */ 216 if (bus_dma_tag_create( sc->mfi_parent_dmat, /* parent */ 217 1, 0, /* algnmnt, boundary */ 218 BUS_SPACE_MAXADDR, /* lowaddr */ 219 BUS_SPACE_MAXADDR, /* highaddr */ 220 NULL, NULL, /* filter, filterarg */ 221 BUS_SPACE_MAXSIZE_32BIT,/* maxsize */ |
222 sc->mfi_total_sgl, /* nsegments */ | 222 sc->mfi_max_sge, /* nsegments */ |
223 BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */ 224 BUS_DMA_ALLOCNOW, /* flags */ 225 busdma_lock_mutex, /* lockfunc */ 226 &sc->mfi_io_lock, /* lockfuncarg */ 227 &sc->mfi_buffer_dmat)) { 228 device_printf(sc->mfi_dev, "Cannot allocate buffer DMA tag\n"); 229 return (ENOMEM); 230 } --- 26 unchanged lines hidden (view full) --- 257 return (ENOMEM); 258 } 259 bzero(sc->mfi_comms, commsz); 260 bus_dmamap_load(sc->mfi_comms_dmat, sc->mfi_comms_dmamap, 261 sc->mfi_comms, commsz, mfi_addr32_cb, &sc->mfi_comms_busaddr, 0); 262 263 /* 264 * Allocate DMA memory for the command frames. Keep them in the | 223 BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */ 224 BUS_DMA_ALLOCNOW, /* flags */ 225 busdma_lock_mutex, /* lockfunc */ 226 &sc->mfi_io_lock, /* lockfuncarg */ 227 &sc->mfi_buffer_dmat)) { 228 device_printf(sc->mfi_dev, "Cannot allocate buffer DMA tag\n"); 229 return (ENOMEM); 230 } --- 26 unchanged lines hidden (view full) --- 257 return (ENOMEM); 258 } 259 bzero(sc->mfi_comms, commsz); 260 bus_dmamap_load(sc->mfi_comms_dmat, sc->mfi_comms_dmamap, 261 sc->mfi_comms, commsz, mfi_addr32_cb, &sc->mfi_comms_busaddr, 0); 262 263 /* 264 * Allocate DMA memory for the command frames. Keep them in the |
265 * lower 4GB for efficiency. Calculate the size of the frames at 266 * the same time; the frame is 64 bytes plus space for the SG lists. | 265 * lower 4GB for efficiency. Calculate the size of the commands at 266 * the same time; each command is one 64 byte frame plus a set of 267 * additional frames for holding sg lists or other data. |
267 * The assumption here is that the SG list will start at the second | 268 * The assumption here is that the SG list will start at the second |
268 * 64 byte segment of the frame and not use the unused bytes in the 269 * frame. While this might seem wasteful, apparently the frames must 270 * be 64 byte aligned, so any savings would be negated by the extra 271 * alignment padding. | 269 * frame and not use the unused bytes in the first frame. While this 270 * isn't technically correct, it simplifies the calculation and allows 271 * for command frames that might be larger than an mfi_io_frame. |
272 */ 273 if (sizeof(bus_addr_t) == 8) { | 272 */ 273 if (sizeof(bus_addr_t) == 8) { |
274 sc->mfi_sgsize = sizeof(struct mfi_sg64); | 274 sc->mfi_sge_size = sizeof(struct mfi_sg64); |
275 sc->mfi_flags |= MFI_FLAGS_SG64; 276 } else { | 275 sc->mfi_flags |= MFI_FLAGS_SG64; 276 } else { |
277 sc->mfi_sgsize = sizeof(struct mfi_sg32); | 277 sc->mfi_sge_size = sizeof(struct mfi_sg32); |
278 } | 278 } |
279 frames = (sc->mfi_sgsize * sc->mfi_total_sgl + MFI_FRAME_SIZE - 1) / 280 MFI_FRAME_SIZE + 1; 281 sc->mfi_frame_size = frames * MFI_FRAME_SIZE; 282 framessz = sc->mfi_frame_size * sc->mfi_max_fw_cmds; | 279 frames = (sc->mfi_sge_size * sc->mfi_max_sge - 1) / MFI_FRAME_SIZE + 2; 280 sc->mfi_cmd_size = frames * MFI_FRAME_SIZE; 281 framessz = sc->mfi_cmd_size * sc->mfi_max_fw_cmds; |
283 if (bus_dma_tag_create( sc->mfi_parent_dmat, /* parent */ 284 64, 0, /* algnmnt, boundary */ 285 BUS_SPACE_MAXADDR_32BIT,/* lowaddr */ 286 BUS_SPACE_MAXADDR, /* highaddr */ 287 NULL, NULL, /* filter, filterarg */ 288 framessz, /* maxsize */ 289 1, /* nsegments */ 290 framessz, /* maxsegsize */ --- 111 unchanged lines hidden (view full) --- 402 */ 403 ncmds = sc->mfi_max_fw_cmds; 404 sc->mfi_commands = malloc(sizeof(struct mfi_command) * ncmds, M_MFIBUF, 405 M_WAITOK | M_ZERO); 406 407 for (i = 0; i < ncmds; i++) { 408 cm = &sc->mfi_commands[i]; 409 cm->cm_frame = (union mfi_frame *)((uintptr_t)sc->mfi_frames + | 282 if (bus_dma_tag_create( sc->mfi_parent_dmat, /* parent */ 283 64, 0, /* algnmnt, boundary */ 284 BUS_SPACE_MAXADDR_32BIT,/* lowaddr */ 285 BUS_SPACE_MAXADDR, /* highaddr */ 286 NULL, NULL, /* filter, filterarg */ 287 framessz, /* maxsize */ 288 1, /* nsegments */ 289 framessz, /* maxsegsize */ --- 111 unchanged lines hidden (view full) --- 401 */ 402 ncmds = sc->mfi_max_fw_cmds; 403 sc->mfi_commands = malloc(sizeof(struct mfi_command) * ncmds, M_MFIBUF, 404 M_WAITOK | M_ZERO); 405 406 for (i = 0; i < ncmds; i++) { 407 cm = &sc->mfi_commands[i]; 408 cm->cm_frame = (union mfi_frame *)((uintptr_t)sc->mfi_frames + |
410 sc->mfi_frame_size * i); | 409 sc->mfi_cmd_size * i); |
411 cm->cm_frame_busaddr = sc->mfi_frames_busaddr + | 410 cm->cm_frame_busaddr = sc->mfi_frames_busaddr + |
412 sc->mfi_frame_size * i; | 411 sc->mfi_cmd_size * i; |
413 cm->cm_frame->header.context = i; 414 cm->cm_sense = &sc->mfi_sense[i]; 415 cm->cm_sense_busaddr= sc->mfi_sense_busaddr + MFI_SENSE_LEN * i; 416 cm->cm_sc = sc; 417 if (bus_dmamap_create(sc->mfi_buffer_dmat, 0, 418 &cm->cm_dmamap) == 0) 419 mfi_release_command(cm); 420 else --- 133 unchanged lines hidden (view full) --- 554 free(ci, M_MFIBUF); 555 mfi_release_command(cm); 556 return (error); 557 } 558 559 /* It's ok if this fails, just use default info instead */ 560 if ((error = mfi_polled_command(sc, cm)) != 0) { 561 device_printf(sc->mfi_dev, "Failed to get controller info\n"); | 412 cm->cm_frame->header.context = i; 413 cm->cm_sense = &sc->mfi_sense[i]; 414 cm->cm_sense_busaddr= sc->mfi_sense_busaddr + MFI_SENSE_LEN * i; 415 cm->cm_sc = sc; 416 if (bus_dmamap_create(sc->mfi_buffer_dmat, 0, 417 &cm->cm_dmamap) == 0) 418 mfi_release_command(cm); 419 else --- 133 unchanged lines hidden (view full) --- 553 free(ci, M_MFIBUF); 554 mfi_release_command(cm); 555 return (error); 556 } 557 558 /* It's ok if this fails, just use default info instead */ 559 if ((error = mfi_polled_command(sc, cm)) != 0) { 560 device_printf(sc->mfi_dev, "Failed to get controller info\n"); |
562 sc->mfi_max_io = (sc->mfi_total_sgl - 1) * PAGE_SIZE / | 561 sc->mfi_max_io = (sc->mfi_max_sge - 1) * PAGE_SIZE / |
563 MFI_SECTOR_LEN; 564 error = 0; 565 goto out; 566 } 567 568 bus_dmamap_sync(sc->mfi_buffer_dmat, cm->cm_dmamap, 569 BUS_DMASYNC_POSTREAD); 570 bus_dmamap_unload(sc->mfi_buffer_dmat, cm->cm_dmamap); --- 729 unchanged lines hidden (view full) --- 1300 device_printf(sc->mfi_dev, "Controller info buffer map failed"); 1301 free(el, M_MFIBUF); 1302 mfi_release_command(cm); 1303 return (error); 1304 } 1305 1306 if ((error = mfi_polled_command(sc, cm)) != 0) { 1307 device_printf(sc->mfi_dev, "Failed to get controller entry\n"); | 562 MFI_SECTOR_LEN; 563 error = 0; 564 goto out; 565 } 566 567 bus_dmamap_sync(sc->mfi_buffer_dmat, cm->cm_dmamap, 568 BUS_DMASYNC_POSTREAD); 569 bus_dmamap_unload(sc->mfi_buffer_dmat, cm->cm_dmamap); --- 729 unchanged lines hidden (view full) --- 1299 device_printf(sc->mfi_dev, "Controller info buffer map failed"); 1300 free(el, M_MFIBUF); 1301 mfi_release_command(cm); 1302 return (error); 1303 } 1304 1305 if ((error = mfi_polled_command(sc, cm)) != 0) { 1306 device_printf(sc->mfi_dev, "Failed to get controller entry\n"); |
1308 sc->mfi_max_io = (sc->mfi_total_sgl - 1) * PAGE_SIZE / | 1307 sc->mfi_max_io = (sc->mfi_max_sge - 1) * PAGE_SIZE / |
1309 MFI_SECTOR_LEN; 1310 free(el, M_MFIBUF); 1311 mfi_release_command(cm); 1312 return (0); 1313 } 1314 1315 bus_dmamap_sync(sc->mfi_buffer_dmat, cm->cm_dmamap, 1316 BUS_DMASYNC_POSTREAD); --- 259 unchanged lines hidden (view full) --- 1576 cm->cm_flags |= MFI_CMD_MAPPED; 1577 1578 /* 1579 * Instead of calculating the total number of frames in the 1580 * compound frame, it's already assumed that there will be at 1581 * least 1 frame, so don't compensate for the modulo of the 1582 * following division. 1583 */ | 1308 MFI_SECTOR_LEN; 1309 free(el, M_MFIBUF); 1310 mfi_release_command(cm); 1311 return (0); 1312 } 1313 1314 bus_dmamap_sync(sc->mfi_buffer_dmat, cm->cm_dmamap, 1315 BUS_DMASYNC_POSTREAD); --- 259 unchanged lines hidden (view full) --- 1575 cm->cm_flags |= MFI_CMD_MAPPED; 1576 1577 /* 1578 * Instead of calculating the total number of frames in the 1579 * compound frame, it's already assumed that there will be at 1580 * least 1 frame, so don't compensate for the modulo of the 1581 * following division. 1582 */ |
1584 cm->cm_total_frame_size += (sc->mfi_sgsize * nsegs); | 1583 cm->cm_total_frame_size += (sc->mfi_sge_size * nsegs); |
1585 cm->cm_extra_frames = (cm->cm_total_frame_size - 1) / MFI_FRAME_SIZE; 1586 1587 /* The caller will take care of delivering polled commands */ 1588 if ((cm->cm_flags & MFI_CMD_POLLED) == 0) { 1589 mfi_enqueue_busy(cm); 1590 mfi_send_frame(sc, cm); 1591 } 1592 1593 return; 1594} 1595 1596static int 1597mfi_send_frame(struct mfi_softc *sc, struct mfi_command *cm) 1598{ 1599 1600 /* 1601 * The bus address of the command is aligned on a 64 byte boundary, 1602 * leaving the least 6 bits as zero. For whatever reason, the 1603 * hardware wants the address shifted right by three, leaving just | 1584 cm->cm_extra_frames = (cm->cm_total_frame_size - 1) / MFI_FRAME_SIZE; 1585 1586 /* The caller will take care of delivering polled commands */ 1587 if ((cm->cm_flags & MFI_CMD_POLLED) == 0) { 1588 mfi_enqueue_busy(cm); 1589 mfi_send_frame(sc, cm); 1590 } 1591 1592 return; 1593} 1594 1595static int 1596mfi_send_frame(struct mfi_softc *sc, struct mfi_command *cm) 1597{ 1598 1599 /* 1600 * The bus address of the command is aligned on a 64 byte boundary, 1601 * leaving the least 6 bits as zero. For whatever reason, the 1602 * hardware wants the address shifted right by three, leaving just |
1604 * 3 zero bits. These three bits are then used to indicate how many 1605 * 64 byte frames beyond the first one are used in the command. The 1606 * extra frames are typically filled with S/G elements. The extra 1607 * frames must also be contiguous. Thus, a compound frame can be at 1608 * most 512 bytes long, allowing for up to 59 32-bit S/G elements or 1609 * 39 64-bit S/G elements for block I/O commands. This means that 1610 * I/O transfers of 256k and higher simply are not possible, which 1611 * is quite odd for such a modern adapter. | 1603 * 3 zero bits. These three bits are then used as a prefetching 1604 * hint for the hardware to predict how many frames need to be 1605 * fetched across the bus. If a command has more than 8 frames 1606 * then the 3 bits are set to 0x7 and the firmware uses other 1607 * information in the command to determine the total amount to fetch. 1608 * However, FreeBSD doesn't support I/O larger than 128K, so 8 frames 1609 * is enough for both 32bit and 64bit systems. |
1612 */ | 1610 */ |
1611 if (cm->cm_extra_frames > 7) 1612 cm->cm_extra_frames = 7; 1613 |
|
1613 MFI_WRITE4(sc, MFI_IQP, (cm->cm_frame_busaddr >> 3) | 1614 cm->cm_extra_frames); 1615 return (0); 1616} 1617 1618static void 1619mfi_complete(struct mfi_softc *sc, struct mfi_command *cm) 1620{ --- 398 unchanged lines hidden --- | 1614 MFI_WRITE4(sc, MFI_IQP, (cm->cm_frame_busaddr >> 3) | 1615 cm->cm_extra_frames); 1616 return (0); 1617} 1618 1619static void 1620mfi_complete(struct mfi_softc *sc, struct mfi_command *cm) 1621{ --- 398 unchanged lines hidden --- |