📄 usbdev.c
字号:
if (b_rec[num - 1] == 0)
{
local_irq_restore(flag);
ret = interruptible_sleep_on_timeout(&rec_queue[num - 1], rec_timeout[num - 1] * HZ/1000);
if (ret <= 0)
{
printk("S3C2410 USB device ep%d receive data timeout!\n", num);
up(&rec_sem[num - 1]);
return reccnt;
}
}
b_rec[num - 1] = 0;
}
else
{
if (down_interruptible(&rec_irq_sem[num - 1]))
{ /* can not wait the irq_sem*/
up(&rec_sem[num - 1]);
return -ERESTARTSYS;
}
}
/******************************************************
read data from FIFO
*******************************************************/
local_irq_save(flag);
endpstatus = USB_ReadOUTEpStatus(num * 2);
if ((endpstatus & 0x01) == 0)
{ /* FIFO is empty */
local_irq_restore(flag);
up(&rec_sem[num - 1]);
return -ERESTARTSYS;
}
len = count - reccnt;
if (len >= epsize)
{
len = USB_ReadEndpoint(num * 2, epsize, recbuf);/* read FIFO */
copy_to_user(buf + reccnt, recbuf, len);
}
else
{
len = USB_ReadEndpoint(num * 2, len, recbuf); /* read FIFO */
copy_to_user(buf + reccnt, recbuf, len);
}
reccnt = reccnt + len;
if (reccnt >= count)
{ /* all data has been received */
local_irq_restore(flag);
up(&rec_sem[num - 1]);
return reccnt;
}
b_rec[num - 1] = 0;
local_irq_restore(flag);
}//end of while(1)
}
/*********************************************************************************************************
** Function name: usbdev_ioctl
** Descriptions : IO control function(be used to set receiveing and transmitting timeout value)
** Input : inode : information of device
** filp : pointer of file
** cmd : command
** arg : additive parameter
** Output : 0 : OK
** other : not OK
** Created by : MingYuan Zheng
** Created Date : 2006-01-12
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
static int usbdev_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
unsigned int num;
if (_IOC_TYPE(cmd) != USBDEV_IOC_MAGIC)
{
/* no such command */
return -ENOTTY;
}
if (_IOC_NR(cmd) >= USBDEV_MAXNR)
{
/* no such minor */
return -ENOTTY;
}
num = (unsigned int)filp->private_data;
if (num > NUMS_REC_ENDPOINTS) /* 超出最大端点数 */
{
/* above the max endpoint number */
return -ENODEV;
}
switch(cmd)
{
/* set the receiving timeout */
case USBDEV_SET_READ_TIMEOUT: /* 设置接收超时时间 */
rec_timeout[num - 1] = arg;
break;
/* set the transmitting timeout */
case USBDEV_SET_WRITE_TIMEOUT: /* 设置发送超时时间 */
send_timeout[num - 1] = arg;
break;
default:
printk(KERN_ERR DEVICE_NAME "No such command!");
return -ENOTTY;
break;
}
return 0;
}
/*********************************************************************************************************
** Function name : usb_irq_handle
** Descriptions : S3C2410 USB device controller Interrupt Service Program
** Input : Linux Interrupt Service input parameter
** Output : NULL
** Created by : MingYuan Zheng
** Created Date : 2006-01-12
**------------- ------------------------------------------------------------------------------------------
** Modified by :
** Modified Date :
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
static void usb_irq_handle(int irq, void *dev_id, struct pt_regs *regs)
{
INT8U usb_ints, ep_ints;
INT32U flag;
usb_ints = UD_USBINT;
ep_ints = UD_INT; /* 读USB中断寄存器 read USB interrupt register */
if (usb_ints & RESET_INT)
USB_BusReset(); /* USB 总线复位处理 process USB bus reset */
if (usb_ints & SUSPEND_INT)
USB_Suspend(); /* USB 设备挂起处理 process USB device suspend */
if (usb_ints & RESUME_INT)
{
UD_USBINT = RESUME_INT; /* USB 设备恢复处理 process USB device resume */
}
if (ep_ints & EP0_INT)
ep0_int_handler(); /* 物理端点0 (Control) 中断处理 EP0(Control) interrupt handler */
if (ep_ints & EP1_INT)
ep1_int_handler(); /* 物理端点1 (IN) 中断处理 EP1(IN) interrupt handler */
if (ep_ints & EP2_INT)
ep2_int_handler(); /* 物理端点2 (OUT) 中断处理 EP2(OUT) interrupt handler */
if (ep_ints & EP3_INT)
ep3_int_handler(); /* 物理端点3 (IN) 中断处理 EP3(IN) interrupt handler */
if (ep_ints & EP4_INT)
ep4_int_handler(); /* 物理端点4 (OUT) 中断处理 EP4(OUT) interrupt handler */
if (bEPPflags.bits.setup_packet)
{ /* 收到 SETUP 包 receive SETUP packet*/
bEPPflags.bits.setup_packet = 0;
control_handler(); /* 控制传输处理 process control transmission */
} // if SETUP packet
/* clear the interrupt of mcu */
SRCPND = INT_USBD; /* 清除相关中断标志 clear the interrupt flag */
INTPND = INT_USBD;
}
/*********************************************************************************************************
** Function name : ep1_int_handler
** Descriptions : the interrupt hanlder of the physical endpoint 1(IN). 物理端点1 (IN) 中断处理(发送)
** Input : NULL
** Output : NULL
** Created by : MingYuan Zheng
** Created Date : 2006-01-12
**------------- ------------------------------------------------------------------------------------------
** Modified by :
** Modified Date :
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void ep1_int_handler(void)
{
USB_SelectClrIntEndpoint(1); /* 选择端点并清除中断 select endpoint/clear interrupt */
if (send_timeout[0] != 0)
{
wake_up_interruptible(&send_queue[0]); /* 唤醒发送等待队列 wake up the sending waiting queue */
b_send[0] = 1;
}
else
{
up(&send_irq_sem[0]); /* 唤醒发送等待信号量 wake up the sending waiting semaphore */
}
}
/*********************************************************************************************************
** Function name : ep2_int_handler
** Descriptions : the interrupt hanlder of the physical endpoint 2(OUT). 物理端点2 (OUT) 中断处理
** Input : NULL
** Output : NULL
** Created by : MingYuan Zheng
** Created Date : 2006-01-12
**------------- ------------------------------------------------------------------------------------------
** Modified by :
** Modified Date :
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void ep2_int_handler(void)
{
INT8U len;
USB_SelectClrIntEndpoint(2); /* 选择端点并清除中断 select endpoint/clear interrupt */
if (rec_timeout[0] != 0)
{
wake_up_interruptible(&rec_queue[0]); /* 唤醒接收等待队列 wake up the receiving waiting queue */
b_rec[0] = 1;
}
else
{
up(&rec_irq_sem[0]); /* 唤醒接收等待信号量 wake up the receiving waiting semaphore */
}
}
/*********************************************************************************************************
** Function name : ep3_int_handler
** Descriptions : the interrupt hanlder of the physical endpoint 3(IN). 物理端点3 (IN) 中断处理
** Input : NULL
** Output : NULL
** Created by : MingYuan Zheng
** Created Date : 2006-01-12
**------------- ------------------------------------------------------------------------------------------
** Modified by :
** Modified Date :
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void ep3_int_handler(void)
{
USB_SelectClrIntEndpoint(3); /* 选择端点并清除中断 select endpoint/clear interrupt */
if (send_timeout[1] != 0)
{
wake_up_interruptible(&send_queue[1]); /* 唤醒发送等待队列 wake up the sending waiting queue */
b_send[1] = 1;
}
else
{
up(&send_irq_sem[1]); /* 唤醒发送等待信号量 wake up the sending waiting semaphore */
}
}
/*********************************************************************************************************
** Function name : ep4_int_handler
** Descriptions : the interrupt hanlder of the physical endpoint 4(OUT). 物理端点4 (OUT) 中断处理
** Input : NULL
** Output : NULL
** Created by : MingYuan Zheng
** Created Date : 2006-01-12
**------------- ------------------------------------------------------------------------------------------
** Modified by :
** Modified Date :
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void ep4_int_handler(void)
{
INT8U len;
USB_SelectClrIntEndpoint(4); /* 选择端点并清除中断 select endpoint/clear interrupt */
if (rec_timeout[1] != 0)
{
wake_up_interruptible(&rec_queue[1]); /* 唤醒接收等待队列 wake up the receiving waiting queue */
}
else
{
up(&rec_irq_sem[1]); /* 唤醒接收等待信号量 wake up the receiving waiting semaphore */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -