/* Called only as a tasklet (software IRQ) */ static void prism2_info_hostscanresults(local_info_t *local, unsigned char *buf, int left) { int i, result_size, copy_len, new_count; struct hfa384x_hostscan_result *results, *prev; unsigned long flags; u16 *pos; u8 *ptr; wake_up_interruptible(&local->hostscan_wq); if (left < 4) { printk(KERN_DEBUG "%s: invalid hostscanresult info frame " "length %d\n", local->dev->name, left); return; } pos = (u16 *) buf; copy_len = result_size = le16_to_cpu(*pos); if (result_size == 0) { printk(KERN_DEBUG "%s: invalid result_size (0) in " "hostscanresults\n", local->dev->name); return; } if (copy_len > sizeof(struct hfa384x_hostscan_result)) copy_len = sizeof(struct hfa384x_hostscan_result); pos++; pos++; left -= 4; ptr = (u8 *) pos; new_count = left / result_size; results = kmalloc(new_count * sizeof(struct hfa384x_hostscan_result), GFP_ATOMIC); if (results == NULL) return; memset(results, 0, new_count * sizeof(struct hfa384x_hostscan_result)); for (i = 0; i < new_count; i++) { memcpy(&results[i], ptr, copy_len); ptr += result_size; left -= result_size; } if (left) { printk(KERN_DEBUG "%s: short HostScan result entry (%d/%d)\n", local->dev->name, left, result_size); } spin_lock_irqsave(&local->lock, flags); local->last_scan_type = PRISM2_HOSTSCAN; prev = local->last_hostscan_results; local->last_hostscan_results = results; local->last_hostscan_results_count = new_count; spin_unlock_irqrestore(&local->lock, flags); kfree(prev); hostap_report_scan_complete(local); }
/* Called only as a tasklet (software IRQ) */ static void prism2_info_scanresults(local_info_t *local, unsigned char *buf, int left) { u16 *pos; int new_count, i; unsigned long flags; struct hfa384x_scan_result *res; struct hfa384x_hostscan_result *results, *prev; if (left < 4) { printk(KERN_DEBUG "%s: invalid scanresult info frame " "length %d\n", local->dev->name, left); return; } pos = (u16 *) buf; pos++; pos++; left -= 4; new_count = left / sizeof(struct hfa384x_scan_result); results = kmalloc_array(new_count, sizeof(struct hfa384x_hostscan_result), GFP_ATOMIC); if (results == NULL) return; /* Convert to hostscan result format. */ res = (struct hfa384x_scan_result *) pos; for (i = 0; i < new_count; i++) { memcpy(&results[i], &res[i], sizeof(struct hfa384x_scan_result)); results[i].atim = 0; } spin_lock_irqsave(&local->lock, flags); local->last_scan_type = PRISM2_SCAN; prev = local->last_scan_results; local->last_scan_results = results; local->last_scan_results_count = new_count; spin_unlock_irqrestore(&local->lock, flags); kfree(prev); hostap_report_scan_complete(local); /* Perform rest of ScanResults handling later in scheduled task */ set_bit(PRISM2_INFO_PENDING_SCANRESULTS, &local->pending_info); schedule_work(&local->info_queue); }