1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > Linux下安装USB转串口驱动(PL2303)

Linux下安装USB转串口驱动(PL2303)

时间:2018-09-24 00:43:20

相关推荐

Linux下安装USB转串口驱动(PL2303)

分类:嵌入式ARM+Linux -01-11 22:26 2077人阅读 评论(0) 收藏 举报

主机:Gentoo Linux 11.2

内核版本:Linux 3.0.6

原创作品,转载请标明出处/yming0221/article/details/7194988

以前在Ubuntu下USB转串口驱动已经编译进内核,而编译的Gentoo内核没有编译进去,这里将内核中PL2303驱动 copy出来单独编译出pl2303.ko然后将其复制进/var/lib/(内核版本)/drivers/usb/serial/目录下

然后使用命令

depmod

modprobe pl2303

然后将usb转串口接口插入usb,使用命令查看dmesg | tail查看如下

查看内核中驱动,看到usbserial.ko驱动,下面单独编译pl2303.ko

从内核中拷贝的pl2303.h

[cpp]view plain copy/* *ProlificPL2303USBtoserialadaptordriverheaderfile * *Thisprogramisfreesoftware;youcanredistributeitand/ormodify *itunderthetermsoftheGNUGeneralPublicLicenseaspublishedby *theFreeSoftwareFoundation;eitherversion2oftheLicense,or *(atyouroption)anylaterversion. * */ #defineBENQ_VENDOR_ID0x04a5 #defineBENQ_PRODUCT_ID_S810x4027 #definePL2303_VENDOR_ID0x067b #definePL2303_PRODUCT_ID0x2303 #definePL2303_PRODUCT_ID_RSAQ20x04bb #definePL2303_PRODUCT_ID_DCU110x1234 #definePL2303_PRODUCT_ID_PHAROS0xaaa0 #definePL2303_PRODUCT_ID_RSAQ30xaaa2 #definePL2303_PRODUCT_ID_ALDIGA0x0611 #definePL2303_PRODUCT_ID_MMX0x0612 #definePL2303_PRODUCT_ID_GPRS0x0609 #definePL2303_PRODUCT_ID_HCR3310x331a #definePL2303_PRODUCT_ID_MOTOROLA0x0307 #defineATEN_VENDOR_ID0x0557 #defineATEN_VENDOR_ID20x0547 #defineATEN_PRODUCT_ID0x #defineIODATA_VENDOR_ID0x04bb #defineIODATA_PRODUCT_ID0x0a03 #defineIODATA_PRODUCT_ID_RSAQ50x0a0e #defineELCOM_VENDOR_ID0x056e #defineELCOM_PRODUCT_ID0x5003 #defineELCOM_PRODUCT_ID_UCSGT0x5004 #defineITEGNO_VENDOR_ID0x0eba #defineITEGNO_PRODUCT_ID0x1080 #defineITEGNO_PRODUCT_ID_20800x2080 #defineMA620_VENDOR_ID0x0df7 #defineMA620_PRODUCT_ID0x0620 #defineRATOC_VENDOR_ID0x0584 #defineRATOC_PRODUCT_ID0xb000 #defineTRIPP_VENDOR_ID0x2478 #defineTRIPP_PRODUCT_ID0x #defineRADIOSHACK_VENDOR_ID0x1453 #defineRADIOSHACK_PRODUCT_ID0x4026 #defineDCU10_VENDOR_ID0x0731 #defineDCU10_PRODUCT_ID0x0528 #defineSITECOM_VENDOR_ID0x6189 #defineSITECOM_PRODUCT_ID0x2068 /*AlcatelOT535/735USBcable*/ #defineALCATEL_VENDOR_ID0x11f7 #defineALCATEL_PRODUCT_ID0x02df /*SamsungI330phonecradle*/ #defineSAMSUNG_VENDOR_ID0x04e8 #defineSAMSUNG_PRODUCT_ID0x8001 #defineSIEMENS_VENDOR_ID0x11f5 #defineSIEMENS_PRODUCT_ID_SX10x0001 #defineSIEMENS_PRODUCT_ID_X650x0003 #defineSIEMENS_PRODUCT_ID_X750x0004 #defineSIEMENS_PRODUCT_ID_EF810x0005 #defineSYNTECH_VENDOR_ID0x0745 #defineSYNTECH_PRODUCT_ID0x0001 /*NokiaCA-42Cable*/ #defineNOKIA_CA42_VENDOR_ID0x078b #defineNOKIA_CA42_PRODUCT_ID0x1234 /*CA-42CLONECablewww.ca-chipset:ProlificTechnologyInc*/ #defineCA_42_CA42_VENDOR_ID0x10b5 #defineCA_42_CA42_PRODUCT_ID0xac70 #defineSAGEM_VENDOR_ID0x079b #defineSAGEM_PRODUCT_ID0x0027 /*LeadtekGPS9531(ID0413:2101)*/ #defineLEADTEK_VENDOR_ID0x0413 #defineLEADTEK_9531_PRODUCT_ID0x2101 /*USBGSMcablefromSpeedDragonMultimedia,Ltd*/ #defineSPEEDDRAGON_VENDOR_ID0x0e55 #defineSPEEDDRAGON_PRODUCT_ID0x110b /*DATAPILOTUniversal-2PhoneCable*/ #defineDATAPILOT_U2_VENDOR_ID0x0731 #defineDATAPILOT_U2_PRODUCT_ID0x /*Belkin"F5U257"SerialAdapter*/ #defineBELKIN_VENDOR_ID0x050d #defineBELKIN_PRODUCT_ID0x0257 /*AlcorMicroCorp.USB2.0TORS-232*/ #defineALCOR_VENDOR_ID0x058F #defineALCOR_PRODUCT_ID0x9720 /*WillcomWS002INDataDriver(byNetIndexInc.)*/ #defineWS002IN_VENDOR_ID0x11f6 #defineWS002IN_PRODUCT_ID0x2001 /*CoregaCG-USBRS232RSerialAdapter*/ #defineCOREGA_VENDOR_ID0x07aa #defineCOREGA_PRODUCT_ID0x002a /*Y.C.CableU.S.A.,Inc-USBtoRS-232*/ #defineYCCABLE_VENDOR_ID0x05ad #defineYCCABLE_PRODUCT_ID0x0fba /*"Superial"USB-Serial*/ #defineSUPERIAL_VENDOR_ID0x5372 #defineSUPERIAL_PRODUCT_ID0x2303 /*Hewlett-PackardLD220-HPPOSPoleDisplay*/ #defineHP_VENDOR_ID0x03f0 #defineHP_LD220_PRODUCT_ID0x3524 /*CressiEdy(divingcomputer)PCinterface*/ #defineCRESSI_VENDOR_ID0x04b8 #defineCRESSI_EDY_PRODUCT_ID0x0521 /*Zeagledivecomputerinterface*/ #defineZEAGLE_VENDOR_ID0x04b8 #defineZEAGLE_N2ITION3_PRODUCT_ID0x0522 /*Sony,USBdatacableforCMD-Jxxmobilephones*/ #defineSONY_VENDOR_ID0x054c #defineSONY_QN3USB_PRODUCT_ID0x0437 /*SanwaKB-USB2multimetercable(ID:11ad:0001)*/ #defineSANWA_VENDOR_ID0x11ad #defineSANWA_PRODUCT_ID0x0001 /*ADLINKND-6530RS232,RS485andRS422adapter*/ #defineADLINK_VENDOR_ID0x0b63 #defineADLINK_ND6530_PRODUCT_ID0x6530 /*WinChipHeadUSB->RS232adapter*/ #defineWINCHIPHEAD_VENDOR_ID0x4348 #defineWINCHIPHEAD_USBSER_PRODUCT_ID0x5523

pl2303.c代码

[cpp]view plain copy/* *ProlificPL2303USBtoserialadaptordriver * *Copyright(C)2001-GregKroah-Hartman(greg@) *Copyright(C)IBMCorp. * *Originaldriverfor2.2.xbyanonymous * *Thisprogramisfreesoftware;youcanredistributeitand/or *modifyitunderthetermsoftheGNUGeneralPublicLicenseversion *2aspublishedbytheFreeSoftwareFoundation. * *SeeDocumentation/usb/usb-serial.txtformoreinformationonusingthis *driver * */ #include<linux/kernel.h> #include<linux/errno.h> #include<linux/init.h> #include<linux/slab.h> #include<linux/tty.h> #include<linux/tty_driver.h> #include<linux/tty_flip.h> #include<linux/serial.h> #include<linux/module.h> #include<linux/moduleparam.h> #include<linux/spinlock.h> #include<linux/uaccess.h> #include<linux/usb.h> #include<linux/usb/serial.h> #include"pl2303.h" /* *VersionInformation */ #defineDRIVER_DESC"ProlificPL2303USBtoserialadaptordriver" staticintdebug; #definePL2303_CLOSING_WAIT(30*HZ) staticconststructusb_device_idid_table[]={ {USB_DEVICE(PL2303_VENDOR_ID,PL2303_PRODUCT_ID)}, {USB_DEVICE(PL2303_VENDOR_ID,PL2303_PRODUCT_ID_RSAQ2)}, {USB_DEVICE(PL2303_VENDOR_ID,PL2303_PRODUCT_ID_DCU11)}, {USB_DEVICE(PL2303_VENDOR_ID,PL2303_PRODUCT_ID_RSAQ3)}, {USB_DEVICE(PL2303_VENDOR_ID,PL2303_PRODUCT_ID_PHAROS)}, {USB_DEVICE(PL2303_VENDOR_ID,PL2303_PRODUCT_ID_ALDIGA)}, {USB_DEVICE(PL2303_VENDOR_ID,PL2303_PRODUCT_ID_MMX)}, {USB_DEVICE(PL2303_VENDOR_ID,PL2303_PRODUCT_ID_GPRS)}, {USB_DEVICE(PL2303_VENDOR_ID,PL2303_PRODUCT_ID_HCR331)}, {USB_DEVICE(PL2303_VENDOR_ID,PL2303_PRODUCT_ID_MOTOROLA)}, {USB_DEVICE(IODATA_VENDOR_ID,IODATA_PRODUCT_ID)}, {USB_DEVICE(IODATA_VENDOR_ID,IODATA_PRODUCT_ID_RSAQ5)}, {USB_DEVICE(ATEN_VENDOR_ID,ATEN_PRODUCT_ID)}, {USB_DEVICE(ATEN_VENDOR_ID2,ATEN_PRODUCT_ID)}, {USB_DEVICE(ELCOM_VENDOR_ID,ELCOM_PRODUCT_ID)}, {USB_DEVICE(ELCOM_VENDOR_ID,ELCOM_PRODUCT_ID_UCSGT)}, {USB_DEVICE(ITEGNO_VENDOR_ID,ITEGNO_PRODUCT_ID)}, {USB_DEVICE(ITEGNO_VENDOR_ID,ITEGNO_PRODUCT_ID_2080)}, {USB_DEVICE(MA620_VENDOR_ID,MA620_PRODUCT_ID)}, {USB_DEVICE(RATOC_VENDOR_ID,RATOC_PRODUCT_ID)}, {USB_DEVICE(TRIPP_VENDOR_ID,TRIPP_PRODUCT_ID)}, {USB_DEVICE(RADIOSHACK_VENDOR_ID,RADIOSHACK_PRODUCT_ID)}, {USB_DEVICE(DCU10_VENDOR_ID,DCU10_PRODUCT_ID)}, {USB_DEVICE(SITECOM_VENDOR_ID,SITECOM_PRODUCT_ID)}, {USB_DEVICE(ALCATEL_VENDOR_ID,ALCATEL_PRODUCT_ID)}, {USB_DEVICE(SAMSUNG_VENDOR_ID,SAMSUNG_PRODUCT_ID)}, {USB_DEVICE(SIEMENS_VENDOR_ID,SIEMENS_PRODUCT_ID_SX1)}, {USB_DEVICE(SIEMENS_VENDOR_ID,SIEMENS_PRODUCT_ID_X65)}, {USB_DEVICE(SIEMENS_VENDOR_ID,SIEMENS_PRODUCT_ID_X75)}, {USB_DEVICE(SIEMENS_VENDOR_ID,SIEMENS_PRODUCT_ID_EF81)}, {USB_DEVICE(BENQ_VENDOR_ID,BENQ_PRODUCT_ID_S81)},/*Benq/SiemensS81*/ {USB_DEVICE(SYNTECH_VENDOR_ID,SYNTECH_PRODUCT_ID)}, {USB_DEVICE(NOKIA_CA42_VENDOR_ID,NOKIA_CA42_PRODUCT_ID)}, {USB_DEVICE(CA_42_CA42_VENDOR_ID,CA_42_CA42_PRODUCT_ID)}, {USB_DEVICE(SAGEM_VENDOR_ID,SAGEM_PRODUCT_ID)}, {USB_DEVICE(LEADTEK_VENDOR_ID,LEADTEK_9531_PRODUCT_ID)}, {USB_DEVICE(SPEEDDRAGON_VENDOR_ID,SPEEDDRAGON_PRODUCT_ID)}, {USB_DEVICE(DATAPILOT_U2_VENDOR_ID,DATAPILOT_U2_PRODUCT_ID)}, {USB_DEVICE(BELKIN_VENDOR_ID,BELKIN_PRODUCT_ID)}, {USB_DEVICE(ALCOR_VENDOR_ID,ALCOR_PRODUCT_ID)}, {USB_DEVICE(WS002IN_VENDOR_ID,WS002IN_PRODUCT_ID)}, {USB_DEVICE(COREGA_VENDOR_ID,COREGA_PRODUCT_ID)}, {USB_DEVICE(YCCABLE_VENDOR_ID,YCCABLE_PRODUCT_ID)}, {USB_DEVICE(SUPERIAL_VENDOR_ID,SUPERIAL_PRODUCT_ID)}, {USB_DEVICE(HP_VENDOR_ID,HP_LD220_PRODUCT_ID)}, {USB_DEVICE(CRESSI_VENDOR_ID,CRESSI_EDY_PRODUCT_ID)}, {USB_DEVICE(ZEAGLE_VENDOR_ID,ZEAGLE_N2ITION3_PRODUCT_ID)}, {USB_DEVICE(SONY_VENDOR_ID,SONY_QN3USB_PRODUCT_ID)}, {USB_DEVICE(SANWA_VENDOR_ID,SANWA_PRODUCT_ID)}, {USB_DEVICE(ADLINK_VENDOR_ID,ADLINK_ND6530_PRODUCT_ID)}, {USB_DEVICE(WINCHIPHEAD_VENDOR_ID,WINCHIPHEAD_USBSER_PRODUCT_ID)}, {}/*Terminatingentry*/ }; MODULE_DEVICE_TABLE(usb,id_table); staticstructusb_driverpl2303_driver={ .name="pl2303", .probe=usb_serial_probe, .disconnect=usb_serial_disconnect, .id_table=id_table, .suspend=usb_serial_suspend, .resume=usb_serial_resume, .no_dynamic_id=1, .supports_autosuspend=1, }; #defineSET_LINE_REQUEST_TYPE0x21 #defineSET_LINE_REQUEST0x20 #defineSET_CONTROL_REQUEST_TYPE0x21 #defineSET_CONTROL_REQUEST0x22 #defineCONTROL_DTR0x01 #defineCONTROL_RTS0x02 #defineBREAK_REQUEST_TYPE0x21 #defineBREAK_REQUEST0x23 #defineBREAK_ON0xffff #defineBREAK_OFF0x0000 #defineGET_LINE_REQUEST_TYPE0xa1 #defineGET_LINE_REQUEST0x21 #defineVENDOR_WRITE_REQUEST_TYPE0x40 #defineVENDOR_WRITE_REQUEST0x01 #defineVENDOR_READ_REQUEST_TYPE0xc0 #defineVENDOR_READ_REQUEST0x01 #defineUART_STATE0x08 #defineUART_STATE_TRANSIENT_MASK0x74 #defineUART_DCD0x01 #defineUART_DSR0x02 #defineUART_BREAK_ERROR0x04 #defineUART_RING0x08 #defineUART_FRAME_ERROR0x10 #defineUART_PARITY_ERROR0x20 #defineUART_OVERRUN_ERROR0x40 #defineUART_CTS0x80 enumpl2303_type{ type_0,/*don'tknowthedifferencebetweentype0and*/ type_1,/*type1,untilsomeonefromprolifictellsus...*/ HX,/*HXversionofthepl2303chip*/ }; structpl2303_private{ spinlock_tlock; wait_queue_head_tdelta_msr_wait; u8line_control; u8line_status; enumpl2303_typetype; }; staticintpl2303_vendor_read(__u16value,__u16index, structusb_serial*serial,unsignedchar*buf) { intres=usb_control_msg(serial->dev,usb_rcvctrlpipe(serial->dev,0), VENDOR_READ_REQUEST,VENDOR_READ_REQUEST_TYPE, value,index,buf,1,100); dbg("0x%x:0x%x:0x%x:0x%x%d-%x",VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST,value,index,res,buf[0]); returnres; } staticintpl2303_vendor_write(__u16value,__u16index, structusb_serial*serial) { intres=usb_control_msg(serial->dev,usb_sndctrlpipe(serial->dev,0), VENDOR_WRITE_REQUEST,VENDOR_WRITE_REQUEST_TYPE, value,index,NULL,0,100); dbg("0x%x:0x%x:0x%x:0x%x%d",VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST,value,index,res); returnres; } staticintpl2303_startup(structusb_serial*serial) { structpl2303_private*priv; enumpl2303_typetype=type_0; unsignedchar*buf; inti; buf=kmalloc(10,GFP_KERNEL); if(buf==NULL) return-ENOMEM; if(serial->dev->descriptor.bDeviceClass==0x02) type=type_0; elseif(serial->dev->descriptor.bMaxPacketSize0==0x40) type=HX; elseif(serial->dev->descriptor.bDeviceClass==0x00) type=type_1; elseif(serial->dev->descriptor.bDeviceClass==0xFF) type=type_1; dbg("devicetype:%d",type); for(i=0;i<serial->num_ports;++i){ priv=kzalloc(sizeof(structpl2303_private),GFP_KERNEL); if(!priv) gotocleanup; spin_lock_init(&priv->lock); init_waitqueue_head(&priv->delta_msr_wait); priv->type=type; usb_set_serial_port_data(serial->port[i],priv); } pl2303_vendor_read(0x8484,0,serial,buf); pl2303_vendor_write(0x0404,0,serial); pl2303_vendor_read(0x8484,0,serial,buf); pl2303_vendor_read(0x8383,0,serial,buf); pl2303_vendor_read(0x8484,0,serial,buf); pl2303_vendor_write(0x0404,1,serial); pl2303_vendor_read(0x8484,0,serial,buf); pl2303_vendor_read(0x8383,0,serial,buf); pl2303_vendor_write(0,1,serial); pl2303_vendor_write(1,0,serial); if(type==HX) pl2303_vendor_write(2,0x44,serial); else pl2303_vendor_write(2,0x24,serial); kfree(buf); return0; cleanup: kfree(buf); for(--i;i>=0;--i){ priv=usb_get_serial_port_data(serial->port[i]); kfree(priv); usb_set_serial_port_data(serial->port[i],NULL); } return-ENOMEM; } staticintset_control_lines(structusb_device*dev,u8value) { intretval; retval=usb_control_msg(dev,usb_sndctrlpipe(dev,0), SET_CONTROL_REQUEST,SET_CONTROL_REQUEST_TYPE, value,0,NULL,0,100); dbg("%s-value=%d,retval=%d",__func__,value,retval); returnretval; } staticvoidpl2303_set_termios(structtty_struct*tty, structusb_serial_port*port,structktermios*old_termios) { structusb_serial*serial=port->serial; structpl2303_private*priv=usb_get_serial_port_data(port); unsignedlongflags; unsignedintcflag; unsignedchar*buf; intbaud; inti; u8control; constintbaud_sup[]={75,150,300,600,1200,1800,2400,3600, 4800,7200,9600,14400,19200,28800,38400, 57600,115200,230400,460800,614400, 921600,1228800,2457600,3000000,6000000}; intbaud_floor,baud_ceil; intk; dbg("%s-port%d",__func__,port->number); /*ThePL2303isreportedtolosebytesifyouchange serialsettingseventothesamevaluesasbefore.Thus weactuallyneedtofilterinthisspecificcase*/ if(!tty_termios_hw_change(tty->termios,old_termios)) return; cflag=tty->termios->c_cflag; buf=kzalloc(7,GFP_KERNEL); if(!buf){ dev_err(&port->dev,"%s-outofmemory.\n",__func__); /*Reportbacknochangeoccurred*/ *tty->termios=*old_termios; return; } i=usb_control_msg(serial->dev,usb_rcvctrlpipe(serial->dev,0), GET_LINE_REQUEST,GET_LINE_REQUEST_TYPE, 0,0,buf,7,100); dbg("0xa1:0x21:0:0%d-%x%x%x%x%x%x%x",i, buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6]); if(cflag&CSIZE){ switch(cflag&CSIZE){ caseCS5: buf[6]=5; break; caseCS6: buf[6]=6; break; caseCS7: buf[6]=7; break; default: caseCS8: buf[6]=8; break; } dbg("%s-databits=%d",__func__,buf[6]); } /*Forreferencebuf[0]:buf[3]baudratevalue*/ /*NOTE:Onlythevaluesdefinedinbaud_suparesupported! *=>ifunsupportedvaluesareset,thePL2303seemstouse *9600baud(atleastmyPL2303Xalwaysdoes) */ baud=tty_get_baud_rate(tty); dbg("%s-baudrequested=%d",__func__,baud); if(baud){ /*Setbaudratetonearestsupportedvalue*/ for(k=0;k<ARRAY_SIZE(baud_sup);k++){ if(baud_sup[k]/baud){ baud_ceil=baud_sup[k]; if(k==0){ baud=baud_ceil; }else{ baud_floor=baud_sup[k-1]; if((baud_ceil%baud) >(baud%baud_floor)) baud=baud_floor; else baud=baud_ceil; } break; } } if(baud>1228800){ /*type_0,type_1onlysupportupto1228800baud*/ if(priv->type!=HX) baud=1228800; elseif(baud>6000000) baud=6000000; } dbg("%s-baudset=%d",__func__,baud); if(baud<=115200){ buf[0]=baud&0xff; buf[1]=(baud>>8)&0xff; buf[2]=(baud>>16)&0xff; buf[3]=(baud>>24)&0xff; }else{ /*apparentlytheformulaforhigherspeedsis: *baudrate=12M*32/(2^buf[1])/buf[0] */ unsignedtmp=12*1000*1000*32/baud; buf[3]=0x80; buf[2]=0; buf[1]=(tmp>=256); while(tmp>=256){ tmp>>=2; buf[1]<<=1; } if(tmp>256){ tmp%=256; } buf[0]=tmp; } } /*Forreferencebuf[4]=0is1stopbits*/ /*Forreferencebuf[4]=1is1.5stopbits*/ /*Forreferencebuf[4]=2is2stopbits*/ if(cflag&CSTOPB){ /*NOTE:Complywith"real"UARTs/RS232: *use1.5insteadof2stopbitswith5databits */ if((cflag&CSIZE)==CS5){ buf[4]=1; dbg("%s-stopbits=1.5",__func__); }else{ buf[4]=2; dbg("%s-stopbits=2",__func__); } }else{ buf[4]=0; dbg("%s-stopbits=1",__func__); } if(cflag&PARENB){ /*Forreferencebuf[5]=0isnoneparity*/ /*Forreferencebuf[5]=1isoddparity*/ /*Forreferencebuf[5]=2isevenparity*/ /*Forreferencebuf[5]=3ismarkparity*/ /*Forreferencebuf[5]=4isspaceparity*/ if(cflag&PARODD){ if(cflag&CMSPAR){ buf[5]=3; dbg("%s-parity=mark",__func__); }else{ buf[5]=1; dbg("%s-parity=odd",__func__); } }else{ if(cflag&CMSPAR){ buf[5]=4; dbg("%s-parity=space",__func__); }else{ buf[5]=2; dbg("%s-parity=even",__func__); } } }else{ buf[5]=0; dbg("%s-parity=none",__func__); } i=usb_control_msg(serial->dev,usb_sndctrlpipe(serial->dev,0), SET_LINE_REQUEST,SET_LINE_REQUEST_TYPE, 0,0,buf,7,100); dbg("0x21:0x20:0:0%d",i); /*changecontrollinesifweareswitchingtoorfromB0*/ spin_lock_irqsave(&priv->lock,flags); control=priv->line_control; if((cflag&CBAUD)==B0) priv->line_control&=~(CONTROL_DTR|CONTROL_RTS); else priv->line_control|=(CONTROL_DTR|CONTROL_RTS); if(control!=priv->line_control){ control=priv->line_control; spin_unlock_irqrestore(&priv->lock,flags); set_control_lines(serial->dev,control); }else{ spin_unlock_irqrestore(&priv->lock,flags); } buf[0]=buf[1]=buf[2]=buf[3]=buf[4]=buf[5]=buf[6]=0; i=usb_control_msg(serial->dev,usb_rcvctrlpipe(serial->dev,0), GET_LINE_REQUEST,GET_LINE_REQUEST_TYPE, 0,0,buf,7,100); dbg("0xa1:0x21:0:0%d-%x%x%x%x%x%x%x",i, buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6]); if(cflag&CRTSCTS){ if(priv->type==HX) pl2303_vendor_write(0x0,0x61,serial); else pl2303_vendor_write(0x0,0x41,serial); }else{ pl2303_vendor_write(0x0,0x0,serial); } /*Saveresultingbaudrate*/ if(baud) tty_encode_baud_rate(tty,baud,baud); kfree(buf); } staticvoidpl2303_dtr_rts(structusb_serial_port*port,inton) { structpl2303_private*priv=usb_get_serial_port_data(port); unsignedlongflags; u8control; spin_lock_irqsave(&priv->lock,flags); /*ChangeDTRandRTS*/ if(on) priv->line_control|=(CONTROL_DTR|CONTROL_RTS); else priv->line_control&=~(CONTROL_DTR|CONTROL_RTS); control=priv->line_control; spin_unlock_irqrestore(&priv->lock,flags); set_control_lines(port->serial->dev,control); } staticvoidpl2303_close(structusb_serial_port*port) { dbg("%s-port%d",__func__,port->number); usb_serial_generic_close(port); usb_kill_urb(port->interrupt_in_urb); } staticintpl2303_open(structtty_struct*tty,structusb_serial_port*port) { structktermiostmp_termios; structusb_serial*serial=port->serial; structpl2303_private*priv=usb_get_serial_port_data(port); intresult; dbg("%s-port%d",__func__,port->number); if(priv->type!=HX){ usb_clear_halt(serial->dev,port->write_urb->pipe); usb_clear_halt(serial->dev,port->read_urb->pipe); }else{ /*resetupstreamdatapipes*/ pl2303_vendor_write(8,0,serial); pl2303_vendor_write(9,0,serial); } /*Setuptermios*/ if(tty) pl2303_set_termios(tty,port,&tmp_termios); dbg("%s-submittingreadurb",__func__); result=usb_serial_generic_submit_read_urb(port,GFP_KERNEL); if(result){ pl2303_close(port); return-EPROTO; } dbg("%s-submittinginterrupturb",__func__); result=usb_submit_urb(port->interrupt_in_urb,GFP_KERNEL); if(result){ dev_err(&port->dev,"%s-failedsubmittinginterrupturb," "error%d\n",__func__,result); pl2303_close(port); return-EPROTO; } port->port.drain_delay=256; return0; } staticintpl2303_tiocmset(structtty_struct*tty, unsignedintset,unsignedintclear) { structusb_serial_port*port=tty->driver_data; structpl2303_private*priv=usb_get_serial_port_data(port); unsignedlongflags; u8control; if(!usb_get_intfdata(port->serial->interface)) return-ENODEV; spin_lock_irqsave(&priv->lock,flags); if(set&TIOCM_RTS) priv->line_control|=CONTROL_RTS; if(set&TIOCM_DTR) priv->line_control|=CONTROL_DTR; if(clear&TIOCM_RTS) priv->line_control&=~CONTROL_RTS; if(clear&TIOCM_DTR) priv->line_control&=~CONTROL_DTR; control=priv->line_control; spin_unlock_irqrestore(&priv->lock,flags); returnset_control_lines(port->serial->dev,control); } staticintpl2303_tiocmget(structtty_struct*tty) { structusb_serial_port*port=tty->driver_data; structpl2303_private*priv=usb_get_serial_port_data(port); unsignedlongflags; unsignedintmcr; unsignedintstatus; unsignedintresult; dbg("%s(%d)",__func__,port->number); if(!usb_get_intfdata(port->serial->interface)) return-ENODEV; spin_lock_irqsave(&priv->lock,flags); mcr=priv->line_control; status=priv->line_status; spin_unlock_irqrestore(&priv->lock,flags); result=((mcr&CONTROL_DTR)?TIOCM_DTR:0) |((mcr&CONTROL_RTS)?TIOCM_RTS:0) |((status&UART_CTS)?TIOCM_CTS:0) |((status&UART_DSR)?TIOCM_DSR:0) |((status&UART_RING)?TIOCM_RI:0) |((status&UART_DCD)?TIOCM_CD:0); dbg("%s-result=%x",__func__,result); returnresult; } staticintpl2303_carrier_raised(structusb_serial_port*port) { structpl2303_private*priv=usb_get_serial_port_data(port); if(priv->line_status&UART_DCD) return1; return0; } staticintwait_modem_info(structusb_serial_port*port,unsignedintarg) { structpl2303_private*priv=usb_get_serial_port_data(port); unsignedlongflags; unsignedintprevstatus; unsignedintstatus; unsignedintchanged; spin_lock_irqsave(&priv->lock,flags); prevstatus=priv->line_status; spin_unlock_irqrestore(&priv->lock,flags); while(1){ interruptible_sleep_on(&priv->delta_msr_wait); /*seeifasignaldidit*/ if(signal_pending(current)) return-ERESTARTSYS; spin_lock_irqsave(&priv->lock,flags); status=priv->line_status; spin_unlock_irqrestore(&priv->lock,flags); changed=prevstatus^status; if(((arg&TIOCM_RNG)&&(changed&UART_RING))|| ((arg&TIOCM_DSR)&&(changed&UART_DSR))|| ((arg&TIOCM_CD)&&(changed&UART_DCD))|| ((arg&TIOCM_CTS)&&(changed&UART_CTS))){ return0; } prevstatus=status; } /*NOTREACHED*/ return0; } staticintpl2303_ioctl(structtty_struct*tty, unsignedintcmd,unsignedlongarg) { structserial_structser; structusb_serial_port*port=tty->driver_data; dbg("%s(%d)cmd=0x%04x",__func__,port->number,cmd); switch(cmd){ caseTIOCGSERIAL: memset(&ser,0,sizeofser); ser.type=PORT_16654; ser.line=port->serial->minor; ser.port=port->number; ser.baud_base=460800; if(copy_to_user((void__user*)arg,&ser,sizeofser)) return-EFAULT; return0; caseTIOCMIWAIT: dbg("%s(%d)TIOCMIWAIT",__func__,port->number); returnwait_modem_info(port,arg); default: dbg("%snotsupported=0x%04x",__func__,cmd); break; } return-ENOIOCTLCMD; } staticvoidpl2303_break_ctl(structtty_struct*tty,intbreak_state) { structusb_serial_port*port=tty->driver_data; structusb_serial*serial=port->serial; u16state; intresult; dbg("%s-port%d",__func__,port->number); if(break_state==0) state=BREAK_OFF; else state=BREAK_ON; dbg("%s-turningbreak%s",__func__, state==BREAK_OFF?"off":"on"); result=usb_control_msg(serial->dev,usb_sndctrlpipe(serial->dev,0), BREAK_REQUEST,BREAK_REQUEST_TYPE,state, 0,NULL,0,100); if(result) dbg("%s-errorsendingbreak=%d",__func__,result); } staticvoidpl2303_release(structusb_serial*serial) { inti; structpl2303_private*priv; dbg("%s",__func__); for(i=0;i<serial->num_ports;++i){ priv=usb_get_serial_port_data(serial->port[i]); kfree(priv); } } staticvoidpl2303_update_line_status(structusb_serial_port*port, unsignedchar*data, unsignedintactual_length) { structpl2303_private*priv=usb_get_serial_port_data(port); structtty_struct*tty; unsignedlongflags; u8status_idx=UART_STATE; u8length=UART_STATE+1; u8prev_line_status; u16idv,idp; idv=le16_to_cpu(port->serial->dev->descriptor.idVendor); idp=le16_to_cpu(port->serial->dev->descriptor.idProduct); if(idv==SIEMENS_VENDOR_ID){ if(idp==SIEMENS_PRODUCT_ID_X65|| idp==SIEMENS_PRODUCT_ID_SX1|| idp==SIEMENS_PRODUCT_ID_X75){ length=1; status_idx=0; } } if(actual_length<length) return; /*Saveofftheuartstatusforotherstolookat*/ spin_lock_irqsave(&priv->lock,flags); prev_line_status=priv->line_status; priv->line_status=data[status_idx]; spin_unlock_irqrestore(&priv->lock,flags); if(priv->line_status&UART_BREAK_ERROR) usb_serial_handle_break(port); wake_up_interruptible(&priv->delta_msr_wait); tty=tty_port_tty_get(&port->port); if(!tty) return; if((priv->line_status^prev_line_status)&UART_DCD) usb_serial_handle_dcd_change(port,tty, priv->line_status&UART_DCD); tty_kref_put(tty); } staticvoidpl2303_read_int_callback(structurb*urb) { structusb_serial_port*port=urb->context; unsignedchar*data=urb->transfer_buffer; unsignedintactual_length=urb->actual_length; intstatus=urb->status; intretval; dbg("%s(%d)",__func__,port->number); switch(status){ case0: /*success*/ break; case-ECONNRESET: case-ENOENT: case-ESHUTDOWN: /*thisurbisterminated,cleanup*/ dbg("%s-urbshuttingdownwithstatus:%d",__func__, status); return; default: dbg("%s-nonzerourbstatusreceived:%d",__func__, status); gotoexit; } usb_serial_debug_data(debug,&port->dev,__func__, urb->actual_length,urb->transfer_buffer); pl2303_update_line_status(port,data,actual_length); exit: retval=usb_submit_urb(urb,GFP_ATOMIC); if(retval) dev_err(&urb->dev->dev, "%s-usb_submit_urbfailedwithresult%d\n", __func__,retval); } staticvoidpl2303_process_read_urb(structurb*urb) { structusb_serial_port*port=urb->context; structpl2303_private*priv=usb_get_serial_port_data(port); structtty_struct*tty; unsignedchar*data=urb->transfer_buffer; chartty_flag=TTY_NORMAL; unsignedlongflags; u8line_status; inti; /*updatelinestatus*/ spin_lock_irqsave(&priv->lock,flags); line_status=priv->line_status; priv->line_status&=~UART_STATE_TRANSIENT_MASK; spin_unlock_irqrestore(&priv->lock,flags); wake_up_interruptible(&priv->delta_msr_wait); if(!urb->actual_length) return; tty=tty_port_tty_get(&port->port); if(!tty) return; /*breaktakesprecedenceoverparity,*/ /*whichtakesprecedenceoverframingerrors*/ if(line_status&UART_BREAK_ERROR) tty_flag=TTY_BREAK; elseif(line_status&UART_PARITY_ERROR) tty_flag=TTY_PARITY; elseif(line_status&UART_FRAME_ERROR) tty_flag=TTY_FRAME; dbg("%s-tty_flag=%d",__func__,tty_flag); /*overrunisspecial,notassociatedwithachar*/ if(line_status&UART_OVERRUN_ERROR) tty_insert_flip_char(tty,0,TTY_OVERRUN); if(port->port.console&&port->sysrq){ for(i=0;i<urb->actual_length;++i) if(!usb_serial_handle_sysrq_char(port,data[i])) tty_insert_flip_char(tty,data[i],tty_flag); }else{ tty_insert_flip_string_fixed_flag(tty,data,tty_flag, urb->actual_length); } tty_flip_buffer_push(tty); tty_kref_put(tty); } /*AllofthedeviceinfoneededforthePL2303SIOserialconverter*/ staticstructusb_serial_driverpl2303_device={ .driver={ .owner=THIS_MODULE, .name="pl2303", }, .id_table=id_table, .usb_driver=&pl2303_driver, .num_ports=1, .bulk_in_size=256, .bulk_out_size=256, .open=pl2303_open, .close=pl2303_close, .dtr_rts=pl2303_dtr_rts, .carrier_raised=pl2303_carrier_raised, .ioctl=pl2303_ioctl, .break_ctl=pl2303_break_ctl, .set_termios=pl2303_set_termios, .tiocmget=pl2303_tiocmget, .tiocmset=pl2303_tiocmset, .process_read_urb=pl2303_process_read_urb, .read_int_callback=pl2303_read_int_callback, .attach=pl2303_startup, .release=pl2303_release, }; staticint__initpl2303_init(void) { intretval; retval=usb_serial_register(&pl2303_device); if(retval) gotofailed_usb_serial_register; retval=usb_register(&pl2303_driver); if(retval) gotofailed_usb_register; printk(KERN_INFOKBUILD_MODNAME":"DRIVER_DESC"\n"); return0; failed_usb_register: usb_serial_deregister(&pl2303_device); failed_usb_serial_register: returnretval; } staticvoid__exitpl2303_exit(void) { usb_deregister(&pl2303_driver); usb_serial_deregister(&pl2303_device); } module_init(pl2303_init); module_exit(pl2303_exit); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); module_param(debug,bool,S_IRUGO|S_IWUSR); MODULE_PARM_DESC(debug,"Debugenabledornot");

Makefile文件:[cpp]view plain copy#KVER=/usr/src/linux KVER=/lib/modules/`uname-r`/build CURDIR=$(shellpwd) #Kernelmodules obj-m:=pl2303.o build:kernel_modules kernel_modules: $(MAKE)-C$(KVER)M=$(CURDIR)modules clean: $(MAKE)-C$(KVER)M=$(CURDIR)clean

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。