⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftdi-elan.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
                int packet_bytes = 0;                int retval = usb_bulk_msg(ftdi->udev,                        usb_rcvbulkpipe(ftdi->udev, ftdi->bulk_in_endpointAddr),                         ftdi->bulk_in_buffer, ftdi->bulk_in_size,                        &packet_bytes, msecs_to_jiffies(500));                char diag[30 *3 + 4];                char *d = diag;                int m = packet_bytes;                u8 *c = ftdi->bulk_in_buffer;                int s = (sizeof(diag) - 1) / 3;                diag[0] = 0;                while (s-- > 0 && m-- > 0) {                        if (s > 0 || m == 0) {                                d += sprintf(d, " %02X", *c++);                        } else                                d += sprintf(d, " ..");                }                if (packet_bytes > 2) {                        ftdi->bulk_in_left = packet_bytes - 2;                        ftdi->bulk_in_last = 1;                        goto have;                } else if (retval == -ETIMEDOUT) {                        if (retry_on_timeout-- > 0) {                                dev_err(&ftdi->udev->dev, "TIMED OUT with packe"                                        "t_bytes = %d with total %d bytes%s\n",                                        packet_bytes, bytes_read, diag);                                goto more;                        } else if (bytes_read > 0) {                                dev_err(&ftdi->udev->dev, "ONLY %d bytes%s\n",                                        bytes_read, diag);                                return -ENOMEM;                        } else {                                dev_err(&ftdi->udev->dev, "TIMED OUT with packe"                                        "t_bytes = %d with total %d bytes%s\n",                                        packet_bytes, bytes_read, diag);                                return -ENOMEM;                        }                } else if (retval == -EILSEQ) {                        dev_err(&ftdi->udev->dev, "error = %d with packet_bytes"                                " = %d with total %d bytes%s\n", retval,                                packet_bytes, bytes_read, diag);                        return retval;                } else if (retval) {                        dev_err(&ftdi->udev->dev, "error = %d with packet_bytes"                                " = %d with total %d bytes%s\n", retval,                                packet_bytes, bytes_read, diag);                        return retval;                } else if (packet_bytes == 2) {                        unsigned char s0 = ftdi->bulk_in_buffer[0];                        unsigned char s1 = ftdi->bulk_in_buffer[1];                        empty_packets += 1;                        if (s0 == 0x31 && s1 == 0x60) {                                if (retry_on_empty-- > 0) {                                        goto more;                                } else                                        return 0;                        } else if (s0 == 0x31 && s1 == 0x00) {                                if (retry_on_empty-- > 0) {                                        goto more;                                } else                                        return 0;                        } else {                                if (retry_on_empty-- > 0) {                                        goto more;                                } else                                        return 0;                        }                } else if (packet_bytes == 1) {                        if (retry_on_empty-- > 0) {                                goto more;                        } else                                return 0;                } else {                        if (retry_on_empty-- > 0) {                                goto more;                        } else                                return 0;                }        }      more:{                goto read;        }      have:if (ftdi->bulk_in_left > 0) {                u8 c = ftdi->bulk_in_buffer[++ftdi->bulk_in_last];                bytes_read += 1;                ftdi->bulk_in_left -= 1;                if (ftdi->recieved == 0 && c == 0xFF) {                        goto have;                } else                        *b++ = c;                if (++ftdi->recieved < ftdi->expected) {                        goto have;                } else if (ftdi->ed_found) {                        int ed_number = (ftdi->response[0] >> 5) & 0x03;                        u16 ed_length = (ftdi->response[2] << 8) |                                ftdi->response[1];                        struct u132_target *target = &ftdi->target[ed_number];                        int payload = (ed_length >> 0) & 0x07FF;                        char diag[30 *3 + 4];                        char *d = diag;                        int m = payload;                        u8 *c = 4 + ftdi->response;                        int s = (sizeof(diag) - 1) / 3;                        diag[0] = 0;                        while (s-- > 0 && m-- > 0) {                                if (s > 0 || m == 0) {                                        d += sprintf(d, " %02X", *c++);                                } else                                        d += sprintf(d, " ..");                        }                        ftdi_elan_do_callback(ftdi, target, 4 + ftdi->response,                                payload);                        ftdi->recieved = 0;                        ftdi->expected = 4;                        ftdi->ed_found = 0;                        b = ftdi->response;                        goto have;                } else if (ftdi->expected == 8) {                        u8 buscmd;                        int respond_head = ftdi->respond_head++;                        struct u132_respond *respond = &ftdi->respond[                                RESPOND_MASK & respond_head];                        u32 data = ftdi->response[7];                        data <<= 8;                        data |= ftdi->response[6];                        data <<= 8;                        data |= ftdi->response[5];                        data <<= 8;                        data |= ftdi->response[4];                        *respond->value = data;                        *respond->result = 0;                        complete(&respond->wait_completion);                        ftdi->recieved = 0;                        ftdi->expected = 4;                        ftdi->ed_found = 0;                        b = ftdi->response;                        buscmd = (ftdi->response[0] >> 0) & 0x0F;                        if (buscmd == 0x00) {                        } else if (buscmd == 0x02) {                        } else if (buscmd == 0x06) {                        } else if (buscmd == 0x0A) {                        } else                                dev_err(&ftdi->udev->dev, "Uxxx unknown(%0X) va"                                        "lue = %08X\n", buscmd, data);                        goto have;                } else {                        if ((ftdi->response[0] & 0x80) == 0x00) {                                ftdi->expected = 8;                                goto have;                        } else {                                int ed_number = (ftdi->response[0] >> 5) & 0x03;                                int ed_type = (ftdi->response[0] >> 0) & 0x03;                                u16 ed_length = (ftdi->response[2] << 8) |                                        ftdi->response[1];                                struct u132_target *target = &ftdi->target[                                        ed_number];                                target->halted = (ftdi->response[0] >> 3) &                                        0x01;                                target->skipped = (ftdi->response[0] >> 2) &                                        0x01;                                target->toggle_bits = (ftdi->response[3] >> 6)                                        & 0x03;                                target->error_count = (ftdi->response[3] >> 4)                                        & 0x03;                                target->condition_code = (ftdi->response[                                        3] >> 0) & 0x0F;                                if ((ftdi->response[0] & 0x10) == 0x00) {                                        b = have_ed_set_response(ftdi, target,                                                ed_length, ed_number, ed_type,                                                b);                                        goto have;                                } else {                                        b = have_ed_get_response(ftdi, target,                                                ed_length, ed_number, ed_type,                                                b);                                        goto have;                                }                        }                }        } else                goto more;}/** create a urb, and a buffer for it, and copy the data to the urb**/static ssize_t ftdi_elan_write(struct file *file,			       const char __user *user_buffer, size_t count,			       loff_t *ppos){        int retval = 0;        struct urb *urb;        char *buf;        struct usb_ftdi *ftdi = file->private_data;        if (ftdi->disconnected > 0) {                return -ENODEV;        }        if (count == 0) {                goto exit;        }        urb = usb_alloc_urb(0, GFP_KERNEL);        if (!urb) {                retval = -ENOMEM;                goto error_1;        }        buf = usb_buffer_alloc(ftdi->udev, count, GFP_KERNEL,                &urb->transfer_dma);        if (!buf) {                retval = -ENOMEM;                goto error_2;        }        if (copy_from_user(buf, user_buffer, count)) {                retval = -EFAULT;                goto error_3;        }        usb_fill_bulk_urb(urb, ftdi->udev, usb_sndbulkpipe(ftdi->udev,                ftdi->bulk_out_endpointAddr), buf, count,                ftdi_elan_write_bulk_callback, ftdi);        urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;        retval = usb_submit_urb(urb, GFP_KERNEL);        if (retval) {                dev_err(&ftdi->udev->dev, "failed submitting write urb, error %"                        "d\n", retval);                goto error_3;        }        usb_free_urb(urb);exit:        return count;error_3:	usb_buffer_free(ftdi->udev, count, buf, urb->transfer_dma);error_2:	usb_free_urb(urb);error_1:	return retval;}static const struct file_operations ftdi_elan_fops = {        .owner = THIS_MODULE,        .llseek = no_llseek,        .ioctl = ftdi_elan_ioctl,        .read = ftdi_elan_read,        .write = ftdi_elan_write,        .open = ftdi_elan_open,        .release = ftdi_elan_release,};/** usb class driver info in order to get a minor number from the usb core,* and to have the device registered with the driver core*/static struct usb_class_driver ftdi_elan_jtag_class = {        .name = "ftdi-%d-jtag",        .fops = &ftdi_elan_fops,        .minor_base = USB_FTDI_ELAN_MINOR_BASE,};/** the following definitions are for the* ELAN FPGA state machgine processor that* lies on the other side of the FTDI chip*/#define cPCIu132rd 0x0#define cPCIu132wr 0x1#define cPCIiord 0x2#define cPCIiowr 0x3#define cPCImemrd 0x6#define cPCImemwr 0x7#define cPCIcfgrd 0xA#define cPCIcfgwr 0xB#define cPCInull 0xF#define cU132cmd_status 0x0#define cU132flash 0x1#define cPIDsetup 0x0#define cPIDout 0x1#define cPIDin 0x2#define cPIDinonce 0x3#define cCCnoerror 0x0#define cCCcrc 0x1#define cCCbitstuff 0x2#define cCCtoggle 0x3#define cCCstall 0x4#define cCCnoresp 0x5#define cCCbadpid1 0x6#define cCCbadpid2 0x7#define cCCdataoverrun 0x8#define cCCdataunderrun 0x9#define cCCbuffoverrun 0xC#define cCCbuffunderrun 0xD#define cCCnotaccessed 0xFstatic int ftdi_elan_write_reg(struct usb_ftdi *ftdi, u32 data){      wait:if (ftdi->disconnected > 0) {                return -ENODEV;        } else {                int command_size;                mutex_lock(&ftdi->u132_lock);                command_size = ftdi->command_next - ftdi->command_head;                if (command_size < COMMAND_SIZE) {                        struct u132_command *command = &ftdi->command[                                COMMAND_MASK & ftdi->command_next];                        command->header = 0x00 | cPCIu132wr;                        command->length = 0x04;                        command->address = 0x00;                        command->width = 0x00;                        command->follows = 4;                        command->value = data;                        command->buffer = &command->value;                        ftdi->command_next += 1;                        ftdi_elan_kick_command_queue(ftdi);                        mutex_unlock(&ftdi->u132_lock);                        return 0;                } else {                        mutex_unlock(&ftdi->u132_lock);                        msleep(100);                        goto wait;                }        }}static int ftdi_elan_write_config(struct usb_ftdi *ftdi, int config_offset,        u8 width, u32 data){        u8 addressofs = config_offset / 4;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -