Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/drivers/media/usb/as102/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 5 kB image not shown  

Quelle  as102_fw.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Abilis Systems Single DVB-T Receiver
 * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
 * Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com>
 */

#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/ctype.h>
#include <linux/delay.h>
#include <linux/firmware.h>

#include "as102_drv.h"
#include "as102_fw.h"

static const char as102_st_fw1[] = "as102_data1_st.hex";
static const char as102_st_fw2[] = "as102_data2_st.hex";
static const char as102_dt_fw1[] = "as102_data1_dt.hex";
static const char as102_dt_fw2[] = "as102_data2_dt.hex";

static unsigned char atohx(unsigned char *dst, char *src)
{
 unsigned char value = 0;

 char msb = tolower(*src) - '0';
 char lsb = tolower(*(src + 1)) - '0';

 if (msb > 9)
  msb -= 7;
 if (lsb > 9)
  lsb -= 7;

 *dst = value = ((msb & 0xF) << 4) | (lsb & 0xF);
 return value;
}

/*
 * Parse INTEL HEX firmware file to extract address and data.
 */

static int parse_hex_line(unsigned char *fw_data, unsigned char *addr,
     unsigned char *data, int *dataLength,
     unsigned char *addr_has_changed) {

 int count = 0;
 unsigned char *src, dst;

 if (*fw_data++ != ':') {
  pr_err("invalid firmware file\n");
  return -EFAULT;
 }

 /* locate end of line */
 for (src = fw_data; *src != '\n'; src += 2) {
  atohx(&dst, src);
  /* parse line to split addr / data */
  switch (count) {
  case 0:
   *dataLength = dst;
   break;
  case 1:
   addr[2] = dst;
   break;
  case 2:
   addr[3] = dst;
   break;
  case 3:
   /* check if data is an address */
   if (dst == 0x04)
    *addr_has_changed = 1;
   else
    *addr_has_changed = 0;
   break;
  case  4:
  case  5:
   if (*addr_has_changed)
    addr[(count - 4)] = dst;
   else
    data[(count - 4)] = dst;
   break;
  default:
   data[(count - 4)] = dst;
   break;
  }
  count++;
 }

 /* return read value + ':' + '\n' */
 return (count * 2) + 2;
}

static int as102_firmware_upload(struct as10x_bus_adapter_t *bus_adap,
     unsigned char *cmd,
     const struct firmware *firmware) {

 struct as10x_fw_pkt_t *fw_pkt;
 int total_read_bytes = 0, errno = 0;
 unsigned char addr_has_changed = 0;

 fw_pkt = kmalloc(sizeof(*fw_pkt), GFP_KERNEL);
 if (!fw_pkt)
  return -ENOMEM;


 for (total_read_bytes = 0; total_read_bytes < firmware->size; ) {
  int read_bytes = 0, data_len = 0;

  /* parse intel hex line */
  read_bytes = parse_hex_line(
    (u8 *) (firmware->data + total_read_bytes),
    fw_pkt->raw.address,
    fw_pkt->raw.data,
    &data_len,
    &addr_has_changed);

  if (read_bytes <= 0)
   goto error;

  /* detect the end of file */
  total_read_bytes += read_bytes;
  if (total_read_bytes == firmware->size) {
   fw_pkt->u.request[0] = 0x00;
   fw_pkt->u.request[1] = 0x03;

   /* send EOF command */
   errno = bus_adap->ops->upload_fw_pkt(bus_adap,
            (uint8_t *)
            fw_pkt, 2, 0);
   if (errno < 0)
    goto error;
  } else {
   if (!addr_has_changed) {
    /* prepare command to send */
    fw_pkt->u.request[0] = 0x00;
    fw_pkt->u.request[1] = 0x01;

    data_len += sizeof(fw_pkt->u.request);
    data_len += sizeof(fw_pkt->raw.address);

    /* send cmd to device */
    errno = bus_adap->ops->upload_fw_pkt(bus_adap,
             (uint8_t *)
             fw_pkt,
             data_len,
             0);
    if (errno < 0)
     goto error;
   }
  }
 }
error:
 kfree(fw_pkt);
 return (errno == 0) ? total_read_bytes : errno;
}

int as102_fw_upload(struct as10x_bus_adapter_t *bus_adap)
{
 int errno = -EFAULT;
 const struct firmware *firmware = NULL;
 unsigned char *cmd_buf = NULL;
 const char *fw1, *fw2;
 struct usb_device *dev = bus_adap->usb_dev;

 /* select fw file to upload */
 if (dual_tuner) {
  fw1 = as102_dt_fw1;
  fw2 = as102_dt_fw2;
 } else {
  fw1 = as102_st_fw1;
  fw2 = as102_st_fw2;
 }

 /* allocate buffer to store firmware upload command and data */
 cmd_buf = kzalloc(MAX_FW_PKT_SIZE, GFP_KERNEL);
 if (cmd_buf == NULL) {
  errno = -ENOMEM;
  goto error;
 }

 /* request kernel to locate firmware file: part1 */
 errno = request_firmware(&firmware, fw1, &dev->dev);
 if (errno < 0) {
  pr_err("%s: unable to locate firmware file: %s\n",
         DRIVER_NAME, fw1);
  goto error;
 }

 /* initiate firmware upload */
 errno = as102_firmware_upload(bus_adap, cmd_buf, firmware);
 if (errno < 0) {
  pr_err("%s: error during firmware upload part1\n",
         DRIVER_NAME);
  goto error;
 }

 pr_info("%s: firmware: %s loaded with success\n",
  DRIVER_NAME, fw1);
 release_firmware(firmware);
 firmware = NULL;

 /* wait for boot to complete */
 mdelay(100);

 /* request kernel to locate firmware file: part2 */
 errno = request_firmware(&firmware, fw2, &dev->dev);
 if (errno < 0) {
  pr_err("%s: unable to locate firmware file: %s\n",
         DRIVER_NAME, fw2);
  goto error;
 }

 /* initiate firmware upload */
 errno = as102_firmware_upload(bus_adap, cmd_buf, firmware);
 if (errno < 0) {
  pr_err("%s: error during firmware upload part2\n",
         DRIVER_NAME);
  goto error;
 }

 pr_info("%s: firmware: %s loaded with success\n",
  DRIVER_NAME, fw2);
error:
 kfree(cmd_buf);
 release_firmware(firmware);

 return errno;
}

Messung V0.5
C=95 H=94 G=94

¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.