void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r) { le32_to_cpus(&r->base); le16_to_cpus(&r->entry_size); le16_to_cpus(&r->size); le32_to_cpus(&r->tail); le32_to_cpus(&r->head); }
void mptsas_fix_ioc_init_endianness(MPIMsgIOCInit *req) { le32_to_cpus(&req->MsgContext); le16_to_cpus(&req->ReplyFrameSize); le32_to_cpus(&req->HostMfaHighAddr); le32_to_cpus(&req->SenseBufferHighAddr); le32_to_cpus(&req->ReplyFifoHostSignalingAddr); mptsas_fix_sgentry_endianness(&req->HostPageBufferSGE); le16_to_cpus(&req->MsgVersion); le16_to_cpus(&req->HeaderVersion); }
static int prism2_ioctl_giwencode(struct net_device *dev, struct iw_request_info *info, struct iw_point *erq, char *key) { struct hostap_interface *iface; local_info_t *local; int i, len; u16 val; struct lib80211_crypt_data *crypt; iface = netdev_priv(dev); local = iface->local; i = erq->flags & IW_ENCODE_INDEX; if (i < 1 || i > 4) i = local->crypt_info.tx_keyidx; else i--; if (i < 0 || i >= WEP_KEYS) return -EINVAL; crypt = local->crypt_info.crypt[i]; erq->flags = i + 1; if (crypt == NULL || crypt->ops == NULL) { erq->length = 0; erq->flags |= IW_ENCODE_DISABLED; return 0; } if (strcmp(crypt->ops->name, "WEP") != 0) { /* only WEP is supported with wireless extensions, so just * report that encryption is used */ erq->length = 0; erq->flags |= IW_ENCODE_ENABLED; return 0; } /* Reads from HFA384X_RID_CNFDEFAULTKEY* return bogus values, so show * the keys from driver buffer */ len = crypt->ops->get_key(key, WEP_KEY_LEN, NULL, crypt->priv); erq->length = (len >= 0 ? len : 0); if (local->func->get_rid(dev, HFA384X_RID_CNFWEPFLAGS, &val, 2, 1) < 0) { printk("CNFWEPFLAGS reading failed\n"); return -EOPNOTSUPP; } le16_to_cpus(&val); if (val & HFA384X_WEPFLAGS_PRIVACYINVOKED) erq->flags |= IW_ENCODE_ENABLED; else erq->flags |= IW_ENCODE_DISABLED; if (val & HFA384X_WEPFLAGS_EXCLUDEUNENCRYPTED) erq->flags |= IW_ENCODE_RESTRICTED; else erq->flags |= IW_ENCODE_OPEN; return 0; }
unsigned char *r8712_get_wpa_ie(unsigned char *pie, int *wpa_ie_len, int limit) { int len; u16 val16; unsigned char wpa_oui_type[] = {0x00, 0x50, 0xf2, 0x01}; u8 *pbuf = pie; while (1) { pbuf = r8712_get_ie(pbuf, _WPA_IE_ID_, &len, limit); if (pbuf) { /*check if oui matches...*/ if (memcmp((pbuf + 2), wpa_oui_type, sizeof(wpa_oui_type))) goto check_next_ie; /*check version...*/ memcpy((u8 *)&val16, (pbuf + 6), sizeof(val16)); le16_to_cpus(&val16); if (val16 != 0x0001) goto check_next_ie; *wpa_ie_len = *(pbuf + 1); return pbuf; } *wpa_ie_len = 0; return NULL; check_next_ie: limit = limit - (pbuf - pie) - 2 - len; if (limit <= 0) break; pbuf += (2 + len); } *wpa_ie_len = 0; return NULL; }
void mptsas_fix_config_endianness(MPIMsgConfig *req) { le16_to_cpus(&req->ExtPageLength); le32_to_cpus(&req->MsgContext); le32_to_cpus(&req->PageAddress); mptsas_fix_sgentry_endianness(&req->PageBufferSGE); }
static int e1000_set_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom, uint8_t *bytes) { struct e1000_adapter *adapter = netdev->priv; struct e1000_hw *hw = &adapter->hw; uint16_t *eeprom_buff; void *ptr; int max_len, first_word, last_word, ret_val = 0; uint16_t i; if(eeprom->len == 0) return -EOPNOTSUPP; if(eeprom->magic != (hw->vendor_id | (hw->device_id << 16))) return -EFAULT; max_len = hw->eeprom.word_size * 2; first_word = eeprom->offset >> 1; last_word = (eeprom->offset + eeprom->len - 1) >> 1; eeprom_buff = kmalloc(max_len, GFP_KERNEL); if(!eeprom_buff) return -ENOMEM; ptr = (void *)eeprom_buff; if(eeprom->offset & 1) { /* need read/modify/write of first changed EEPROM word */ /* only the second byte of the word is being modified */ ret_val = e1000_read_eeprom(hw, first_word, 1, &eeprom_buff[0]); ptr++; } if(((eeprom->offset + eeprom->len) & 1) && (ret_val == 0)) { /* need read/modify/write of last changed EEPROM word */ /* only the first byte of the word is being modified */ ret_val = e1000_read_eeprom(hw, last_word, 1, &eeprom_buff[last_word - first_word]); } /* Device's eeprom is always little-endian, word addressable */ for (i = 0; i < last_word - first_word + 1; i++) le16_to_cpus(&eeprom_buff[i]); memcpy(ptr, bytes, eeprom->len); for (i = 0; i < last_word - first_word + 1; i++) eeprom_buff[i] = cpu_to_le16(eeprom_buff[i]); ret_val = e1000_write_eeprom(hw, first_word, last_word - first_word + 1, eeprom_buff); /* Update the checksum over the first part of the EEPROM if needed */ if((ret_val == 0) && first_word <= EEPROM_CHECKSUM_REG) e1000_update_eeprom_checksum(hw); kfree(eeprom_buff); return ret_val; }
/* All VHDX structures on disk are little endian */ static void vhdx_header_le_import(VHDXHeader *h) { assert(h != NULL); le32_to_cpus(&h->signature); le32_to_cpus(&h->checksum); le64_to_cpus(&h->sequence_number); leguid_to_cpus(&h->file_write_guid); leguid_to_cpus(&h->data_write_guid); leguid_to_cpus(&h->log_guid); le16_to_cpus(&h->log_version); le16_to_cpus(&h->version); le32_to_cpus(&h->log_length); le64_to_cpus(&h->log_offset); }
static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum, int asnum, struct usb_host_interface *ifp, int num_ep, unsigned char *buffer, int size) { unsigned char *buffer0 = buffer; struct usb_endpoint_descriptor *d; struct usb_host_endpoint *endpoint; int n, i; d = (struct usb_endpoint_descriptor *) buffer; buffer += d->bLength; size -= d->bLength; if (d->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE) n = USB_DT_ENDPOINT_AUDIO_SIZE; else if (d->bLength >= USB_DT_ENDPOINT_SIZE) n = USB_DT_ENDPOINT_SIZE; else { dev_warn(ddev, "config %d interface %d altsetting %d has an " "invalid endpoint descriptor of length %d, skipping\n", cfgno, inum, asnum, d->bLength); goto skip_to_next_endpoint_or_interface_descriptor; } i = d->bEndpointAddress & ~USB_ENDPOINT_DIR_MASK; if (i >= 16 || i == 0) { dev_warn(ddev, "config %d interface %d altsetting %d has an " "invalid endpoint with address 0x%X, skipping\n", cfgno, inum, asnum, d->bEndpointAddress); goto skip_to_next_endpoint_or_interface_descriptor; } /* Only store as many endpoints as we have room for */ if (ifp->desc.bNumEndpoints >= num_ep) goto skip_to_next_endpoint_or_interface_descriptor; endpoint = &ifp->endpoint[ifp->desc.bNumEndpoints]; ++ifp->desc.bNumEndpoints; memcpy(&endpoint->desc, d, n); le16_to_cpus(&endpoint->desc.wMaxPacketSize); /* Skip over any Class Specific or Vendor Specific descriptors; * find the next endpoint or interface descriptor */ endpoint->extra = buffer; i = find_next_descriptor(buffer, size, USB_DT_ENDPOINT, USB_DT_INTERFACE, &n); endpoint->extralen = i; if (n > 0) dev_dbg(ddev, "skipped %d descriptor%s after %s\n", n, plural(n), "endpoint"); return buffer - buffer0 + i; skip_to_next_endpoint_or_interface_descriptor: i = find_next_descriptor(buffer, size, USB_DT_ENDPOINT, USB_DT_INTERFACE, NULL); return buffer - buffer0 + i; }
static int aqc111_read16_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, u16 *data) { int ret = 0; ret = aqc111_read_cmd(dev, cmd, value, index, sizeof(*data), data); le16_to_cpus(data); return ret; }
static int e1000_get_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom, u8 *bytes) { struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; u16 *eeprom_buff; int first_word; int last_word; int ret_val = 0; u16 i; if (eeprom->len == 0) return -EINVAL; eeprom->magic = adapter->pdev->vendor | (adapter->pdev->device << 16); first_word = eeprom->offset >> 1; last_word = (eeprom->offset + eeprom->len - 1) >> 1; eeprom_buff = kmalloc(sizeof(u16) * (last_word - first_word + 1), GFP_KERNEL); if (!eeprom_buff) return -ENOMEM; if (hw->nvm.type == e1000_nvm_eeprom_spi) { ret_val = e1000_read_nvm(hw, first_word, last_word - first_word + 1, eeprom_buff); } else { for (i = 0; i < last_word - first_word + 1; i++) { ret_val = e1000_read_nvm(hw, first_word + i, 1, &eeprom_buff[i]); if (ret_val) break; } } if (ret_val) { /* a read error occurred, throw away the result */ memset(eeprom_buff, 0xff, sizeof(u16) * (last_word - first_word + 1)); } else { /* Device's eeprom is always little-endian, word addressable */ for (i = 0; i < last_word - first_word + 1; i++) le16_to_cpus(&eeprom_buff[i]); } memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len); kfree(eeprom_buff); return ret_val; }
/** * usb_get_device_descriptor - (re)reads the device descriptor * @dev: the device whose device descriptor is being updated * @size: how much of the descriptor to read * Context: !in_interrupt () * * Updates the copy of the device descriptor stored in the device structure, * which dedicates space for this purpose. Note that several fields are * converted to the host CPU's byte order: the USB version (bcdUSB), and * vendors product and version fields (idVendor, idProduct, and bcdDevice). * That lets device drivers compare against non-byteswapped constants. * * Not exported, only for use by the core. If drivers really want to read * the device descriptor directly, they can call usb_get_descriptor() with * type = USB_DT_DEVICE and index = 0. * * This call is synchronous, and may not be used in an interrupt context. * * Returns the number of bytes received on success, or else the status code * returned by the underlying usb_control_msg() call. */ int usb_get_device_descriptor(struct usb_device *dev, unsigned int size) { struct usb_device_descriptor *desc; int ret; if (size > sizeof(*desc)) return -EINVAL; desc = kmalloc(sizeof(*desc), GFP_NOIO); if (!desc) return -ENOMEM; ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, size); if (ret >= 0) { le16_to_cpus(&desc->bcdUSB); le16_to_cpus(&desc->idVendor); le16_to_cpus(&desc->idProduct); le16_to_cpus(&desc->bcdDevice); memcpy(&dev->descriptor, desc, size); } msleep(1); kfree(desc); return ret; }
static int nc_vendor_read(struct usbnet *dev, u8 req, u8 regnum, u16 *retval_ptr) { int status = usbnet_read_cmd(dev, req, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, regnum, retval_ptr, sizeof *retval_ptr); if (status > 0) status = 0; if (!status) le16_to_cpus(retval_ptr); return status; }
static int nc_vendor_read(struct usbnet *dev, u8 req, u8 regnum, u16 *retval_ptr) { int status = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, regnum, retval_ptr, sizeof *retval_ptr, USB_CTRL_GET_TIMEOUT); if (status > 0) status = 0; if (!status) le16_to_cpus(retval_ptr); return status; }
void IntelMausi::intelEEPROMChecks(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; int ret_val; u16 buf = 0; if (hw->mac.type != e1000_82573) return; ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &buf); le16_to_cpus(&buf); if (!ret_val && (!(buf & (1 << 0)))) { /* Deep Smart Power Down (DSPD) */ IOLog("Ethernet [IntelMausi]: Warning: detected DSPD enabled in EEPROM.\n"); } }
static int e1000_get_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom, uint8_t *bytes) { struct e1000_adapter *adapter = netdev->priv; struct e1000_hw *hw = &adapter->hw; uint16_t *eeprom_buff; int first_word, last_word; int ret_val = 0; uint16_t i; if(eeprom->len == 0) return -EINVAL; eeprom->magic = hw->vendor_id | (hw->device_id << 16); first_word = eeprom->offset >> 1; last_word = (eeprom->offset + eeprom->len - 1) >> 1; eeprom_buff = kmalloc(sizeof(uint16_t) * (last_word - first_word + 1), GFP_KERNEL); if(!eeprom_buff) return -ENOMEM; if(hw->eeprom.type == e1000_eeprom_spi) ret_val = e1000_read_eeprom(hw, first_word, last_word - first_word + 1, eeprom_buff); else { for (i = 0; i < last_word - first_word + 1; i++) if((ret_val = e1000_read_eeprom(hw, first_word + i, 1, &eeprom_buff[i]))) break; } /* Device's eeprom is always little-endian, word addressable */ for (i = 0; i < last_word - first_word + 1; i++) le16_to_cpus(&eeprom_buff[i]); memcpy(bytes, (uint8_t *)eeprom_buff + (eeprom->offset & 1), eeprom->len); kfree(eeprom_buff); return ret_val; }
/* * The request on endpoint 0 has completed. * Call the user provided completion routine and try * to send the next request. */ static void usb_ctrl_complete(struct urb *urb) { struct st5481_adapter *adapter = urb->context; struct st5481_ctrl *ctrl = &adapter->ctrl; struct ctrl_msg *ctrl_msg; if (unlikely(urb->status < 0)) { switch (urb->status) { case -ENOENT: case -ESHUTDOWN: case -ECONNRESET: DBG(1,"urb killed status %d", urb->status); return; // Give up default: WARNING("urb status %d",urb->status); break; } } ctrl_msg = (struct ctrl_msg *)urb->setup_packet; if (ctrl_msg->dr.bRequest == USB_REQ_CLEAR_FEATURE) { /* Special case handling for pipe reset */ le16_to_cpus(&ctrl_msg->dr.wIndex); /* toggle is reset on clear */ usb_settoggle(adapter->usb_dev, ctrl_msg->dr.wIndex & ~USB_DIR_IN, (ctrl_msg->dr.wIndex & USB_DIR_IN) == 0, 0); } if (ctrl_msg->complete) ctrl_msg->complete(ctrl_msg->context); clear_bit(0, &ctrl->busy); // Try to send next control message usb_next_ctrl_msg(urb, adapter); return; }
/* * The request on endpoint 0 has completed. * Call the user provided completion routine and try * to send the next request. */ static void usb_ctrl_complete(struct urb *urb) { struct st5481_adapter *adapter = urb->context; struct st5481_ctrl *ctrl = &adapter->ctrl; struct ctrl_msg *ctrl_msg; if (urb->status < 0) { if (urb->status != -ENOENT) { WARN("urb status %d",urb->status); } else { DBG(1,"urb killed"); return; // Give up } } ctrl_msg = (struct ctrl_msg *)urb->setup_packet; if (ctrl_msg->dr.bRequest == USB_REQ_CLEAR_FEATURE) { /* Special case handling for pipe reset */ le16_to_cpus(&ctrl_msg->dr.wIndex); usb_endpoint_running(adapter->usb_dev, ctrl_msg->dr.wIndex & ~USB_DIR_IN, (ctrl_msg->dr.wIndex & USB_DIR_IN) == 0); /* toggle is reset on clear */ usb_settoggle(adapter->usb_dev, ctrl_msg->dr.wIndex & ~USB_DIR_IN, (ctrl_msg->dr.wIndex & USB_DIR_IN) == 0, 0); } if (ctrl_msg->complete) ctrl_msg->complete(ctrl_msg->context); clear_bit(0, &ctrl->busy); // Try to send next control message usb_next_ctrl_msg(urb, adapter); return; }
static int ax88179_read_cmd_nopm(struct usbnet *dev, u8 cmd, u16 value, u16 index, u16 size, void *data, int eflag) { int ret; if (eflag && (2 == size)) { u16 buf; ret = __ax88179_read_cmd(dev, cmd, value, index, size, &buf, 1); le16_to_cpus(&buf); *((u16 *)data) = buf; } else if (eflag && (4 == size)) { u32 buf; ret = __ax88179_read_cmd(dev, cmd, value, index, size, &buf, 1); le32_to_cpus(&buf); *((u32 *)data) = buf; } else { ret = __ax88179_read_cmd(dev, cmd, value, index, size, data, 1); } return ret; }
static int ixgbe_get_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom, u8 *bytes) { struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_hw *hw = &adapter->hw; u16 *eeprom_buff; int first_word, last_word, eeprom_len; int ret_val = 0; u16 i; if (eeprom->len == 0) return -EINVAL; eeprom->magic = hw->vendor_id | (hw->device_id << 16); first_word = eeprom->offset >> 1; last_word = (eeprom->offset + eeprom->len - 1) >> 1; eeprom_len = last_word - first_word + 1; eeprom_buff = kmalloc(sizeof(u16) * eeprom_len, GFP_KERNEL); if (!eeprom_buff) return -ENOMEM; for (i = 0; i < eeprom_len; i++) { if ((ret_val = hw->eeprom.ops.read(hw, first_word + i, &eeprom_buff[i]))) break; } /* Device's eeprom is always little-endian, word addressable */ for (i = 0; i < eeprom_len; i++) le16_to_cpus(&eeprom_buff[i]); memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len); kfree(eeprom_buff); return ret_val; }
static int prism2_ioctl_giwfreq(struct net_device *dev, struct iw_request_info *info, struct iw_freq *freq, char *extra) { struct hostap_interface *iface; local_info_t *local; u16 val; iface = netdev_priv(dev); local = iface->local; if (local->func->get_rid(dev, HFA384X_RID_CURRENTCHANNEL, &val, 2, 1) < 0) return -EINVAL; le16_to_cpus(&val); if (val < 1 || val > FREQ_COUNT) return -EINVAL; freq->m = freq_list[val - 1] * 100000; freq->e = 1; return 0; }
static void usb_ctrl_complete(struct urb *urb) { struct st5481_adapter *adapter = urb->context; struct st5481_ctrl *ctrl = &adapter->ctrl; struct ctrl_msg *ctrl_msg; if (unlikely(urb->status < 0)) { switch (urb->status) { case -ENOENT: case -ESHUTDOWN: case -ECONNRESET: DBG(1, "urb killed status %d", urb->status); return; default: WARNING("urb status %d", urb->status); break; } } ctrl_msg = (struct ctrl_msg *)urb->setup_packet; if (ctrl_msg->dr.bRequest == USB_REQ_CLEAR_FEATURE) { le16_to_cpus(&ctrl_msg->dr.wIndex); usb_reset_endpoint(adapter->usb_dev, ctrl_msg->dr.wIndex); } if (ctrl_msg->complete) ctrl_msg->complete(ctrl_msg->context); clear_bit(0, &ctrl->busy); usb_next_ctrl_msg(urb, adapter); return; }
static int usb_hub_configure(struct usb_hub *hub, struct usb_endpoint_descriptor *endpoint) { struct usb_device *dev = hub->dev; struct usb_hub_status hubstatus; char portstr[USB_MAXCHILDREN + 1]; unsigned int pipe; int i, maxp, ret; DBG_HOST_HUB("### >>> Enter hub.c file --> usb_hub_configure function \n"); hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL); if (!hub->descriptor) { err("Unable to kmalloc %Zd bytes for hub descriptor", sizeof(*hub->descriptor)); return -1; } /* Request the entire hub descriptor. */ ret = usb_get_hub_descriptor(dev, hub->descriptor, sizeof(*hub->descriptor)); /* <hub->descriptor> is large enough for a hub with 127 ports; * the hub can/will return fewer bytes here. */ if (ret < 0) { err("Unable to get hub descriptor (err = %d)", ret); kfree(hub->descriptor); return -1; } dev->maxchild = hub->descriptor->bNbrPorts; info("%d port%s detected", hub->descriptor->bNbrPorts, (hub->descriptor->bNbrPorts == 1) ? "" : "s"); le16_to_cpus(&hub->descriptor->wHubCharacteristics); if (hub->descriptor->wHubCharacteristics & HUB_CHAR_COMPOUND) dbg("part of a compound device"); else dbg("standalone hub"); switch (hub->descriptor->wHubCharacteristics & HUB_CHAR_LPSM) { case 0x00: dbg("ganged power switching"); break; case 0x01: dbg("individual port power switching"); break; case 0x02: case 0x03: dbg("unknown reserved power switching mode"); break; } switch (hub->descriptor->wHubCharacteristics & HUB_CHAR_OCPM) { case 0x00: dbg("global over-current protection"); break; case 0x08: dbg("individual port over-current protection"); break; case 0x10: case 0x18: dbg("no over-current protection"); break; } switch (dev->descriptor.bDeviceProtocol) { case 0: break; case 1: dbg("Single TT"); hub->tt.hub = dev; break; case 2: dbg("TT per port"); hub->tt.hub = dev; hub->tt.multi = 1; break; default: dbg("Unrecognized hub protocol %d", dev->descriptor.bDeviceProtocol); break; } switch (hub->descriptor->wHubCharacteristics & HUB_CHAR_TTTT) { case 0x00: if (dev->descriptor.bDeviceProtocol != 0) dbg("TT requires at most 8 FS bit times"); break; case 0x20: dbg("TT requires at most 16 FS bit times"); break; case 0x40: dbg("TT requires at most 24 FS bit times"); break; case 0x60: dbg("TT requires at most 32 FS bit times"); break; } dbg("Port indicators are %s supported", (hub->descriptor->wHubCharacteristics & HUB_CHAR_PORTIND) ? "" : "not"); dbg("power on to power good time: %dms", hub->descriptor->bPwrOn2PwrGood * 2); dbg("hub controller current requirement: %dmA", hub->descriptor->bHubContrCurrent); for (i = 0; i < dev->maxchild; i++) portstr[i] = hub->descriptor->DeviceRemovable[((i + 1) / 8)] & (1 << ((i + 1) % 8)) ? 'F' : 'R'; portstr[dev->maxchild] = 0; dbg("port removable status: %s", portstr); ret = usb_get_hub_status(dev, &hubstatus); if (ret < 0) { err("Unable to get hub status (err = %d)", ret); kfree(hub->descriptor); return -1; } le16_to_cpus(&hubstatus.wHubStatus); dbg("local power source is %s", (hubstatus.wHubStatus & HUB_STATUS_LOCAL_POWER) ? "lost (inactive)" : "good"); dbg("%sover-current condition exists", (hubstatus.wHubStatus & HUB_STATUS_OVERCURRENT) ? "" : "no "); /* Start the interrupt endpoint */ pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); if (maxp > sizeof(hub->buffer)) maxp = sizeof(hub->buffer); hub->urb = usb_alloc_urb(0); if (!hub->urb) { err("couldn't allocate interrupt urb"); kfree(hub->descriptor); return -1; } FILL_INT_URB(hub->urb, dev, pipe, hub->buffer, maxp, hub_irq, hub, endpoint->bInterval); ret = usb_submit_urb(hub->urb); if (ret) { err("usb_submit_urb failed (%d)", ret); kfree(hub->descriptor); return -1; } /* Wake up khubd */ wake_up(&khubd_wait); usb_hub_power_on(hub); return 0; }
/* * WARNING - If a driver calls usb_reset_device, you should simulate a * disconnect() and probe() for other interfaces you doesn't claim. This * is left up to the driver writer right now. This insures other drivers * have a chance to re-setup their interface. * * Take a look at proc_resetdevice in devio.c for some sample code to * do this. */ int usb_reset_device(struct usb_device *dev) { struct usb_device *parent = dev->parent; struct usb_device_descriptor descriptor; int i, ret, port = -1; DBG_HOST_HUB("### >>> Enter hub.c file --> usb_reset_device function \n"); if (!parent) { err("attempting to reset root hub!"); return -EINVAL; } for (i = 0; i < parent->maxchild; i++) if (parent->children[i] == dev) { port = i; break; } if (port < 0) return -ENOENT; down(&usb_address0_sem); /* Send a reset to the device */ if (usb_hub_port_reset(parent, port, dev, HUB_SHORT_RESET_TIME)) { usb_hub_port_disable(parent, port); up(&usb_address0_sem); return(-ENODEV); } /* Reprogram the Address */ ret = usb_set_address(dev); if (ret < 0) { err("USB device not accepting new address (error=%d)", ret); usb_hub_port_disable(parent, port); up(&usb_address0_sem); return ret; } /* Let the SET_ADDRESS settle */ wait_ms(10); up(&usb_address0_sem); /* * Now we fetch the configuration descriptors for the device and * see if anything has changed. If it has, we dump the current * parsed descriptors and reparse from scratch. Then we leave * the device alone for the caller to finish setting up. * * If nothing changed, we reprogram the configuration and then * the alternate settings. */ ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &descriptor, sizeof(descriptor)); if (ret < 0) return ret; le16_to_cpus(&descriptor.bcdUSB); le16_to_cpus(&descriptor.idVendor); le16_to_cpus(&descriptor.idProduct); le16_to_cpus(&descriptor.bcdDevice); if (memcmp(&dev->descriptor, &descriptor, sizeof(descriptor))) { usb_destroy_configuration(dev); ret = usb_get_device_descriptor(dev); if (ret < sizeof(dev->descriptor)) { if (ret < 0) err("unable to get device descriptor (error=%d)", ret); else err("USB device descriptor short read (expected %Zi, got %i)", sizeof(dev->descriptor), ret); clear_bit(dev->devnum, &dev->bus->devmap.devicemap); dev->devnum = -1; return -EIO; } ret = usb_get_configuration(dev); if (ret < 0) { err("unable to get configuration (error=%d)", ret); usb_destroy_configuration(dev); clear_bit(dev->devnum, &dev->bus->devmap.devicemap); dev->devnum = -1; return 1; } dev->actconfig = dev->config; usb_set_maxpacket(dev); return 1; } ret = usb_set_configuration(dev, dev->actconfig->bConfigurationValue); if (ret < 0) { err("failed to set active configuration (error=%d)", ret); return ret; } for (i = 0; i < dev->actconfig->bNumInterfaces; i++) { struct usb_interface *intf = &dev->actconfig->interface[i]; struct usb_interface_descriptor *as = &intf->altsetting[intf->act_altsetting]; ret = usb_set_interface(dev, as->bInterfaceNumber, as->bAlternateSetting); if (ret < 0) { err("failed to set active alternate setting for interface %d (error=%d)", i, ret); return ret; } } return 0; }
int hostap_set_encryption(local_info_t *local) { u16 val; int i, keylen, len, idx; char keybuf[WEP_KEY_LEN + 1]; enum { NONE, WEP, OTHER } encrypt_type; if (local->crypt == NULL || local->crypt->ops == NULL) encrypt_type = NONE; else if (strcmp(local->crypt->ops->name, "WEP") == 0) encrypt_type = WEP; else encrypt_type = OTHER; if (local->func->get_rid(local->dev, HFA384X_RID_CNFWEPFLAGS, &val, 2, 1) < 0) { printk(KERN_DEBUG "Could not read current WEP flags.\n"); goto fail; } le16_to_cpus(&val); if (encrypt_type != NONE) val |= HFA384X_WEPFLAGS_PRIVACYINVOKED; else val &= ~HFA384X_WEPFLAGS_PRIVACYINVOKED; if (local->open_wep || encrypt_type == NONE || (local->ieee_802_1x && local->host_decrypt)) val &= ~HFA384X_WEPFLAGS_EXCLUDEUNENCRYPTED; else val |= HFA384X_WEPFLAGS_EXCLUDEUNENCRYPTED; if (encrypt_type != NONE && (encrypt_type == OTHER || local->host_encrypt)) val |= HFA384X_WEPFLAGS_HOSTENCRYPT; else val &= ~HFA384X_WEPFLAGS_HOSTENCRYPT; if (encrypt_type != NONE && (encrypt_type == OTHER || local->host_decrypt)) val |= HFA384X_WEPFLAGS_HOSTDECRYPT; else val &= ~HFA384X_WEPFLAGS_HOSTDECRYPT; if (hostap_set_word(local->dev, HFA384X_RID_CNFWEPFLAGS, val)) { printk(KERN_DEBUG "Could not write new WEP flags (0x%x)\n", val); goto fail; } if (encrypt_type != WEP) return 0; /* 104-bit support seems to require that all the keys are set to the * same keylen */ keylen = 6; /* first 5 octets */ idx = local->crypt->ops->get_key_idx(local->crypt->priv); len = local->crypt->ops->get_key(idx, keybuf, sizeof(keybuf), local->crypt->priv); if (idx >= 0 && idx < WEP_KEYS && len > 5) keylen = WEP_KEY_LEN + 1; /* first 13 octets */ for (i = 0; i < WEP_KEYS; i++) { memset(keybuf, 0, sizeof(keybuf)); (void) local->crypt->ops->get_key(i, keybuf, sizeof(keybuf), local->crypt->priv); if (local->func->set_rid(local->dev, HFA384X_RID_CNFDEFAULTKEY0 + i, keybuf, keylen)) { printk(KERN_DEBUG "Could not set key %d (len=%d)\n", i, keylen); goto fail; } } if (hostap_set_word(local->dev, HFA384X_RID_CNFWEPDEFAULTKEYID, idx)) { printk(KERN_DEBUG "Could not set default keyid %d\n", idx); goto fail; } return 0; fail: printk(KERN_DEBUG "%s: encryption setup failed\n", local->dev->name); return -1; }
static int visor_startup (struct usb_serial *serial) { int response; int i; unsigned char *transfer_buffer = kmalloc (256, GFP_KERNEL); if (!transfer_buffer) { err(__FUNCTION__ " - kmalloc(%d) failed.", 256); return -ENOMEM; } dbg(__FUNCTION__); dbg(__FUNCTION__ " - Set config to 1"); usb_set_configuration (serial->dev, 1); /* send a get connection info request */ response = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), VISOR_GET_CONNECTION_INFORMATION, 0xc2, 0x0000, 0x0000, transfer_buffer, 0x12, 300); if (response < 0) { err(__FUNCTION__ " - error getting connection information"); } else { struct visor_connection_info *connection_info = (struct visor_connection_info *)transfer_buffer; char *string; le16_to_cpus(&connection_info->num_ports); info("%s: Number of ports: %d", serial->type->name, connection_info->num_ports); for (i = 0; i < connection_info->num_ports; ++i) { switch (connection_info->connections[i].port_function_id) { case VISOR_FUNCTION_GENERIC: string = "Generic"; break; case VISOR_FUNCTION_DEBUGGER: string = "Debugger"; break; case VISOR_FUNCTION_HOTSYNC: string = "HotSync"; break; case VISOR_FUNCTION_CONSOLE: string = "Console"; break; case VISOR_FUNCTION_REMOTE_FILE_SYS: string = "Remote File System"; break; default: string = "unknown"; break; } info("%s: port %d, is for %s use and is bound to ttyUSB%d", serial->type->name, connection_info->connections[i].port, string, serial->minor + i); } } if ((serial->dev->descriptor.idVendor == PALM_VENDOR_ID) || (serial->dev->descriptor.idVendor == SONY_VENDOR_ID)) { /* Palm OS 4.0 Hack */ response = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), PALM_GET_SOME_UNKNOWN_INFORMATION, 0xc2, 0x0000, 0x0000, transfer_buffer, 0x14, 300); if (response < 0) { err(__FUNCTION__ " - error getting first unknown palm command"); } else { usb_serial_debug_data (__FILE__, __FUNCTION__, 0x14, transfer_buffer); } response = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), PALM_GET_SOME_UNKNOWN_INFORMATION, 0xc2, 0x0000, 0x0000, transfer_buffer, 0x14, 300); if (response < 0) { err(__FUNCTION__ " - error getting second unknown palm command"); } else { usb_serial_debug_data (__FILE__, __FUNCTION__, 0x14, transfer_buffer); } } /* ask for the number of bytes available, but ignore the response as it is broken */ response = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), VISOR_REQUEST_BYTES_AVAILABLE, 0xc2, 0x0000, 0x0005, transfer_buffer, 0x02, 300); if (response < 0) { err(__FUNCTION__ " - error getting bytes available request"); } kfree (transfer_buffer); /* continue on with initialization */ return 0; }
/* Set priv->firmware type, determine firmware properties * This function can be called before we have registerred with netdev, * so all errors go out with dev_* rather than printk * * If non-NULL stores a firmware description in fw_name. * If non-NULL stores a HW version in hw_ver * * These are output via generic cfg80211 ethtool support. */ int determine_fw_capabilities(struct orinoco_private *priv, char *fw_name, size_t fw_name_len, u32 *hw_ver) { struct device *dev = priv->dev; struct hermes *hw = &priv->hw; int err; struct comp_id nic_id, sta_id; unsigned int firmver; char tmp[SYMBOL_MAX_VER_LEN + 1] __attribute__((aligned(2))); /* Get the hardware version */ err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_NICID, &nic_id); if (err) { dev_err(dev, "Cannot read hardware identity: error %d\n", err); return err; } le16_to_cpus(&nic_id.id); le16_to_cpus(&nic_id.variant); le16_to_cpus(&nic_id.major); le16_to_cpus(&nic_id.minor); dev_info(dev, "Hardware identity %04x:%04x:%04x:%04x\n", nic_id.id, nic_id.variant, nic_id.major, nic_id.minor); if (hw_ver) *hw_ver = (((nic_id.id & 0xff) << 24) | ((nic_id.variant & 0xff) << 16) | ((nic_id.major & 0xff) << 8) | (nic_id.minor & 0xff)); priv->firmware_type = determine_firmware_type(&nic_id); /* Get the firmware version */ err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_STAID, &sta_id); if (err) { dev_err(dev, "Cannot read station identity: error %d\n", err); return err; } le16_to_cpus(&sta_id.id); le16_to_cpus(&sta_id.variant); le16_to_cpus(&sta_id.major); le16_to_cpus(&sta_id.minor); dev_info(dev, "Station identity %04x:%04x:%04x:%04x\n", sta_id.id, sta_id.variant, sta_id.major, sta_id.minor); switch (sta_id.id) { case 0x15: dev_err(dev, "Primary firmware is active\n"); return -ENODEV; case 0x14b: dev_err(dev, "Tertiary firmware is active\n"); return -ENODEV; case 0x1f: /* Intersil, Agere, Symbol Spectrum24 */ case 0x21: /* Symbol Spectrum24 Trilogy */ break; default: dev_notice(dev, "Unknown station ID, please report\n"); break; } /* Default capabilities */ priv->has_sensitivity = 1; priv->has_mwo = 0; priv->has_preamble = 0; priv->has_port3 = 1; priv->has_ibss = 1; priv->has_wep = 0; priv->has_big_wep = 0; priv->has_alt_txcntl = 0; priv->has_ext_scan = 0; priv->has_wpa = 0; priv->do_fw_download = 0; /* Determine capabilities from the firmware version */ switch (priv->firmware_type) { case FIRMWARE_TYPE_AGERE: /* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout, ELSA, Melco, HP, IBM, Dell 1150, Compaq 110/210 */ if (fw_name) snprintf(fw_name, fw_name_len, "Lucent/Agere %d.%02d", sta_id.major, sta_id.minor); firmver = ((unsigned long)sta_id.major << 16) | sta_id.minor; priv->has_ibss = (firmver >= 0x60006); priv->has_wep = (firmver >= 0x40020); priv->has_big_wep = 1; /* FIXME: this is wrong - how do we tell Gold cards from the others? */ priv->has_mwo = (firmver >= 0x60000); priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */ priv->ibss_port = 1; priv->has_hostscan = (firmver >= 0x8000a); priv->do_fw_download = 1; priv->broken_monitor = (firmver >= 0x80000); priv->has_alt_txcntl = (firmver >= 0x90000); /* All 9.x ? */ priv->has_ext_scan = (firmver >= 0x90000); /* All 9.x ? */ priv->has_wpa = (firmver >= 0x9002a); /* Tested with Agere firmware : * 1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II * Tested CableTron firmware : 4.32 => Anton */ break; case FIRMWARE_TYPE_SYMBOL: /* Symbol , 3Com AirConnect, Intel, Ericsson WLAN */ /* Intel MAC : 00:02:B3:* */ /* 3Com MAC : 00:50:DA:* */ memset(tmp, 0, sizeof(tmp)); /* Get the Symbol firmware version */ err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_SECONDARYVERSION_SYMBOL, SYMBOL_MAX_VER_LEN, NULL, &tmp); if (err) { dev_warn(dev, "Error %d reading Symbol firmware info. " "Wildly guessing capabilities...\n", err); firmver = 0; tmp[0] = '\0'; } else { /* The firmware revision is a string, the format is * something like : "V2.20-01". * Quick and dirty parsing... - Jean II */ firmver = ((tmp[1] - '0') << 16) | ((tmp[3] - '0') << 12) | ((tmp[4] - '0') << 8) | ((tmp[6] - '0') << 4) | (tmp[7] - '0'); tmp[SYMBOL_MAX_VER_LEN] = '\0'; } if (fw_name) snprintf(fw_name, fw_name_len, "Symbol %s", tmp); priv->has_ibss = (firmver >= 0x20000); priv->has_wep = (firmver >= 0x15012); priv->has_big_wep = (firmver >= 0x20000); priv->has_pm = (firmver >= 0x20000 && firmver < 0x22000) || (firmver >= 0x29000 && firmver < 0x30000) || firmver >= 0x31000; priv->has_preamble = (firmver >= 0x20000); priv->ibss_port = 4; /* Symbol firmware is found on various cards, but * there has been no attempt to check firmware * download on non-spectrum_cs based cards. * * Given that the Agere firmware download works * differently, we should avoid doing a firmware * download with the Symbol algorithm on non-spectrum * cards. * * For now we can identify a spectrum_cs based card * because it has a firmware reset function. */ priv->do_fw_download = (priv->stop_fw != NULL); priv->broken_disableport = (firmver == 0x25013) || (firmver >= 0x30000 && firmver <= 0x31000); priv->has_hostscan = (firmver >= 0x31001) || (firmver >= 0x29057 && firmver < 0x30000); /* Tested with Intel firmware : 0x20015 => Jean II */ /* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */ break; case FIRMWARE_TYPE_INTERSIL: /* D-Link, Linksys, Adtron, ZoomAir, and many others... * Samsung, Compaq 100/200 and Proxim are slightly * different and less well tested */ /* D-Link MAC : 00:40:05:* */ /* Addtron MAC : 00:90:D1:* */ if (fw_name) snprintf(fw_name, fw_name_len, "Intersil %d.%d.%d", sta_id.major, sta_id.minor, sta_id.variant); firmver = ((unsigned long)sta_id.major << 16) | ((unsigned long)sta_id.minor << 8) | sta_id.variant; priv->has_ibss = (firmver >= 0x000700); /* FIXME */ priv->has_big_wep = priv->has_wep = (firmver >= 0x000800); priv->has_pm = (firmver >= 0x000700); priv->has_hostscan = (firmver >= 0x010301); if (firmver >= 0x000800) priv->ibss_port = 0; else { dev_notice(dev, "Intersil firmware earlier than v0.8.x" " - several features not supported\n"); priv->ibss_port = 1; } break; } if (fw_name) dev_info(dev, "Firmware determined as %s\n", fw_name); #ifndef CONFIG_HERMES_PRISM if (priv->firmware_type == FIRMWARE_TYPE_INTERSIL) { dev_err(dev, "Support for Prism chipset is not enabled\n"); return -ENODEV; } #endif return 0; }
static void v9fs_uint16_read(P9Req *req, uint16_t *val) { v9fs_memread(req, val, 2); le16_to_cpus(val); }
static int visor_startup (struct usb_serial *serial) { int response; int i; unsigned char *transfer_buffer; dbg("%s", __FUNCTION__); dbg("%s - Set config to 1", __FUNCTION__); usb_set_configuration (serial->dev, 1); if ((serial->dev->descriptor.idVendor == HANDSPRING_VENDOR_ID) && (serial->dev->descriptor.idProduct == HANDSPRING_VISOR_ID)) { struct visor_connection_info *connection_info; char *string; int num_ports; transfer_buffer = kmalloc (sizeof (*connection_info), GFP_KERNEL); if (!transfer_buffer) { err("%s - kmalloc(%d) failed.", __FUNCTION__, sizeof (*connection_info)); return -ENOMEM; } /* send a get connection info request */ response = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), VISOR_GET_CONNECTION_INFORMATION, 0xc2, 0x0000, 0x0000, transfer_buffer, sizeof (*connection_info), 300); if (response < 0) { err("%s - error getting connection information", __FUNCTION__); goto exit; } connection_info = (struct visor_connection_info *)transfer_buffer; le16_to_cpus(&connection_info->num_ports); num_ports = connection_info->num_ports; /* handle devices that report invalid stuff here */ if (num_ports > 2) num_ports = 2; info("%s: Number of ports: %d", serial->type->name, connection_info->num_ports); for (i = 0; i < num_ports; ++i) { switch (connection_info->connections[i].port_function_id) { case VISOR_FUNCTION_GENERIC: string = "Generic"; break; case VISOR_FUNCTION_DEBUGGER: string = "Debugger"; break; case VISOR_FUNCTION_HOTSYNC: string = "HotSync"; break; case VISOR_FUNCTION_CONSOLE: string = "Console"; break; case VISOR_FUNCTION_REMOTE_FILE_SYS: string = "Remote File System"; break; default: string = "unknown"; break; } info("%s: port %d, is for %s use and is bound to ttyUSB%d", serial->type->name, connection_info->connections[i].port, string, serial->minor + i); } } else { struct palm_ext_connection_info *connection_info; transfer_buffer = kmalloc (sizeof (*connection_info), GFP_KERNEL); if (!transfer_buffer) { err("%s - kmalloc(%d) failed.", __FUNCTION__, sizeof (*connection_info)); return -ENOMEM; } response = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), PALM_GET_EXT_CONNECTION_INFORMATION, 0xc2, 0x0000, 0x0000, transfer_buffer, sizeof (*connection_info), 300); if (response < 0) { err("%s - error %d getting connection info", __FUNCTION__, response); } else { usb_serial_debug_data (__FILE__, __FUNCTION__, 0x14, transfer_buffer); } } /* Do our horrible Treo hack, if we should */ treo_attach(serial); /* ask for the number of bytes available, but ignore the response as it is broken */ response = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), VISOR_REQUEST_BYTES_AVAILABLE, 0xc2, 0x0000, 0x0005, transfer_buffer, 0x02, 300); if (response < 0) { err("%s - error getting bytes available request", __FUNCTION__); } exit: kfree (transfer_buffer); /* continue on with initialization */ return 0; }
static int e1000_set_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom, u8 *bytes) { struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; u16 *eeprom_buff; void *ptr; int max_len; int first_word; int last_word; int ret_val = 0; u16 i; if (eeprom->len == 0) return -EOPNOTSUPP; if (eeprom->magic != (adapter->pdev->vendor | (adapter->pdev->device << 16))) return -EFAULT; if (adapter->flags & FLAG_READ_ONLY_NVM) return -EINVAL; max_len = hw->nvm.word_size * 2; first_word = eeprom->offset >> 1; last_word = (eeprom->offset + eeprom->len - 1) >> 1; eeprom_buff = kmalloc(max_len, GFP_KERNEL); if (!eeprom_buff) return -ENOMEM; ptr = (void *)eeprom_buff; if (eeprom->offset & 1) { /* need read/modify/write of first changed EEPROM word */ /* only the second byte of the word is being modified */ ret_val = e1000_read_nvm(hw, first_word, 1, &eeprom_buff[0]); ptr++; } if (((eeprom->offset + eeprom->len) & 1) && (!ret_val)) /* need read/modify/write of last changed EEPROM word */ /* only the first byte of the word is being modified */ ret_val = e1000_read_nvm(hw, last_word, 1, &eeprom_buff[last_word - first_word]); if (ret_val) goto out; /* Device's eeprom is always little-endian, word addressable */ for (i = 0; i < last_word - first_word + 1; i++) le16_to_cpus(&eeprom_buff[i]); memcpy(ptr, bytes, eeprom->len); for (i = 0; i < last_word - first_word + 1; i++) cpu_to_le16s(&eeprom_buff[i]); ret_val = e1000_write_nvm(hw, first_word, last_word - first_word + 1, eeprom_buff); if (ret_val) goto out; /* * Update the checksum over the first part of the EEPROM if needed * and flush shadow RAM for applicable controllers */ if ((first_word <= NVM_CHECKSUM_REG) || (hw->mac.type == e1000_82583) || (hw->mac.type == e1000_82574) || (hw->mac.type == e1000_82573)) ret_val = e1000e_update_nvm_checksum(hw); out: kfree(eeprom_buff); return ret_val; }
/* Metadata initial parser * * This loads all the metadata entry fields. This may cause additional * fields to be processed (e.g. parent locator, etc..). * * There are 5 Metadata items that are always required: * - File Parameters (block size, has a parent) * - Virtual Disk Size (size, in bytes, of the virtual drive) * - Page 83 Data (scsi page 83 guid) * - Logical Sector Size (logical sector size in bytes, either 512 or * 4096. We only support 512 currently) * - Physical Sector Size (512 or 4096) * * Also, if the File Parameters indicate this is a differencing file, * we must also look for the Parent Locator metadata item. */ static int vhdx_parse_metadata(BlockDriverState *bs, BDRVVHDXState *s) { int ret = 0; uint8_t *buffer; int offset = 0; uint32_t i = 0; VHDXMetadataTableEntry md_entry; buffer = qemu_blockalign(bs, VHDX_METADATA_TABLE_MAX_SIZE); ret = bdrv_pread(bs->file, s->metadata_rt.file_offset, buffer, VHDX_METADATA_TABLE_MAX_SIZE); if (ret < 0) { goto exit; } memcpy(&s->metadata_hdr, buffer, sizeof(s->metadata_hdr)); offset += sizeof(s->metadata_hdr); le64_to_cpus(&s->metadata_hdr.signature); le16_to_cpus(&s->metadata_hdr.reserved); le16_to_cpus(&s->metadata_hdr.entry_count); if (memcmp(&s->metadata_hdr.signature, "metadata", 8)) { ret = -EINVAL; goto exit; } s->metadata_entries.present = 0; if ((s->metadata_hdr.entry_count * sizeof(md_entry)) > (VHDX_METADATA_TABLE_MAX_SIZE - offset)) { ret = -EINVAL; goto exit; } for (i = 0; i < s->metadata_hdr.entry_count; i++) { memcpy(&md_entry, buffer + offset, sizeof(md_entry)); offset += sizeof(md_entry); leguid_to_cpus(&md_entry.item_id); le32_to_cpus(&md_entry.offset); le32_to_cpus(&md_entry.length); le32_to_cpus(&md_entry.data_bits); le32_to_cpus(&md_entry.reserved2); if (guid_eq(md_entry.item_id, file_param_guid)) { if (s->metadata_entries.present & META_FILE_PARAMETER_PRESENT) { ret = -EINVAL; goto exit; } s->metadata_entries.file_parameters_entry = md_entry; s->metadata_entries.present |= META_FILE_PARAMETER_PRESENT; continue; } if (guid_eq(md_entry.item_id, virtual_size_guid)) { if (s->metadata_entries.present & META_VIRTUAL_DISK_SIZE_PRESENT) { ret = -EINVAL; goto exit; } s->metadata_entries.virtual_disk_size_entry = md_entry; s->metadata_entries.present |= META_VIRTUAL_DISK_SIZE_PRESENT; continue; } if (guid_eq(md_entry.item_id, page83_guid)) { if (s->metadata_entries.present & META_PAGE_83_PRESENT) { ret = -EINVAL; goto exit; } s->metadata_entries.page83_data_entry = md_entry; s->metadata_entries.present |= META_PAGE_83_PRESENT; continue; } if (guid_eq(md_entry.item_id, logical_sector_guid)) { if (s->metadata_entries.present & META_LOGICAL_SECTOR_SIZE_PRESENT) { ret = -EINVAL; goto exit; } s->metadata_entries.logical_sector_size_entry = md_entry; s->metadata_entries.present |= META_LOGICAL_SECTOR_SIZE_PRESENT; continue; } if (guid_eq(md_entry.item_id, phys_sector_guid)) { if (s->metadata_entries.present & META_PHYS_SECTOR_SIZE_PRESENT) { ret = -EINVAL; goto exit; } s->metadata_entries.phys_sector_size_entry = md_entry; s->metadata_entries.present |= META_PHYS_SECTOR_SIZE_PRESENT; continue; } if (guid_eq(md_entry.item_id, parent_locator_guid)) { if (s->metadata_entries.present & META_PARENT_LOCATOR_PRESENT) { ret = -EINVAL; goto exit; } s->metadata_entries.parent_locator_entry = md_entry; s->metadata_entries.present |= META_PARENT_LOCATOR_PRESENT; continue; } if (md_entry.data_bits & VHDX_META_FLAGS_IS_REQUIRED) { /* cannot read vhdx file - required region table entry that * we do not understand. per spec, we must fail to open */ ret = -ENOTSUP; goto exit; } } if (s->metadata_entries.present != META_ALL_PRESENT) { ret = -ENOTSUP; goto exit; } ret = bdrv_pread(bs->file, s->metadata_entries.file_parameters_entry.offset + s->metadata_rt.file_offset, &s->params, sizeof(s->params)); if (ret < 0) { goto exit; } le32_to_cpus(&s->params.block_size); le32_to_cpus(&s->params.data_bits); /* We now have the file parameters, so we can tell if this is a * differencing file (i.e.. has_parent), is dynamic or fixed * sized (leave_blocks_allocated), and the block size */ /* The parent locator required iff the file parameters has_parent set */ if (s->params.data_bits & VHDX_PARAMS_HAS_PARENT) { if (s->metadata_entries.present & META_PARENT_LOCATOR_PRESENT) { /* TODO: parse parent locator fields */ ret = -ENOTSUP; /* temp, until differencing files are supported */ goto exit; } else { /* if has_parent is set, but there is not parent locator present, * then that is an invalid combination */ ret = -EINVAL; goto exit; } } /* determine virtual disk size, logical sector size, * and phys sector size */ ret = bdrv_pread(bs->file, s->metadata_entries.virtual_disk_size_entry.offset + s->metadata_rt.file_offset, &s->virtual_disk_size, sizeof(uint64_t)); if (ret < 0) { goto exit; } ret = bdrv_pread(bs->file, s->metadata_entries.logical_sector_size_entry.offset + s->metadata_rt.file_offset, &s->logical_sector_size, sizeof(uint32_t)); if (ret < 0) { goto exit; } ret = bdrv_pread(bs->file, s->metadata_entries.phys_sector_size_entry.offset + s->metadata_rt.file_offset, &s->physical_sector_size, sizeof(uint32_t)); if (ret < 0) { goto exit; } le64_to_cpus(&s->virtual_disk_size); le32_to_cpus(&s->logical_sector_size); le32_to_cpus(&s->physical_sector_size); if (s->logical_sector_size == 0 || s->params.block_size == 0) { ret = -EINVAL; goto exit; } /* both block_size and sector_size are guaranteed powers of 2 */ s->sectors_per_block = s->params.block_size / s->logical_sector_size; s->chunk_ratio = (VHDX_MAX_SECTORS_PER_BLOCK) * (uint64_t)s->logical_sector_size / (uint64_t)s->params.block_size; /* These values are ones we will want to use for division / multiplication * later on, and they are all guaranteed (per the spec) to be powers of 2, * so we can take advantage of that for shift operations during * reads/writes */ if (s->logical_sector_size & (s->logical_sector_size - 1)) { ret = -EINVAL; goto exit; } if (s->sectors_per_block & (s->sectors_per_block - 1)) { ret = -EINVAL; goto exit; } if (s->chunk_ratio & (s->chunk_ratio - 1)) { ret = -EINVAL; goto exit; } s->block_size = s->params.block_size; if (s->block_size & (s->block_size - 1)) { ret = -EINVAL; goto exit; } s->logical_sector_size_bits = 31 - clz32(s->logical_sector_size); s->sectors_per_block_bits = 31 - clz32(s->sectors_per_block); s->chunk_ratio_bits = 63 - clz64(s->chunk_ratio); s->block_size_bits = 31 - clz32(s->block_size); ret = 0; exit: qemu_vfree(buffer); return ret; }