@@ -87,6 +87,19 @@ struct usbtmc_device_data {
8787 u8 bTag_last_write ; /* needed for abort */
8888 u8 bTag_last_read ; /* needed for abort */
8989
90+ /* data for interrupt in endpoint handling */
91+ u8 bNotify1 ;
92+ u8 bNotify2 ;
93+ u16 ifnum ;
94+ u8 iin_bTag ;
95+ u8 * iin_buffer ;
96+ atomic_t iin_data_valid ;
97+ unsigned int iin_ep ;
98+ int iin_ep_present ;
99+ int iin_interval ;
100+ struct urb * iin_urb ;
101+ u16 iin_wMaxPacketSize ;
102+
90103 u8 rigol_quirk ;
91104
92105 /* attributes from the USB TMC spec for this device */
@@ -99,6 +112,7 @@ struct usbtmc_device_data {
99112 struct usbtmc_dev_capabilities capabilities ;
100113 struct kref kref ;
101114 struct mutex io_mutex ; /* only one i/o function running at a time */
115+ wait_queue_head_t waitq ;
102116};
103117#define to_usbtmc_data (d ) container_of(d, struct usbtmc_device_data, kref)
104118
@@ -373,6 +387,84 @@ static int usbtmc_ioctl_abort_bulk_out(struct usbtmc_device_data *data)
373387 return rv ;
374388}
375389
390+ static int usbtmc488_ioctl_read_stb (struct usbtmc_device_data * data ,
391+ void __user * arg )
392+ {
393+ struct device * dev = & data -> intf -> dev ;
394+ u8 * buffer ;
395+ u8 tag ;
396+ __u8 stb ;
397+ int rv ;
398+
399+ dev_dbg (dev , "Enter ioctl_read_stb iin_ep_present: %d\n" ,
400+ data -> iin_ep_present );
401+
402+ buffer = kmalloc (8 , GFP_KERNEL );
403+ if (!buffer )
404+ return - ENOMEM ;
405+
406+ atomic_set (& data -> iin_data_valid , 0 );
407+
408+ rv = usb_control_msg (data -> usb_dev ,
409+ usb_rcvctrlpipe (data -> usb_dev , 0 ),
410+ USBTMC488_REQUEST_READ_STATUS_BYTE ,
411+ USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE ,
412+ data -> iin_bTag ,
413+ data -> ifnum ,
414+ buffer , 0x03 , USBTMC_TIMEOUT );
415+ if (rv < 0 ) {
416+ dev_err (dev , "stb usb_control_msg returned %d\n" , rv );
417+ goto exit ;
418+ }
419+
420+ if (buffer [0 ] != USBTMC_STATUS_SUCCESS ) {
421+ dev_err (dev , "control status returned %x\n" , buffer [0 ]);
422+ rv = - EIO ;
423+ goto exit ;
424+ }
425+
426+ if (data -> iin_ep_present ) {
427+ rv = wait_event_interruptible_timeout (
428+ data -> waitq ,
429+ atomic_read (& data -> iin_data_valid ) != 0 ,
430+ USBTMC_TIMEOUT );
431+ if (rv < 0 ) {
432+ dev_dbg (dev , "wait interrupted %d\n" , rv );
433+ goto exit ;
434+ }
435+
436+ if (rv == 0 ) {
437+ dev_dbg (dev , "wait timed out\n" );
438+ rv = - ETIME ;
439+ goto exit ;
440+ }
441+
442+ tag = data -> bNotify1 & 0x7f ;
443+ if (tag != data -> iin_bTag ) {
444+ dev_err (dev , "expected bTag %x got %x\n" ,
445+ data -> iin_bTag , tag );
446+ }
447+
448+ stb = data -> bNotify2 ;
449+ } else {
450+ stb = buffer [2 ];
451+ }
452+
453+ rv = copy_to_user (arg , & stb , sizeof (stb ));
454+ if (rv )
455+ rv = - EFAULT ;
456+
457+ exit :
458+ /* bump interrupt bTag */
459+ data -> iin_bTag += 1 ;
460+ if (data -> iin_bTag > 127 )
461+ /* 1 is for SRQ see USBTMC-USB488 subclass spec section 4.3.1 */
462+ data -> iin_bTag = 2 ;
463+
464+ kfree (buffer );
465+ return rv ;
466+ }
467+
376468/*
377469 * Sends a REQUEST_DEV_DEP_MSG_IN message on the Bulk-IN endpoint.
378470 * @transfer_size: number of bytes to request from the device.
@@ -1069,6 +1161,10 @@ static long usbtmc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
10691161 case USBTMC_IOCTL_ABORT_BULK_IN :
10701162 retval = usbtmc_ioctl_abort_bulk_in (data );
10711163 break ;
1164+
1165+ case USBTMC488_IOCTL_READ_STB :
1166+ retval = usbtmc488_ioctl_read_stb (data , (void __user * )arg );
1167+ break ;
10721168 }
10731169
10741170skip_io_on_zombie :
@@ -1092,6 +1188,57 @@ static struct usb_class_driver usbtmc_class = {
10921188 .minor_base = USBTMC_MINOR_BASE ,
10931189};
10941190
1191+ static void usbtmc_interrupt (struct urb * urb )
1192+ {
1193+ struct usbtmc_device_data * data = urb -> context ;
1194+ struct device * dev = & data -> intf -> dev ;
1195+ int status = urb -> status ;
1196+ int rv ;
1197+
1198+ dev_dbg (& data -> intf -> dev , "int status: %d len %d\n" ,
1199+ status , urb -> actual_length );
1200+
1201+ switch (status ) {
1202+ case 0 : /* SUCCESS */
1203+ /* check for valid STB notification */
1204+ if (data -> iin_buffer [0 ] > 0x81 ) {
1205+ data -> bNotify1 = data -> iin_buffer [0 ];
1206+ data -> bNotify2 = data -> iin_buffer [1 ];
1207+ atomic_set (& data -> iin_data_valid , 1 );
1208+ wake_up_interruptible (& data -> waitq );
1209+ goto exit ;
1210+ }
1211+ dev_warn (dev , "invalid notification: %x\n" , data -> iin_buffer [0 ]);
1212+ break ;
1213+ case - EOVERFLOW :
1214+ dev_err (dev , "overflow with length %d, actual length is %d\n" ,
1215+ data -> iin_wMaxPacketSize , urb -> actual_length );
1216+ case - ECONNRESET :
1217+ case - ENOENT :
1218+ case - ESHUTDOWN :
1219+ case - EILSEQ :
1220+ case - ETIME :
1221+ /* urb terminated, clean up */
1222+ dev_dbg (dev , "urb terminated, status: %d\n" , status );
1223+ return ;
1224+ default :
1225+ dev_err (dev , "unknown status received: %d\n" , status );
1226+ }
1227+ exit :
1228+ rv = usb_submit_urb (urb , GFP_ATOMIC );
1229+ if (rv )
1230+ dev_err (dev , "usb_submit_urb failed: %d\n" , rv );
1231+ }
1232+
1233+ static void usbtmc_free_int (struct usbtmc_device_data * data )
1234+ {
1235+ if (!data -> iin_ep_present || !data -> iin_urb )
1236+ return ;
1237+ usb_kill_urb (data -> iin_urb );
1238+ kfree (data -> iin_buffer );
1239+ usb_free_urb (data -> iin_urb );
1240+ kref_put (& data -> kref , usbtmc_delete );
1241+ }
10951242
10961243static int usbtmc_probe (struct usb_interface * intf ,
10971244 const struct usb_device_id * id )
@@ -1114,6 +1261,8 @@ static int usbtmc_probe(struct usb_interface *intf,
11141261 usb_set_intfdata (intf , data );
11151262 kref_init (& data -> kref );
11161263 mutex_init (& data -> io_mutex );
1264+ init_waitqueue_head (& data -> waitq );
1265+ atomic_set (& data -> iin_data_valid , 0 );
11171266 data -> zombie = 0 ;
11181267
11191268 /* Determine if it is a Rigol or not */
@@ -1134,9 +1283,12 @@ static int usbtmc_probe(struct usb_interface *intf,
11341283 data -> bTag = 1 ;
11351284 data -> TermCharEnabled = 0 ;
11361285 data -> TermChar = '\n' ;
1286+ /* 2 <= bTag <= 127 USBTMC-USB488 subclass specification 4.3.1 */
1287+ data -> iin_bTag = 2 ;
11371288
11381289 /* USBTMC devices have only one setting, so use that */
11391290 iface_desc = data -> intf -> cur_altsetting ;
1291+ data -> ifnum = iface_desc -> desc .bInterfaceNumber ;
11401292
11411293 /* Find bulk in endpoint */
11421294 for (n = 0 ; n < iface_desc -> desc .bNumEndpoints ; n ++ ) {
@@ -1161,6 +1313,20 @@ static int usbtmc_probe(struct usb_interface *intf,
11611313 break ;
11621314 }
11631315 }
1316+ /* Find int endpoint */
1317+ for (n = 0 ; n < iface_desc -> desc .bNumEndpoints ; n ++ ) {
1318+ endpoint = & iface_desc -> endpoint [n ].desc ;
1319+
1320+ if (usb_endpoint_is_int_in (endpoint )) {
1321+ data -> iin_ep_present = 1 ;
1322+ data -> iin_ep = endpoint -> bEndpointAddress ;
1323+ data -> iin_wMaxPacketSize = usb_endpoint_maxp (endpoint );
1324+ data -> iin_interval = endpoint -> bInterval ;
1325+ dev_dbg (& intf -> dev , "Found Int in endpoint at %u\n" ,
1326+ data -> iin_ep );
1327+ break ;
1328+ }
1329+ }
11641330
11651331 retcode = get_capabilities (data );
11661332 if (retcode )
@@ -1169,6 +1335,39 @@ static int usbtmc_probe(struct usb_interface *intf,
11691335 retcode = sysfs_create_group (& intf -> dev .kobj ,
11701336 & capability_attr_grp );
11711337
1338+ if (data -> iin_ep_present ) {
1339+ /* allocate int urb */
1340+ data -> iin_urb = usb_alloc_urb (0 , GFP_KERNEL );
1341+ if (!data -> iin_urb ) {
1342+ dev_err (& intf -> dev , "Failed to allocate int urb\n" );
1343+ goto error_register ;
1344+ }
1345+
1346+ /* will reference data in int urb */
1347+ kref_get (& data -> kref );
1348+
1349+ /* allocate buffer for interrupt in */
1350+ data -> iin_buffer = kmalloc (data -> iin_wMaxPacketSize ,
1351+ GFP_KERNEL );
1352+ if (!data -> iin_buffer ) {
1353+ dev_err (& intf -> dev , "Failed to allocate int buf\n" );
1354+ goto error_register ;
1355+ }
1356+
1357+ /* fill interrupt urb */
1358+ usb_fill_int_urb (data -> iin_urb , data -> usb_dev ,
1359+ usb_rcvintpipe (data -> usb_dev , data -> iin_ep ),
1360+ data -> iin_buffer , data -> iin_wMaxPacketSize ,
1361+ usbtmc_interrupt ,
1362+ data , data -> iin_interval );
1363+
1364+ retcode = usb_submit_urb (data -> iin_urb , GFP_KERNEL );
1365+ if (retcode ) {
1366+ dev_err (& intf -> dev , "Failed to submit iin_urb\n" );
1367+ goto error_register ;
1368+ }
1369+ }
1370+
11721371 retcode = sysfs_create_group (& intf -> dev .kobj , & data_attr_grp );
11731372
11741373 retcode = usb_register_dev (intf , & usbtmc_class );
@@ -1185,6 +1384,7 @@ static int usbtmc_probe(struct usb_interface *intf,
11851384error_register :
11861385 sysfs_remove_group (& intf -> dev .kobj , & capability_attr_grp );
11871386 sysfs_remove_group (& intf -> dev .kobj , & data_attr_grp );
1387+ usbtmc_free_int (data );
11881388 kref_put (& data -> kref , usbtmc_delete );
11891389 return retcode ;
11901390}
@@ -1196,6 +1396,7 @@ static void usbtmc_disconnect(struct usb_interface *intf)
11961396 dev_dbg (& intf -> dev , "usbtmc_disconnect called\n" );
11971397
11981398 data = usb_get_intfdata (intf );
1399+ usbtmc_free_int (data );
11991400 usb_deregister_dev (intf , & usbtmc_class );
12001401 sysfs_remove_group (& intf -> dev .kobj , & capability_attr_grp );
12011402 sysfs_remove_group (& intf -> dev .kobj , & data_attr_grp );
0 commit comments