Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
hpidspcd.c
Go to the documentation of this file.
1 /***********************************************************************/
24 /***********************************************************************/
25 #define SOURCEFILE_NAME "hpidspcd.c"
26 #include "hpidspcd.h"
27 #include "hpidebug.h"
28 #include "hpi_version.h"
29 
32  const struct firmware *firmware;
33  struct pci_dev *dev;
34 };
35 
36 /*-------------------------------------------------------------------*/
37 short hpi_dsp_code_open(u32 adapter, void *os_data, struct dsp_code *dsp_code,
38  u32 *os_error_code)
39 {
40  const struct firmware *firmware;
41  struct pci_dev *dev = os_data;
42  struct code_header header;
43  char fw_name[20];
44  short err_ret = HPI_ERROR_DSP_FILE_NOT_FOUND;
45  int err;
46 
47  sprintf(fw_name, "asihpi/dsp%04x.bin", adapter);
48 
49  err = request_firmware(&firmware, fw_name, &dev->dev);
50 
51  if (err || !firmware) {
52  dev_printk(KERN_ERR, &dev->dev,
53  "%d, request_firmware failed for %s\n", err,
54  fw_name);
55  goto error1;
56  }
57  if (firmware->size < sizeof(header)) {
58  dev_printk(KERN_ERR, &dev->dev, "Header size too small %s\n",
59  fw_name);
60  goto error2;
61  }
62  memcpy(&header, firmware->data, sizeof(header));
63 
64  if ((header.type != 0x45444F43) || /* "CODE" */
65  (header.adapter != adapter)
66  || (header.size != firmware->size)) {
67  dev_printk(KERN_ERR, &dev->dev,
68  "Invalid firmware header size %d != file %zd\n",
69  header.size, firmware->size);
70  goto error2;
71  }
72 
73  if ((header.version >> 9) != (HPI_VER >> 9)) {
74  /* Consider even and subsequent odd minor versions to be compatible */
75  dev_printk(KERN_ERR, &dev->dev,
76  "Incompatible firmware version "
77  "DSP image %X != Driver %X\n", header.version,
78  HPI_VER);
79  goto error2;
80  }
81 
82  if (header.version != HPI_VER) {
83  dev_printk(KERN_INFO, &dev->dev,
84  "Firmware: release version mismatch DSP image %X != Driver %X\n",
85  header.version, HPI_VER);
86  }
87 
88  HPI_DEBUG_LOG(DEBUG, "dsp code %s opened\n", fw_name);
89  dsp_code->pvt = kmalloc(sizeof(*dsp_code->pvt), GFP_KERNEL);
90  if (!dsp_code->pvt) {
91  err_ret = HPI_ERROR_MEMORY_ALLOC;
92  goto error2;
93  }
94 
95  dsp_code->pvt->dev = dev;
96  dsp_code->pvt->firmware = firmware;
97  dsp_code->header = header;
98  dsp_code->block_length = header.size / sizeof(u32);
99  dsp_code->word_count = sizeof(header) / sizeof(u32);
100  return 0;
101 
102 error2:
103  release_firmware(firmware);
104 error1:
105  dsp_code->block_length = 0;
106  return err_ret;
107 }
108 
109 /*-------------------------------------------------------------------*/
111 {
112  HPI_DEBUG_LOG(DEBUG, "dsp code closed\n");
113  release_firmware(dsp_code->pvt->firmware);
114  kfree(dsp_code->pvt);
115 }
116 
117 /*-------------------------------------------------------------------*/
119 {
120  /* Go back to start of data, after header */
121  dsp_code->word_count = sizeof(struct code_header) / sizeof(u32);
122 }
123 
124 /*-------------------------------------------------------------------*/
126 {
127  if (dsp_code->word_count + 1 > dsp_code->block_length)
129 
130  *pword = ((u32 *)(dsp_code->pvt->firmware->data))[dsp_code->
131  word_count];
132  dsp_code->word_count++;
133  return 0;
134 }
135 
136 /*-------------------------------------------------------------------*/
137 short hpi_dsp_code_read_block(size_t words_requested,
138  struct dsp_code *dsp_code, u32 **ppblock)
139 {
140  if (dsp_code->word_count + words_requested > dsp_code->block_length)
142 
143  *ppblock =
144  ((u32 *)(dsp_code->pvt->firmware->data)) +
145  dsp_code->word_count;
146  dsp_code->word_count += words_requested;
147  return 0;
148 }