static ssize_t asd_show_dev_rev(struct device *dev, struct device_attribute *attr, char *buf) { struct asd_ha_struct *asd_ha = dev_to_asd_ha(dev); return snprintf(buf, PAGE_SIZE, "%s\n", asd_dev_rev[asd_ha->revision_id]); }
static ssize_t asd_show_update_bios(struct device *dev, struct device_attribute *attr, char *buf) { int i; struct asd_ha_struct *asd_ha = dev_to_asd_ha(dev); for (i = 0; flash_error_table[i].err_code != 0; i++) { if (flash_error_table[i].err_code == asd_ha->bios_status) break; } if (asd_ha->bios_status != FLASH_IN_PROGRESS) asd_ha->bios_status = FLASH_OK; return snprintf(buf, PAGE_SIZE, "status=%x %s\n", flash_error_table[i].err_code, flash_error_table[i].reason); }
static ssize_t asd_show_dev_pcba_sn(struct device *dev, struct device_attribute *attr, char *buf) { struct asd_ha_struct *asd_ha = dev_to_asd_ha(dev); return snprintf(buf, PAGE_SIZE, "%s\n", asd_ha->hw_prof.pcba_sn); }
static ssize_t asd_show_dev_bios_build(struct device *dev, struct device_attribute *attr,char *buf) { struct asd_ha_struct *asd_ha = dev_to_asd_ha(dev); return snprintf(buf, PAGE_SIZE, "%d\n", asd_ha->hw_prof.bios.bld); }
static ssize_t asd_store_update_bios(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct asd_ha_struct *asd_ha = dev_to_asd_ha(dev); char *cmd_ptr, *filename_ptr; struct bios_file_header header, *hdr_ptr; int res, i; u32 csum = 0; int flash_command = FLASH_CMD_NONE; int err = 0; cmd_ptr = kcalloc(count, 2, GFP_KERNEL); if (!cmd_ptr) { err = FAIL_OUT_MEMORY; goto out; } filename_ptr = cmd_ptr + count; res = sscanf(buf, "%s %s", cmd_ptr, filename_ptr); if (res != 2) { err = FAIL_PARAMETERS; goto out1; } for (i = 0; flash_command_table[i].code != FLASH_CMD_NONE; i++) { if (!memcmp(flash_command_table[i].command, cmd_ptr, strlen(cmd_ptr))) { flash_command = flash_command_table[i].code; break; } } if (flash_command == FLASH_CMD_NONE) { err = FAIL_PARAMETERS; goto out1; } if (asd_ha->bios_status == FLASH_IN_PROGRESS) { err = FLASH_IN_PROGRESS; goto out1; } err = request_firmware(&asd_ha->bios_image, filename_ptr, &asd_ha->pcidev->dev); if (err) { asd_printk("Failed to load bios image file %s, error %d\n", filename_ptr, err); err = FAIL_OPEN_BIOS_FILE; goto out1; } hdr_ptr = (struct bios_file_header *)asd_ha->bios_image->data; if ((hdr_ptr->contrl_id.vendor != asd_ha->pcidev->vendor || hdr_ptr->contrl_id.device != asd_ha->pcidev->device) && (hdr_ptr->contrl_id.sub_vendor != asd_ha->pcidev->vendor || hdr_ptr->contrl_id.sub_device != asd_ha->pcidev->device)) { ASD_DPRINTK("The PCI vendor or device id does not match\n"); ASD_DPRINTK("vendor=%x dev=%x sub_vendor=%x sub_dev=%x" " pci vendor=%x pci dev=%x\n", hdr_ptr->contrl_id.vendor, hdr_ptr->contrl_id.device, hdr_ptr->contrl_id.sub_vendor, hdr_ptr->contrl_id.sub_device, asd_ha->pcidev->vendor, asd_ha->pcidev->device); err = FAIL_CHECK_PCI_ID; goto out2; } if (hdr_ptr->filelen != asd_ha->bios_image->size) { err = FAIL_FILE_SIZE; goto out2; } /* calculate checksum */ for (i = 0; i < hdr_ptr->filelen; i++) csum += asd_ha->bios_image->data[i]; if ((csum & 0x0000ffff) != hdr_ptr->checksum) { ASD_DPRINTK("BIOS file checksum mismatch\n"); err = FAIL_CHECK_SUM; goto out2; } if (flash_command == FLASH_CMD_UPDATE) { asd_ha->bios_status = FLASH_IN_PROGRESS; err = asd_write_flash_seg(asd_ha, &asd_ha->bios_image->data[sizeof(*hdr_ptr)], 0, hdr_ptr->filelen-sizeof(*hdr_ptr)); if (!err) err = asd_verify_flash_seg(asd_ha, &asd_ha->bios_image->data[sizeof(*hdr_ptr)], 0, hdr_ptr->filelen-sizeof(*hdr_ptr)); } else { asd_ha->bios_status = FLASH_IN_PROGRESS; err = asd_verify_flash_seg(asd_ha, &asd_ha->bios_image->data[sizeof(header)], 0, hdr_ptr->filelen-sizeof(header)); } out2: release_firmware(asd_ha->bios_image); out1: kfree(cmd_ptr); out: asd_ha->bios_status = err; if (!err) return count; else return -err; }