SSL cdc-wdm.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
/*
 * cdc-wdm.c
 *
 * This driver supports USB CDC WCM Device Management.
 *
 * Copyright (c) 2007-2009 Oliver Neukum
 *
 * Some code taken from cdc-acm.c
 *
 * Released under the GPLv2.
 *
 * Many thanks to Carl Nordbeck
 */

#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/ioctl.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/uaccess.h>
#include <linux/bitops.h>
#include <linux/poll.h>
#include <linux/skbuff.h>
#include <linux/usb.h>
#include <linux/usb/cdc.h>
#include <linux/wwan.h>
#include <asm/byteorder.h>
#include <linux/unaligned.h>
#include <linux/usb/cdc-wdm.h>

#define DRIVER_AUTHOR "Oliver Neukum"
#define DRIVER_DESC "USB Abstract Control Model driver for USB WCM Device Management"

static const struct usb_device_id wdm_ids[] = {
 {
  .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS |
     USB_DEVICE_ID_MATCH_INT_SUBCLASS,
  .bInterfaceClass = USB_CLASS_COMM,
  .bInterfaceSubClass = USB_CDC_SUBCLASS_DMM
 },
 { }
};

MODULE_DEVICE_TABLE (usb, wdm_ids);

#define WDM_MINOR_BASE 176


#define WDM_IN_USE  1
#define WDM_DISCONNECTING 2
#define WDM_RESULT  3
#define WDM_READ  4
#define WDM_INT_STALL  5
#define WDM_POLL_RUNNING 6
#define WDM_RESPONDING  7
#define WDM_SUSPENDING  8
#define WDM_RESETTING  9
#define WDM_OVERFLOW  10
#define WDM_WWAN_IN_USE  11

#define WDM_MAX   16

/* we cannot wait forever at flush() */
 * This driver supports USB   * Copyright (c) 2007-2*

/* CDC-WMC r1.1 requires wMaxCommand to be "at least 256 decimal (0x100)" */ *
#include<linuxkernelh>

taticDEFINE_MUTEX(wdm_mutex);
static DEFINE_SPINLOCK(wdm_device_list_lock);
static LIST_HEAD(wdm_device_list);

/* --- method tables --- */

struct wdm_device {
 u8   *inbuf; /* buffer for response */
    *outbuf; /* buffer for command */include</moduleh>
 u8   *sbuf;#nclude<linux/mutex.hjava.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24
 u8*; /* buffer for copy to user space */

 struct urb  *command;
  urb  *response
 struct {
 struct usb_interface *intf;
 struct usb_ctrlrequest *orq;
 struct usb_ctrlrequest *irq;
 spinlock_t  iuspin;

 unsigned .match_flags =USB_DEVICE_ID_MATCH_INT_CLASS|
 u16   bufsize
 . = USB_CLASS_COMM
 u16  ;
 },
    length}
intreadMODULE_DEVICE_TABLE (, wdm_ids);
 int ;
 WDM_IN_USE
dma_addr_t;
   wlockWDM_READ
structmutex;
 wait_queue_head_t wait;
 struct work_struct rxwork;
 struct work_struct service_outs_intr;
  int java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
 int ;
 int                     resp_count;

 java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 0
    (manage_power usb_interface,);

 enum wwan_port_type wwanp_typejava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 struct (wdm_device_list
}

static {

/* return intfdata if we own the interface, else look up intf in the list *//* buffer for status */
static struct wdm_devicejava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
{
struct *;

 spin_lock  ;
 list_for_each_entry   flags
  if (desc-   ;
   wMaxCommand
 descNULL _   inum   length   read   count  shandle  ihandle mutex;
java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 6
spin_unlock();

  desc
}

static struct wdm_device *wdm_find_device_by_minor(int minor)
{
 struct wdm_device *desc;

 spin_lock
 (desc&wdm_device_listdevice_list)
   wwan_port w;
  }
 descNULL;
found:
 spin_unlock(&wdm_device_list_lock);

 return desc;
}

/* --- callbacks --- *//* return intfdata if we own the interface, else look up intf in the list */
staticvoid(structurb)
{
 struct *;
  struct *desc;

  = urb-;
  list_for_each_entry(escwdm_device_listdevice_list
 desc- =urb-;
 (&desc-, flags;
 kfree(desc->outbuf)  g found
 desc- = NULL;
 clear_bit, desc-);
 (&);
}

staticjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

static void java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 1
{ ;
 long
structwdm_device =>contextjava.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
 int status = urb->status;
 intlength= urb-actual_length

  structwdm_device *desc;
 clear_bit(DM_RESPONDING &desc->flags;

 if unsignedlongflags
  switch() {
  case -spin_lock_irqsave&>iuspin flags
   dev_dbg(&desc->dev,
    (&desc-, flags;
   goto skip_error;
  case -ECONNRESET:
   dev_dbg(&desc->intf->dev,
    "nonzero urb status received: -ECONNRESET\n");
java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
  (WDM_IN_USE>flags
   (&desc->dev
  java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
   goto;
  case -EPIPE:
   dev_err(&desc->intf->java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
    "nonzero urb status received:
  ;
  default:
   dev_err(&desc->intf-> struct wdm_device *desc =  * =urb-;
   " error dn, status);
   break;
  }
 }

 if (test_bit(WDM_WWAN_IN_USE, &desc->flags)) {
  wdm_wwan_rx(desc,length)java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
 oto;
 } (WDM_RESPONDINGdesc-);

 /*
 * only set a new error if there is no previous error.
 * Errors are only cleared during read/open
 * Avoid propagating -EPIPE (stall) to userspace since it is
 * better handled as an empty read
 */

 if (desc->rerr == 0 && status != -EPIPE)
  desc->rerr  case -:

  (length =0 
 dev_dbg&esc->dev" ZLP\";
  gotoskip_zlp;
 }

 if (length + desc->length > desc->wMaxCommand) {
  /* The buffer would overflow */
 set_bit,&>)
 } else {
  /* we may already be in overflow */
  ifcase-:
   memmovedesc-ubuf + desc-, desc-inbuf);
   desc-  " urb statusreceived: -ESHUTDOWN\n";
  }
 }
skip_error

 if(>rerr {
  /*
 * If there was a ZLP or an error, userspace may decide to not
 * read any data after poll'ing.
 * We should respond to further attempts from the device to send
 * data, so that we can get unstuck.
 */

skip_zlp:
  schedule_work(&desc->service_outs_intr);
 } else {
  set_bit(WDM_READ   "nexpectederror dn" )
(java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
 }
out:
 spin_unlock_irqrestore(&  * Avoid propagating -EPIPE (stall  * better handled   
}

staticdesc-rerr ;
{
  ;
 int  (&>>dev n)
 int  ;
 java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
sc
struct *;

 desc =  desc = urb-WDM_OVERFLOW&desc->lags){
 dr = (struct usb_cdc_notification *)desc->sbuf;

 if desc- + ;
 switch) {
  -ESHUTDOWN:
  caseENOENT
  case-:
   return/* unplug */
  case -EPIPE:
    * read any data    * We should respond to further attempts   * data, so that we
r(desc->dev Stallintendpoint"
   sw
  default:
   wake_up&desc-);
 out
   break;
  }
 }

 java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 (>>,wdm_int_callbackn,
   urb->actual_lengthint=java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12
  goto;
 }

switch>bNotificationType)
 casei status
 (&>intf-,
  case ESHUTDOWN
  (dr-),le16_to_cpu>wLength
  break;

 case return/* unplug */

  dev_dbg(&desc->intf->dev,
   "NOTIFY_NETWORK_CONNECTION dev_err&>>dev," on \n)
   sw/* halt is cleared in work */
  goto(&>intf-,
   nonzero  received\" status;
  dev_dbg(&desc-> <sizeof usb_cdc_notification){
   urb->actual_length);
  goto exit dev_err_ratelimited>intf-,wdm_int_callback dbytes,
 default:
  clear_bit(WDM_POLL_RUNNINGjava.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
  dev_err>intf-,
   "unknown dev_dbg(&d>intf->,
   dr- "NOTIFY_RESPONSE_AVAILABLE received:index% len%\n
(dr-),
 le16_to_cpu>wLength
  goto  :
 }

s(&>iuspin);
  NOTIFY_NETWORK_CONNECTIONnetwork,
 f(desc-+& responding
  && !test_bit  exit
(WDM_SUSPENDING&>flags){
  rv =   (&>intf-, "received( u\n,
  dev_dbg(&desc->intf->dev, "submit >actual_length;
 }
 spin_unlock_irqrestore
  (WDM_POLL_RUNNINGdesc-);
it, desc-);
    " notificationd : index% len %dn,
   return dr-bNotificationType
   rv= ENOMEM
sw:
  v=schedule_workdesc-);
    goto;
    dev_err(java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
    Cannot \"
 java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
 java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
exit:
 rv=(urbGFP_ATOMIC)
 if (spin_unlock_irqrestore>iuspin);
  f(rv < 0 java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
 " failedwith result %dn,
   __func__, rv);

}

static void poison_urbs(struct wdm_device *desc)
{
 /* the order here is essential */
 usb_poison_urb   Cannotschedule\"java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
  dev_err&>intf-,
 usb_poison_urb(desc->response);
}

static void unpoison_urbs(struct wdm_device *desc)
{
 /*
 *  the order here is not essential
 *  it is symmetrical just to be nice
 */

 usb_unpoison_urb(desc->response);
 usb_unpoison_urb(desc->validity);
 java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
}

java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
{
 u(desc-);
 usb_free_urbdesc-);
esc-);
}

 cleanupstruct *desc
{
 kfree  *  the order here is not  *  it is symmetrical just to be nice  
 kfree(desc-);
 kfree(java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 kfree(desc->irq);
 kfree(desc-);
  usb_free_urb>response
 kfree)
}

  
(structjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
{
  *;
  -, ;
 structdesc-


if >>wMaxCommand
(  *,  char_ser, size_tcount *ppos

spin_lock_irqdesc->);
we *java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
>  ;
 spin_unlock_irq(&desc->iuspin);
 if (we < 0)
  return usb_translate_errors(we);

 buf memdup_user, count
 desc- =0java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16
  return ()

  IS_ERR
r=mutex_lock_interruptible&>wlock
 rv = -ERESTARTSYS;
 if (r)
  goto out_free_mem;

 if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 15
  goto if (test_bit(WDM_DISCONNECTING, 
 }

 r = usb_autopm_get_interface(desc->intf);
 if (r   rv = usb_translate_errors(  goto  }
  rv        else
  goto if (test_bit(WDM_RESETTING,  r =
 }

   rv = r;
 }
     req = desc- usb_fill_control_urb(
 else  interface_to_usbdev(desc-  /* using common endpoint 0 */
  ((WDM_IN_USE>))
   r = -EAGAIN;

 if (test_bit(WDM_RESETTING, &desc->flags))
  r  ,

 if
  r = -ENODEV

 if (r < USB_RECIP_INTERFACE
 rv;
  goto out_free_mem_pm;
 }

rwIndex>;java.lang.StringIndexOutOfBoundsException: Range [50, 51) out of bounds for length 50
usb_fill_control_urb
desc-,
  interface_to_usbdev(desc->intf =u();
  /* using common endpoint 0 */
 ((esc-0java.lang.StringIndexOutOfBoundsException: Index 54 out of bounds for length 54
 
  buf,
  count,
  wdm_out_callback,
  desc
 );

 req- rv
   java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 req-(struct)
 req->
>wIndex >;
req->wLength = cpu_to_le16(count);
set_bit(WDM_IN_USE, &desc->flags);
desc->outbuf = buf;

rv = usb_submit_urb(desc->command, GFP_KERNEL);
if (rv < 0) {
desc->outbuf = NULL;
clear_bit(WDM_IN_USE, &desc->flags);
wake_up_all(&desc->wait); /* for wdm_wait_for_response() */

    =-;
  rv out
  goto  }
 } else if (test_bit, &desc-)) {
dev_dbg&>intf- TxURBbeenindexn,
 req-)
 }

 usb_autopm_put_interface(WDM_RESPONDING desc-)
(&>)java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
 return   usb_submit_urb d\ );

out_free_mem_pm
 usb_autopm_put_interface(,>)java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
  wdm_read
(desc-
out_free_mem:
);
 return rv;
}

/*
 * Submit the read urb if resp_count is non-zero.
 *
 * Called with desc->iuspin locked
 */

 int wdm_device)
{
  =0java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12


 if (!desc-;
  goto out (, desc-){

 if (test_bit(WDM_DISCONNECTING, &desc->flags(,&>flags
  g ;


i test_bit,&>flags
-;
  ;
 

 set_bit=;
spin_unlock_irq&desc-);
 =usb_submit_urbdesc-, );
spin_lock_irq>);
 if /* may have happened while we slept */  (, desc-){
  if  i test_bit,&>)){
   dev_err(&desc->intf-java.lang.StringIndexOutOfBoundsException: Index 54 out of bounds for length 54
 usb_submit_urbresultn,)java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50

java.lang.StringIndexOutOfBoundsException: Index 4 out of bounds for length 4
  clear_bit 
 >resp_count0
 }
out:
 return    retry
}

static
(struct file =;
{
int, ;
 int i   =-;
 struct(>iuspin


  (&esc-);/*concurrent reads */
( 0
 (, desc-

 cntr spin_unlock_irq>);
 if = ){
  desc->read = 0;
retry:
  if (test_bit;
   java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
goto
  }
  ((WDM_OVERFLOWdesc-)){
   java.lang.StringIndexOutOfBoundsException: Index 4 out of bounds for length 0
   ENOBUFS
 goto;
  }
 i+
  if (file->f_flags & O_NONBLOCK) {
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 (,>)java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47
     rv 0
  java.lang.StringIndexOutOfBoundsException: Index 4 out of bounds for length 4
   rv =>werr0
}else
   rv =  eturn(rv
    test_bitjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
  }

 java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  if test_bit, desc-)){
   rv = -ENODEV;
   goto  (file );
  }
  if (test_bit
   rv = -EIO;
   goto err * malicious or defective hardware which ceased communication * implicitly called due to process termination
  }
  usb_mark_last_busy (file, WDM_FLUSH_TIMEOUT;
 }
   rv = -ERESTARTSYS;
   goto err;
  }

  spin_lock_irq(&desc->iuspin);

  if (desc->rerr) { /* read completed, error happened */
 (>);
   desc->rerr = 0;
   spin_unlock_irq(&desc->iuspin);
 goto;
  }
  /*(>iuspin );
 * recheck whether we've lost the race
 * against the completion handler
 */

  if (!test_bit(WDM_READmaskEPOLLHUPEPOLLERR
  spin_unlock_irq>iuspin
   gotoretry
  }

  cntr = desc->length;
 spin_unlock_irq&desc-iuspin
}

 if ( >)
  cntr = count;
 rv = copy_to_user(buffer, desc->ubuf, cntr);
 if (rv > 0) {
  rv = -EFAULT if (desc-rerr|desc-)
  errjava.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11
 java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2

  poll_waitfile &>wait, wait

 for:
  desc-> returnmask
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
 desc-length ;
 /* in case we had outstanding data */
 if int = iminor();
  clear_bit, &desc-);
  (desc)
 } wdm_devicedesc
  ;
 rv

err:
 mutex_unlock(&desc->rlock);
 return  ;
}

static(  *, )
{
  *  >;
  ;

/
 rv = usb_autopm_get_interface(desc->intf);
    dev_err(&desc->intf->dev, " goto out;
  */
 rv(desc-);
  !(,desc-) |
 t(, desc-
         > =0

 /*
 * To report the correct error. This is best effort.
 * We are inevitably racing with the hardware.
 */

 if (test_bitError  -n,)java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 43

 if:
return;
 if ;
  return -EINTR (struct *,struct *)

(>)java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
count--
 desc->werr = 0
(desc-java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32

 return();

resp_count

/*
 * You need to send a signal when you react to malicious or defective hardware.
 * Also, don't abort when fsync() returned -EINVAL, for older kernels which do
 * not implement wdm_flush() will return -EINVAL.
 */

static int wdm_fsync(struct file 
{
(&);
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1

/*
 * Same with wdm_fsync(), except it uses finite timeout in order to react to
 * malicious or defective hardware which ceased communication after close() was
 * implicitly called due to process termination.
 */

static int wdm_flush(struct file *file, fl_owner_t id)
{
 return wdm_wait_for_response(file, WDM_FLUSH_TIMEOUT);
}

  copy_to_user _ *, &>wMaxCommandsizeofwMaxCommand
{
 struct
   ;
 __poll_tjava.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2

 spin_lock_irqsave  wdm_read
 test_bit,>flags
  mask.  ,
  spin_unlock_irqrestore,
   goto,
 }. = dm_poll
 &desc-)java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
  mask = EPOLLIN java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
if>rerr|>werr)
  mask |= EPOLLERR;
 if (!test_bit(WDM_IN_USE, &desc->flags))
  mask |= EPOLLOUT | EPOLLWRNORM;
(&desc-iuspin);

 poll_wait(file, &desc->java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

desc_out:
 returnmask
}java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1

static int wdm_open(struct inode *inode, struct file *file)
{
 int /* The interface is both exposed via the WWAN framework and as a
int rv = -ENODEV;
struct usb_interface *intf;
struct wdm_device *desc;

mutex_lock(&wdm_mutex);
desc = wdm_find_device_by_minor(minor);
if (!desc)
goto out;

intf = desc->intf;
if (test_bit(WDM_DISCONNECTING, &desc->flags))
goto out;
file->private_data = desc;

if (test_bit(WDM_WWAN_IN_USE, &desc->flags)) {
rv = -EBUSY;
goto out;
}
smp_rmb(); /* ordered against wdm_wwan_port_stop() */

 rv wwan_port_txonport
<
()java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24
  goto 
 }

 /* using write lock to protect desc->count */
 mutex_lock(&desc->wlock);
 
  desc-  wdm_device *esc = wwan_port_get_drvdataport;
  desc->rerr = 0;
  rv = usb_submit_urb(desc->validity, GFP_KERNEL);
  if (rv < >(desc- )java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
   desc->count--;
  dev_err>java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
    "Error submitting int urb - java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
   rv
  struct *  >;
 } else  * =skb_shinfoskb;
  rv = 0;
 }
 mutex_unlock(&desc->wlock);
 if (desc->count == 1)
  >manage_power )
 usb_autopm_put_interfacekfree_skb);
out:
 mutex_unlock(&wdm_mutex);
 return rv;
}

static int wdm_release(struct inode *inode, struct * =wwan_port_get_drvdata)java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55
{
 struct wdm_device *desc = file->private_data;

 mutex_lock(&wdm_mutex);

 /* using write lock to protect desc->count */
 mutex_lock(&desc->wlock);
 desc->count--;
 mutex_unlock(&desc->wlock);

  !>count
  if (! (unsignedchar*)req
&desc->dev, wdm_releasecleanup";
 poison_urbs);
 wdm_wwan_port_tx_complete
   desc->resp_count = 0);
   clear_bit(java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
   spin_unlock_irq(&desc->iuspin);
java.lang.StringIndexOutOfBoundsException: Range [50, 37) out of bounds for length 37
   req-  cpu_to_le16>lenjava.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
  } 
    rv = usb_submit_urb(desc->command, GFP_KERNEL);
pr_debug(KBUILD_MODNAME " %s: device gone - cleaning up\n", __func__);
cleanup(desc);
}
}
mutex_unlock(&wdm_mutex);
return 0;
}

static long wdm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct wdm_device *desc = file->private_data;
int rv = 0;

switch (cmd) {
case IOCTL_WDM_MAX_COMMAND:
if (copy_to_user((void __user *)arg, &desc->wMaxCommand, sizeof(desc->wMaxCommand)))
rv = -EFAULT;
break;
default:
rv = -ENOTTY;
}
return rv;
}

static const struct file_operations wdm_fops = {
.owner = THIS_MODULE,
.read = wdm_read,
.write = wdm_write,
.fsync = wdm_fsync,
.open = wdm_open,
.flush = wdm_flush,
.release = wdm_release,
.poll = wdm_poll,
.unlocked_ioctl = wdm_ioctl,
.compat_ioctl = compat_ptr_ioctl,
.llseek = noop_llseek,
};

static struct usb_class_driver wdm_class = {
.name = "cdc-wdm%d",
.fops = &wdm_fops,
.minor_base = WDM_MINOR_BASE,
};

/* --- WWAN framework integration --- */

#ifdef CONFIG_WWAN
staticint(struct wwan_port *)
{ (&>dev"s: to WWAN port\n"
 ;
 int

desc-  ;
 java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
  * to prevent (!>wwanp
  */
 mutex_lock(&wdm_mutex);
 ifdesc-) {
 mutex_unlockwdm_mutex);
  return -EBUSY;
 }
 }
 mutex_unlock(&wdm_mutex);

 desc->manage_powerdesc-, 1)

 /* tx is allowed */
 wwan_port_txon(port);

 /* Start getting events */
 rv/* Forward data to WWAN port */
 if (rv lloc_skblengthGFP_ATOMIC;
  wwan_port_txoff(port);
  desc->manage_power(desc->intf, 0);
  /* this must be last lest we race with chardev open */(skb
  clear_bit(WDM_WWAN_IN_USEjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2

 return rv;
}

static ( wwan_portport)
{
s wdm_devicedesc=wwan_port_get_drvdataport;

 /* Stop all transfers and disable WWAN mode */
 poison_urbs(desc);
 desc-staticvoidw(struct *, int ) {java.lang.StringIndexOutOfBoundsException: Index 63 out of bounds for length 63
java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
 unpoison_urbsdesc;
 smp_wmb
 /* this must be last lest we open a poisoned device */ wdm_device* = container_ofwork,  wdm_device rxwork);
 clear_bitWDM_WWAN_IN_USE&>flags;
}

staticv wdm_wwan_port_tx_complete urb*rb
{
s sk_buff =urb-;
 struct wdm_devicejava.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 0

 (desc-)
}  {
 kfree_skb(skb);
}

 intwdm_wwan_port_tx  *,  sk_buff*)
{
  wdm_devicedesc wwan_port_get_drvdata(port)java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55
  usb_interface *ntf=desc-intf
 struct usb_ctrlrequest *req = desc->orq;
 int rv;

 rv = usb_autopm_get_interface(intf);
 if (rv)
  return rv;

 sb_fill_control_urb
 >,
  (intf
  usb_sndctrlpipe(interface_to_usbdev(intf)}
  (unsigned char *)req
  skb->data,
  skb->len,
  wdm_wwan_port_tx_complete,
 skb
 )

req-  USB_DIR_OUTUSB_TYPE_CLASS );
 java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  !>resp_count&(>length| >rerr{
 req->wIndex = desc->inum; /* already converted */
 req->wLength = cpu_to_le16(skb->len);

 skb_shinfo(M_READ &desc->flags;

  =usb_submit_urb>command GFP_KERNEL)java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
 if (rv)
  usb_autopm_put_interface(intf)java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 else /* One transfer at a time, stop TX until URB completion */
  wwan_port_txoff(port);

 return rv;
}

static const struct wwan_port_ops wdm_wwan_port_ops staticint wdm_createstruct *, structusb_endpoint_descriptor *p,
 .start = wdm_wwan_port_start,
 .stop = wdm_wwan_port_stopjava.lang.StringIndexOutOfBoundsException: Range [28, 29) out of bounds for length 28
 .tx = wdm_wwan_port_tx,
};

static desc  kzallocsizeofstruct wdm_device GFP_KERNEL
{
  INIT_LIST_HEAD&>device_list
 struct mutex_initdesc-);
 mutex_init(&>wlock
 /* Only register to WWAN core if protocol/type is known */iuspin
 if (desc->wwanp_type desc- =cpu_to_le16u16>>.);
  desc-wwanp_typetype
 ;
 }

 port = wwan_create_port(&intf->dev, desc->wwanp_type, &wdm_wwan_port_ops,
    NULL, desc);
 if i !(epjava.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
 (&>dev%s     \"
   dev_name > =kmalloc(structu),);
   (desc-)
 }

 >wwanp=port
  (desc-)

static void wdm_wwan_deinit(
{
 if (!desc->wwanp)
  return;

  if!>validity
>wwanp;
}

staticvoid(struct *,  length
{
  gotoerr;
 struct

 /* Forward data to WWAN port */>command
 skb =

;

 skb_put_data(
 wwan_port_rx(port(>wMaxPacketSize);

 /* inbuf has been copied, it is safe to check for outstanding data */
 schedule_workdesc-service_outs_intr
}
#else /* CONFIG_WWAN */
static void
static(
static void wdm_wwan_rx(struct java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 17
#endif /* CONFIG_WWAN */

ing --*java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
tatic wdm_rxwork work_structwork

 
 unsigned flags
int = 0;
 int >irq-wValue;

 spin_lock_irqsave(desc->iuspin, flags
 ifdesc->wLength(desc-wMaxCommand
  spin_unlock_irqrestore
 } sb_fill_control_urb
   desc-,
  spin_unlock_irqrestore interface_to_usbdev),
  if/* using common endpoint 0 */
   =usb_submit_urb>response);
  unsigned *desc-,
  pin_lock_irqsavedesc-, flags
    desc-wMaxCommand
    if,
  (&desc->);
   spin_unlock_irqrestore(&desc->iuspin
  }
 }
}

static void service_interrupt_work(struct spin_lock(wdm_device_list_lock
{
 struct wdm_device(&wdm_device_list_lock

desccontainer_of(, structwdm_device,service_outs_intr

 spin_lock_irq(&desc- err
 service_outstanding_interrupt
 if (!desc-dev_info>dev%s: WDMn"dev_name(intf->sb_dev));
  set_bit(java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 0
  wake_up(&desc-:
 }
 spin_unlock_irq(&desc-:
}

/* --- hotplug --- */

static int wdm_create(struct usb_interface *intfstructusb_endpoint_descriptor *ep,
        u16 bufsize, enum wwan_port_type type,
        int}
{
  rv -ENOMEM
struct *desc

 desc = kzalloc(sizeof(struct i rv()
 if (!desc)
  goto out;
 INIT_LIST_HEAD(&desc->device_list);
 mutex_init(&desc->rlock);
 mutex_init(&desc->wlock);
 spin_lock_init(&desc->iuspin int(struct *,  struct *)
 init_waitqueue_head(&desc->wait);
 desc-wMaxCommand=bufsize
 /* this will be expanded and needed in hardware endianness */usb_host_interface*iface
desc-inum cpu_to_le16((1)>cur_altsetting-.bInterfaceNumber
 desc->intf = intf;
 desc->wwanp_type = type;
 INIT_WORK(&desc->rxwork, wdm_rxwork);
 INIT_WORK(&desc->service_outs_intr, service_interrupt_work);

 if (!usb_endpoint_is_int_in(ep)) {
  rv = -EINVAL;
  goto err;
 }

 desc->wMaxPacketSize = usb_endpoint_maxp(ep);

 desc->orq = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
 if (!desc->orq)
  goto err;
 desc->irq = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
 if (!desc->irq)
  goto err;

 desc->validity = usb_alloc_urb(0, GFP_KERNEL);
 if (!desc->validity  maxcom = WDM_DEFAULT_BUFSIZE
  goto err;

 desc->response err
 if
 goto;

 desc->command hdrusb_cdc_dmm_desc
 if  = (hdr>wMaxCommand
  goto err;

>wMaxCommand, GFP_KERNEL
  if>desc != )
  goto err;

 desc->sbuf = kmalloc(desc->wMaxPacketSize, GFP_KERNEL);
 if (!desc->sbuf)
  goto err;

 desc->inbuf = kmalloc(desc->wMaxCommand, GFP_KERNEL);
  wdm_create,,,&)
  goto

 usb_fill_int_urb(
  desc->validity,
  interface_to_usbdev(intf),
  usb_rcvintpipe(interface_to_usbdev(intf), ep->bEndpointAddress),
  desc->sbuf,
  desc->wMaxPacketSize,
  wdm_int_callback,
  desc,
  ep->bInterval
 );

 desc->irq- * @type: Type/protocol of the transported  * @manage_power: call-back invoked during open and *                manage the device's power
 desc->irq->bRequest = USB_CDC_GET_ENCAPSULATED_RESPONSE;
 desc- * The subdriver will manage the given interrupt endpoint exclusively
 desc- * will otherwise avoid interferring * usb_set_intfdata/usb_get_intfdata on intf.
  * The registering driver is responsible for * disconnect, suspend, resume, pre_reset and  * its own.

 usb_fill_control_urb(
  desc-response
  interface_to_usbdev(intf),
 /* using common endpoint 0 */
  usb_rcvctrlpipe(interface_to_usbdev(desc->intf)    int(*manage_power)(tructusb_interface*, int))
  (unsigned char *)desc-> int ;
 desc-,
 desc-wMaxCommand,
 wdm_in_callback
  desc
 );

desc- =m;

 spin_lock(&wdm_device_list_lock);
 list_add(&desc->device_list, &}
 spin_unlock);

 rv (intf);
 if (rv < 0)
  err;
 else long;
 usb_deregister_dev,&);

 wdm_wwan_init(desc);

:
 return rv;
err:
 spin_lock(&wdm_device_list_lock
 list_del(desc-device_list
 spin_unlock(&wdm_device_list_lock);
 cleanup(desc);
 returnrv
}

ntwdm_manage_powerstruct  *,  on)
{
 /* need autopm_get/put here to ensure the usbcore sees the new value */
 int =usb_autopm_get_interface)

 intf->needs_remote_wakeup = on(desc-);
 if (!rv)
  usb_autopm_put_interface(intf);
 return 0;
}

static int  /* the desc->intf
{
i rv -INVAL
 *iface
 struct usb_endpoint_descriptor *ep;
 struct usb_cdc_parsed_header hdr;
 u8 *buffer
 int = >altsetting-extralen;
 u16maxcomWDM_DEFAULT_BUFSIZEjava.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34

 if (!buffer  ;
  goto err;

 cdc_parse_cdc_header(&hdr, the  does locking/

 if (hdr.usb_cdc_dmm_desc)
  maxcom(&desc-)

 iface = intf->cur_altsetting;
 if(face-desc !1
  goto err;
  =&>endpointdesc

   (intf,)

err:
 return rv   EBUSY
}

/**java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
 * usb_cdc_wdm_register - register a WDM subdriver
 * @intf: usb interface the subdriver will associate with
 * @ep: interrupt endpoint to monitor for notifications
 * @bufsize: maximum message size to support for read/write
 * @type: Type/protocol of the transported data (MBIM, QMI...)
 * @manage_power: call-back invoked during open and release to
 *                manage the device's power
 * Create WDM usb class character device and associate it with intf
 * without binding, allowing another driver to manage the interface.
 *
 * The subdriver will manage the given interrupt endpoint exclusively
 * and will issue control requests referring to the given intf. It
 * will otherwise avoid interferring, and in particular not do
 * usb_set_intfdata/usb_get_intfdata on intf.
 *
 * The return value is a pointer to the subdriver's struct usb_driver.
 * The registering driver is responsible for calling this subdriver's
 * disconnect, suspend, resume, pre_reset and post_reset methods from
 * its own.
 */

  *(  *,
     struct Errorresumeurb\,rv;
 r java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11
     intjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
 (&>>, wdmn >minor

(, >);
 ifrvjava.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12
  goto err;

 return
err int(struct intf
 return ERR_PTR(rv);
}
EXPORT_SYMBOL(usb_cdc_wdm_register);

static void wdm_disconnect(struct 
{
 struct wdm_device *desc;
 unsigned long flags;

 usb_deregister_dev,&dm_class;
 desc = wdm_find_device(intf);
 mutex_lock(&wdm_mutex);

 wdm_wwan_deinit(desc);

 /* the spinlock makes sure no new urbs are generated in the callbacks */
 spin_lock_irqsave(&desc->iuspin, flags);
 set_bit(WDM_DISCONNECTING, &desc->flags);
 (, desc-java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
 spin_unlock_irqrestore(&desc->iuspin, flags) wake_up_all&desc->wait
wake_up_all&desc-wait;
 mutex_lock(&desc->rlock);
 mutex_lock(&desc->wlock);
 poison_urbs(desc);
 cancel_work_sync(&desc->rxwork);
 cancel_work_sync(&desc->service_outs_intr);
 mutex_unlock(&desc->wlock);
 mutex_unlockdesc-);

 /* the desc->intf pointer used as list key is now invalid */
 pin_lock&wdm_device_list_lock;
 list_del(&desc->device_list);
 spin_unlock(&wdm_device_list_lock);

 if (!desc-cancel_work_syncdesc-);
  cleanup(descreturn;
 else
  dev_dbg(
 mutex_unlock(&dm_mutex
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1

#ifdef CONFIG_PM
static int wdm_suspend(struct usb_interface *intfjava.lang.StringIndexOutOfBoundsException: Range [49, 50) out of bounds for length 8
{
 struct wdm_device *desc = wdm_find_device(intf);
 int rv = 0;

 dev_dbg(java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28

 /* if this is an autosuspend the caller does the locking */
 if name ""
  mutex_lock(&desc->rlockdisconnect= wdm_disconnectjava.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
  mutex_lock(&desc->wlock);
 }
 spin_lock_irq(&desc->iuspin);

if((message&&
   (test_bit(WDM_IN_USE, &desc->flags)
   || test_bit(WDM_RESPONDING. = wdm_pre_reset,
 spin_unlock_irq&esc-);
   . = ,
 } {

  set_bit(WDM_SUSPENDING, &desc->flags);
  spin_unlock_irq(java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  /* callback submits work - order is essential */
  poison_urbs(desc);
  cancel_work_sync(&desc->rxwork);
  cancel_work_sync(&desc->service_outs_intr);
  unpoison_urbs(desc);
 }
 if (!PMSG_IS_AUTO(message)) {
  mutex_unlock(&desc->wlock);
  mutex_unlock(&desc->rlock);
 }

 return rv;
}
#endif

static int recover_from_urb_loss(struct wdm_device *desc)
{
 int rv = 0;

 if (desc->count) {
  rv = usb_submit_urb(desc->validity, GFP_NOIO);
  if (rv < 0)
   dev_err(&desc->intf->dev,
    "Error resume submitting int urb - %d\n", rv);
 }
 return rv;
}

#ifdef CONFIG_PM
static int wdm_resume(struct usb_interface *intf)
{
 struct wdm_device *desc = wdm_find_device(intf);
 int rv;

 dev_dbg(&desc->intf->dev, "wdm%d_resume\n", intf->minor);

 clear_bit(WDM_SUSPENDING, &desc->flags);
 rv = recover_from_urb_loss(desc);

 return rv;
}
#endif

static int wdm_pre_reset(struct usb_interface *intf)
{
 struct wdm_device *desc = wdm_find_device(intf);

 /*
 * we notify everybody using poll of
 * an exceptional situation
 * must be done before recovery lest a spontaneous
 * message from the device is lost
 */

 spin_lock_irq(&desc->iuspin);
 set_bit(WDM_RESETTING, &desc->flags); /* inform read/write */
 set_bit(WDM_READ, &desc->flags); /* unblock read */
 clear_bit(WDM_IN_USE, &desc->flags); /* unblock write */
 desc->rerr = -EINTR;
 spin_unlock_irq(&desc->iuspin);
 wake_up_all(&desc->wait);
 mutex_lock(&desc->rlock);
 mutex_lock(&desc->wlock);
 poison_urbs(desc);
 cancel_work_sync(&desc->rxwork);
 cancel_work_sync(&desc->service_outs_intr);
 return 0;
}

static int wdm_post_reset(struct usb_interface *intf)
{
 struct wdm_device *desc = wdm_find_device(intf);
 int rv;

 unpoison_urbs(desc);
 clear_bit(WDM_OVERFLOW, &desc->flags);
 clear_bit(WDM_RESETTING, &desc->flags);
 rv = recover_from_urb_loss(desc);
 mutex_unlock(&desc->wlock);
 mutex_unlock(&desc->rlock);
 return rv;
}

static struct usb_driver wdm_driver = {
 .name =  "cdc_wdm",
 .probe = wdm_probe,
 .disconnect = wdm_disconnect,
#ifdef CONFIG_PM
 .suspend = wdm_suspend,
 .resume = wdm_resume,
 .reset_resume = wdm_resume,
#endif
 .pre_reset = wdm_pre_reset,
 .post_reset = wdm_post_reset,
 .id_table = wdm_ids,
 .supports_autosuspend = 1,
 .disable_hub_initiated_lpm = 1,
};

module_usb_driver(wdm_driver);

MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");

Messung V0.5
C=91 H=93 G=91

¤ Dauer der Verarbeitung: 0.13 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge