Deleted Added
full compact
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 ---