[新增] 华清 源码

This commit is contained in:
gaoyang3513
2023-12-24 10:29:22 +00:00
commit 3f3b436a9f
149 changed files with 10507 additions and 0 deletions

22
usb/ex1/Makefile Executable file
View File

@ -0,0 +1,22 @@
ifeq ($(KERNELRELEASE),)
ifeq ($(ARCH),arm)
KERNELDIR ?= /home/farsight/fs4412/linux-3.14.25-fs4412
ROOTFS ?= /nfs/rootfs
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_PATH=$(ROOTFS) modules_install
clean:
rm -rf *.o *.ko .*.cmd *.mod.* modules.order Module.symvers .tmp_versions
else
obj-m := pdiusbd12.o
endif

297
usb/ex1/pdiusbd12.c Executable file
View File

@ -0,0 +1,297 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/usb.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/uaccess.h>
#include "pdiusbd12.h"
#define PDIUSBD12_MAJOR 256
#define PDIUSBD12_MINOR 10
#define PDIUSBD12_DEV_NAME "pdiusbd12"
struct pdiusbd12_dev {
int pipe_ep1_out;
int pipe_ep1_in;
int pipe_ep2_out;
int pipe_ep2_in;
int maxp_ep1_out;
int maxp_ep1_in;
int maxp_ep2_out;
int maxp_ep2_in;
struct urb *ep2inurb;
int errors;
unsigned int ep2inlen;
unsigned char ep1inbuf[16];
unsigned char ep1outbuf[16];
unsigned char ep2inbuf[64];
unsigned char ep2outbuf[64];
struct usb_device *usbdev;
wait_queue_head_t wq;
struct cdev cdev;
dev_t dev;
};
static unsigned int minor = PDIUSBD12_MINOR;
static int pdiusbd12_open(struct inode *inode, struct file *filp)
{
struct pdiusbd12_dev *pdiusbd12;
pdiusbd12 = container_of(inode->i_cdev, struct pdiusbd12_dev, cdev);
filp->private_data = pdiusbd12;
return 0;
}
static int pdiusbd12_release(struct inode *inode, struct file *filp)
{
struct pdiusbd12_dev *pdiusbd12;
pdiusbd12 = container_of(inode->i_cdev, struct pdiusbd12_dev, cdev);
usb_kill_urb(pdiusbd12->ep2inurb);
return 0;
}
void usb_read_complete(struct urb * urb)
{
struct pdiusbd12_dev *pdiusbd12 = urb->context;
switch (urb->status) {
case 0:
pdiusbd12->ep2inlen = urb->actual_length;
break;
case -ECONNRESET:
case -ENOENT:
case -ESHUTDOWN:
default:
pdiusbd12->ep2inlen = 0;
break;
}
pdiusbd12->errors = urb->status;
wake_up_interruptible(&pdiusbd12->wq);
}
static ssize_t pdiusbd12_read(struct file *filp, char __user *buf, size_t count, loff_t *f_ops)
{
int ret;
struct usb_device *usbdev;
struct pdiusbd12_dev *pdiusbd12 = filp->private_data;
count = count > sizeof(pdiusbd12->ep2inbuf) ? sizeof(pdiusbd12->ep1inbuf) : count;
ret = count;
usbdev = pdiusbd12->usbdev;
usb_fill_bulk_urb(pdiusbd12->ep2inurb, usbdev, pdiusbd12->pipe_ep2_in, pdiusbd12->ep2inbuf, ret, usb_read_complete, pdiusbd12);
if (usb_submit_urb(pdiusbd12->ep2inurb, GFP_KERNEL))
return -EIO;
interruptible_sleep_on(&pdiusbd12->wq);
if (pdiusbd12->errors)
return pdiusbd12->errors;
else {
if (copy_to_user(buf, pdiusbd12->ep2inbuf, pdiusbd12->ep2inlen))
return -EFAULT;
else
return pdiusbd12->ep2inlen;
}
}
static ssize_t pdiusbd12_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_ops)
{
int len;
ssize_t ret = 0;
struct pdiusbd12_dev *pdiusbd12 = filp->private_data;
count = count > sizeof(pdiusbd12->ep2outbuf) ? sizeof(pdiusbd12->ep2outbuf) : count;
if (copy_from_user(pdiusbd12->ep2outbuf, buf, count))
return -EFAULT;
ret = usb_bulk_msg(pdiusbd12->usbdev, pdiusbd12->pipe_ep2_out, pdiusbd12->ep2outbuf, count, &len, 10 * HZ);
if (ret)
return ret;
else
return len;
}
long pdiusbd12_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
int ret;
int len;
struct pdiusbd12_dev *pdiusbd12 = filp->private_data;
if (_IOC_TYPE(cmd) != PDIUSBD12_MAGIC)
return -ENOTTY;
switch (cmd) {
case PDIUSBD12_GET_KEY:
ret = usb_interrupt_msg(pdiusbd12->usbdev, pdiusbd12->pipe_ep1_in, pdiusbd12->ep1inbuf, 8, &len, 10 * HZ);
if (ret)
return ret;
else {
if (copy_to_user((unsigned char __user *)arg, pdiusbd12->ep1inbuf, len))
return -EFAULT;
else
return 0;
}
break;
case PDIUSBD12_SET_LED:
if (copy_from_user(pdiusbd12->ep1outbuf, (unsigned char __user *)arg, 8))
return -EFAULT;
ret = usb_interrupt_msg(pdiusbd12->usbdev, pdiusbd12->pipe_ep1_out, pdiusbd12->ep1outbuf, 8, &len, 10 * HZ);
if (ret)
return ret;
else
return 0;
default:
return -ENOTTY;
}
return 0;
}
static struct file_operations pdiusbd12_ops = {
.owner = THIS_MODULE,
.open = pdiusbd12_open,
.release = pdiusbd12_release,
.read = pdiusbd12_read,
.write = pdiusbd12_write,
.unlocked_ioctl = pdiusbd12_ioctl,
};
int pdiusbd12_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
static struct pdiusbd12_dev *pdiusbd12;
struct usb_device *usbdev;
struct usb_host_interface *interface;
struct usb_endpoint_descriptor *endpoint;
int ret = 0;
pdiusbd12 = kmalloc(sizeof(struct pdiusbd12_dev), GFP_KERNEL);
if (!pdiusbd12)
return -ENOMEM;
usbdev = interface_to_usbdev(intf);
interface = intf->cur_altsetting;
if (interface->desc.bNumEndpoints != 4) {
ret = -ENODEV;
goto out_no_dev;
}
/* EP1 Interrupt IN */
endpoint = &interface->endpoint[0].desc;
if (!(endpoint->bEndpointAddress & 0x80)) { /* IN */
ret = -ENODEV;
goto out_no_dev;
}
if ((endpoint->bmAttributes & 0x7F) != 3) { /* Interrupt */
ret = -ENODEV;
goto out_no_dev;
}
pdiusbd12->pipe_ep1_in = usb_rcvintpipe(usbdev, endpoint->bEndpointAddress);
pdiusbd12->maxp_ep1_in = usb_maxpacket(usbdev, pdiusbd12->pipe_ep1_in, usb_pipeout(pdiusbd12->pipe_ep1_in));
/* EP1 Interrupt Out */
endpoint = &interface->endpoint[1].desc;
if (endpoint->bEndpointAddress & 0x80) { /* OUT */
ret = -ENODEV;
goto out_no_dev;
}
if ((endpoint->bmAttributes & 0x7F) != 3) { /* Interrupt */
ret = -ENODEV;
goto out_no_dev;
}
pdiusbd12->pipe_ep1_out = usb_sndintpipe(usbdev, endpoint->bEndpointAddress);
pdiusbd12->maxp_ep1_out = usb_maxpacket(usbdev, pdiusbd12->pipe_ep1_out, usb_pipeout(pdiusbd12->pipe_ep1_out));
/* EP2 Bulk IN */
endpoint = &interface->endpoint[2].desc;
if (!(endpoint->bEndpointAddress & 0x80)) { /* IN */
ret = -ENODEV;
goto out_no_dev;
}
if ((endpoint->bmAttributes & 0x7F) != 2) { /* Bulk */
ret = -ENODEV;
goto out_no_dev;
}
pdiusbd12->pipe_ep2_in = usb_rcvintpipe(usbdev, endpoint->bEndpointAddress);
pdiusbd12->maxp_ep2_in = usb_maxpacket(usbdev, pdiusbd12->pipe_ep2_in, usb_pipeout(pdiusbd12->pipe_ep2_in));
endpoint = &interface->endpoint[3].desc;
if (endpoint->bEndpointAddress & 0x80) { /* OUT */
ret = -ENODEV;
goto out_no_dev;
}
if ((endpoint->bmAttributes & 0x7F) != 2) { /* Bulk */
ret = -ENODEV;
goto out_no_dev;
}
pdiusbd12->pipe_ep2_out = usb_sndintpipe(usbdev, endpoint->bEndpointAddress);
pdiusbd12->maxp_ep2_out = usb_maxpacket(usbdev, pdiusbd12->pipe_ep2_out, usb_pipeout(pdiusbd12->pipe_ep2_out));
pdiusbd12->ep2inurb = usb_alloc_urb(0, GFP_KERNEL);
pdiusbd12->usbdev = usbdev;
usb_set_intfdata(intf, pdiusbd12);
pdiusbd12->dev = MKDEV(PDIUSBD12_MAJOR, minor++);
ret = register_chrdev_region (pdiusbd12->dev, 1, PDIUSBD12_DEV_NAME);
if (ret < 0)
goto out_reg_region;
cdev_init(&pdiusbd12->cdev, &pdiusbd12_ops);
pdiusbd12->cdev.owner = THIS_MODULE;
ret = cdev_add(&pdiusbd12->cdev, pdiusbd12->dev, 1);
if (ret)
goto out_cdev_add;
init_waitqueue_head(&pdiusbd12->wq);
return 0;
out_cdev_add:
unregister_chrdev_region(pdiusbd12->dev, 1);
out_reg_region:
usb_free_urb(pdiusbd12->ep2inurb);
out_no_dev:
kfree(pdiusbd12);
return ret;
}
void pdiusbd12_disconnect(struct usb_interface *intf)
{
struct pdiusbd12_dev *pdiusbd12 = usb_get_intfdata(intf);
cdev_del(&pdiusbd12->cdev);
unregister_chrdev_region(pdiusbd12->dev, 1);
usb_kill_urb(pdiusbd12->ep2inurb);
usb_free_urb(pdiusbd12->ep2inurb);
kfree(pdiusbd12);
}
static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x8888, 0x000b) },
{ }
};
MODULE_DEVICE_TABLE(usb, id_table);
static struct usb_driver pdiusbd12_driver =
{
.name = "pdiusbd12",
.id_table = id_table,
.probe = pdiusbd12_probe,
.disconnect = pdiusbd12_disconnect,
};
module_usb_driver(pdiusbd12_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("PDIUSBD12 driver");

17
usb/ex1/pdiusbd12.h Executable file
View File

@ -0,0 +1,17 @@
#ifndef _PDIUSBD12_H
#define _PDIUSBD12_H
struct d12key {
unsigned char key[8];
};
struct d12led {
unsigned char led[8];
};
#define PDIUSBD12_MAGIC 'p'
#define PDIUSBD12_GET_KEY _IOR(PDIUSBD12_MAGIC, 0, struct d12key)
#define PDIUSBD12_SET_LED _IOW(PDIUSBD12_MAGIC, 1, struct d12led)
#endif

72
usb/ex1/test.c Executable file
View File

@ -0,0 +1,72 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
#include "pdiusbd12.h"
int main(int argc, char *argv[])
{
int fd;
int ret;
unsigned char key[8];
unsigned char led[8];
unsigned int count, i;
fd = open("/dev/pdiusbd12", O_RDWR);
if (fd == -1)
goto fail;
while (1) {
ret = ioctl(fd, PDIUSBD12_GET_KEY, key);
if (ret == -1) {
if (errno == ETIMEDOUT)
continue;
else
goto fail;
}
switch (key[0]) {
case 0x00:
puts("KEYn released");
break;
case 0x01:
puts("KEY2 pressed");
break;
case 0x02:
puts("KEY3 pressed");
break;
case 0x04:
puts("KEY4 pressed");
break;
case 0x08:
puts("KEY5 pressed");
break;
case 0x10:
puts("KEY6 pressed");
break;
case 0x20:
puts("KEY7 pressed");
break;
case 0x40:
puts("KEY8 pressed");
break;
case 0x80:
puts("KEY9 pressed");
break;
}
if (key[0] != 0) {
led[0] = key[0];
ret = ioctl(fd, PDIUSBD12_SET_LED, key);
if (ret == -1)
goto fail;
}
}
fail:
perror("usb test");
exit(EXIT_FAILURE);
}