Staging: comedi: convert usbdux* to use firmware_request

The firmware is now in the linux-firmware tree, so we can move these two
drivers to use the proper request_firmware infrastructure.


From: Bernd Porr <BerndPorr@f2s.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
Bernd Porr 2009-04-17 21:21:46 +01:00 committed by Greg Kroah-Hartman
parent ff89514f8d
commit 81874ff789
2 changed files with 82 additions and 286 deletions

View File

@ -809,32 +809,56 @@ static int usbduxsub_upload(struct usbduxsub *usbduxsub,
return 0; return 0;
} }
static int firmwareUpload(struct usbduxsub *usbduxsub, uint8_t *firmwareBinary, #define FIRMWARE_MAX_LEN 0x2000
static int firmwareUpload(struct usbduxsub *usbduxsub,
const u8 *firmwareBinary,
int sizeFirmware) int sizeFirmware)
{ {
int ret; int ret;
uint8_t *fwBuf;
if (!firmwareBinary) if (!firmwareBinary)
return 0; return 0;
if (sizeFirmware>FIRMWARE_MAX_LEN) {
dev_err(&usbduxsub->interface->dev,
"comedi_: usbdux firmware binary it too large for FX2.\n");
return -ENOMEM;
}
/* we generate a local buffer for the firmware */
fwBuf = kzalloc(sizeFirmware, GFP_KERNEL);
if (!fwBuf) {
dev_err(&usbduxsub->interface->dev,
"comedi_: mem alloc for firmware failed\n");
return -ENOMEM;
}
memcpy(fwBuf,firmwareBinary,sizeFirmware);
ret = usbduxsub_stop(usbduxsub); ret = usbduxsub_stop(usbduxsub);
if (ret < 0) { if (ret < 0) {
dev_err(&usbduxsub->interface->dev, dev_err(&usbduxsub->interface->dev,
"comedi_: can not stop firmware\n"); "comedi_: can not stop firmware\n");
kfree(fwBuf);
return ret; return ret;
} }
ret = usbduxsub_upload(usbduxsub, firmwareBinary, 0, sizeFirmware);
ret = usbduxsub_upload(usbduxsub, fwBuf, 0, sizeFirmware);
if (ret < 0) { if (ret < 0) {
dev_err(&usbduxsub->interface->dev, dev_err(&usbduxsub->interface->dev,
"comedi_: firmware upload failed\n"); "comedi_: firmware upload failed\n");
kfree(fwBuf);
return ret; return ret;
} }
ret = usbduxsub_start(usbduxsub); ret = usbduxsub_start(usbduxsub);
if (ret < 0) { if (ret < 0) {
dev_err(&usbduxsub->interface->dev, dev_err(&usbduxsub->interface->dev,
"comedi_: can not start firmware\n"); "comedi_: can not start firmware\n");
kfree(fwBuf);
return ret; return ret;
} }
kfree(fwBuf);
return 0; return 0;
} }
@ -2260,134 +2284,6 @@ static void tidy_up(struct usbduxsub *usbduxsub_tmp)
usbduxsub_tmp->pwm_cmd_running = 0; usbduxsub_tmp->pwm_cmd_running = 0;
} }
static unsigned hex2unsigned(char *h)
{
unsigned hi, lo;
if (h[0] > '9')
hi = h[0] - 'A' + 0x0a;
else
hi = h[0] - '0';
if (h[1] > '9')
lo = h[1] - 'A' + 0x0a;
else
lo = h[1] - '0';
return hi * 0x10 + lo;
}
/* for FX2 */
#define FIRMWARE_MAX_LEN 0x2000
/* taken from David Brownell's fxload and adjusted for this driver */
static int read_firmware(struct usbduxsub *usbduxsub, const void *firmwarePtr,
long size)
{
struct device *dev = &usbduxsub->interface->dev;
int i = 0;
unsigned char *fp = (char *)firmwarePtr;
unsigned char *firmwareBinary;
int res = 0;
int maxAddr = 0;
firmwareBinary = kzalloc(FIRMWARE_MAX_LEN, GFP_KERNEL);
if (!firmwareBinary) {
dev_err(dev, "comedi_: mem alloc for firmware failed\n");
return -ENOMEM;
}
for (;;) {
char buf[256], *cp;
char type;
int len;
int idx, off;
int j = 0;
/* get one line */
while ((i < size) && (fp[i] != 13) && (fp[i] != 10)) {
buf[j] = fp[i];
i++;
j++;
if (j >= sizeof(buf)) {
dev_err(dev, "comedi_: bogus firmware file!\n");
kfree(firmwareBinary);
return -1;
}
}
/* get rid of LF/CR/... */
while ((i < size) && ((fp[i] == 13) || (fp[i] == 10)
|| (fp[i] == 0))) {
i++;
}
buf[j] = 0;
/* dev_dbg(dev, "comedi_: buf=%s\n", buf); */
/*
* EXTENSION:
* "# comment-till-end-of-line", for copyrights etc
*/
if (buf[0] == '#')
continue;
if (buf[0] != ':') {
dev_err(dev, "comedi_: upload: not an ihex record: %s",
buf);
kfree(firmwareBinary);
return -EFAULT;
}
/* Read the length field (up to 16 bytes) */
len = hex2unsigned(buf + 1);
/* Read the target offset */
off = (hex2unsigned(buf + 3) * 0x0100) + hex2unsigned(buf + 5);
if ((off + len) > maxAddr)
maxAddr = off + len;
if (maxAddr >= FIRMWARE_MAX_LEN) {
dev_err(dev, "comedi_: firmware upload goes "
"beyond FX2 RAM boundaries.\n");
kfree(firmwareBinary);
return -EFAULT;
}
/* dev_dbg(dev, "comedi_: off=%x, len=%x:\n", off, len); */
/* Read the record type */
type = hex2unsigned(buf + 7);
/* If this is an EOF record, then make it so. */
if (type == 1)
break;
if (type != 0) {
dev_err(dev, "comedi_: unsupported record type: %u\n",
type);
kfree(firmwareBinary);
return -EFAULT;
}
for (idx = 0, cp = buf + 9; idx < len; idx += 1, cp += 2) {
firmwareBinary[idx + off] = hex2unsigned(cp);
/*printk("%02x ",firmwareBinary[idx+off]); */
}
/*printk("\n"); */
if (i >= size) {
dev_err(dev, "comedi_: unexpected end of hex file\n");
break;
}
}
res = firmwareUpload(usbduxsub, firmwareBinary, maxAddr + 1);
kfree(firmwareBinary);
return res;
}
static void usbdux_firmware_request_complete_handler(const struct firmware *fw, static void usbdux_firmware_request_complete_handler(const struct firmware *fw,
void *context) void *context)
{ {
@ -2405,7 +2301,7 @@ static void usbdux_firmware_request_complete_handler(const struct firmware *fw,
* we need to upload the firmware here because fw will be * we need to upload the firmware here because fw will be
* freed once we've left this function * freed once we've left this function
*/ */
ret = read_firmware(usbduxsub_tmp, fw->data, fw->size); ret = firmwareUpload(usbduxsub_tmp, fw->data, fw->size);
if (ret) { if (ret) {
dev_err(&usbdev->dev, dev_err(&usbdev->dev,
@ -2662,11 +2558,13 @@ static int usbduxsub_probe(struct usb_interface *uinterf,
ret = request_firmware_nowait(THIS_MODULE, ret = request_firmware_nowait(THIS_MODULE,
FW_ACTION_HOTPLUG, FW_ACTION_HOTPLUG,
"usbdux_firmware.hex", "usbdux_firmware.bin",
&udev->dev, &udev->dev,
usbduxsub + index, usbduxsub + index,
usbdux_firmware_request_complete_handler); usbdux_firmware_request_complete_handler);
if (ret) { if (ret) {
dev_err(dev, "Could not load firmware (err=%d)\n", ret); dev_err(dev, "Could not load firmware (err=%d)\n", ret);
return ret; return ret;
@ -2739,8 +2637,8 @@ static int usbdux_attach(struct comedi_device *dev, struct comedi_devconfig *it)
/* trying to upload the firmware into the chip */ /* trying to upload the firmware into the chip */
if (comedi_aux_data(it->options, 0) && if (comedi_aux_data(it->options, 0) &&
it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]) { it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]) {
read_firmware(udev, comedi_aux_data(it->options, 0), firmwareUpload(udev, comedi_aux_data(it->options, 0),
it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]); it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]);
} }
dev->board_name = BOARDNAME; dev->board_name = BOARDNAME;

View File

@ -524,33 +524,6 @@ static int usbduxfastsub_upload(struct usbduxfastsub_s *udfs,
return 0; return 0;
} }
int firmwareUpload(struct usbduxfastsub_s *udfs, unsigned char *firmwareBinary,
int sizeFirmware)
{
int ret;
if (!firmwareBinary)
return 0;
ret = usbduxfastsub_stop(udfs);
if (ret < 0) {
printk(KERN_ERR "comedi_: usbduxfast: can not stop firmware\n");
return ret;
}
ret = usbduxfastsub_upload(udfs, firmwareBinary, 0, sizeFirmware);
if (ret < 0) {
printk(KERN_ERR "comedi_: usbduxfast: firmware upload failed\n");
return ret;
}
ret = usbduxfastsub_start(udfs);
if (ret < 0) {
printk(KERN_ERR "comedi_: usbduxfast: can not start firmware\n");
return ret;
}
return 0;
}
int usbduxfastsub_submit_InURBs(struct usbduxfastsub_s *udfs) int usbduxfastsub_submit_InURBs(struct usbduxfastsub_s *udfs)
{ {
int ret; int ret;
@ -1365,136 +1338,61 @@ static int usbduxfast_ai_insn_read(struct comedi_device *dev,
return i; return i;
} }
static unsigned hex2unsigned(char *h)
{
unsigned hi, lo;
if (h[0] > '9')
hi = h[0] - 'A' + 0x0a;
else
hi = h[0] - '0';
if (h[1] > '9')
lo = h[1] - 'A' + 0x0a;
else
lo = h[1] - '0';
return hi * 0x10 + lo;
}
/* for FX2 */
#define FIRMWARE_MAX_LEN 0x2000 #define FIRMWARE_MAX_LEN 0x2000
/* static int firmwareUpload(struct usbduxfastsub_s *usbduxfastsub,
* taken from David Brownell's fxload and adjusted for this driver const u8 *firmwareBinary,
*/ int sizeFirmware)
static int read_firmware(struct usbduxfastsub_s *udfs, const void *firmwarePtr,
long size)
{ {
int i = 0; int ret;
unsigned char *fp = (char *)firmwarePtr; uint8_t *fwBuf;
unsigned char *firmwareBinary;
int res = 0;
int maxAddr = 0;
firmwareBinary = kmalloc(FIRMWARE_MAX_LEN, GFP_KERNEL); if (!firmwareBinary)
if (!firmwareBinary) { return 0;
printk(KERN_ERR "comedi_: usbduxfast: mem alloc for firmware "
" failed\n"); if (sizeFirmware>FIRMWARE_MAX_LEN) {
dev_err(&usbduxfastsub->interface->dev,
"comedi_: usbduxfast firmware binary it too large for FX2.\n");
return -ENOMEM; return -ENOMEM;
} }
for (;;) { /* we generate a local buffer for the firmware */
char buf[256], *cp; fwBuf = kzalloc(sizeFirmware, GFP_KERNEL);
char type; if (!fwBuf) {
int len; dev_err(&usbduxfastsub->interface->dev,
int idx, off; "comedi_: mem alloc for firmware failed\n");
int j = 0; return -ENOMEM;
/* get one line */
while ((i < size) && (fp[i] != 13) && (fp[i] != 10)) {
buf[j] = fp[i];
i++;
j++;
if (j >= sizeof(buf)) {
printk(KERN_ERR "comedi_: usbduxfast: bogus "
"firmware file!\n");
kfree(firmwareBinary);
return -1;
}
}
/* get rid of LF/CR/... */
while ((i < size) && ((fp[i] == 13) || (fp[i] == 10)
|| (fp[i] == 0)))
i++;
buf[j] = 0;
/* printk("comedi_: buf=%s\n",buf); */
/*
* EXTENSION: "# comment-till-end-of-line",
* for copyrights etc
*/
if (buf[0] == '#')
continue;
if (buf[0] != ':') {
printk(KERN_ERR "comedi_: usbduxfast: upload: not an "
"ihex record: %s", buf);
kfree(firmwareBinary);
return -EFAULT;
}
/* Read the length field (up to 16 bytes) */
len = hex2unsigned(buf + 1);
/* Read the target offset */
off = (hex2unsigned(buf + 3) * 0x0100) + hex2unsigned(buf + 5);
if ((off + len) > maxAddr)
maxAddr = off + len;
if (maxAddr >= FIRMWARE_MAX_LEN) {
printk(KERN_ERR "comedi_: usbduxfast: firmware upload "
"goes beyond FX2 RAM boundaries.");
kfree(firmwareBinary);
return -EFAULT;
}
/* printk("comedi_: usbduxfast: off=%x, len=%x:",off,len); */
/* Read the record type */
type = hex2unsigned(buf + 7);
/* If this is an EOF record, then make it so. */
if (type == 1)
break;
if (type != 0) {
printk(KERN_ERR "comedi_: usbduxfast: unsupported "
"record type: %u\n", type);
kfree(firmwareBinary);
return -EFAULT;
}
for (idx = 0, cp = buf + 9; idx < len; idx += 1, cp += 2) {
firmwareBinary[idx + off] = hex2unsigned(cp);
/* printk("%02x ",firmwareBinary[idx+off]); */
}
/* printk("\n"); */
if (i >= size) {
printk(KERN_ERR "comedi_: usbduxfast: unexpected end "
"of hex file\n");
break;
}
} }
res = firmwareUpload(udfs, firmwareBinary, maxAddr + 1); memcpy(fwBuf,firmwareBinary,sizeFirmware);
kfree(firmwareBinary);
return res; ret = usbduxfastsub_stop(usbduxfastsub);
if (ret < 0) {
dev_err(&usbduxfastsub->interface->dev,
"comedi_: can not stop firmware\n");
kfree(fwBuf);
return ret;
}
ret = usbduxfastsub_upload(usbduxfastsub, fwBuf, 0, sizeFirmware);
if (ret < 0) {
dev_err(&usbduxfastsub->interface->dev,
"comedi_: firmware upload failed\n");
kfree(fwBuf);
return ret;
}
ret = usbduxfastsub_start(usbduxfastsub);
if (ret < 0) {
dev_err(&usbduxfastsub->interface->dev,
"comedi_: can not start firmware\n");
kfree(fwBuf);
return ret;
}
kfree(fwBuf);
return 0;
} }
static void tidy_up(struct usbduxfastsub_s *udfs) static void tidy_up(struct usbduxfastsub_s *udfs)
{ {
#ifdef CONFIG_COMEDI_DEBUG #ifdef CONFIG_COMEDI_DEBUG
@ -1544,7 +1442,7 @@ static void usbduxfast_firmware_request_complete_handler(const struct firmware *
* we need to upload the firmware here because fw will be * we need to upload the firmware here because fw will be
* freed once we've left this function * freed once we've left this function
*/ */
ret = read_firmware(usbduxfastsub_tmp, fw->data, fw->size); ret = firmwareUpload(usbduxfastsub_tmp, fw->data, fw->size);
if (ret) { if (ret) {
dev_err(&usbdev->dev, dev_err(&usbdev->dev,
@ -1666,7 +1564,7 @@ static int usbduxfastsub_probe(struct usb_interface *uinterf,
ret = request_firmware_nowait(THIS_MODULE, ret = request_firmware_nowait(THIS_MODULE,
FW_ACTION_HOTPLUG, FW_ACTION_HOTPLUG,
"usbduxfast_firmware.hex", "usbduxfast_firmware.bin",
&udev->dev, &udev->dev,
usbduxfastsub + index, usbduxfastsub + index,
usbduxfast_firmware_request_complete_handler); usbduxfast_firmware_request_complete_handler);
@ -1751,9 +1649,9 @@ static int usbduxfast_attach(struct comedi_device *dev, struct comedi_devconfig
/* trying to upload the firmware into the chip */ /* trying to upload the firmware into the chip */
if (comedi_aux_data(it->options, 0) && if (comedi_aux_data(it->options, 0) &&
it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]) { it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]) {
read_firmware(&usbduxfastsub[index], firmwareUpload(&usbduxfastsub[index],
comedi_aux_data(it->options, 0), comedi_aux_data(it->options, 0),
it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]); it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]);
} }
dev->board_name = BOARDNAME; dev->board_name = BOARDNAME;