int irecv_short_time_control_transfer(irecv_client_t client, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, unsigned char *data, uint16_t wLength) { // pod2g: dirty hack for limera1n support. IOReturn kresult; IOUSBDevRequest req; bzero(&req, sizeof(req)); //struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)client->handle->os_priv; struct darwin_device_priv *dpriv = (struct darwin_device_priv *)client->handle->dev->os_priv; req.bmRequestType = bmRequestType; req.bRequest = bRequest; req.wValue = OSSwapLittleToHostInt16 (wValue); req.wIndex = OSSwapLittleToHostInt16 (wIndex); req.wLength = OSSwapLittleToHostInt16 (wLength); req.pData = data + LIBUSB_CONTROL_SETUP_SIZE; kresult = (*(dpriv->device))->DeviceRequestAsync(dpriv->device, &req, (IOAsyncCallback1) dummy_callback, NULL); usleep(5 * 1000); kresult = (*(dpriv->device))->USBDeviceAbortPipeZero (dpriv->device); return kresult == KERN_SUCCESS ? 0 : -1; }
bool AtherosL1Ethernet::at_clean_tx_irq(at_adapter* adapter) { struct at_tpd_ring *tpd_ring = &adapter->tpd_ring; struct at_buffer* buffer_info; u16 sw_tpd_next_to_clean; u16 cmb_tpd_next_to_clean; sw_tpd_next_to_clean = (u16)atomic_read(&tpd_ring->next_to_clean); cmb_tpd_next_to_clean = OSSwapLittleToHostInt16(adapter->cmb.cmb->tpd_cons_idx); DbgPrint("atl1c_clean_rx_irq() sw_tpd_next_to_clean=%d,cmb_tpd_next_to_clean=%d\n", sw_tpd_next_to_clean ,cmb_tpd_next_to_clean); while (cmb_tpd_next_to_clean != sw_tpd_next_to_clean) { TpdDescr* tpd; tpd = AT_TPD_DESC(tpd_ring, sw_tpd_next_to_clean); buffer_info = &tpd_ring->buffer_info[sw_tpd_next_to_clean]; //TO-DO: Add cleaning if (++sw_tpd_next_to_clean == tpd_ring->count) sw_tpd_next_to_clean = 0; } atomic_set(&tpd_ring->next_to_clean, sw_tpd_next_to_clean); return (sw_tpd_next_to_clean == (u16)atomic_read(&tpd_ring->next_to_use)) ? TRUE : FALSE; }
static uint16_t _dispatch_transform_swap_to_host(uint16_t x, int32_t byteOrder) { if (byteOrder == OSLittleEndian) { return OSSwapLittleToHostInt16(x); } return OSSwapBigToHostInt16(x); }
void AtherosL1Ethernet::at_clean_rx_irq(at_adapter *adapter) { mbuf_t skb = NULL; u32 packet_size; int i, count; u16 length, rrd_next_to_clean; struct at_rfd_ring *rfd_ring = &adapter->rfd_ring; struct at_rrd_ring *rrd_ring = &adapter->rrd_ring; struct at_buffer * buffer_info; rx_return_desc_t* rrd; count = 0; rrd_next_to_clean = (u16)atomic_read(&rrd_ring->next_to_clean); DEBUGOUT1("at_clean_rx_irq() rrd_next_to_clean=%d\n", rrd_next_to_clean); while (1) { rrd = AT_RRD_DESC(rrd_ring, rrd_next_to_clean); i = 1; if (rrd->xsz.valid) { // packet valid chk_rrd: // check rrd status if (rrd->num_buf != 1) { DEBUGOUT1("RRD NumRfd %d\n", rrd->num_buf); DEBUGOUT1("packet length = %d\n", rrd->xsz.xsum_sz.pkt_size); } else { goto rrd_ok; } // rrd seems to be bad if (i-- > 0) { // rrd may not be DMAed completely DEBUGOUT("RRD may not be DMAed completely\n"); usec_delay(1); goto chk_rrd; } // bad rrd AT_ERR("BAD RRD\n"); // see if update RFD index if (rrd->num_buf > 1) { u16 num_buf; num_buf = (rrd->xsz.xsum_sz.pkt_size+adapter->rx_buffer_len - 1)/ adapter->rx_buffer_len; DEBUGOUT1("RRD.buf_index (%d)\n", rrd->buf_indx); if (rrd->num_buf == num_buf) { // clean alloc flag for bad rrd while (rfd_ring->next_to_clean != (rrd->buf_indx + num_buf) ) { DEBUGOUT1("clear index (%d)\n", rfd_ring->next_to_clean); rfd_ring->buffer_info[rfd_ring->next_to_clean].alloced = 0; if (++rfd_ring->next_to_clean == rfd_ring->count) { rfd_ring->next_to_clean = 0; } } // end while } // end if (rrd->num_buf == ...) } // update rrd rrd->xsz.valid = 0; if (++rrd_next_to_clean == rrd_ring->count) rrd_next_to_clean = 0; count++; continue; } else { // current rrd still not be updated break; } rrd_ok: // clean alloc flag for bad rrd while (rfd_ring->next_to_clean != rrd->buf_indx) { rfd_ring->buffer_info[rfd_ring->next_to_clean].alloced = 0; if (++rfd_ring->next_to_clean == rfd_ring->count) { rfd_ring->next_to_clean = 0; } } buffer_info = &rfd_ring->buffer_info[rrd->buf_indx]; if (++rfd_ring->next_to_clean == rfd_ring->count) { rfd_ring->next_to_clean = 0; } // update rrd next to clean if (++rrd_next_to_clean == rrd_ring->count) rrd_next_to_clean = 0; count++; if (rrd->pkt_flg&PACKET_FLAG_ERR) { if (rrd->err_flg& (ERR_FLAG_CRC|ERR_FLAG_TRUNC|ERR_FLAG_CODE|ERR_FLAG_OV)) { /* packet error , don't need upstream */ buffer_info->alloced = 0; rrd->xsz.valid = 0; DEBUGOUT1("rrd error flag %x\n", rrd->err_flg); continue; } } /* Good Receive */ length = OSSwapLittleToHostInt16(rrd->xsz.xsum_sz.pkt_size); packet_size = length - 4; // CRC // alloc new buffer skb = allocatePacket(packet_size + 2); if (NULL == skb) { DbgPrint("Memory squeeze, deferring packet.\n"); break; } DEBUGOUT1("pktsize=%d\n", packet_size); // copy packet to user buffer if (buffer_info->memDesc) { memcpy( mbuf_data(skb),buffer_info->memDesc->getBytesNoCopy(), packet_size); } //TO-DO: Add network stack notification netIface_->inputPacket(skb, packet_size, IONetworkInterface::kInputOptionQueuePacket); netIface_->flushInputQueue(); /* DEBUGOUT1("pkt:%02x %02x %02x %02x %02x %02x-%02x\n", skb->data[0], skb->data[1], skb->data[2], skb->data[3], skb->data[4], skb->data[5], skb->data[12]); */ // let protocol layer free skb buffer_info->alloced = 0; rrd->xsz.valid = 0; } atomic_set(&rrd_ring->next_to_clean, rrd_next_to_clean); at_alloc_rx_buffers(adapter); // update mailbox ? if (0 != count) { at_update_mailbox(adapter); } }
int smb_netshareenum(SMBHANDLE inConnection, CFDictionaryRef *outDict, int DiskAndPrintSharesOnly) { int error = 0; NTSTATUS status; SMBServerPropertiesV1 properties; CFMutableDictionaryRef shareDict = NULL; uint32_t ii; CFStringRef shareName, comments; u_int16_t shareType; struct statfs *fs = NULL; int fs_cnt = 0; fs = smb_getfsstat(&fs_cnt); shareDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); if (shareDict == NULL) { error = ENOMEM; goto done; } status = SMBGetServerProperties(inConnection, &properties, kPropertiesVersion, sizeof(properties)); if (!NT_SUCCESS(status)) { /* Should never happen */ error = errno; goto done; } /* Only use RPC if the server supports DCE/RPC and UNICODE */ if (properties.capabilities & SMB_CAP_RPC_REMOTE_APIS) { PSHARE_ENUM_STRUCT InfoStruct = NULL; NET_API_STATUS api_status; /* Try getting a list of shares with the SRVSVC RPC service. */ api_status = NetShareEnum(properties.serverName, 1, &InfoStruct); if (api_status == 0) { for (ii = 0; ii < InfoStruct->ShareInfo.Level1->EntriesRead; ii++) { shareType = OSSwapLittleToHostInt16(InfoStruct->ShareInfo.Level1->Buffer[ii].shi1_type); /* They only want the disk and printer shares */ if (DiskAndPrintSharesOnly && (shareType != SMB_ST_DISK) && (shareType != SMB_ST_PRINTER)) continue; shareName = convertToStringRef(InfoStruct->ShareInfo.Level1->Buffer[ii].shi1_netname, 1024, TRUE); if (shareName == NULL) { continue; } if (InfoStruct->ShareInfo.Level1->Buffer[ii].shi1_remark) { comments = convertToStringRef(InfoStruct->ShareInfo.Level1->Buffer[ii].shi1_remark, 1024, TRUE); } else { comments = NULL; } addShareToDictionary(inConnection, shareDict, shareName, comments, shareType, fs, fs_cnt); CFRelease(shareName); if (comments) { CFRelease(comments); } } NetApiBufferFree(InfoStruct); goto done; } SMBLogInfo("Looking up shares with RPC failed api_status = %d", ASL_LEVEL_DEBUG, api_status); } /* * OK, that didn't work - either they don't support RPC or we * got an error in either case try RAP if enabled (lanman_on pref is set). */ if (properties.internalFlags & kLanmanOn) { void *rBuffer = NULL; unsigned char *endBuffer; uint32_t rBufferSize = 0; struct smb_share_info_1 *shareInfo1; uint32_t entriesRead = 0; SMBLogInfo("Looking up shares RAP", ASL_LEVEL_DEBUG); /* Try getting a list of shares with the RAP protocol. */ error = RapNetShareEnum(inConnection, 1, &rBuffer, &rBufferSize, &entriesRead, NULL); if (error) { SMBLogInfo("Looking up shares with RAP failed, error=%d", ASL_LEVEL_DEBUG, error); goto done; } endBuffer = (unsigned char *)rBuffer + rBufferSize; for (shareInfo1 = (struct smb_share_info_1 *)rBuffer, ii = 0; (ii < entriesRead) && (((unsigned char *)shareInfo1 + sizeof(smb_share_info_1)) <= endBuffer); ii++, shareInfo1++) { shareInfo1->shi1_pad = 0; /* Just to be safe */ /* Note we need to swap this item */ shareType = OSSwapLittleToHostInt16(shareInfo1->shi1_type); shareName = convertToStringRef(shareInfo1->shi1_netname, sizeof(shareInfo1->shi1_netname), FALSE); if (shareName == NULL) { continue; } /* Assume we have no comments for this entry */ comments = NULL; /* * The shi1_remark gets swapped in the rap processing, someday we just * take another look at this an make it work the same for all values. */ if ((shareInfo1->shi1_remark != 0) && (shareInfo1->shi1_remark < rBufferSize)) { unsigned char *remarks = (unsigned char *)rBuffer + shareInfo1->shi1_remark; /* * Make sure the comments don't start pass the end of the buffer * and we have a comment. */ if ((remarks < endBuffer) && *remarks) { size_t maxlen = endBuffer - remarks; /* Now make sure the comment is a null terminate string */ maxlen = smb_strnlen((const char *)remarks, maxlen); remarks[maxlen] = 0; comments = convertToStringRef(remarks, maxlen, FALSE); } } addShareToDictionary(inConnection, shareDict, shareName, comments, shareType, fs, fs_cnt); CFRelease(shareName); if (comments) { CFRelease(comments); } } RapNetApiBufferFree(rBuffer); } done: if (fs) { free(fs); } if (error) { *outDict = NULL; if (shareDict) { CFRelease(shareDict); } } else { *outDict = shareDict; } return error; }
OSSet * IOGUIDPartitionScheme::scan(SInt32 * score) { // // Scan the provider media for a GUID partition map. Returns the set // of media objects representing each of the partitions (the retain for // the set is passed to the caller), or null should no partition map be // found. The default probe score can be adjusted up or down, based on // the confidence of the scan. // IOBufferMemoryDescriptor * buffer = 0; IOByteCount bufferSize = 0; UInt32 fdiskID = 0; disk_blk0 * fdiskMap = 0; UInt64 gptBlock = 0; UInt32 gptCheck = 0; UInt32 gptCount = 0; UInt32 gptID = 0; gpt_ent * gptMap = 0; UInt32 gptSize = 0; UInt32 headerCheck = 0; gpt_hdr * headerMap = 0; UInt32 headerSize = 0; IOMedia * media = getProvider(); UInt64 mediaBlockSize = media->getPreferredBlockSize(); bool mediaIsOpen = false; OSSet * partitions = 0; IOReturn status = kIOReturnError; // Determine whether this media is formatted. if ( media->isFormatted() == false ) goto scanErr; // Determine whether this media has an appropriate block size. if ( (mediaBlockSize % sizeof(disk_blk0)) ) goto scanErr; // Allocate a buffer large enough to hold one map, rounded to a media block. bufferSize = IORound(sizeof(disk_blk0), mediaBlockSize); buffer = IOBufferMemoryDescriptor::withCapacity( /* capacity */ bufferSize, /* withDirection */ kIODirectionIn ); if ( buffer == 0 ) goto scanErr; // Allocate a set to hold the set of media objects representing partitions. partitions = OSSet::withCapacity(8); if ( partitions == 0 ) goto scanErr; // Open the media with read access. mediaIsOpen = open(this, 0, kIOStorageAccessReader); if ( mediaIsOpen == false ) goto scanErr; // Read the protective map into our buffer. status = media->read(this, 0, buffer); if ( status != kIOReturnSuccess ) goto scanErr; fdiskMap = (disk_blk0 *) buffer->getBytesNoCopy(); // Determine whether the protective map signature is present. if ( OSSwapLittleToHostInt16(fdiskMap->signature) != DISK_SIGNATURE ) { goto scanErr; } // Scan for valid partition entries in the protective map. for ( unsigned index = 0; index < DISK_NPART; index++ ) { if ( fdiskMap->parts[index].systid ) { if ( fdiskMap->parts[index].systid == 0xEE ) { if ( fdiskID ) goto scanErr; fdiskID = index + 1; } } } if ( fdiskID == 0 ) goto scanErr; // Read the partition header into our buffer. status = media->read(this, mediaBlockSize, buffer); if ( status != kIOReturnSuccess ) goto scanErr; headerMap = (gpt_hdr *) buffer->getBytesNoCopy(); // Determine whether the partition header signature is present. if ( memcmp(headerMap->hdr_sig, GPT_HDR_SIG, strlen(GPT_HDR_SIG)) ) { goto scanErr; } // Determine whether the partition header size is valid. headerCheck = OSSwapLittleToHostInt32(headerMap->hdr_crc_self); headerSize = OSSwapLittleToHostInt32(headerMap->hdr_size); if ( headerSize < offsetof(gpt_hdr, padding) ) { goto scanErr; } if ( headerSize > mediaBlockSize ) { goto scanErr; } // Determine whether the partition header checksum is valid. headerMap->hdr_crc_self = 0; if ( crc32(0, headerMap, headerSize) != headerCheck ) { goto scanErr; } // Determine whether the partition entry size is valid. gptCheck = OSSwapLittleToHostInt32(headerMap->hdr_crc_table); gptSize = OSSwapLittleToHostInt32(headerMap->hdr_entsz); if ( gptSize < sizeof(gpt_ent) ) { goto scanErr; } if ( gptSize > UINT16_MAX ) { goto scanErr; } // Determine whether the partition entry count is valid. gptBlock = OSSwapLittleToHostInt64(headerMap->hdr_lba_table); gptCount = OSSwapLittleToHostInt32(headerMap->hdr_entries); if ( gptCount > UINT16_MAX ) { goto scanErr; } // Allocate a buffer large enough to hold one map, rounded to a media block. buffer->release(); bufferSize = IORound(gptCount * gptSize, mediaBlockSize); buffer = IOBufferMemoryDescriptor::withCapacity( /* capacity */ bufferSize, /* withDirection */ kIODirectionIn ); if ( buffer == 0 ) goto scanErr; // Read the partition header into our buffer. status = media->read(this, gptBlock * mediaBlockSize, buffer); if ( status != kIOReturnSuccess ) goto scanErr; gptMap = (gpt_ent *) buffer->getBytesNoCopy(); // Determine whether the partition entry checksum is valid. if ( crc32(0, gptMap, gptCount * gptSize) != gptCheck ) { goto scanErr; } // Scan for valid partition entries in the partition map. for ( gptID = 1; gptID <= gptCount; gptID++ ) { gptMap = (gpt_ent *) ( ((UInt8 *) buffer->getBytesNoCopy()) + (gptID * gptSize) - gptSize ); uuid_unswap( gptMap->ent_type ); uuid_unswap( gptMap->ent_uuid ); if ( isPartitionUsed( gptMap ) ) { // Determine whether the partition is corrupt (fatal). if ( isPartitionCorrupt( gptMap, gptID ) ) { goto scanErr; } // Determine whether the partition is invalid (skipped). if ( isPartitionInvalid( gptMap, gptID ) ) { continue; } // Create a media object to represent this partition. IOMedia * newMedia = instantiateMediaObject( gptMap, gptID ); if ( newMedia ) { partitions->setObject(newMedia); newMedia->release(); } } } // Release our resources. close(this); buffer->release(); return partitions; scanErr: // Release our resources. if ( mediaIsOpen ) close(this); if ( partitions ) partitions->release(); if ( buffer ) buffer->release(); return 0; }
OSSet * IOFDiskPartitionScheme::scan(SInt32 * score) { // // Scan the provider media for an FDisk partition map. Returns the set // of media objects representing each of the partitions (the retain for // the set is passed to the caller), or null should no partition map be // found. The default probe score can be adjusted up or down, based on // the confidence of the scan. // IOBufferMemoryDescriptor * buffer = 0; UInt32 bufferSize = 0; UInt32 fdiskBlock = 0; UInt32 fdiskBlockExtn = 0; UInt32 fdiskBlockNext = 0; UInt32 fdiskID = 0; disk_blk0 * fdiskMap = 0; IOMedia * media = getProvider(); UInt64 mediaBlockSize = media->getPreferredBlockSize(); bool mediaIsOpen = false; OSSet * partitions = 0; IOReturn status = kIOReturnError; // Determine whether this media is formatted. if ( media->isFormatted() == false ) goto scanErr; // Determine whether this media has an appropriate block size. if ( (mediaBlockSize % sizeof(disk_blk0)) ) goto scanErr; // Allocate a buffer large enough to hold one map, rounded to a media block. bufferSize = IORound(sizeof(disk_blk0), mediaBlockSize); buffer = IOBufferMemoryDescriptor::withCapacity( /* capacity */ bufferSize, /* withDirection */ kIODirectionIn ); if ( buffer == 0 ) goto scanErr; // Allocate a set to hold the set of media objects representing partitions. partitions = OSSet::withCapacity(4); if ( partitions == 0 ) goto scanErr; // Open the media with read access. mediaIsOpen = open(this, 0, kIOStorageAccessReader); if ( mediaIsOpen == false ) goto scanErr; // Scan the media for FDisk partition map(s). do { // Read the next FDisk map into our buffer. status = media->read(this, fdiskBlock * mediaBlockSize, buffer); if ( status != kIOReturnSuccess ) goto scanErr; fdiskMap = (disk_blk0 *) buffer->getBytesNoCopy(); // Determine whether the partition map signature is present. if ( OSSwapLittleToHostInt16(fdiskMap->signature) != DISK_SIGNATURE ) { goto scanErr; } // Scan for valid partition entries in the partition map. fdiskBlockNext = 0; for ( unsigned index = 0; index < DISK_NPART; index++ ) { // Determine whether this is an extended (vs. data) partition. if ( isPartitionExtended(fdiskMap->parts + index) ) // (extended) { // If peer extended partitions exist, we accept only the first. if ( fdiskBlockNext == 0 ) // (no peer extended partition) { fdiskBlockNext = fdiskBlockExtn + OSSwapLittleToHostInt32( /* data */ fdiskMap->parts[index].relsect ); if ( fdiskBlockNext * mediaBlockSize >= media->getSize() ) { fdiskBlockNext = 0; // (exceeds confines of media) } } } else if ( isPartitionUsed(fdiskMap->parts + index) ) // (data) { // Prepare this partition's ID. fdiskID = ( fdiskBlock == 0 ) ? (index + 1) : (fdiskID + 1); // Determine whether the partition is corrupt (fatal). if ( isPartitionCorrupt( /* partition */ fdiskMap->parts + index, /* partitionID */ fdiskID, /* fdiskBlock */ fdiskBlock ) ) { goto scanErr; } // Determine whether the partition is invalid (skipped). if ( isPartitionInvalid( /* partition */ fdiskMap->parts + index, /* partitionID */ fdiskID, /* fdiskBlock */ fdiskBlock ) ) { continue; } // Create a media object to represent this partition. IOMedia * newMedia = instantiateMediaObject( /* partition */ fdiskMap->parts + index, /* partitionID */ fdiskID, /* fdiskBlock */ fdiskBlock ); if ( newMedia ) { partitions->setObject(newMedia); newMedia->release(); } } } // Prepare for first extended partition, if any. if ( fdiskBlock == 0 ) { fdiskID = DISK_NPART; fdiskBlockExtn = fdiskBlockNext; } } while ( (fdiskBlock = fdiskBlockNext) ); // Release our resources. close(this); buffer->release(); return partitions; scanErr: // Release our resources. if ( mediaIsOpen ) close(this); if ( partitions ) partitions->release(); if ( buffer ) buffer->release(); return 0; }
uint16_t fmle16(uint16_t x) { return OSSwapLittleToHostInt16(x); }
int irecv_control_transfer( irecv_client_t client, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, unsigned char *data, uint16_t wLength, unsigned int timeout) { #ifndef _WIN32 #ifndef __APPLE__ return libusb_control_transfer(client->handle, bmRequestType, bRequest, wValue, wIndex, data, wLength, timeout); #else if (timeout <= 10) { // pod2g: dirty hack for limera1n support. IOReturn kresult; IOUSBDevRequest req; bzero(&req, sizeof(req)); //struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)client->handle->os_priv; struct darwin_device_priv *dpriv = (struct darwin_device_priv *)client->handle->dev->os_priv; req.bmRequestType = bmRequestType; req.bRequest = bRequest; req.wValue = OSSwapLittleToHostInt16 (wValue); req.wIndex = OSSwapLittleToHostInt16 (wIndex); req.wLength = OSSwapLittleToHostInt16 (wLength); req.pData = data + LIBUSB_CONTROL_SETUP_SIZE; kresult = (*(dpriv->device))->DeviceRequestAsync(dpriv->device, &req, (IOAsyncCallback1) dummy_callback, NULL); usleep(5 * 1000); kresult = (*(dpriv->device))->USBDeviceAbortPipeZero (dpriv->device); return kresult == KERN_SUCCESS ? 0 : -1; } else { return libusb_control_transfer(client->handle, bmRequestType, bRequest, wValue, wIndex, data, wLength, timeout); } #endif #else DWORD count = 0; DWORD ret; BOOL bRet; OVERLAPPED overlapped; if (data == NULL) wLength = 0; usb_control_request* packet = (usb_control_request*) malloc(sizeof(usb_control_request) + wLength); packet->bmRequestType = bmRequestType; packet->bRequest = bRequest; packet->wValue = wValue; packet->wIndex = wIndex; packet->wLength = wLength; if (bmRequestType < 0x80 && wLength > 0) { memcpy(packet->data, data, wLength); } memset(&overlapped, 0, sizeof(overlapped)); overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); DeviceIoControl(client->handle, 0x2200A0, packet, sizeof(usb_control_request) + wLength, packet, sizeof(usb_control_request) + wLength, NULL, &overlapped); ret = WaitForSingleObject(overlapped.hEvent, timeout); bRet = GetOverlappedResult(client->handle, &overlapped, &count, FALSE); CloseHandle(overlapped.hEvent); if (!bRet) { CancelIo(client->handle); free(packet); return -1; } count -= sizeof(usb_control_request); if (count > 0) { if (bmRequestType >= 0x80) { memcpy(data, packet->data, count); } } free(packet); return count; #endif }
IOReturn WLCard:: _handleRx() { UInt16 packet[1182]; /* 60 byte header + 2304 data bytes */ WLFrame* frameDescriptor = (WLFrame*)packet; UInt16* frameData = &packet[30]; UInt16 FID = getRegister(wlRxFID); setRegister(wlSelect0, FID); setRegister(wlOffset0, 0); if (_waitForNotBusy(wlOffset0) != kIOReturnSuccess) { WLLogWarn("WLCard::_handleRx: Timeout or error\n"); return kIOReturnError; } /* * Read frame descriptor correcting the byte order as we go (the * control and 802.11 fields are little endian, the 802.3 fields are * big endian). */ int i; for (i = 0; i < 30; i++) packet[i] = getRegister(wlData0, false); frameDescriptor->status = OSSwapLittleToHostInt16(frameDescriptor->status); frameDescriptor->dataLen = OSSwapLittleToHostInt16(frameDescriptor->dataLen); frameDescriptor->channel = _channel; /* * If the frame has an FCS error, is received on a MAC port other * than the monitor mode port, or is a message type other than * normal, we don't want it. */ if (frameDescriptor->status & 0x1 || (frameDescriptor->status & 0x700) != 0x700 || frameDescriptor->status & 0xe000) { return kIOReturnSuccess; } if (frameDescriptor->dataLen > 2304) { WLLogCrit("WLCard::_handleRx: Oversized packet (%d bytes)\n", frameDescriptor->dataLen); return kIOReturnSuccess; } /* * Read in the packet data. Read 4 extra words for IV + ICV if * applicable. */ UInt16 dataLength = (frameDescriptor->dataLen / 2) + 4; for (i = 0; i < dataLength; i++) frameData[i] = getRegister(wlData0, false); if (_packetQueue) { UInt32 packetLength = sizeof(WLFrame) + (dataLength * 2); if (!_packetQueue->enqueue(packet, packetLength)) WLLogCrit("WLCard::_handleRx: packet queue overflow\n"); } return kIOReturnSuccess; }