static void callbackfn_rbu(const struct firmware *fw, void *context) { rbu_data.entry_created = 0; if (!fw || !fw->size) return; spin_lock(&rbu_data.lock); if (!strcmp(image_type, "mono")) { if (!img_update_realloc(fw->size)) memcpy(rbu_data.image_update_buffer, fw->data, fw->size); } else if (!strcmp(image_type, "packet")) { /* * we need to free previous packets if a * new hunk of packets needs to be downloaded */ packet_empty_list(); if (packetize_data(fw->data, fw->size)) /* Incase something goes wrong when we are * in middle of packetizing the data, we * need to free up whatever packets might * have been created before we quit. */ packet_empty_list(); } else pr_debug("invalid image type specified.\n"); spin_unlock(&rbu_data.lock); }
static ssize_t write_rbu_image_type(struct kobject *kobj, struct bin_attribute *bin_attr, char *buffer, loff_t pos, size_t count) { int rc = count; int req_firm_rc = 0; int i; spin_lock(&rbu_data.lock); /* * Find the first newline or space */ for (i = 0; i < count; ++i) if (buffer[i] == '\n' || buffer[i] == ' ') { buffer[i] = '\0'; break; } if (i == count) buffer[count] = '\0'; if (strstr(buffer, "mono")) strcpy(image_type, "mono"); else if (strstr(buffer, "packet")) strcpy(image_type, "packet"); else if (strstr(buffer, "init")) { /* * If due to the user error the driver gets in a bad * state where even though it is loaded , the * /sys/class/firmware/dell_rbu entries are missing. * to cover this situation the user can recreate entries * by writing init to image_type. */ if (!rbu_data.entry_created) { spin_unlock(&rbu_data.lock); req_firm_rc = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG, "dell_rbu", &rbu_device->dev, &context, callbackfn_rbu); if (req_firm_rc) { printk(KERN_ERR "dell_rbu:%s request_firmware_nowait" " failed %d\n", __func__, rc); rc = -EIO; } else rbu_data.entry_created = 1; spin_lock(&rbu_data.lock); } } else { printk(KERN_WARNING "dell_rbu: image_type is invalid\n"); spin_unlock(&rbu_data.lock); return -EINVAL; } /* we must free all previous allocations */ packet_empty_list(); img_update_free(); spin_unlock(&rbu_data.lock); return rc; }
static __exit void dcdrbu_exit(void) { spin_lock(&rbu_data.lock); packet_empty_list(); img_update_free(); spin_unlock(&rbu_data.lock); platform_device_unregister(rbu_device); }
static void callbackfn_rbu(const struct firmware *fw, void *context) { int rc = 0; if (!fw || !fw->size) { rbu_data.entry_created = 0; return; } spin_lock(&rbu_data.lock); if (!strcmp(image_type, "mono")) { if (!img_update_realloc(fw->size)) memcpy(rbu_data.image_update_buffer, fw->data, fw->size); } else if (!strcmp(image_type, "packet")) { /* * we need to free previous packets if a * new hunk of packets needs to be downloaded */ packet_empty_list(); if (packetize_data(fw->data, fw->size)) /* Incase something goes wrong when we are * in middle of packetizing the data, we * need to free up whatever packets might * have been created before we quit. */ packet_empty_list(); } else pr_debug("invalid image type specified.\n"); spin_unlock(&rbu_data.lock); rc = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG, "dell_rbu", &rbu_device->dev, &context, callbackfn_rbu); if (rc) printk(KERN_ERR "dell_rbu:%s request_firmware_nowait failed" " %d\n", __FUNCTION__, rc); else rbu_data.entry_created = 1; }
static ssize_t write_rbu_packet_size(struct kobject *kobj, char *buffer, loff_t pos, size_t count) { unsigned long temp; spin_lock(&rbu_data.lock); packet_empty_list(); sscanf(buffer, "%lu", &temp); if (temp < 0xffffffff) rbu_data.packetsize = temp; spin_unlock(&rbu_data.lock); return count; }