Date: Sat, 22 Sep 2007 12:34:36 GMT From: Hans Petter Selasky <hselasky@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 126690 for review Message-ID: <200709221234.l8MCYa1U087231@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=126690 Change 126690 by hselasky@hselasky_laptop001 on 2007/09/22 12:33:43 - convert kernel USB flags into a bitmap (scripted) - "xfer->frlengths" now has the type "uint32_t *" - "xfer->actlen < xfer->sumlen" is the new way to check if a USB transfer is short. - new check for mismatch between "wMaxPacketSize" and the configured data transfer rate. See "ch->bytes_per_frame > xfer->max_frame_size". Observe that high-speed isochronous transfers can have multiple "wMaxPacketSize" packets per 125us. Therefore we compare against "max_frame_size" and not "max_packet_size". - use ("xfer->frbuffers + 0" or "&xfer->buf_data") and ("usbd_copy_in()" or "usbd_copy_out()") to transfer Isochronous USB data, hence "xfer->buffer" is now gone! - "usbreq_set_interface()" has been renamed "usbd_set_alt_interface_index()" to clearly show that this function does more than just an USB control request. - passing a mutex to "usbd_do_request_flags()" and all "usbreq_xxx()" functions is now mandatory. - transform "xfer->length" into "xfer->frlengths[]". This is the new way to set the transfer length. Additional notes: Control transfers get "xfer->nframes = 2" when "frames" is zero in the USB config structure. Else "xfer->nframes" defaults to 1 for BULK and INTERRUPT. For ISOCHRONOUS a non zero value must be specified. Affected files ... .. //depot/projects/usb/src/sys/dev/sound/usb/uaudio.c#15 edit Differences ... ==== //depot/projects/usb/src/sys/dev/sound/usb/uaudio.c#15 (text+ko) ==== @@ -459,7 +459,7 @@ .direction = UE_DIR_IN, .bufsize = 0, /* use "wMaxPacketSize * frames" */ .frames = UAUDIO_NFRAMES, - .flags = USBD_SHORT_XFER_OK, + .flags = { .short_xfer_ok = 1, }, .callback = &uaudio_chan_record_callback, }, @@ -469,7 +469,7 @@ .direction = UE_DIR_IN, .bufsize = 0, /* use "wMaxPacketSize * frames" */ .frames = UAUDIO_NFRAMES, - .flags = USBD_SHORT_XFER_OK, + .flags = { .short_xfer_ok = 1, }, .callback = &uaudio_chan_record_callback, }, }; @@ -482,7 +482,7 @@ .direction = UE_DIR_IN, .bufsize = 0, /* use "wMaxPacketSize * frames" */ .frames = (UAUDIO_NFRAMES * 8), - .flags = USBD_SHORT_XFER_OK, + .flags = { .short_xfer_ok = 1, }, .callback = &uaudio_chan_record_callback, }, @@ -492,7 +492,7 @@ .direction = UE_DIR_IN, .bufsize = 0, /* use "wMaxPacketSize * frames" */ .frames = (UAUDIO_NFRAMES * 8), - .flags = USBD_SHORT_XFER_OK, + .flags = { .short_xfer_ok = 1, }, .callback = &uaudio_chan_record_callback, }, }; @@ -505,7 +505,7 @@ .direction = UE_DIR_OUT, .bufsize = 0, /* use "wMaxPacketSize * frames" */ .frames = UAUDIO_NFRAMES, - .flags = USBD_SHORT_XFER_OK, + .flags = { .short_xfer_ok = 1, }, .callback = &uaudio_chan_play_callback, }, @@ -515,7 +515,7 @@ .direction = UE_DIR_OUT, .bufsize = 0, /* use "wMaxPacketSize * frames" */ .frames = UAUDIO_NFRAMES, - .flags = USBD_SHORT_XFER_OK, + .flags = { .short_xfer_ok = 1, }, .callback = &uaudio_chan_play_callback, }, }; @@ -528,7 +528,7 @@ .direction = UE_DIR_OUT, .bufsize = 0, /* use "wMaxPacketSize * frames" */ .frames = (UAUDIO_NFRAMES * 8), - .flags = USBD_SHORT_XFER_OK, + .flags = { .short_xfer_ok = 1, }, .callback = &uaudio_chan_play_callback, }, @@ -538,7 +538,7 @@ .direction = UE_DIR_OUT, .bufsize = 0, /* use "wMaxPacketSize * frames" */ .frames = (UAUDIO_NFRAMES * 8), - .flags = USBD_SHORT_XFER_OK, + .flags = { .short_xfer_ok = 1, }, .callback = &uaudio_chan_play_callback, }, }; @@ -582,7 +582,7 @@ .endpoint = UE_ADDR_ANY, .direction = UE_DIR_OUT, .bufsize = UMIDI_BULK_SIZE, - .flags = (USBD_PIPE_BOF|USBD_USE_DMA|USBD_SHORT_XFER_OK), + .flags = { .pipe_bof = 1, .short_xfer_ok = 1, }, .callback = &umidi_bulk_write_callback, }, @@ -591,7 +591,7 @@ .endpoint = UE_ADDR_ANY, .direction = UE_DIR_IN, .bufsize = UMIDI_BULK_SIZE, - .flags = (USBD_PIPE_BOF|USBD_USE_DMA|USBD_SHORT_XFER_OK), + .flags = { .pipe_bof = 1, .short_xfer_ok = 1, }, .callback = &umidi_bulk_read_callback, }, @@ -600,7 +600,7 @@ .endpoint = 0x00, /* Control pipe */ .direction = UE_DIR_ANY, .bufsize = sizeof(usb_device_request_t), - .flags = USBD_USE_DMA, + .flags = { }, .callback = &umidi_write_clear_stall_callback, .timeout = 1000, /* 1 second */ .interval = 50, /* 50ms */ @@ -611,7 +611,7 @@ .endpoint = 0x00, /* Control pipe */ .direction = UE_DIR_ANY, .bufsize = sizeof(usb_device_request_t), - .flags = USBD_USE_DMA, + .flags = { }, .callback = &umidi_read_clear_stall_callback, .timeout = 1000, /* 1 second */ .interval = 50, /* 50ms */ @@ -1221,10 +1221,10 @@ uaudio_chan_play_callback(struct usbd_xfer *xfer) { struct uaudio_chan *ch = xfer->priv_sc; - u_int16_t * p_len = xfer->frlengths; - u_int8_t * buf = xfer->buffer; + uint32_t * p_len = xfer->frlengths; u_int32_t n; u_int32_t total = (ch->bytes_per_frame * xfer->nframes); + uint32_t offset; USBD_CHECK_STATUS(xfer); @@ -1234,7 +1234,7 @@ } tr_transferred: - if (xfer->actlen < total) { + if (xfer->actlen < xfer->sumlen) { DPRINTF(0, "short transfer, " "%d of %d bytes\n", xfer->actlen, total); } @@ -1242,17 +1242,18 @@ chn_intr(ch->pcm_ch); tr_setup: - for (n = 0; n < xfer->nframes; n++) { - p_len[n] = ch->bytes_per_frame; - } - - if (total > xfer->length) { + if (ch->bytes_per_frame > xfer->max_frame_size) { DPRINTF(0, "bytes per transfer, %d, " "exceeds maximum, %d!\n", - total, xfer->length); + ch->bytes_per_frame, + xfer->max_frame_size); return; } + for (n = 0; n < xfer->nframes; n++) { + p_len[n] = ch->bytes_per_frame; + } + if (ch->end == ch->start) { DPRINTF(0, "no buffer!\n"); return; @@ -1260,6 +1261,8 @@ DPRINTF(5, "transfer %d bytes\n", total); + offset = 0; + while (total > 0) { n = (ch->end - ch->cur); @@ -1267,11 +1270,11 @@ n = total; } - bcopy(ch->cur, buf, n); + usbd_copy_in(xfer->frbuffers + 0, offset, ch->cur, n); total -= n; ch->cur += n; - buf += n; + offset += n; if (ch->cur >= ch->end) { ch->cur = ch->start; @@ -1286,12 +1289,12 @@ uaudio_chan_record_callback(struct usbd_xfer *xfer) { struct uaudio_chan *ch = xfer->priv_sc; - u_int8_t * buf1 = xfer->buffer; - u_int8_t * buf2 = xfer->buffer; - u_int16_t * p_len = xfer->frlengths; + uint32_t * p_len = xfer->frlengths; u_int32_t n; u_int32_t m; u_int32_t total = (xfer->nframes * ch->bytes_per_frame); + uint32_t offset0; + uint32_t offset1; USBD_CHECK_STATUS(xfer); @@ -1308,8 +1311,12 @@ DPRINTF(5, "transferred %d bytes\n", xfer->actlen); } + offset0 = 0; + for (n = 0; n < xfer->nframes; n++) { + offset1 = offset0; + while (p_len[n] > 0) { m = (ch->end - ch->cur); @@ -1318,10 +1325,10 @@ m = p_len[n]; } - bcopy(buf1, ch->cur, m); + usbd_copy_out(xfer->frbuffers + 0, offset1, ch->cur, m); p_len[n] -= m; - buf1 += m; + offset1 += m; ch->cur += m; if (ch->cur >= ch->end) { @@ -1329,24 +1336,24 @@ } } - buf2 += ch->bytes_per_frame; - buf1 = buf2; + offset0 += ch->bytes_per_frame; } chn_intr(ch->pcm_ch); tr_setup: - for (n = 0; n < xfer->nframes; n++) { - p_len[n] = ch->bytes_per_frame; - } - - if (total > xfer->length) { + if (ch->bytes_per_frame > xfer->max_frame_size) { DPRINTF(0, "bytes per transfer, %d, " "exceeds maximum, %d!\n", - total, xfer->length); + ch->bytes_per_frame, + xfer->max_frame_size); return; } + for (n = 0; n < xfer->nframes; n++) { + p_len[n] = ch->bytes_per_frame; + } + if (ch->end == ch->start) { DPRINTF(0, "no buffer!\n"); return; @@ -1417,7 +1424,7 @@ DPRINTF(0, "endpoint=0x%02x, speed=%d, iface=%d alt=%d\n", endpoint, ch->sample_rate, iface_index, alt_index); - err = usbreq_set_interface(sc->sc_udev, iface_index, alt_index); + err = usbd_set_alt_interface_index(sc->sc_udev, iface_index, alt_index); if (err) { DPRINTF(0, "setting of alternate index failed: %s!\n", usbd_errstr(err)); @@ -3016,7 +3023,7 @@ USETW(req.wIndex, mc->wIndex); USETW(req.wLength, len); - err = usbd_do_request(udev, &req, data); + err = usbd_do_request(udev, &Giant, &req, data); if (err) { DPRINTF(0, "err=%s\n", usbd_errstr(err)); return 0; @@ -3038,13 +3045,14 @@ static void uaudio_mixer_write_cfg_callback(struct usbd_xfer *xfer) { - usb_device_request_t *req = xfer->buffer; + usb_device_request_t req; struct uaudio_softc *sc = xfer->priv_sc; struct uaudio_mixer_node *mc = sc->sc_mixer_curr; u_int16_t len; u_int8_t repeat = 1; u_int8_t update; u_int8_t chan; + uint8_t buf[2]; USBD_CHECK_STATUS(xfer); @@ -3077,20 +3085,24 @@ if (update) { - req->bmRequestType = UT_WRITE_CLASS_INTERFACE; - req->bRequest = SET_CUR; - USETW(req->wValue, mc->wValue[chan]); - USETW(req->wIndex, mc->wIndex); - USETW(req->wLength, len); + req.bmRequestType = UT_WRITE_CLASS_INTERFACE; + req.bRequest = SET_CUR; + USETW(req.wValue, mc->wValue[chan]); + USETW(req.wIndex, mc->wIndex); + USETW(req.wLength, len); if (len > 0) { - req->bData[0] = (mc->wData[chan] & 0xFF); + buf[0] = (mc->wData[chan] & 0xFF); } if (len > 1) { - req->bData[1] = (mc->wData[chan] >> 8) & 0xFF; + buf[1] = (mc->wData[chan] >> 8) & 0xFF; } - xfer->length = (sizeof(*req)+len); + usbd_copy_in(xfer->frbuffers + 0, 0, &req, sizeof(req)); + usbd_copy_in(xfer->frbuffers + 1, 0, buf, len); + + xfer->frlengths[0] = sizeof(req); + xfer->frlengths[1] = len; usbd_start_hardware(xfer); return; } @@ -3124,7 +3136,7 @@ data[1] = speed >> 8; data[2] = speed >> 16; - return usbd_do_request(udev, &req, data); + return usbd_do_request(udev, &Giant, &req, data); } static int @@ -3310,7 +3322,7 @@ { struct umidi_chan *chan = xfer->priv_sc; struct umidi_sub_chan *sub; - u_int8_t buf[4]; + u_int8_t buf[1]; u_int8_t cmd_len; u_int8_t cn; u_int16_t pos; @@ -3341,14 +3353,15 @@ while (xfer->actlen >= 4) { - usbd_copy_out(&(xfer->buf_data), pos, buf, 4); + usbd_copy_out(&(xfer->buf_data), pos, buf, 1); cmd_len = umidi_cmd_to_len[buf[0] & 0xF]; /* command length */ cn = buf[0] >> 4; /* cable number */ sub = &(chan->sub[cn]); if (cmd_len && (cn < chan->max_cable) && sub->read_open) { - usb_cdev_put_data(&(sub->cdev), buf+1, cmd_len, 1); + usb_cdev_put_data(&(sub->cdev), &(xfer->buf_data), + pos+1, cmd_len, 1); } else { /* ignore the command */ } @@ -3364,6 +3377,7 @@ usbd_transfer_start(chan->xfer[3]); return; } + xfer->frlengths[0] = xfer->max_data_length; usbd_start_hardware(xfer); return; } @@ -3564,12 +3578,15 @@ sub = &(chan->sub[chan->curr_cable]); if (sub->write_open) { - usb_cdev_get_data(&(sub->cdev), &buf, 1, &actlen, 0); + usb_cdev_get_data(&(sub->cdev), &(xfer->buf_data), + total_length, 1, &actlen, 0); } else { actlen = 0; } if (actlen) { + usbd_copy_out(&(xfer->buf_data), total_length, &buf, 1); + tr_any = 1; DPRINTF(0, "byte=0x%02x\n", buf); @@ -3607,7 +3624,7 @@ } if (total_length) { - xfer->length = total_length; + xfer->frlengths[0] = total_length; usbd_start_hardware(xfer); } return; @@ -3741,7 +3758,7 @@ u_int32_t n; u_int8_t buf[32]; - if (usbreq_set_interface(sc->sc_udev, chan->iface_index, + if (usbd_set_alt_interface_index(sc->sc_udev, chan->iface_index, chan->iface_alt_index)) { DPRINTF(0, "setting of alternate index failed!\n"); goto detach;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200709221234.l8MCYa1U087231>