/* At this point, the vendor driver downloads the whole firmware * image, hacks around with version IDs, and uploads it again, * completely overwriting the boot code. We do not do this here as * it is not required on any tested devices, and it is suspected to
* cause problems. */
error:
release_firmware(ur_fw); return r;
}
if (fw_bcdDevice != bcdDevice) {
dev_info(&udev->dev, "firmware version %#06x and device bootcode version " "%#06x differ\n", fw_bcdDevice, bcdDevice); if (bcdDevice <= 0x4313)
dev_warn(&udev->dev, "device has old bootcode, please " "report success or failure\n");
r = handle_version_mismatch(usb, ub_fw); if (r) goto error;
} else {
dev_dbg_f(&udev->dev, "firmware device id %#06x is equal to the " "actual device id\n", fw_bcdDevice);
}
r = request_fw_file(&uph_fw,
get_fw_name(usb, fw_name, sizeof(fw_name), "uphr"),
&udev->dev); if (r) goto error;
r = upload_code(udev, uph_fw->data, uph_fw->size, FW_START, REBOOT); if (r) {
dev_err(&udev->dev, "Could not upload firmware code uph. Error number %d\n",
r);
}
/* Read data from device address space using "firmware interface" which does
* not require firmware to be loaded. */ int zd_usb_read_fw(struct zd_usb *usb, zd_addr_t addr, u8 *data, u16 len)
{ int r; struct usb_device *udev = zd_usb_to_usbdev(usb);
u8 *buf;
/* Use "DMA-aware" buffer. */
buf = kmalloc(len, GFP_KERNEL); if (!buf) return -ENOMEM;
r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
USB_REQ_FIRMWARE_READ_DATA, USB_DIR_IN | 0x40, addr, 0,
buf, len, 5000); if (r < 0) {
dev_err(&udev->dev, "read over firmware interface failed: %d\n", r); gotoexit;
} elseif (r != len) {
dev_err(&udev->dev, "incomplete read over firmware interface: %d/%d\n",
r, len);
r = -EIO; gotoexit;
}
r = 0;
memcpy(data, buf, len); exit:
kfree(buf); return r;
}
/* Sometimes USB_INT_ID_REGS is not overridden, but comes after * USB_INT_ID_RETRY_FAILED. Read-reg retry then gets this * delayed USB_INT_ID_REGS, but leaves USB_INT_ID_REGS of * retry unhandled. Next read-reg command then might catch * this wrong USB_INT_ID_REGS. Fix by ignoring wrong reads.
*/ if (!check_read_regs(usb, intr->read_regs.req,
intr->read_regs.req_count)) goto out;
if (length < sizeof(struct rx_length_info)) { /* It's not a complete packet anyhow. */
dev_dbg_f(zd_usb_dev(usb), "invalid, small RX packet : %d\n",
length); return;
}
length_info = (struct rx_length_info *)
(buffer + length - sizeof(struct rx_length_info));
/* It might be that three frames are merged into a single URB * transaction. We have to check for the length info tag. * * While testing we discovered that length_info might be unaligned, * because if USB transactions are merged, the last packet will not * be padded. Unaligned access might also happen if the length_info * structure is not present.
*/ if (get_unaligned_le16(&length_info->tag) == RX_LENGTH_INFO_TAG)
{ unsignedint l, k, n; for (i = 0, l = 0;; i++) {
k = get_unaligned_le16(&length_info->length[i]); if (k == 0) return;
n = l+k; if (n > length) return;
zd_mac_rx(zd_usb_to_hw(usb), buffer+l, k); if (i >= 2) return;
l = (n+3) & ~3;
}
} else {
zd_mac_rx(zd_usb_to_hw(usb), buffer, length);
}
}
if (length%rx->usb_packet_size > rx->usb_packet_size-4) { /* If there is an old first fragment, we don't care. */
dev_dbg_f(urb_dev(urb), "*** first fragment ***\n");
ZD_ASSERT(length <= ARRAY_SIZE(rx->fragment));
spin_lock_irqsave(&rx->lock, flags);
memcpy(rx->fragment, buffer, length);
rx->fragment_length = length;
spin_unlock_irqrestore(&rx->lock, flags); goto resubmit;
}
spin_lock_irqsave(&rx->lock, flags); if (rx->fragment_length > 0) { /* We are on a second fragment, we believe */
ZD_ASSERT(length + rx->fragment_length <=
ARRAY_SIZE(rx->fragment));
dev_dbg_f(urb_dev(urb), "*** second fragment ***\n");
memcpy(rx->fragment+rx->fragment_length, buffer, length);
handle_rx_packet(usb, rx->fragment,
rx->fragment_length + length);
rx->fragment_length = 0;
spin_unlock_irqrestore(&rx->lock, flags);
} else {
spin_unlock_irqrestore(&rx->lock, flags);
handle_rx_packet(usb, buffer, length);
}
resubmit:
r = usb_submit_urb(urb, GFP_ATOMIC); if (r)
dev_dbg_f(urb_dev(urb), "urb %p resubmit error %d\n", urb, r);
}
staticint __zd_usb_enable_rx(struct zd_usb *usb)
{ int i, r; struct zd_usb_rx *rx = &usb->rx; struct urb **urbs;
dev_dbg_f(zd_usb_dev(usb), "\n");
r = -ENOMEM;
urbs = kcalloc(RX_URBS_COUNT, sizeof(struct urb *), GFP_KERNEL); if (!urbs) goto error; for (i = 0; i < RX_URBS_COUNT; i++) {
urbs[i] = alloc_rx_urb(usb); if (!urbs[i]) goto error;
}
ZD_ASSERT(!irqs_disabled());
spin_lock_irq(&rx->lock); if (rx->urbs) {
spin_unlock_irq(&rx->lock);
r = 0; goto error;
}
rx->urbs = urbs;
rx->urbs_count = RX_URBS_COUNT;
spin_unlock_irq(&rx->lock);
for (i = 0; i < RX_URBS_COUNT; i++) {
r = usb_submit_urb(urbs[i], GFP_KERNEL); if (r) goto error_submit;
}
return 0;
error_submit: for (i = 0; i < RX_URBS_COUNT; i++) {
usb_kill_urb(urbs[i]);
}
spin_lock_irq(&rx->lock);
rx->urbs = NULL;
rx->urbs_count = 0;
spin_unlock_irq(&rx->lock);
error: if (urbs) { for (i = 0; i < RX_URBS_COUNT; i++)
free_rx_urb(urbs[i]);
} return r;
}
int zd_usb_enable_rx(struct zd_usb *usb)
{ int r; struct zd_usb_rx *rx = &usb->rx;
mutex_lock(&rx->setup_mutex);
r = __zd_usb_enable_rx(usb);
mutex_unlock(&rx->setup_mutex);
if (do_reset) {
__zd_usb_disable_rx(usb);
__zd_usb_enable_rx(usb);
}
mutex_unlock(&rx->setup_mutex);
if (do_reset)
zd_usb_reset_rx_idle_timer(usb);
}
/** * zd_usb_disable_tx - disable transmission * @usb: the zd1211rw-private USB structure * * Frees all URBs in the free list and marks the transmission as disabled.
*/ void zd_usb_disable_tx(struct zd_usb *usb)
{ struct zd_usb_tx *tx = &usb->tx; unsignedlong flags;
atomic_set(&tx->enabled, 0);
/* kill all submitted tx-urbs */
usb_kill_anchored_urbs(&tx->submitted);
/** * tx_urb_complete - completes the execution of an URB * @urb: a URB * * This function is called if the URB has been transferred to a device or an * error has happened.
*/ staticvoid tx_urb_complete(struct urb *urb)
{ int r; struct sk_buff *skb; struct ieee80211_tx_info *info; struct zd_usb *usb; struct zd_usb_tx *tx;
skb = (struct sk_buff *)urb->context;
info = IEEE80211_SKB_CB(skb); /* * grab 'usb' pointer before handing off the skb (since * it might be freed by zd_mac_tx_to_dev or mac80211)
*/
usb = &zd_hw_mac(info->rate_driver_data[0])->chip.usb;
tx = &usb->tx;
switch (urb->status) { case 0: break; case -ESHUTDOWN: case -EINVAL: case -ENODEV: case -ENOENT: case -ECONNRESET: case -EPIPE:
dev_dbg_f(urb_dev(urb), "urb %p error %d\n", urb, urb->status); break; default:
dev_dbg_f(urb_dev(urb), "urb %p error %d\n", urb, urb->status); goto resubmit;
}
free_urb:
skb_unlink(skb, &usb->tx.submitted_skbs);
zd_mac_tx_to_dev(skb, urb->status);
usb_free_urb(urb);
tx_dec_submitted_urbs(usb); return;
resubmit:
usb_anchor_urb(urb, &tx->submitted);
r = usb_submit_urb(urb, GFP_ATOMIC); if (r) {
usb_unanchor_urb(urb);
dev_dbg_f(urb_dev(urb), "error resubmit urb %p %d\n", urb, r); goto free_urb;
}
}
/** * zd_usb_tx: initiates transfer of a frame of the device * * @usb: the zd1211rw-private USB structure * @skb: a &struct sk_buff pointer * * This function transmits a frame to the device. It doesn't wait for * completion. The frame must contain the control set and have all the * control set information available. * * The function returns 0 if the transfer has been successfully initiated.
*/ int zd_usb_tx(struct zd_usb *usb, struct sk_buff *skb)
{ int r; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct usb_device *udev = zd_usb_to_usbdev(usb); struct urb *urb; struct zd_usb_tx *tx = &usb->tx;
if (!atomic_read(&tx->enabled)) {
r = -ENOENT; goto out;
}
urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) {
r = -ENOMEM; goto out;
}
if (id->driver_info & DEVICE_INSTALLER) return eject_installer(intf);
switch (udev->speed) { case USB_SPEED_LOW: case USB_SPEED_FULL: case USB_SPEED_HIGH: break; default:
dev_dbg_f(&intf->dev, "Unknown USB speed\n");
r = -ENODEV; goto error;
}
r = usb_reset_device(udev); if (r) {
dev_err(&intf->dev, "couldn't reset usb device. Error number %d\n", r); goto error;
}
hw = zd_mac_alloc_hw(intf); if (hw == NULL) {
r = -ENOMEM; goto error;
}
usb = &zd_hw_mac(hw)->chip.usb;
usb->is_zd1211b = (id->driver_info == DEVICE_ZD1211B) != 0;
r = zd_mac_preinit_hw(hw); if (r) {
dev_dbg_f(&intf->dev, "couldn't initialize mac. Error number %d\n", r); goto error;
}
r = ieee80211_register_hw(hw); if (r) {
dev_dbg_f(&intf->dev, "couldn't register device. Error number %d\n", r); goto error;
}
/* Either something really bad happened, or we're just dealing with
* a DEVICE_INSTALLER. */ if (hw == NULL) return;
mac = zd_hw_mac(hw);
usb = &mac->chip.usb;
dev_dbg_f(zd_usb_dev(usb), "\n");
ieee80211_unregister_hw(hw);
/* Just in case something has gone wrong! */
zd_usb_disable_tx(usb);
zd_usb_disable_rx(usb);
zd_usb_disable_int(usb);
/* If the disconnect has been caused by a removal of the * driver module, the reset allows reloading of the driver. If the * reset will not be executed here, the upload of the firmware in the * probe function caused by the reloading of the driver will fail.
*/
usb_reset_device(interface_to_usbdev(intf));
staticint zd_ep_regs_out_msg(struct usb_device *udev, void *data, int len, int *actual_length, int timeout)
{ /* In USB 2.0 mode EP_REGS_OUT endpoint is interrupt type. However in * USB 1.1 mode endpoint is bulk. Select correct type URB by endpoint * descriptor.
*/ struct usb_host_endpoint *ep; unsignedint pipe;
pipe = usb_sndintpipe(udev, EP_REGS_OUT);
ep = usb_pipe_endpoint(udev, pipe); if (!ep) return -EINVAL;
/* The created block size seems to be larger than expected. * However results appear to be correct.
*/ if (rr->length < struct_size(regs, regs, count)) {
dev_dbg_f(zd_usb_dev(usb), "error: actual length %d less than expected %zu\n",
rr->length, struct_size(regs, regs, count)); returnfalse;
}
if (rr->length > sizeof(rr->buffer)) {
dev_dbg_f(zd_usb_dev(usb), "error: actual length %d exceeds buffer size %zu\n",
rr->length, sizeof(rr->buffer)); returnfalse;
}
for (i = 0; i < count; i++) { struct reg_data *rd = ®s->regs[i]; if (rd->addr != req->addr[i]) {
dev_dbg_f(zd_usb_dev(usb), "rd[%d] addr %#06hx expected %#06hx\n", i,
le16_to_cpu(rd->addr),
le16_to_cpu(req->addr[i])); returnfalse;
}
}
/* Submit last iowrite16v URB */
r = zd_submit_waiting_urb(usb, true); if (r) {
dev_dbg_f(zd_usb_dev(usb), "error in zd_submit_waiting_usb(). " "Error number %d\n", r);
if (count == 0) return 0; if (count > USB_MAX_IOWRITE16_COUNT) {
dev_dbg_f(zd_usb_dev(usb), "error: count %u exceeds possible max %u\n",
count, USB_MAX_IOWRITE16_COUNT); return -EINVAL;
}
udev = zd_usb_to_usbdev(usb);
ep = usb_pipe_endpoint(udev, usb_sndintpipe(udev, EP_REGS_OUT)); if (!ep) return -ENOENT;
urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) return -ENOMEM;
req_len = struct_size(req, reg_writes, count);
req = kmalloc(req_len, GFP_KERNEL); if (!req) {
r = -ENOMEM; goto error;
}
req->id = cpu_to_le16(USB_REQ_WRITE_REGS); for (i = 0; i < count; i++) { struct reg_data *rw = &req->reg_writes[i];
rw->addr = cpu_to_le16((u16)ioreqs[i].addr);
rw->value = cpu_to_le16(ioreqs[i].value);
}
/* In USB 2.0 mode endpoint is interrupt type. However in USB 1.1 mode * endpoint is bulk. Select correct type URB by endpoint descriptor.
*/ if (usb_endpoint_xfer_int(&ep->desc))
usb_fill_int_urb(urb, udev, usb_sndintpipe(udev, EP_REGS_OUT),
req, req_len, iowrite16v_urb_complete, usb,
ep->desc.bInterval); else
usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, EP_REGS_OUT),
req, req_len, iowrite16v_urb_complete, usb);
urb->transfer_flags |= URB_FREE_BUFFER;
/* Submit previous URB */
r = zd_submit_waiting_urb(usb, false); if (r) {
dev_dbg_f(zd_usb_dev(usb), "error in zd_submit_waiting_usb(). " "Error number %d\n", r); goto error;
}
/* Delay submit so that URB_NO_INTERRUPT flag can be set for all URBs * of currect batch except for very last.
*/
usb->urb_async_waiting = urb; return 0;
error:
usb_free_urb(urb); return r;
}
int zd_usb_iowrite16v(struct zd_usb *usb, conststruct zd_ioreq16 *ioreqs, unsignedint count)
{ int r;
zd_usb_iowrite16v_async_start(usb);
r = zd_usb_iowrite16v_async(usb, ioreqs, count); if (r) {
zd_usb_iowrite16v_async_end(usb, 0); return r;
} return zd_usb_iowrite16v_async_end(usb, 50 /* ms */);
}
int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits)
{ int r; struct usb_device *udev; struct usb_req_rfwrite *req = NULL; int i, req_len, actual_req_len;
u16 bit_value_template;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.