Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
firmware.c
Go to the documentation of this file.
1 /*
2  * Linux driver for TerraTec DMX 6Fire USB
3  *
4  * Firmware loader
5  *
6  * Author: Torsten Schenk <[email protected]>
7  * Created: Jan 01, 2011
8  * Copyright: (C) Torsten Schenk
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  */
15 
16 #include <linux/firmware.h>
17 #include <linux/module.h>
18 #include <linux/bitrev.h>
19 #include <linux/kernel.h>
20 
21 #include "firmware.h"
22 #include "chip.h"
23 
24 MODULE_FIRMWARE("6fire/dmx6firel2.ihx");
25 MODULE_FIRMWARE("6fire/dmx6fireap.ihx");
26 MODULE_FIRMWARE("6fire/dmx6firecf.bin");
27 
28 enum {
29  FPGA_BUFSIZE = 512, FPGA_EP = 2
30 };
31 
32 /*
33  * wMaxPacketSize of pcm endpoints.
34  * keep synced with rates_in_packet_size and rates_out_packet_size in pcm.c
35  * fpp: frames per isopacket
36  *
37  * CAUTION: keep sizeof <= buffer[] in usb6fire_fw_init
38  */
39 static const u8 ep_w_max_packet_size[] = {
40  0xe4, 0x00, 0xe4, 0x00, /* alt 1: 228 EP2 and EP6 (7 fpp) */
41  0xa4, 0x01, 0xa4, 0x01, /* alt 2: 420 EP2 and EP6 (13 fpp)*/
42  0x94, 0x01, 0x5c, 0x02 /* alt 3: 404 EP2 and 604 EP6 (25 fpp) */
43 };
44 
45 static const u8 known_fw_versions[][4] = {
46  { 0x03, 0x01, 0x0b, 0x00 }
47 };
48 
49 struct ihex_record {
52  u8 data[256];
53  char error; /* true if an error occurred parsing this record */
54 
55  u8 max_len; /* maximum record length in whole ihex */
56 
57  /* private */
58  const char *txt_data;
59  unsigned int txt_length;
60  unsigned int txt_offset; /* current position in txt_data */
61 };
62 
63 static u8 usb6fire_fw_ihex_hex(const u8 *data, u8 *crc)
64 {
65  u8 val = 0;
66  int hval;
67 
68  hval = hex_to_bin(data[0]);
69  if (hval >= 0)
70  val |= (hval << 4);
71 
72  hval = hex_to_bin(data[1]);
73  if (hval >= 0)
74  val |= hval;
75 
76  *crc += val;
77  return val;
78 }
79 
80 /*
81  * returns true if record is available, false otherwise.
82  * iff an error occurred, false will be returned and record->error will be true.
83  */
84 static bool usb6fire_fw_ihex_next_record(struct ihex_record *record)
85 {
86  u8 crc = 0;
87  u8 type;
88  int i;
89 
90  record->error = false;
91 
92  /* find begin of record (marked by a colon) */
93  while (record->txt_offset < record->txt_length
94  && record->txt_data[record->txt_offset] != ':')
95  record->txt_offset++;
96  if (record->txt_offset == record->txt_length)
97  return false;
98 
99  /* number of characters needed for len, addr and type entries */
100  record->txt_offset++;
101  if (record->txt_offset + 8 > record->txt_length) {
102  record->error = true;
103  return false;
104  }
105 
106  record->len = usb6fire_fw_ihex_hex(record->txt_data +
107  record->txt_offset, &crc);
108  record->txt_offset += 2;
109  record->address = usb6fire_fw_ihex_hex(record->txt_data +
110  record->txt_offset, &crc) << 8;
111  record->txt_offset += 2;
112  record->address |= usb6fire_fw_ihex_hex(record->txt_data +
113  record->txt_offset, &crc);
114  record->txt_offset += 2;
115  type = usb6fire_fw_ihex_hex(record->txt_data +
116  record->txt_offset, &crc);
117  record->txt_offset += 2;
118 
119  /* number of characters needed for data and crc entries */
120  if (record->txt_offset + 2 * (record->len + 1) > record->txt_length) {
121  record->error = true;
122  return false;
123  }
124  for (i = 0; i < record->len; i++) {
125  record->data[i] = usb6fire_fw_ihex_hex(record->txt_data
126  + record->txt_offset, &crc);
127  record->txt_offset += 2;
128  }
129  usb6fire_fw_ihex_hex(record->txt_data + record->txt_offset, &crc);
130  if (crc) {
131  record->error = true;
132  return false;
133  }
134 
135  if (type == 1 || !record->len) /* eof */
136  return false;
137  else if (type == 0)
138  return true;
139  else {
140  record->error = true;
141  return false;
142  }
143 }
144 
145 static int usb6fire_fw_ihex_init(const struct firmware *fw,
146  struct ihex_record *record)
147 {
148  record->txt_data = fw->data;
149  record->txt_length = fw->size;
150  record->txt_offset = 0;
151  record->max_len = 0;
152  /* read all records, if loop ends, record->error indicates,
153  * whether ihex is valid. */
154  while (usb6fire_fw_ihex_next_record(record))
155  record->max_len = max(record->len, record->max_len);
156  if (record->error)
157  return -EINVAL;
158  record->txt_offset = 0;
159  return 0;
160 }
161 
162 static int usb6fire_fw_ezusb_write(struct usb_device *device,
163  int type, int value, char *data, int len)
164 {
165  int ret;
166 
167  ret = usb_control_msg(device, usb_sndctrlpipe(device, 0), type,
169  value, 0, data, len, HZ);
170  if (ret < 0)
171  return ret;
172  else if (ret != len)
173  return -EIO;
174  return 0;
175 }
176 
177 static int usb6fire_fw_ezusb_read(struct usb_device *device,
178  int type, int value, char *data, int len)
179 {
180  int ret = usb_control_msg(device, usb_rcvctrlpipe(device, 0), type,
182  0, data, len, HZ);
183  if (ret < 0)
184  return ret;
185  else if (ret != len)
186  return -EIO;
187  return 0;
188 }
189 
190 static int usb6fire_fw_fpga_write(struct usb_device *device,
191  char *data, int len)
192 {
193  int actual_len;
194  int ret;
195 
196  ret = usb_bulk_msg(device, usb_sndbulkpipe(device, FPGA_EP), data, len,
197  &actual_len, HZ);
198  if (ret < 0)
199  return ret;
200  else if (actual_len != len)
201  return -EIO;
202  return 0;
203 }
204 
205 static int usb6fire_fw_ezusb_upload(
206  struct usb_interface *intf, const char *fwname,
207  unsigned int postaddr, u8 *postdata, unsigned int postlen)
208 {
209  int ret;
210  u8 data;
211  struct usb_device *device = interface_to_usbdev(intf);
212  const struct firmware *fw = NULL;
213  struct ihex_record *rec = kmalloc(sizeof(struct ihex_record),
214  GFP_KERNEL);
215 
216  if (!rec)
217  return -ENOMEM;
218 
219  ret = request_firmware(&fw, fwname, &device->dev);
220  if (ret < 0) {
221  kfree(rec);
222  snd_printk(KERN_ERR PREFIX "error requesting ezusb "
223  "firmware %s.\n", fwname);
224  return ret;
225  }
226  ret = usb6fire_fw_ihex_init(fw, rec);
227  if (ret < 0) {
228  kfree(rec);
229  release_firmware(fw);
230  snd_printk(KERN_ERR PREFIX "error validating ezusb "
231  "firmware %s.\n", fwname);
232  return ret;
233  }
234  /* upload firmware image */
235  data = 0x01; /* stop ezusb cpu */
236  ret = usb6fire_fw_ezusb_write(device, 0xa0, 0xe600, &data, 1);
237  if (ret < 0) {
238  kfree(rec);
239  release_firmware(fw);
240  snd_printk(KERN_ERR PREFIX "unable to upload ezusb "
241  "firmware %s: begin message.\n", fwname);
242  return ret;
243  }
244 
245  while (usb6fire_fw_ihex_next_record(rec)) { /* write firmware */
246  ret = usb6fire_fw_ezusb_write(device, 0xa0, rec->address,
247  rec->data, rec->len);
248  if (ret < 0) {
249  kfree(rec);
250  release_firmware(fw);
251  snd_printk(KERN_ERR PREFIX "unable to upload ezusb "
252  "firmware %s: data urb.\n", fwname);
253  return ret;
254  }
255  }
256 
257  release_firmware(fw);
258  kfree(rec);
259  if (postdata) { /* write data after firmware has been uploaded */
260  ret = usb6fire_fw_ezusb_write(device, 0xa0, postaddr,
261  postdata, postlen);
262  if (ret < 0) {
263  snd_printk(KERN_ERR PREFIX "unable to upload ezusb "
264  "firmware %s: post urb.\n", fwname);
265  return ret;
266  }
267  }
268 
269  data = 0x00; /* resume ezusb cpu */
270  ret = usb6fire_fw_ezusb_write(device, 0xa0, 0xe600, &data, 1);
271  if (ret < 0) {
272  snd_printk(KERN_ERR PREFIX "unable to upload ezusb "
273  "firmware %s: end message.\n", fwname);
274  return ret;
275  }
276  return 0;
277 }
278 
279 static int usb6fire_fw_fpga_upload(
280  struct usb_interface *intf, const char *fwname)
281 {
282  int ret;
283  int i;
284  struct usb_device *device = interface_to_usbdev(intf);
286  const char *c;
287  const char *end;
288  const struct firmware *fw;
289 
290  if (!buffer)
291  return -ENOMEM;
292 
293  ret = request_firmware(&fw, fwname, &device->dev);
294  if (ret < 0) {
295  snd_printk(KERN_ERR PREFIX "unable to get fpga firmware %s.\n",
296  fwname);
297  kfree(buffer);
298  return -EIO;
299  }
300 
301  c = fw->data;
302  end = fw->data + fw->size;
303 
304  ret = usb6fire_fw_ezusb_write(device, 8, 0, NULL, 0);
305  if (ret < 0) {
306  kfree(buffer);
307  release_firmware(fw);
308  snd_printk(KERN_ERR PREFIX "unable to upload fpga firmware: "
309  "begin urb.\n");
310  return ret;
311  }
312 
313  while (c != end) {
314  for (i = 0; c != end && i < FPGA_BUFSIZE; i++, c++)
315  buffer[i] = byte_rev_table[(u8) *c];
316 
317  ret = usb6fire_fw_fpga_write(device, buffer, i);
318  if (ret < 0) {
319  release_firmware(fw);
320  kfree(buffer);
321  snd_printk(KERN_ERR PREFIX "unable to upload fpga "
322  "firmware: fw urb.\n");
323  return ret;
324  }
325  }
326  release_firmware(fw);
327  kfree(buffer);
328 
329  ret = usb6fire_fw_ezusb_write(device, 9, 0, NULL, 0);
330  if (ret < 0) {
331  snd_printk(KERN_ERR PREFIX "unable to upload fpga firmware: "
332  "end urb.\n");
333  return ret;
334  }
335  return 0;
336 }
337 
338 /* check, if the firmware version the devices has currently loaded
339  * is known by this driver. 'version' needs to have 4 bytes version
340  * info data. */
341 static int usb6fire_fw_check(u8 *version)
342 {
343  int i;
344 
345  for (i = 0; i < ARRAY_SIZE(known_fw_versions); i++)
346  if (!memcmp(version, known_fw_versions + i, 4))
347  return 0;
348 
349  snd_printk(KERN_ERR PREFIX "invalid fimware version in device: %*ph. "
350  "please reconnect to power. if this failure "
351  "still happens, check your firmware installation.",
352  4, version);
353  return -EINVAL;
354 }
355 
357 {
358  int i;
359  int ret;
360  struct usb_device *device = interface_to_usbdev(intf);
361  /* buffer: 8 receiving bytes from device and
362  * sizeof(EP_W_MAX_PACKET_SIZE) bytes for non-const copy */
363  u8 buffer[12];
364 
365  ret = usb6fire_fw_ezusb_read(device, 1, 0, buffer, 8);
366  if (ret < 0) {
367  snd_printk(KERN_ERR PREFIX "unable to receive device "
368  "firmware state.\n");
369  return ret;
370  }
371  if (buffer[0] != 0xeb || buffer[1] != 0xaa || buffer[2] != 0x55) {
372  snd_printk(KERN_ERR PREFIX "unknown device firmware state "
373  "received from device: ");
374  for (i = 0; i < 8; i++)
375  snd_printk("%02x ", buffer[i]);
376  snd_printk("\n");
377  return -EIO;
378  }
379  /* do we need fpga loader ezusb firmware? */
380  if (buffer[3] == 0x01) {
381  ret = usb6fire_fw_ezusb_upload(intf,
382  "6fire/dmx6firel2.ihx", 0, NULL, 0);
383  if (ret < 0)
384  return ret;
385  return FW_NOT_READY;
386  }
387  /* do we need fpga firmware and application ezusb firmware? */
388  else if (buffer[3] == 0x02) {
389  ret = usb6fire_fw_check(buffer + 4);
390  if (ret < 0)
391  return ret;
392  ret = usb6fire_fw_fpga_upload(intf, "6fire/dmx6firecf.bin");
393  if (ret < 0)
394  return ret;
395  memcpy(buffer, ep_w_max_packet_size,
396  sizeof(ep_w_max_packet_size));
397  ret = usb6fire_fw_ezusb_upload(intf, "6fire/dmx6fireap.ihx",
398  0x0003, buffer, sizeof(ep_w_max_packet_size));
399  if (ret < 0)
400  return ret;
401  return FW_NOT_READY;
402  }
403  /* all fw loaded? */
404  else if (buffer[3] == 0x03)
405  return usb6fire_fw_check(buffer + 4);
406  /* unknown data? */
407  else {
408  snd_printk(KERN_ERR PREFIX "unknown device firmware state "
409  "received from device: ");
410  for (i = 0; i < 8; i++)
411  snd_printk("%02x ", buffer[i]);
412  snd_printk("\n");
413  return -EIO;
414  }
415  return 0;
416 }
417