ia64/xen-unstable

changeset 3835:3d2ed612bf7a

bitkeeper revision 1.1159.263.1 (42110e81vH_yoemMp8R1uc9AeO0gfw)

USB cleanups and reducing trust of the frontend for iso transfers.
author mwilli2@equilibrium.research
date Mon Feb 14 20:48:01 2005 +0000 (2005-02-14)
parents 177865f3143e
children 3b3ed38bd02b
files linux-2.6.10-xen-sparse/drivers/xen/usbback/usbback.c
line diff
     1.1 --- a/linux-2.6.10-xen-sparse/drivers/xen/usbback/usbback.c	Mon Feb 07 11:58:09 2005 +0000
     1.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/usbback/usbback.c	Mon Feb 14 20:48:01 2005 +0000
     1.3 @@ -69,7 +69,6 @@ typedef struct
     1.4   */
     1.5  typedef struct {
     1.6      usbif_priv_t       *usbif_priv;
     1.7 -    usbif_iso_t        *iso_sched;
     1.8      unsigned long      id;
     1.9      int                nr_pages;
    1.10      unsigned short     operation;
    1.11 @@ -280,8 +279,6 @@ static void __end_usb_io_op(struct urb *
    1.12          int i;
    1.13          usbif_iso_t *sched = (usbif_iso_t *)MMAP_VADDR(pending_idx, pending_req->nr_pages - 1);
    1.14  
    1.15 -        ASSERT(sched == pending_req->sched);
    1.16 -
    1.17          /* If we're dealing with an iso pipe, we need to copy back the schedule. */
    1.18          for ( i = 0; i < purb->number_of_packets; i++ )
    1.19          {
    1.20 @@ -501,6 +498,32 @@ static void dispatch_usb_probe(usbif_pri
    1.21      make_response(up, id, USBIF_OP_PROBE, ret, portid, 0);
    1.22  }
    1.23  
    1.24 +/**
    1.25 + * check_iso_schedule - safety check the isochronous schedule for an URB
    1.26 + * @purb : the URB in question
    1.27 + */
    1.28 +static int check_iso_schedule(struct urb *purb)
    1.29 +{
    1.30 +    int i;
    1.31 +    unsigned long total_length = 0;
    1.32 +    
    1.33 +    for ( i = 0; i < purb->number_of_packets; i++ )
    1.34 +    {
    1.35 +        struct usb_iso_packet_descriptor *desc = &purb->iso_frame_desc[i];
    1.36 +        
    1.37 +        if ( desc->offset >= purb->transfer_buffer_length
    1.38 +            || ( desc->offset + desc->length) > purb->transfer_buffer_length )
    1.39 +            return -EINVAL;
    1.40 +
    1.41 +        total_length += desc->length;
    1.42 +
    1.43 +        if ( total_length > purb->transfer_buffer_length )
    1.44 +            return -EINVAL;
    1.45 +    }
    1.46 +    
    1.47 +    return 0;
    1.48 +}
    1.49 +
    1.50  owned_port_t *find_port_for_request(usbif_priv_t *up, usbif_request_t *req);
    1.51  
    1.52  static void dispatch_usb_io(usbif_priv_t *up, usbif_request_t *req)
    1.53 @@ -588,7 +611,6 @@ static void dispatch_usb_io(usbif_priv_t
    1.54          kfree(setup);
    1.55          return;
    1.56      }
    1.57 -
    1.58      else if ( setup[0] == 0x1 && setup[1] == 0xB )
    1.59      {
    1.60          /* The host kernel needs to know what device interface is in use
    1.61 @@ -719,8 +741,11 @@ static void dispatch_usb_io(usbif_priv_t
    1.62  
    1.63      purb->number_of_packets = req->num_iso;
    1.64  
    1.65 +    if ( purb->number_of_packets * sizeof(usbif_iso_t) > PAGE_SIZE )
    1.66 +        goto urb_error;
    1.67 +
    1.68      /* Make sure there's always some kind of timeout. */
    1.69 -    purb->timeout = ( req->timeout > 0 ) ?  (req->timeout * HZ) / 1000
    1.70 +    purb->timeout = ( req->timeout > 0 ) ? (req->timeout * HZ) / 1000
    1.71                      :  1000;
    1.72  
    1.73      purb->setup_packet = setup;
    1.74 @@ -731,31 +756,27 @@ static void dispatch_usb_io(usbif_priv_t
    1.75          usbif_iso_t *iso_sched = (usbif_iso_t *)MMAP_VADDR(pending_idx, i - 1);
    1.76  
    1.77          /* If we're dealing with an iso pipe, we need to copy in a schedule. */
    1.78 -        for ( j = 0; j < req->num_iso; j++ )
    1.79 +        for ( j = 0; j < purb->number_of_packets; j++ )
    1.80          {
    1.81              purb->iso_frame_desc[j].length = iso_sched[j].length;
    1.82              purb->iso_frame_desc[j].offset = iso_sched[j].buffer_offset;
    1.83              iso_sched[j].status = 0;
    1.84          }
    1.85 -        pending_req->iso_sched = iso_sched;
    1.86      }
    1.87  
    1.88 -    {
    1.89 -        int ret;
    1.90 -        ret = usb_submit_urb(purb);
    1.91 -        
    1.92 -        dump_urb(purb);
    1.93 -        
    1.94 -        if ( ret != 0 )
    1.95 -        {
    1.96 -            usbif_put(up);
    1.97 -            free_pending(pending_idx);
    1.98 -            goto bad_descriptor;
    1.99 -        }
   1.100 -    }
   1.101 -    
   1.102 +    if ( check_iso_schedule(purb) != 0 )
   1.103 +        goto urb_error;
   1.104 +
   1.105 +    if ( usb_submit_urb(purb) != 0 )
   1.106 +        goto urb_error;
   1.107 +
   1.108      return;
   1.109  
   1.110 + urb_error:
   1.111 +    dump_urb(purb);    
   1.112 +    usbif_put(up);
   1.113 +    free_pending(pending_idx);
   1.114 +
   1.115   bad_descriptor:
   1.116      kfree ( setup );
   1.117      if ( purb != NULL )