From owner-svn-src-stable@FreeBSD.ORG Mon Dec 16 08:51:59 2013 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 701029B1; Mon, 16 Dec 2013 08:51:59 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 59C7D177B; Mon, 16 Dec 2013 08:51:59 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id rBG8pxV1044684; Mon, 16 Dec 2013 08:51:59 GMT (envelope-from hselasky@svn.freebsd.org) Received: (from hselasky@localhost) by svn.freebsd.org (8.14.7/8.14.7/Submit) id rBG8pw9i044678; Mon, 16 Dec 2013 08:51:58 GMT (envelope-from hselasky@svn.freebsd.org) Message-Id: <201312160851.rBG8pw9i044678@svn.freebsd.org> From: Hans Petter Selasky Date: Mon, 16 Dec 2013 08:51:58 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r259454 - in stable/9/sys/dev/usb: . storage wlan X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 16 Dec 2013 08:51:59 -0000 Author: hselasky Date: Mon Dec 16 08:51:58 2013 New Revision: 259454 URL: http://svnweb.freebsd.org/changeset/base/259454 Log: MFC r244503 and r246565: Make sure all USB drivers allocate buffer memory through the USB API and/or busdma. The following assumptions have been made: umass - buffers passed from CAM/SCSI layer are OK network - mbufs are OK. Some other nits while at it. Modified: stable/9/sys/dev/usb/storage/ustorage_fs.c stable/9/sys/dev/usb/usb_msctest.c stable/9/sys/dev/usb/wlan/if_uath.c stable/9/sys/dev/usb/wlan/if_uathvar.h stable/9/sys/dev/usb/wlan/if_upgt.c stable/9/sys/dev/usb/wlan/if_upgtvar.h stable/9/sys/dev/usb/wlan/if_urtw.c stable/9/sys/dev/usb/wlan/if_urtwvar.h Directory Properties: stable/9/sys/ (props changed) stable/9/sys/dev/ (props changed) Modified: stable/9/sys/dev/usb/storage/ustorage_fs.c ============================================================================== --- stable/9/sys/dev/usb/storage/ustorage_fs.c Mon Dec 16 08:10:38 2013 (r259453) +++ stable/9/sys/dev/usb/storage/ustorage_fs.c Mon Dec 16 08:51:58 2013 (r259454) @@ -74,7 +74,7 @@ SYSCTL_INT(_hw_usb_ustorage_fs, OID_AUTO /* Define some limits */ #ifndef USTORAGE_FS_BULK_SIZE -#define USTORAGE_FS_BULK_SIZE (1UL << 17) /* bytes */ +#define USTORAGE_FS_BULK_SIZE (1U << 17) /* bytes */ #endif #ifndef USTORAGE_FS_MAX_LUN @@ -85,8 +85,6 @@ SYSCTL_INT(_hw_usb_ustorage_fs, OID_AUTO #define USTORAGE_QDATA_MAX 40 /* bytes */ #endif -#define sc_cmd_data sc_cbw.CBWCDB - /* * The SCSI ID string must be exactly 28 characters long * exluding the terminating zero. @@ -176,8 +174,9 @@ struct ustorage_fs_lun { struct ustorage_fs_softc { - ustorage_fs_bbb_cbw_t sc_cbw; /* Command Wrapper Block */ - ustorage_fs_bbb_csw_t sc_csw; /* Command Status Block */ + ustorage_fs_bbb_cbw_t *sc_cbw; /* Command Wrapper Block */ + ustorage_fs_bbb_csw_t *sc_csw; /* Command Status Block */ + void *sc_dma_ptr; /* Main data buffer */ struct mtx sc_mtx; @@ -275,7 +274,6 @@ static struct usb_config ustorage_fs_bbb .endpoint = UE_ADDR_ANY, .direction = UE_DIR_OUT, .bufsize = sizeof(ustorage_fs_bbb_cbw_t), - .flags = {.ext_buffer = 1,}, .callback = &ustorage_fs_t_bbb_command_callback, .usb_mode = USB_MODE_DEVICE, }, @@ -295,7 +293,7 @@ static struct usb_config ustorage_fs_bbb .endpoint = UE_ADDR_ANY, .direction = UE_DIR_OUT, .bufsize = USTORAGE_FS_BULK_SIZE, - .flags = {.proxy_buffer = 1,.short_xfer_ok = 1,.ext_buffer = 1}, + .flags = {.proxy_buffer = 1,.short_xfer_ok = 1}, .callback = &ustorage_fs_t_bbb_data_read_callback, .usb_mode = USB_MODE_DEVICE, }, @@ -315,7 +313,7 @@ static struct usb_config ustorage_fs_bbb .endpoint = UE_ADDR_ANY, .direction = UE_DIR_IN, .bufsize = sizeof(ustorage_fs_bbb_csw_t), - .flags = {.short_xfer_ok = 1,.ext_buffer = 1,}, + .flags = {.short_xfer_ok = 1}, .callback = &ustorage_fs_t_bbb_status_callback, .usb_mode = USB_MODE_DEVICE, }, @@ -409,6 +407,14 @@ ustorage_fs_attach(device_t dev) "transfers, %s\n", usbd_errstr(err)); goto detach; } + + sc->sc_cbw = usbd_xfer_get_frame_buffer(sc->sc_xfer[ + USTORAGE_FS_T_BBB_COMMAND], 0); + sc->sc_csw = usbd_xfer_get_frame_buffer(sc->sc_xfer[ + USTORAGE_FS_T_BBB_STATUS], 0); + sc->sc_dma_ptr = usbd_xfer_get_frame_buffer(sc->sc_xfer[ + USTORAGE_FS_T_BBB_DATA_READ], 0); + /* start Mass Storage State Machine */ mtx_lock(&sc->sc_mtx); @@ -518,44 +524,44 @@ ustorage_fs_t_bbb_command_callback(struc switch (USB_GET_STATE(xfer)) { case USB_ST_TRANSFERRED: - tag = UGETDW(sc->sc_cbw.dCBWSignature); + tag = UGETDW(sc->sc_cbw->dCBWSignature); if (tag != CBWSIGNATURE) { /* do nothing */ DPRINTF("invalid signature 0x%08x\n", tag); break; } - tag = UGETDW(sc->sc_cbw.dCBWTag); + tag = UGETDW(sc->sc_cbw->dCBWTag); /* echo back tag */ - USETDW(sc->sc_csw.dCSWTag, tag); + USETDW(sc->sc_csw->dCSWTag, tag); /* reset status */ - sc->sc_csw.bCSWStatus = 0; + sc->sc_csw->bCSWStatus = 0; /* reset data offset, data length and data remainder */ sc->sc_transfer.offset = 0; sc->sc_transfer.data_rem = - UGETDW(sc->sc_cbw.dCBWDataTransferLength); + UGETDW(sc->sc_cbw->dCBWDataTransferLength); /* reset data flags */ sc->sc_transfer.data_short = 0; /* extract LUN */ - sc->sc_transfer.lun = sc->sc_cbw.bCBWLUN; + sc->sc_transfer.lun = sc->sc_cbw->bCBWLUN; if (sc->sc_transfer.data_rem == 0) { sc->sc_transfer.cbw_dir = DIR_NONE; } else { - if (sc->sc_cbw.bCBWFlags & CBWFLAGS_IN) { + if (sc->sc_cbw->bCBWFlags & CBWFLAGS_IN) { sc->sc_transfer.cbw_dir = DIR_WRITE; } else { sc->sc_transfer.cbw_dir = DIR_READ; } } - sc->sc_transfer.cmd_len = sc->sc_cbw.bCDBLength; - if ((sc->sc_transfer.cmd_len > sizeof(sc->sc_cbw.CBWCDB)) || + sc->sc_transfer.cmd_len = sc->sc_cbw->bCDBLength; + if ((sc->sc_transfer.cmd_len > sizeof(sc->sc_cbw->CBWCDB)) || (sc->sc_transfer.cmd_len == 0)) { /* just halt - this is invalid */ DPRINTF("invalid command length %d bytes\n", @@ -597,9 +603,6 @@ tr_setup: usbd_xfer_set_stall(xfer); DPRINTF("stall pipe\n"); } - - usbd_xfer_set_frame_data(xfer, 0, &sc->sc_cbw, - sizeof(sc->sc_cbw)); usbd_transfer_submit(xfer); break; @@ -616,9 +619,9 @@ tr_setup: goto tr_setup; } if (err) { - if (sc->sc_csw.bCSWStatus == 0) { + if (sc->sc_csw->bCSWStatus == 0) { /* set some default error code */ - sc->sc_csw.bCSWStatus = CSWSTATUS_FAILED; + sc->sc_csw->bCSWStatus = CSWSTATUS_FAILED; } if (sc->sc_transfer.cbw_dir == DIR_READ) { /* dump all data */ @@ -699,6 +702,9 @@ ustorage_fs_t_bbb_data_read_callback(str switch (USB_GET_STATE(xfer)) { case USB_ST_TRANSFERRED: + /* XXX copy data from DMA buffer */ + memcpy(sc->sc_transfer.data_ptr, sc->sc_dma_ptr, actlen); + sc->sc_transfer.data_rem -= actlen; sc->sc_transfer.data_ptr += actlen; sc->sc_transfer.offset += actlen; @@ -721,8 +727,7 @@ tr_setup: usbd_xfer_set_stall(xfer); } - usbd_xfer_set_frame_data(xfer, 0, sc->sc_transfer.data_ptr, - max_bulk); + usbd_xfer_set_frame_data(xfer, 0, sc->sc_dma_ptr, max_bulk); usbd_transfer_submit(xfer); break; @@ -778,8 +783,10 @@ tr_setup: usbd_xfer_set_stall(xfer); } - usbd_xfer_set_frame_data(xfer, 0, sc->sc_transfer.data_ptr, - max_bulk); + /* XXX copy data to DMA buffer */ + memcpy(sc->sc_dma_ptr, sc->sc_transfer.data_ptr, max_bulk); + + usbd_xfer_set_frame_data(xfer, 0, sc->sc_dma_ptr, max_bulk); usbd_transfer_submit(xfer); break; @@ -813,16 +820,13 @@ ustorage_fs_t_bbb_status_callback(struct case USB_ST_SETUP: tr_setup: - USETDW(sc->sc_csw.dCSWSignature, CSWSIGNATURE); - USETDW(sc->sc_csw.dCSWDataResidue, sc->sc_transfer.data_rem); + USETDW(sc->sc_csw->dCSWSignature, CSWSIGNATURE); + USETDW(sc->sc_csw->dCSWDataResidue, sc->sc_transfer.data_rem); if (sc->sc_transfer.data_error) { sc->sc_transfer.data_error = 0; usbd_xfer_set_stall(xfer); } - - usbd_xfer_set_frame_data(xfer, 0, &sc->sc_csw, - sizeof(sc->sc_csw)); usbd_transfer_submit(xfer); break; @@ -934,17 +938,17 @@ ustorage_fs_verify(struct ustorage_fs_so /* * Get the starting Logical Block Address */ - lba = get_be32(&sc->sc_cmd_data[2]); + lba = get_be32(&sc->sc_cbw->CBWCDB[2]); /* * We allow DPO (Disable Page Out = don't save data in the cache) * but we don't implement it. */ - if ((sc->sc_cmd_data[1] & ~0x10) != 0) { + if ((sc->sc_cbw->CBWCDB[1] & ~0x10) != 0) { currlun->sense_data = SS_INVALID_FIELD_IN_CDB; return (1); } - vlen = get_be16(&sc->sc_cmd_data[7]); + vlen = get_be16(&sc->sc_cbw->CBWCDB[7]); if (vlen == 0) { goto done; } @@ -1092,8 +1096,8 @@ ustorage_fs_read_capacity(struct ustorag { uint8_t *buf = sc->sc_transfer.data_ptr; struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun; - uint32_t lba = get_be32(&sc->sc_cmd_data[2]); - uint8_t pmi = sc->sc_cmd_data[8]; + uint32_t lba = get_be32(&sc->sc_cbw->CBWCDB[2]); + uint8_t pmi = sc->sc_cbw->CBWCDB[8]; /* Check the PMI and LBA fields */ if ((pmi > 1) || ((pmi == 0) && (lba != 0))) { @@ -1126,7 +1130,7 @@ ustorage_fs_mode_sense(struct ustorage_f uint8_t *buf0; uint16_t len; uint16_t limit; - uint8_t mscmnd = sc->sc_cmd_data[0]; + uint8_t mscmnd = sc->sc_cbw->CBWCDB[0]; uint8_t pc; uint8_t page_code; uint8_t changeable_values; @@ -1134,13 +1138,13 @@ ustorage_fs_mode_sense(struct ustorage_f buf0 = buf; - if ((sc->sc_cmd_data[1] & ~0x08) != 0) { + if ((sc->sc_cbw->CBWCDB[1] & ~0x08) != 0) { /* Mask away DBD */ currlun->sense_data = SS_INVALID_FIELD_IN_CDB; return (1); } - pc = sc->sc_cmd_data[2] >> 6; - page_code = sc->sc_cmd_data[2] & 0x3f; + pc = sc->sc_cbw->CBWCDB[2] >> 6; + page_code = sc->sc_cbw->CBWCDB[2] & 0x3f; if (pc == 3) { currlun->sense_data = SS_SAVING_PARAMETERS_NOT_SUPPORTED; return (1); @@ -1237,9 +1241,9 @@ ustorage_fs_start_stop(struct ustorage_f currlun->sense_data = SS_INVALID_COMMAND; return (1); } - immed = sc->sc_cmd_data[1] & 0x01; - loej = sc->sc_cmd_data[4] & 0x02; - start = sc->sc_cmd_data[4] & 0x01; + immed = sc->sc_cbw->CBWCDB[1] & 0x01; + loej = sc->sc_cbw->CBWCDB[4] & 0x02; + start = sc->sc_cbw->CBWCDB[4] & 0x01; if (immed || loej || start) { /* compile fix */ @@ -1264,8 +1268,8 @@ ustorage_fs_prevent_allow(struct ustorag currlun->sense_data = SS_INVALID_COMMAND; return (1); } - prevent = sc->sc_cmd_data[4] & 0x01; - if ((sc->sc_cmd_data[4] & ~0x01) != 0) { + prevent = sc->sc_cbw->CBWCDB[4] & 0x01; + if ((sc->sc_cbw->CBWCDB[4] & ~0x01) != 0) { /* Mask away Prevent */ currlun->sense_data = SS_INVALID_FIELD_IN_CDB; return (1); @@ -1369,18 +1373,18 @@ ustorage_fs_read(struct ustorage_fs_soft * Get the starting Logical Block Address and check that it's not * too big */ - if (sc->sc_cmd_data[0] == SC_READ_6) { - lba = (((uint32_t)sc->sc_cmd_data[1]) << 16) | - get_be16(&sc->sc_cmd_data[2]); + if (sc->sc_cbw->CBWCDB[0] == SC_READ_6) { + lba = (((uint32_t)sc->sc_cbw->CBWCDB[1]) << 16) | + get_be16(&sc->sc_cbw->CBWCDB[2]); } else { - lba = get_be32(&sc->sc_cmd_data[2]); + lba = get_be32(&sc->sc_cbw->CBWCDB[2]); /* * We allow DPO (Disable Page Out = don't save data in the * cache) and FUA (Force Unit Access = don't read from the * cache), but we don't implement them. */ - if ((sc->sc_cmd_data[1] & ~0x18) != 0) { + if ((sc->sc_cbw->CBWCDB[1] & ~0x18) != 0) { currlun->sense_data = SS_INVALID_FIELD_IN_CDB; return (1); } @@ -1427,11 +1431,11 @@ ustorage_fs_write(struct ustorage_fs_sof * Get the starting Logical Block Address and check that it's not * too big. */ - if (sc->sc_cmd_data[0] == SC_WRITE_6) - lba = (((uint32_t)sc->sc_cmd_data[1]) << 16) | - get_be16(&sc->sc_cmd_data[2]); + if (sc->sc_cbw->CBWCDB[0] == SC_WRITE_6) + lba = (((uint32_t)sc->sc_cbw->CBWCDB[1]) << 16) | + get_be16(&sc->sc_cbw->CBWCDB[2]); else { - lba = get_be32(&sc->sc_cmd_data[2]); + lba = get_be32(&sc->sc_cbw->CBWCDB[2]); /* * We allow DPO (Disable Page Out = don't save data in the @@ -1439,11 +1443,11 @@ ustorage_fs_write(struct ustorage_fs_sof * medium). We don't implement DPO; we implement FUA by * performing synchronous output. */ - if ((sc->sc_cmd_data[1] & ~0x18) != 0) { + if ((sc->sc_cbw->CBWCDB[1] & ~0x18) != 0) { currlun->sense_data = SS_INVALID_FIELD_IN_CDB; return (1); } - if (sc->sc_cmd_data[1] & 0x08) { + if (sc->sc_cbw->CBWCDB[1] & 0x08) { /* FUA */ /* XXX set SYNC flag here */ } @@ -1483,7 +1487,7 @@ ustorage_fs_min_len(struct ustorage_fs_s * there must be something wrong about this SCSI * command */ - sc->sc_csw.bCSWStatus = CSWSTATUS_PHASE; + sc->sc_csw->bCSWStatus = CSWSTATUS_PHASE; return (1); } /* compute the minimum length */ @@ -1519,18 +1523,18 @@ ustorage_fs_check_cmd(struct ustorage_fs uint16_t mask, uint8_t needs_medium) { struct ustorage_fs_lun *currlun; - uint8_t lun = (sc->sc_cmd_data[1] >> 5); + uint8_t lun = (sc->sc_cbw->CBWCDB[1] >> 5); uint8_t i; /* Verify the length of the command itself */ if (min_cmd_size > sc->sc_transfer.cmd_len) { DPRINTF("%u > %u\n", min_cmd_size, sc->sc_transfer.cmd_len); - sc->sc_csw.bCSWStatus = CSWSTATUS_PHASE; + sc->sc_csw->bCSWStatus = CSWSTATUS_PHASE; return (1); } /* Mask away the LUN */ - sc->sc_cmd_data[1] &= 0x1f; + sc->sc_cbw->CBWCDB[1] &= 0x1f; /* Check if LUN is correct */ if (lun != sc->sc_transfer.lun) { @@ -1540,7 +1544,7 @@ ustorage_fs_check_cmd(struct ustorage_fs if (sc->sc_transfer.lun <= sc->sc_last_lun) { sc->sc_transfer.currlun = currlun = sc->sc_lun + sc->sc_transfer.lun; - if (sc->sc_cmd_data[0] != SC_REQUEST_SENSE) { + if (sc->sc_cbw->CBWCDB[0] != SC_REQUEST_SENSE) { currlun->sense_data = SS_NO_SENSE; currlun->sense_data_info = 0; currlun->info_valid = 0; @@ -1551,8 +1555,8 @@ ustorage_fs_check_cmd(struct ustorage_fs * else must fail! */ if ((currlun->unit_attention_data != SS_NO_SENSE) && - (sc->sc_cmd_data[0] != SC_INQUIRY) && - (sc->sc_cmd_data[0] != SC_REQUEST_SENSE)) { + (sc->sc_cbw->CBWCDB[0] != SC_INQUIRY) && + (sc->sc_cbw->CBWCDB[0] != SC_REQUEST_SENSE)) { currlun->sense_data = currlun->unit_attention_data; currlun->unit_attention_data = SS_NO_SENSE; return (1); @@ -1564,8 +1568,8 @@ ustorage_fs_check_cmd(struct ustorage_fs * INQUIRY and REQUEST SENSE commands are explicitly allowed * to use unsupported LUNs; all others may not. */ - if ((sc->sc_cmd_data[0] != SC_INQUIRY) && - (sc->sc_cmd_data[0] != SC_REQUEST_SENSE)) { + if ((sc->sc_cbw->CBWCDB[0] != SC_INQUIRY) && + (sc->sc_cbw->CBWCDB[0] != SC_REQUEST_SENSE)) { return (1); } } @@ -1575,7 +1579,7 @@ ustorage_fs_check_cmd(struct ustorage_fs * non-zero. */ for (i = 0; i != min_cmd_size; i++) { - if (sc->sc_cmd_data[i] && !(mask & (1UL << i))) { + if (sc->sc_cbw->CBWCDB[i] && !(mask & (1UL << i))) { if (currlun) { currlun->sense_data = SS_INVALID_FIELD_IN_CDB; } @@ -1613,12 +1617,12 @@ ustorage_fs_do_cmd(struct ustorage_fs_so sc->sc_transfer.data_ptr = sc->sc_qdata; DPRINTF("cmd_data[0]=0x%02x, data_rem=0x%08x\n", - sc->sc_cmd_data[0], sc->sc_transfer.data_rem); + sc->sc_cbw->CBWCDB[0], sc->sc_transfer.data_rem); - switch (sc->sc_cmd_data[0]) { + switch (sc->sc_cbw->CBWCDB[0]) { case SC_INQUIRY: sc->sc_transfer.cmd_dir = DIR_WRITE; - error = ustorage_fs_min_len(sc, sc->sc_cmd_data[4], -1U); + error = ustorage_fs_min_len(sc, sc->sc_cbw->CBWCDB[4], -1U); if (error) { break; } @@ -1633,7 +1637,7 @@ ustorage_fs_do_cmd(struct ustorage_fs_so case SC_MODE_SELECT_6: sc->sc_transfer.cmd_dir = DIR_READ; - error = ustorage_fs_min_len(sc, sc->sc_cmd_data[4], -1U); + error = ustorage_fs_min_len(sc, sc->sc_cbw->CBWCDB[4], -1U); if (error) { break; } @@ -1649,7 +1653,7 @@ ustorage_fs_do_cmd(struct ustorage_fs_so case SC_MODE_SELECT_10: sc->sc_transfer.cmd_dir = DIR_READ; error = ustorage_fs_min_len(sc, - get_be16(&sc->sc_cmd_data[7]), -1U); + get_be16(&sc->sc_cbw->CBWCDB[7]), -1U); if (error) { break; } @@ -1664,7 +1668,7 @@ ustorage_fs_do_cmd(struct ustorage_fs_so case SC_MODE_SENSE_6: sc->sc_transfer.cmd_dir = DIR_WRITE; - error = ustorage_fs_min_len(sc, sc->sc_cmd_data[4], -1U); + error = ustorage_fs_min_len(sc, sc->sc_cbw->CBWCDB[4], -1U); if (error) { break; } @@ -1680,7 +1684,7 @@ ustorage_fs_do_cmd(struct ustorage_fs_so case SC_MODE_SENSE_10: sc->sc_transfer.cmd_dir = DIR_WRITE; error = ustorage_fs_min_len(sc, - get_be16(&sc->sc_cmd_data[7]), -1U); + get_be16(&sc->sc_cbw->CBWCDB[7]), -1U); if (error) { break; } @@ -1708,7 +1712,7 @@ ustorage_fs_do_cmd(struct ustorage_fs_so break; case SC_READ_6: - i = sc->sc_cmd_data[4]; + i = sc->sc_cbw->CBWCDB[4]; sc->sc_transfer.cmd_dir = DIR_WRITE; temp = ((i == 0) ? 256UL : i); error = ustorage_fs_min_len(sc, temp << 9, mask9); @@ -1726,7 +1730,7 @@ ustorage_fs_do_cmd(struct ustorage_fs_so case SC_READ_10: sc->sc_transfer.cmd_dir = DIR_WRITE; - temp = get_be16(&sc->sc_cmd_data[7]); + temp = get_be16(&sc->sc_cbw->CBWCDB[7]); error = ustorage_fs_min_len(sc, temp << 9, mask9); if (error) { break; @@ -1742,10 +1746,10 @@ ustorage_fs_do_cmd(struct ustorage_fs_so case SC_READ_12: sc->sc_transfer.cmd_dir = DIR_WRITE; - temp = get_be32(&sc->sc_cmd_data[6]); + temp = get_be32(&sc->sc_cbw->CBWCDB[6]); if (temp >= (1UL << (32 - 9))) { /* numerical overflow */ - sc->sc_csw.bCSWStatus = CSWSTATUS_FAILED; + sc->sc_csw->bCSWStatus = CSWSTATUS_FAILED; error = 1; break; } @@ -1776,7 +1780,7 @@ ustorage_fs_do_cmd(struct ustorage_fs_so case SC_READ_FORMAT_CAPACITIES: sc->sc_transfer.cmd_dir = DIR_WRITE; error = ustorage_fs_min_len(sc, - get_be16(&sc->sc_cmd_data[7]), -1U); + get_be16(&sc->sc_cbw->CBWCDB[7]), -1U); if (error) { break; } @@ -1791,7 +1795,7 @@ ustorage_fs_do_cmd(struct ustorage_fs_so case SC_REQUEST_SENSE: sc->sc_transfer.cmd_dir = DIR_WRITE; - error = ustorage_fs_min_len(sc, sc->sc_cmd_data[4], -1U); + error = ustorage_fs_min_len(sc, sc->sc_cbw->CBWCDB[4], -1U); if (error) { break; } @@ -1860,7 +1864,7 @@ ustorage_fs_do_cmd(struct ustorage_fs_so break; case SC_WRITE_6: - i = sc->sc_cmd_data[4]; + i = sc->sc_cbw->CBWCDB[4]; sc->sc_transfer.cmd_dir = DIR_READ; temp = ((i == 0) ? 256UL : i); error = ustorage_fs_min_len(sc, temp << 9, mask9); @@ -1878,7 +1882,7 @@ ustorage_fs_do_cmd(struct ustorage_fs_so case SC_WRITE_10: sc->sc_transfer.cmd_dir = DIR_READ; - temp = get_be16(&sc->sc_cmd_data[7]); + temp = get_be16(&sc->sc_cbw->CBWCDB[7]); error = ustorage_fs_min_len(sc, temp << 9, mask9); if (error) { break; @@ -1894,10 +1898,10 @@ ustorage_fs_do_cmd(struct ustorage_fs_so case SC_WRITE_12: sc->sc_transfer.cmd_dir = DIR_READ; - temp = get_be32(&sc->sc_cmd_data[6]); + temp = get_be32(&sc->sc_cbw->CBWCDB[6]); if (temp > (mask9 >> 9)) { /* numerical overflow */ - sc->sc_csw.bCSWStatus = CSWSTATUS_FAILED; + sc->sc_csw->bCSWStatus = CSWSTATUS_FAILED; error = 1; break; } Modified: stable/9/sys/dev/usb/usb_msctest.c ============================================================================== --- stable/9/sys/dev/usb/usb_msctest.c Mon Dec 16 08:10:38 2013 (r259453) +++ stable/9/sys/dev/usb/usb_msctest.c Mon Dec 16 08:51:58 2013 (r259454) @@ -139,8 +139,8 @@ struct bbb_csw { struct bbb_transfer { struct mtx mtx; struct cv cv; - struct bbb_cbw cbw; - struct bbb_csw csw; + struct bbb_cbw *cbw; + struct bbb_csw *csw; struct usb_xfer *xfer[ST_MAX]; @@ -158,7 +158,7 @@ struct bbb_transfer { uint8_t status_try; int error; - uint8_t buffer[SCSI_MAX_LEN] __aligned(4); + uint8_t *buffer; }; static usb_callback_t bbb_command_callback; @@ -184,7 +184,6 @@ static const struct usb_config bbb_confi .endpoint = UE_ADDR_ANY, .direction = UE_DIR_OUT, .bufsize = sizeof(struct bbb_cbw), - .flags = {.ext_buffer = 1,}, .callback = &bbb_command_callback, .timeout = 4 * USB_MS_HZ, /* 4 seconds */ }, @@ -193,8 +192,8 @@ static const struct usb_config bbb_confi .type = UE_BULK, .endpoint = UE_ADDR_ANY, .direction = UE_DIR_IN, - .bufsize = BULK_SIZE, - .flags = {.ext_buffer = 1,.proxy_buffer = 1,.short_xfer_ok = 1,}, + .bufsize = MAX(SCSI_MAX_LEN, BULK_SIZE), + .flags = {.proxy_buffer = 1,.short_xfer_ok = 1,}, .callback = &bbb_data_read_callback, .timeout = 4 * USB_MS_HZ, /* 4 seconds */ }, @@ -232,7 +231,7 @@ static const struct usb_config bbb_confi .endpoint = UE_ADDR_ANY, .direction = UE_DIR_IN, .bufsize = sizeof(struct bbb_csw), - .flags = {.ext_buffer = 1,.short_xfer_ok = 1,}, + .flags = {.short_xfer_ok = 1,}, .callback = &bbb_status_callback, .timeout = 1 * USB_MS_HZ, /* 1 second */ }, @@ -241,7 +240,6 @@ static const struct usb_config bbb_confi static void bbb_done(struct bbb_transfer *sc, int error) { - sc->error = error; sc->state = ST_COMMAND; sc->status_try = 1; @@ -290,18 +288,17 @@ bbb_command_callback(struct usb_xfer *xf case USB_ST_SETUP: sc->status_try = 0; - tag = UGETDW(sc->cbw.dCBWTag) + 1; - USETDW(sc->cbw.dCBWSignature, CBWSIGNATURE); - USETDW(sc->cbw.dCBWTag, tag); - USETDW(sc->cbw.dCBWDataTransferLength, (uint32_t)sc->data_len); - sc->cbw.bCBWFlags = ((sc->dir == DIR_IN) ? CBWFLAGS_IN : CBWFLAGS_OUT); - sc->cbw.bCBWLUN = sc->lun; - sc->cbw.bCDBLength = sc->cmd_len; - if (sc->cbw.bCDBLength > sizeof(sc->cbw.CBWCDB)) { - sc->cbw.bCDBLength = sizeof(sc->cbw.CBWCDB); + tag = UGETDW(sc->cbw->dCBWTag) + 1; + USETDW(sc->cbw->dCBWSignature, CBWSIGNATURE); + USETDW(sc->cbw->dCBWTag, tag); + USETDW(sc->cbw->dCBWDataTransferLength, (uint32_t)sc->data_len); + sc->cbw->bCBWFlags = ((sc->dir == DIR_IN) ? CBWFLAGS_IN : CBWFLAGS_OUT); + sc->cbw->bCBWLUN = sc->lun; + sc->cbw->bCDBLength = sc->cmd_len; + if (sc->cbw->bCDBLength > sizeof(sc->cbw->CBWCDB)) { + sc->cbw->bCDBLength = sizeof(sc->cbw->CBWCDB); DPRINTFN(0, "Truncating long command\n"); } - usbd_xfer_set_frame_data(xfer, 0, &sc->cbw, sizeof(sc->cbw)); usbd_transfer_submit(xfer); break; @@ -430,9 +427,9 @@ bbb_status_callback(struct usb_xfer *xfe /* very simple status check */ - if (actlen < (int)sizeof(sc->csw)) { + if (actlen < (int)sizeof(struct bbb_csw)) { bbb_done(sc, USB_ERR_SHORT_XFER); - } else if (sc->csw.bCSWStatus == CSWSTATUS_GOOD) { + } else if (sc->csw->bCSWStatus == CSWSTATUS_GOOD) { bbb_done(sc, 0); /* success */ } else { bbb_done(sc, ERR_CSW_FAILED); /* error */ @@ -440,7 +437,6 @@ bbb_status_callback(struct usb_xfer *xfe break; case USB_ST_SETUP: - usbd_xfer_set_frame_data(xfer, 0, &sc->csw, sizeof(sc->csw)); usbd_transfer_submit(xfer); break; @@ -478,9 +474,9 @@ bbb_command_start(struct bbb_transfer *s sc->data_timeout = (data_timeout + USB_MS_HZ); sc->actlen = 0; sc->cmd_len = cmd_len; - memset(&sc->cbw.CBWCDB, 0, sizeof(sc->cbw.CBWCDB)); - memcpy(&sc->cbw.CBWCDB, cmd_ptr, cmd_len); - DPRINTFN(1, "SCSI cmd = %*D\n", (int)cmd_len, (char *)sc->cbw.CBWCDB, ":"); + memset(&sc->cbw->CBWCDB, 0, sizeof(sc->cbw->CBWCDB)); + memcpy(&sc->cbw->CBWCDB, cmd_ptr, cmd_len); + DPRINTFN(1, "SCSI cmd = %*D\n", (int)cmd_len, (char *)sc->cbw->CBWCDB, ":"); mtx_lock(&sc->mtx); usbd_transfer_start(sc->xfer[sc->state]); @@ -549,6 +545,14 @@ bbb_attach(struct usb_device *udev, uint bbb_detach(sc); return (NULL); } + /* store pointer to DMA buffers */ + sc->buffer = usbd_xfer_get_frame_buffer( + sc->xfer[ST_DATA_RD], 0); + sc->cbw = usbd_xfer_get_frame_buffer( + sc->xfer[ST_COMMAND], 0); + sc->csw = usbd_xfer_get_frame_buffer( + sc->xfer[ST_STATUS], 0); + return (sc); } Modified: stable/9/sys/dev/usb/wlan/if_uath.c ============================================================================== --- stable/9/sys/dev/usb/wlan/if_uath.c Mon Dec 16 08:10:38 2013 (r259453) +++ stable/9/sys/dev/usb/wlan/if_uath.c Mon Dec 16 08:51:58 2013 (r259454) @@ -217,9 +217,8 @@ static const struct usb_config uath_usbc .type = UE_BULK, .endpoint = 0x1, .direction = UE_DIR_OUT, - .bufsize = UATH_MAX_CMDSZ, + .bufsize = UATH_MAX_CMDSZ * UATH_CMD_LIST_COUNT, .flags = { - .ext_buffer = 1, .force_short_xfer = 1, .pipe_bof = 1, }, @@ -242,9 +241,8 @@ static const struct usb_config uath_usbc .type = UE_BULK, .endpoint = 0x2, .direction = UE_DIR_OUT, - .bufsize = UATH_MAX_TXBUFSZ, + .bufsize = UATH_MAX_TXBUFSZ * UATH_TX_DATA_LIST_COUNT, .flags = { - .ext_buffer = 1, .force_short_xfer = 1, .pipe_bof = 1 }, @@ -258,10 +256,8 @@ static struct ieee80211vap *uath_vap_cre const uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN]); static void uath_vap_delete(struct ieee80211vap *); -static int uath_alloc_cmd_list(struct uath_softc *, struct uath_cmd [], - int, int); -static void uath_free_cmd_list(struct uath_softc *, struct uath_cmd [], - int); +static int uath_alloc_cmd_list(struct uath_softc *, struct uath_cmd []); +static void uath_free_cmd_list(struct uath_softc *, struct uath_cmd []); static int uath_host_available(struct uath_softc *); static int uath_get_capability(struct uath_softc *, uint32_t, uint32_t *); static int uath_get_devcap(struct uath_softc *); @@ -362,22 +358,26 @@ uath_attach(device_t dev) callout_init(&sc->stat_ch, 0); callout_init_mtx(&sc->watchdog_ch, &sc->sc_mtx, 0); - /* - * Allocate xfers for firmware commands. - */ - error = uath_alloc_cmd_list(sc, sc->sc_cmd, UATH_CMD_LIST_COUNT, - UATH_MAX_CMDSZ); - if (error != 0) { - device_printf(sc->sc_dev, - "could not allocate Tx command list\n"); - goto fail; - } - error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer, uath_usbconfig, UATH_N_XFERS, sc, &sc->sc_mtx); if (error) { device_printf(dev, "could not allocate USB transfers, " "err=%s\n", usbd_errstr(error)); + goto fail; + } + + sc->sc_cmd_dma_buf = + usbd_xfer_get_frame_buffer(sc->sc_xfer[UATH_INTR_TX], 0); + sc->sc_tx_dma_buf = + usbd_xfer_get_frame_buffer(sc->sc_xfer[UATH_BULK_TX], 0); + + /* + * Setup buffers for firmware commands. + */ + error = uath_alloc_cmd_list(sc, sc->sc_cmd); + if (error != 0) { + device_printf(sc->sc_dev, + "could not allocate Tx command list\n"); goto fail1; } @@ -492,8 +492,8 @@ uath_attach(device_t dev) fail4: if_free(ifp); fail3: UATH_UNLOCK(sc); -fail2: usbd_transfer_unsetup(sc->sc_xfer, UATH_N_XFERS); -fail1: uath_free_cmd_list(sc, sc->sc_cmd, UATH_CMD_LIST_COUNT); +fail2: uath_free_cmd_list(sc, sc->sc_cmd); +fail1: usbd_transfer_unsetup(sc->sc_xfer, UATH_N_XFERS); fail: return (error); } @@ -524,7 +524,7 @@ uath_detach(device_t dev) UATH_LOCK(sc); uath_free_rx_data_list(sc); uath_free_tx_data_list(sc); - uath_free_cmd_list(sc, sc->sc_cmd, UATH_CMD_LIST_COUNT); + uath_free_cmd_list(sc, sc->sc_cmd); UATH_UNLOCK(sc); if_free(ifp); @@ -533,45 +533,35 @@ uath_detach(device_t dev) } static void -uath_free_cmd_list(struct uath_softc *sc, struct uath_cmd cmds[], int ncmd) +uath_free_cmd_list(struct uath_softc *sc, struct uath_cmd cmds[]) { int i; - for (i = 0; i < ncmd; i++) - if (cmds[i].buf != NULL) - free(cmds[i].buf, M_USBDEV); + for (i = 0; i != UATH_CMD_LIST_COUNT; i++) + cmds[i].buf = NULL; } static int -uath_alloc_cmd_list(struct uath_softc *sc, struct uath_cmd cmds[], - int ncmd, int maxsz) +uath_alloc_cmd_list(struct uath_softc *sc, struct uath_cmd cmds[]) { - int i, error; + int i; STAILQ_INIT(&sc->sc_cmd_active); STAILQ_INIT(&sc->sc_cmd_pending); STAILQ_INIT(&sc->sc_cmd_waiting); STAILQ_INIT(&sc->sc_cmd_inactive); - for (i = 0; i < ncmd; i++) { + for (i = 0; i != UATH_CMD_LIST_COUNT; i++) { struct uath_cmd *cmd = &cmds[i]; cmd->sc = sc; /* backpointer for callbacks */ cmd->msgid = i; - cmd->buf = malloc(maxsz, M_USBDEV, M_NOWAIT); - if (cmd->buf == NULL) { - device_printf(sc->sc_dev, - "could not allocate xfer buffer\n"); - error = ENOMEM; - goto fail; - } + cmd->buf = ((uint8_t *)sc->sc_cmd_dma_buf) + + (i * UATH_MAX_CMDSZ); STAILQ_INSERT_TAIL(&sc->sc_cmd_inactive, cmd, next); UATH_STAT_INC(sc, st_cmd_inactive); } return (0); - -fail: uath_free_cmd_list(sc, cmds, ncmd); - return (error); } static int @@ -942,10 +932,7 @@ uath_free_data_list(struct uath_softc *s dp->buf = NULL; } } else { - if (dp->buf != NULL) { - free(dp->buf, M_USBDEV); - dp->buf = NULL; - } + dp->buf = NULL; } #ifdef UATH_DEBUG if (dp->ni != NULL) @@ -956,7 +943,7 @@ uath_free_data_list(struct uath_softc *s static int uath_alloc_data_list(struct uath_softc *sc, struct uath_data data[], - int ndata, int maxsz, int fillmbuf) + int ndata, int maxsz, void *dma_buf) { int i, error; @@ -964,7 +951,7 @@ uath_alloc_data_list(struct uath_softc * struct uath_data *dp = &data[i]; dp->sc = sc; - if (fillmbuf) { + if (dma_buf == NULL) { /* XXX check maxsz */ dp->m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); if (dp->m == NULL) { @@ -976,20 +963,14 @@ uath_alloc_data_list(struct uath_softc * dp->buf = mtod(dp->m, uint8_t *); } else { dp->m = NULL; - dp->buf = malloc(maxsz, M_USBDEV, M_NOWAIT); - if (dp->buf == NULL) { - device_printf(sc->sc_dev, - "could not allocate buffer\n"); - error = ENOMEM; - goto fail; - } + dp->buf = ((uint8_t *)dma_buf) + (i * maxsz); } dp->ni = NULL; } return (0); -fail: uath_free_data_list(sc, data, ndata, fillmbuf); +fail: uath_free_data_list(sc, data, ndata, 1 /* free mbufs */); return (error); } @@ -1001,7 +982,7 @@ uath_alloc_rx_data_list(struct uath_soft /* XXX is it enough to store the RX packet with MCLBYTES bytes? */ error = uath_alloc_data_list(sc, sc->sc_rx, UATH_RX_DATA_LIST_COUNT, MCLBYTES, - 1 /* setup mbufs */); + NULL /* setup mbufs */); if (error != 0) return (error); @@ -1024,7 +1005,7 @@ uath_alloc_tx_data_list(struct uath_soft error = uath_alloc_data_list(sc, sc->sc_tx, UATH_TX_DATA_LIST_COUNT, UATH_MAX_TXBUFSZ, - 0 /* no mbufs */); + sc->sc_tx_dma_buf); if (error != 0) return (error); @@ -2741,8 +2722,7 @@ setup: UATH_STAT_DEC(sc, st_rx_inactive); STAILQ_INSERT_TAIL(&sc->sc_rx_active, data, next); UATH_STAT_INC(sc, st_rx_active); - usbd_xfer_set_frame_data(xfer, 0, data->buf, - usbd_xfer_max_len(xfer)); + usbd_xfer_set_frame_data(xfer, 0, data->buf, MCLBYTES); usbd_transfer_submit(xfer); /* @@ -2890,7 +2870,7 @@ static device_method_t uath_methods[] = DEVMETHOD(device_probe, uath_match), DEVMETHOD(device_attach, uath_attach), DEVMETHOD(device_detach, uath_detach), - { 0, 0 } + DEVMETHOD_END }; static driver_t uath_driver = { .name = "uath", Modified: stable/9/sys/dev/usb/wlan/if_uathvar.h ============================================================================== --- stable/9/sys/dev/usb/wlan/if_uathvar.h Mon Dec 16 08:10:38 2013 (r259453) +++ stable/9/sys/dev/usb/wlan/if_uathvar.h Mon Dec 16 08:51:58 2013 (r259454) @@ -186,6 +186,8 @@ struct uath_softc { struct ifnet *sc_ifp; device_t sc_dev; struct usb_device *sc_udev; + void *sc_cmd_dma_buf; + void *sc_tx_dma_buf; struct mtx sc_mtx; uint32_t sc_debug; Modified: stable/9/sys/dev/usb/wlan/if_upgt.c ============================================================================== --- stable/9/sys/dev/usb/wlan/if_upgt.c Mon Dec 16 08:10:38 2013 (r259453) +++ stable/9/sys/dev/usb/wlan/if_upgt.c Mon Dec 16 08:51:58 2013 (r259454) @@ -201,9 +201,8 @@ static const struct usb_config upgt_conf .type = UE_BULK, .endpoint = UE_ADDR_ANY, .direction = UE_DIR_OUT, - .bufsize = MCLBYTES, + .bufsize = MCLBYTES * UPGT_TX_MAXCOUNT, .flags = { - .ext_buffer = 1, .force_short_xfer = 1, .pipe_bof = 1 }, @@ -214,9 +213,8 @@ static const struct usb_config upgt_conf .type = UE_BULK, .endpoint = UE_ADDR_ANY, .direction = UE_DIR_IN, - .bufsize = MCLBYTES, + .bufsize = MCLBYTES * UPGT_RX_MAXCOUNT, .flags = { - .ext_buffer = 1, .pipe_bof = 1, .short_xfer_ok = 1 }, @@ -261,22 +259,27 @@ upgt_attach(device_t dev) callout_init(&sc->sc_led_ch, 0); callout_init(&sc->sc_watchdog_ch, 0); - /* Allocate TX and RX xfers. */ - error = upgt_alloc_tx(sc); - if (error) - goto fail1; - error = upgt_alloc_rx(sc); - if (error) - goto fail2; - error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer, upgt_config, UPGT_N_XFERS, sc, &sc->sc_mtx); if (error) { device_printf(dev, "could not allocate USB transfers, " "err=%s\n", usbd_errstr(error)); - goto fail3; + goto fail1; } + sc->sc_rx_dma_buf = usbd_xfer_get_frame_buffer( + sc->sc_xfer[UPGT_BULK_RX], 0); + sc->sc_tx_dma_buf = usbd_xfer_get_frame_buffer( + sc->sc_xfer[UPGT_BULK_TX], 0); + + /* Setup TX and RX buffers */ + error = upgt_alloc_tx(sc); + if (error) + goto fail2; + error = upgt_alloc_rx(sc); + if (error) + goto fail3; + ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); if (ifp == NULL) { device_printf(dev, "can not if_alloc()\n"); @@ -379,9 +382,9 @@ upgt_attach(device_t dev) return (0); fail5: if_free(ifp); -fail4: usbd_transfer_unsetup(sc->sc_xfer, UPGT_N_XFERS); -fail3: upgt_free_rx(sc); -fail2: upgt_free_tx(sc); +fail4: upgt_free_rx(sc); +fail3: upgt_free_tx(sc); +fail2: usbd_transfer_unsetup(sc->sc_xfer, UPGT_N_XFERS); fail1: mtx_destroy(&sc->sc_mtx); return (error); @@ -1978,13 +1981,7 @@ upgt_alloc_tx(struct upgt_softc *sc) *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***