Beispiel #1
0
/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_host_hub_device_sm
* Returned Value : None
* Comments       :
*     called when a hub changes state; sm = state machine
*END*--------------------------------------------------------------------*/
static void usb_host_hub_device_sm
   (
         /* [IN] structure with USB pipe information on the interface */
         PIPE_STRUCT_PTR   pipe,

         /* [IN] parameters */
         pointer           param,

         /* [IN] buffer of data from IN stage */
         pointer           buffer,

         /* [IN] length of data from IN stage */
         uint_32           len,

         /* [IN] status of transaction */
         USB_STATUS        status
   )
{ /* Body */
    register HUB_DEVICE_STRUCT_PTR hub_instance = (HUB_DEVICE_STRUCT_PTR) param;
    _mqx_int                       i;

    switch (hub_instance->STATE) {
        case HUB_GET_DESCRIPTOR_TINY_PROCESS: 

            /* here we get number of ports from USB data */
            hub_instance->HUB_PORT_NR = ((HUB_DESCRIPTOR_STRUCT_PTR) buffer)->BNRPORTS;
            hub_instance->STATE = HUB_GET_DESCRIPTOR_PROCESS;
            usb_class_hub_get_descriptor((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, 7 + hub_instance->HUB_PORT_NR / 8 + 1);
            break;

        case HUB_GET_DESCRIPTOR_PROCESS: 
            {
                /* here, we get information from the hub and fill info in hub_instance */
                HUB_DESCRIPTOR_STRUCT_PTR hub_desc = (HUB_DESCRIPTOR_STRUCT_PTR) buffer;

                hub_instance->HUB_PORTS = USB_mem_alloc_zero(hub_instance->HUB_PORT_NR * sizeof(HUB_PORT_STRUCT));
            
                for (i = 0; i < hub_instance->HUB_PORT_NR; i++) 
                {
                    /* get REMOVABLE bit from the desriptor for appropriate installed port */
                    (hub_instance->HUB_PORTS + i)->APP_STATUS = hub_desc->DEVICEREMOVABLE[(i + 1) / 8] & (0x01 << ((i + 1) % 8)) ? HUB_PORT_REMOVABLE : 0;
                }
            }

            /* pass fluently to HUB_SET_PORT_FEATURE_PROCESS */
            hub_instance->STATE = HUB_SET_PORT_FEATURE_PROCESS;
            hub_instance->port_iterator = 0;

        case HUB_SET_PORT_FEATURE_PROCESS: 
//              if (hub_instance->port_iterator)
                /* register, that the port is now powered */
//                hub_instance->HUB_PORTS[hub_instance->port_iterator - 1].POWERED = 1;
            if (hub_instance->port_iterator < hub_instance->HUB_PORT_NR) 
            {
                usb_class_hub_set_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, ++hub_instance->port_iterator, PORT_POWER);
                break;
            } /* EndIf */
            /* else */

            /* pass fluently to HUB_CLEAR_PORT_FEATURE_PROCESS */
            hub_instance->STATE = HUB_CLEAR_PORT_FEATURE_PROCESS;
            hub_instance->port_iterator = 0;
        case HUB_CLEAR_PORT_FEATURE_PROCESS: 
            if (hub_instance->port_iterator < hub_instance->HUB_PORT_NR) 
            {
                usb_class_hub_clear_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, ++hub_instance->port_iterator, C_PORT_CONNECTION);
                break;
            } /* EndIf */
            /* else */

            /* pass fluently to HUB_GET_PORT_STATUS_PROCESS */
            hub_instance->STATE = HUB_GET_PORT_STATUS_PROCESS;
            hub_instance->port_iterator = 0;
        case HUB_GET_PORT_STATUS_PROCESS: 
            if (hub_instance->port_iterator)
                /* register the current status of the port, do the conversion LSB -> MSB */
                (hub_instance->HUB_PORTS + hub_instance->port_iterator - 1)->STATUS = SHORT_LE_TO_HOST(*(uint_16*)buffer);
            if (hub_instance->port_iterator < hub_instance->HUB_PORT_NR)
            {
                usb_class_hub_get_port_status((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, ++hub_instance->port_iterator, 4);
                break;
            } /* EndIf */
            /* else */
            
            /* test if device is attached since startup */
            for (i = 0; i < hub_instance->HUB_PORT_NR; i++)
                if ((hub_instance->HUB_PORTS + i)->STATUS & (1 << PORT_CONNECTION))
                {
                    /* if some device is attached since startup, then start session */
                    hub_instance->port_iterator = i;
                    hub_instance->STATE = HUB_NONE;
                    (hub_instance->HUB_PORTS + i)->APP_STATUS |= HUB_PORT_ATTACHED;
                    usb_class_hub_set_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, PORT_RESET);
                    break;
                }

            usb_class_hub_wait_for_interrupt((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_int_callback, (pointer) hub_instance, hub_instance->HUB_PORT_NR / 8 + 1);
            break;
            
        case HUB_RESET_DEVICE_PORT_PROCESS:
            hub_instance->STATE = HUB_NONE;
            
            usb_class_hub_set_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, PORT_RESET);

            usb_class_hub_wait_for_interrupt((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_int_callback, (pointer) hub_instance, hub_instance->HUB_PORT_NR / 8 + 1);
            break;

        case HUB_ADDRESS_DEVICE_PORT_PROCESS:
            /* compute speed */
            if ((hub_instance->HUB_PORTS + hub_instance->port_iterator)->STATUS & (1 << PORT_HIGH_SPEED))
                i = USB_SPEED_HIGH;
            else if ((hub_instance->HUB_PORTS + hub_instance->port_iterator)->STATUS & (1 << PORT_LOW_SPEED))
                i = USB_SPEED_LOW;
            else
                i = USB_SPEED_FULL;
            
            /* FIXME: accessing intf_handle directly without validation to get its host handle is not good method */
            usb_dev_list_attach_device(
                ((USB_HUB_CLASS_INTF_STRUCT_PTR) hub_instance->CCS.class_intf_handle)->G.host_handle,
                i, /* port speed */
                pipe->DEVICE_ADDRESS, /* hub address */
                hub_instance->port_iterator + 1 /* hub port */
                );

            /* test if there is still device which was not reset */
            for (i = 0; i < hub_instance->HUB_PORT_NR; i++)
                if (((hub_instance->HUB_PORTS + i)->STATUS & (1 << PORT_CONNECTION)) && !((hub_instance->HUB_PORTS + i)->APP_STATUS & HUB_PORT_ATTACHED))
                {
                    /* if some device is attached since startup, then start session */
                    hub_instance->port_iterator = i;
                    hub_instance->STATE = HUB_NONE;
                    (hub_instance->HUB_PORTS + i)->APP_STATUS |= HUB_PORT_ATTACHED;
                    usb_class_hub_set_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, PORT_RESET);
                    break;
                }

            usb_class_hub_wait_for_interrupt((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_int_callback, (pointer) hub_instance, hub_instance->HUB_PORT_NR / 8 + 1);
            break;
        
        case HUB_DETACH_DEVICE_PORT_PROCESS:
            /* FIXME: accessing intf_handle directly without validation to get its host handle is not good method */
            usb_dev_list_detach_device(
                ((USB_HUB_CLASS_INTF_STRUCT_PTR) hub_instance->CCS.class_intf_handle)->G.host_handle,
                pipe->DEVICE_ADDRESS, /* hub address */
                hub_instance->port_iterator + 1 /* hub port */
                );
            
            /* reset the app status */
            (hub_instance->HUB_PORTS + hub_instance->port_iterator)->APP_STATUS = 0x00;

            /* test if there is still device which was not reset */
            for (i = 0; i < hub_instance->HUB_PORT_NR; i++)
                if (((hub_instance->HUB_PORTS + i)->STATUS & (1 << PORT_CONNECTION)) && !((hub_instance->HUB_PORTS + i)->APP_STATUS & HUB_PORT_ATTACHED))
                {
                    /* if some device is attached since startup, then start session */
                    hub_instance->port_iterator = i;
                    hub_instance->STATE = HUB_NONE;
                    (hub_instance->HUB_PORTS + i)->APP_STATUS |= HUB_PORT_ATTACHED;
                    usb_class_hub_set_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, PORT_RESET);
                    break;
                }

            usb_class_hub_wait_for_interrupt((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_int_callback, (pointer) hub_instance, hub_instance->HUB_PORT_NR / 8 + 1);
            break;
            
        case HUB_GET_PORT_STATUS_ASYNC:
        {
            uint_32 stat = LONG_LE_TO_HOST(*(uint_32*)buffer);
            
            /* register the current status of the port */
            (hub_instance->HUB_PORTS + hub_instance->port_iterator)->STATUS = stat;
    
            /* let's see what happened */
            if ((1 << C_PORT_CONNECTION) & stat)
            {
                /* get if a device on port was attached or detached */
                if ((hub_instance->HUB_PORTS + hub_instance->port_iterator)->APP_STATUS & HUB_PORT_ATTACHED)
                {
                    hub_instance->STATE = HUB_DETACH_DEVICE_PORT_PROCESS;
                    usb_class_hub_clear_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, C_PORT_CONNECTION);
                }
                else 
                {
                    hub_instance->STATE = HUB_RESET_DEVICE_PORT_PROCESS;
                    usb_class_hub_clear_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, C_PORT_CONNECTION);
                }
                break;
            }
            else if ((1 << C_PORT_RESET) & stat)
            {
                hub_instance->STATE = HUB_ADDRESS_DEVICE_PORT_PROCESS;
                (hub_instance->HUB_PORTS + hub_instance->port_iterator)->APP_STATUS |= HUB_PORT_ATTACHED;
                usb_class_hub_clear_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, C_PORT_RESET);
                break;
            }
            else if ((1 << C_PORT_ENABLE) & stat)
            {
                /* unexpected event (error), just ignore the port */
                hub_instance->STATE = HUB_DETACH_DEVICE_PORT_PROCESS;
                usb_class_hub_clear_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, C_PORT_ENABLE);
                break;
            }
            else if ((1 << C_PORT_OVER_CURRENT) & stat) 
            {
                /* unexpected event (error), just ignore the port */
                hub_instance->STATE = HUB_NONE;
                usb_class_hub_clear_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, C_PORT_OVER_CURRENT);
                usb_class_hub_wait_for_interrupt((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_int_callback, (pointer) hub_instance, hub_instance->HUB_PORT_NR / 8 + 1);
                break;
            }
            else if ((1 << C_PORT_POWER) & stat) 
            {
                /* unexpected event (error), just ignore the port */
                hub_instance->STATE = HUB_NONE;
                usb_class_hub_clear_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, C_PORT_POWER);
                usb_class_hub_wait_for_interrupt((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_int_callback, (pointer) hub_instance, hub_instance->HUB_PORT_NR / 8 + 1);
                break;
            }
            /* FIXME: handle more events */

            break;
        }

        case HUB_GET_STATUS_ASYNC:
        {
            HUB_STATUS_STRUCT_PTR hub_stat = (HUB_STATUS_STRUCT_PTR) buffer;
            uint_32 change = SHORT_LE_TO_HOST(hub_stat->WHUBCHANGE);

            if ((1 << C_HUB_LOCAL_POWER) & change) 
            {
                hub_instance->STATE = HUB_NONE;
                usb_class_hub_clear_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, C_HUB_LOCAL_POWER);
                usb_class_hub_wait_for_interrupt((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_int_callback, (pointer) hub_instance, hub_instance->HUB_PORT_NR / 8 + 1);
            }
            else if ((1 << C_HUB_OVER_CURRENT) & change) 
            {
                hub_instance->STATE = HUB_NONE;
                usb_class_hub_clear_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, C_HUB_OVER_CURRENT);
                usb_class_hub_wait_for_interrupt((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_int_callback, (pointer) hub_instance, hub_instance->HUB_PORT_NR / 8 + 1);
            }
            break;
        }
        
    } /* EndSwitch */
    return;
} /* EndBody */
Beispiel #2
0
static void usb_host_mass_test_storage
   (
      void
   )
{ /* Body */
   USB_STATUS                                 status = USB_OK;
   uint_8                                     bLun = 0;
   INQUIRY_DATA_FORMAT                        inquiry;
   CAPACITY_LIST                              capacity_list;
   #if 0
   MODE_SELECT_PARAMETER_LIST                 md_list;
   #endif
   MASS_STORAGE_READ_CAPACITY_CMD_STRUCT_INFO read_capacity;
   REQ_SENSE_DATA_FORMAT                      req_sense;
   FORMAT_UNIT_PARAMETER_BLOCK                formatunit = { 0};
   _mqx_int                                   block_len;
   DEVICE_DESCRIPTOR_PTR                      pdd;
   CBW_STRUCT_PTR cbw_ptr = pCmd->CBW_PTR;
   CSW_STRUCT_PTR csw_ptr = pCmd->CSW_PTR;

   USB_mem_zero(buff_out,0x0F);
   USB_mem_zero(buff_in,0x400C);
   USB_mem_zero(pCmd->CSW_PTR,sizeof(CSW_STRUCT));
   USB_mem_zero(pCmd->CBW_PTR,sizeof(CBW_STRUCT));
   USB_mem_zero(pCmd,sizeof(COMMAND_OBJECT_STRUCT));
   
   pCmd->CBW_PTR  = cbw_ptr;
   pCmd->CSW_PTR  = csw_ptr;
   pCmd->LUN      = bLun;
   pCmd->CALL_PTR = (pointer)&mass_device.class_intf;
   pCmd->CALLBACK = usb_host_mass_bulk_callback;

   printf("\n =============START OF A NEW SESSION==================");

   if (USB_OK != _usb_hostdev_get_descriptor(
      mass_device.dev_handle,
      NULL,
      USB_DESC_TYPE_DEV,
      0,
      0,
      (pointer *) &pdd))
   {
      printf ("\nCould not retrieve device descriptor.");
      return;
   }
   else
      printf("\nVID = 0x%04x, PID = 0x%04x", SHORT_LE_TO_HOST(*(uint_16*)pdd->idVendor), SHORT_LE_TO_HOST(*(uint_16*)pdd->idProduct));

   /* Test the GET MAX LUN command */
   printf("\nTesting: GET MAX LUN Command");
   fflush(stdout);
   bCallBack = FALSE;

   status = usb_class_mass_getmaxlun_bulkonly(
      (pointer)&mass_device.class_intf, &bLun,
      usb_host_mass_ctrl_callback);

   if ((status != USB_OK) && (status != USB_STATUS_TRANSFER_QUEUED))
   {
      printf ("\n...ERROR");
      return;
   }
   else
   {
      /* Wait till command comes back */
      while (!bCallBack) {;}
      if (!bStatus) {
         printf("...OK\n");
      }
      else {
         printf("...Unsupported by device (bStatus=0x%x)\n", bStatus);
      }
   }

   /* Test the TEST UNIT READY command */
   printf("Testing: TEST UNIT READY Command");
   fflush(stdout);

   bCallBack = FALSE;

   status =  usb_mass_ufi_test_unit_ready(pCmd);
   
   if ((status != USB_OK) && (status != USB_STATUS_TRANSFER_QUEUED))
   {
      printf ("\n...ERROR");
      return;
   }
   else
   {
      /* Wait till command comes back */
      while (!bCallBack){;}
      if (!bStatus) {
         printf("...OK\n");
      }
      else {
         printf("...Unsupported by device (bStatus=0x%x)\n", bStatus);
      }
   }

   /* Test the REQUEST SENSE command */
   printf("Testing: REQUEST SENSE Command");
   fflush(stdout);
   bCallBack = FALSE;

   status = usb_mass_ufi_request_sense(pCmd, &req_sense,
      sizeof(REQ_SENSE_DATA_FORMAT));

   if ((status != USB_OK) && (status != USB_STATUS_TRANSFER_QUEUED))
   {
      printf ("\n...ERROR");
      return;
   }
   else
   {
      /* Wait till command comes back */
      while (!bCallBack){;}
      if (!bStatus) {
         printf("...OK\n");
      }
      else {
         printf("...Unsupported by device (bStatus=0x%x)\n", bStatus);
      }
   }

   /* Test the INQUIRY command */
   printf("Testing: INQUIRY Command");
   fflush(stdout);

   bCallBack = FALSE;

   status = usb_mass_ufi_inquiry(pCmd, (uchar_ptr) &inquiry,
      sizeof(INQUIRY_DATA_FORMAT));

   if ((status != USB_OK) && (status != USB_STATUS_TRANSFER_QUEUED))
   {
      printf ("\n...ERROR");
      return;
   }
   else
   {
      /* Wait till command comes back */
      while (!bCallBack){;}
      if (!bStatus) {
         printf("...OK\n");
      }
      else {
         printf("...Unsupported by device (bStatus=0x%x)\n", bStatus);
      }
   }
   
   /* Test the REQUEST SENSE command */
   printf("Testing: REQUEST SENSE Command");
   fflush(stdout);
   bCallBack = FALSE;

   status = usb_mass_ufi_request_sense(pCmd, &req_sense,
      sizeof(REQ_SENSE_DATA_FORMAT));

   if ((status != USB_OK) && (status != USB_STATUS_TRANSFER_QUEUED))
   {
      printf ("\n...ERROR");
      return;
   }
   else
   {
      /* Wait till command comes back */
      while (!bCallBack){;}
      if (!bStatus) {
         printf("...OK\n");
      }
      else {
         printf("...Unsupported by device (bStatus=0x%x)\n", bStatus);
      }
   }
   
   /* Test the READ FORMAT CAPACITY command */
   printf("Testing: READ FORMAT CAPACITIES Command");
   fflush(stdout);
   bCallBack = FALSE;

   status = usb_mass_ufi_format_capacity(pCmd, (uchar_ptr)&capacity_list,
      sizeof(CAPACITY_LIST));

   if ((status != USB_OK) && (status != USB_STATUS_TRANSFER_QUEUED))
   {
      printf ("\n...ERROR");
      return;
   }
   else
   {
      while (!bCallBack){;}
      if (!bStatus) {
         printf("...OK\n");
      }
      else {
         printf("...Unsupported by device (bStatus=0x%x)\n", bStatus);
      }
   }
   
   /* Test the REQUEST SENSE command */
   printf("Testing: REQUEST SENSE Command");
   fflush(stdout);
   bCallBack = FALSE;

   status = usb_mass_ufi_request_sense(pCmd, &req_sense,
      sizeof(REQ_SENSE_DATA_FORMAT));

   if ((status != USB_OK) && (status != USB_STATUS_TRANSFER_QUEUED))
   {
      printf ("\n...ERROR");
      return;
   }
   else
   {
      /* Wait till command comes back */
      while (!bCallBack){;}
      if (!bStatus) {
         printf("...OK\n");
      }
      else {
         printf("...Unsupported by device (bStatus=0x%x)\n", bStatus);
      }
   }
   
   /* Test the READ CAPACITY command */
   printf("Testing: READ CAPACITY Command");
   fflush(stdout);
   bCallBack = FALSE;

   status = usb_mass_ufi_read_capacity(pCmd, (uchar_ptr)&read_capacity,
      sizeof(MASS_STORAGE_READ_CAPACITY_CMD_STRUCT_INFO));

   if ((status != USB_OK) && (status != USB_STATUS_TRANSFER_QUEUED))
   {
      printf ("\n...ERROR");
      return;
   }
   else
   {
      while (!bCallBack){;}
      if (!bStatus) {
         printf("...OK\n");
      }
      else {
         printf("...Unsupported by device (bStatus=0x%x)\n", bStatus);
      }
   }
   
   block_len = HOST_TO_BE_LONG(* (uint_32 *) &read_capacity.BLENGTH);

#if 0
   /* Test the MODE SELECT command */
   printf("Testing: MODE SELECT Command");
   fflush(stdout);
   bCallBack = FALSE;

   //md_list. Fill parameters here
   USB_mem_zero (&md_list, sizeof (MODE_SELECT_PARAMETER_LIST));
   md_list.MODE_PARAM_HEADER.BLENGTH[1] = 0x06;
   
   status = usb_mass_ufi_mode_select(pCmd, &md_list, 8);

   if ((status != USB_OK) && (status != USB_STATUS_TRANSFER_QUEUED))
   {
      printf ("\n...ERROR");
      return;
   }
   else
   {
      /* Wait till command comes back */
      while (!bCallBack){;}
      if (!bStatus) {
         printf("...OK\n");
      }
      else {
         printf("...Unsupported by device (bStatus=0x%x)\n", bStatus);
      }
   }
#endif

   /* Test the REQUEST SENSE command */
   printf("Testing: REQUEST SENSE Command");
   fflush(stdout);
   bCallBack = FALSE;

   status = usb_mass_ufi_request_sense(pCmd, &req_sense,
      sizeof(REQ_SENSE_DATA_FORMAT));

   if ((status != USB_OK) && (status != USB_STATUS_TRANSFER_QUEUED))
   {
      printf ("\n...ERROR");
      return;
   }
   else
   {
      /* Wait till command comes back */
      while (!bCallBack){;}
      if (!bStatus) {
         printf("...OK\n");
      }
      else {
         printf("...Unsupported by device (bStatus=0x%x)\n", bStatus);
      }
   }
   
   /* Test the READ(10) command */
   printf("Testing: READ(10) Command");
   fflush(stdout);
   bCallBack = FALSE;

   status = usb_mass_ufi_read_10(pCmd, 0, buff_in, block_len, 1);

   if ((status != USB_OK) && (status != USB_STATUS_TRANSFER_QUEUED))
   {
      printf ("\n...ERROR");
      return;
   }
   else
   {
      /* Wait till command comes back */
      while (!bCallBack){;}
      if (!bStatus) {
         printf("...OK\n");
      }
      else {
         printf("...Unsupported by device (bStatus=0x%x)\n", bStatus);
      }
   }
   
   /* Test the MODE SENSE command */
   printf("Testing: MODE SENSE Command");
   fflush(stdout);
   bCallBack = FALSE;

   status = usb_mass_ufi_mode_sense(pCmd,
      2, //PC
      0x3F, //page code
      buff_in,
      (uint_32)0x08);

   if ((status != USB_OK) && (status != USB_STATUS_TRANSFER_QUEUED))
   {
      printf ("\n...ERROR");
      return;
   }
   else
   {
      /* Wait till command comes back */
      while (!bCallBack){;}
      if (!bStatus) {
         printf("...OK\n");
      }
      else {
         printf("...Unsupported by device (bStatus=0x%x)\n", bStatus);
      }
   }
   
   /* Test the PREVENT ALLOW command */
   printf("Testing: PREVENT-ALLOW MEDIUM REMOVAL Command");
   fflush(stdout);
   bCallBack = FALSE;

   status = usb_mass_ufi_prevent_allow_medium_removal(
      pCmd,
      1 // prevent
      );

   if ((status != USB_OK) && (status != USB_STATUS_TRANSFER_QUEUED))
   {
      printf ("\n...ERROR");
      return;
   }
   else
   {
      /* Wait till command comes back */
      while (!bCallBack){;}
      if (!bStatus) {
         printf("...OK\n");
      }
      else {
         printf("...Unsupported by device (bStatus=0x%x)\n", bStatus);
      }
   }
   
   /* Test the REQUEST SENSE command */
   printf("Testing: REQUEST SENSE Command");
   fflush(stdout);
   bCallBack = FALSE;

   status = usb_mass_ufi_request_sense(pCmd, &req_sense,
      sizeof(REQ_SENSE_DATA_FORMAT));

   if ((status != USB_OK) && (status != USB_STATUS_TRANSFER_QUEUED))
   {
      printf ("\n...ERROR");
      return;
   }
   else
   {
      /* Wait till command comes back */
      while (!bCallBack){;}
      if (!bStatus) {
         printf("...OK\n");
      }
      else {
         printf("...Unsupported by device (bStatus=0x%x)\n", bStatus);
      }
   }
   
   /* Test the VERIFY command */
   printf("Testing: VERIFY Command");
   fflush(stdout);
   bCallBack = FALSE;

   status = usb_mass_ufi_verify(
      pCmd,
      0x400, // block address
      1 //length to be verified
      );

   if ((status != USB_OK) && (status != USB_STATUS_TRANSFER_QUEUED))
   {
      printf ("\n...ERROR");
      return;
   }
   else
   {
      /* Wait till command comes back */
      while (!bCallBack){;}
      if (!bStatus) {
         printf("...OK\n");
      }
      else {
         printf("...Unsupported by device (bStatus=0x%x)\n", bStatus);
      }
   }
   
   /* Test the WRITE(10) command */
   printf("Testing: WRITE(10) Command");
   fflush(stdout);
   bCallBack = FALSE;

   status = usb_mass_ufi_write_10(pCmd, 8, buff_out, block_len, 1);

   if ((status != USB_OK) && (status != USB_STATUS_TRANSFER_QUEUED))
   {
      printf ("\n...ERROR");
      return;
   }
   else
   {
      /* Wait till command comes back */
      while (!bCallBack){;}
      if (!bStatus) {
         printf("...OK\n");
      }
      else {
         printf("...Unsupported by device (bStatus=0x%x)\n", bStatus);
      }
   }

   /* Test the REQUEST SENSE command */
   printf("Testing: REQUEST SENSE Command");
   fflush(stdout);
   bCallBack = FALSE;

   status = usb_mass_ufi_request_sense(pCmd, &req_sense,
      sizeof(REQ_SENSE_DATA_FORMAT));

   if ((status != USB_OK) && (status != USB_STATUS_TRANSFER_QUEUED))
   {
      printf ("\n...ERROR");
      return;
   }
   else
   {
      /* Wait till command comes back */
      while (!bCallBack){;}
      if (!bStatus) {
         printf("...OK\n");
      }
      else {
         printf("...Unsupported by device (bStatus=0x%x)\n", bStatus);
      }
   }

   /* Test the START-STOP UNIT command */
   printf("Testing: START-STOP UNIT Command");
   fflush(stdout);
   bCallBack = FALSE;

   status = usb_mass_ufi_start_stop(pCmd, 0, 1);

   if ((status != USB_OK) && (status != USB_STATUS_TRANSFER_QUEUED))
   {
      printf ("\n...ERROR");
      return;
   }
   else
   {
      /* Wait till command comes back */
      while (!bCallBack){;}
      if (!bStatus) {
         printf("...OK\n");
      }
      else {
         printf("...Unsupported by device (bStatus=0x%x)\n", bStatus);
      }
   }

   printf("\nTest done!");
   fflush(stdout);
} /* Endbody */
/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_audio_control_get_descriptors
* Returned Value : USB_OK
* Comments       :
*     This function is hunting for descriptors in the device configuration
*     and fills back fields if the descriptor was found.
*     Must be run in locked state and validated USB device or
*     directly from attach event.
*END*--------------------------------------------------------------------*/
USB_STATUS usb_class_audio_control_get_descriptors
(
    /* [IN] pointer to device instance */
    _usb_device_instance_handle      			dev_handle,

    /* [IN] pointer to interface descriptor */
    _usb_interface_descriptor_handle 			intf_handle,

    /* [OUT] pointer to header descriptor */
    USB_AUDIO_CTRL_DESC_HEADER_PTR _PTR_        header_desc,

    /* [OUT] pointer to input terminal descriptor */
    USB_AUDIO_CTRL_DESC_IT_PTR _PTR_        	it_desc,

    /* [OUT] pointer to output terminal descriptor */
    USB_AUDIO_CTRL_DESC_OT_PTR _PTR_        	ot_desc,

    /* [OUT] pointer to feature unit descriptor */
    USB_AUDIO_CTRL_DESC_FU_PTR _PTR_     		fu_desc
)
{
    INTERFACE_DESCRIPTOR_PTR   intf_ptr = (INTERFACE_DESCRIPTOR_PTR)intf_handle;
    USB_STATUS                 status;
    int_32 i;
    USB_AUDIO_CTRL_FUNC_DESC_PTR      fd;

#ifdef _HOST_DEBUG_
    DEBUG_LOG_TRACE("usb_class_audio_control_get_descriptors");
#endif

    status = USB_OK;
    /* collect all interface functional descriptors */
    for (i = 0; ; i++) {
        if (USB_OK != _usb_hostdev_get_descriptor(
                    dev_handle,
                    intf_handle,
                    USB_DESC_TYPE_CS_INTERFACE,  /* Functional descriptor for interface */
                    i,                           /* Index of descriptor */
                    intf_ptr->bAlternateSetting, /* Index of interface alternate */
                    (pointer _PTR_) &fd))
        {
            /* Here we can check capabilities from functional descriptors */
            /* But for now, nothing is checked */
            if (fu_desc == NULL)
                status = USBERR_INIT_FAILED;
            break;
        }
        /* Check if this union descriptor describes master for this interface */
        switch (fd->header.bDescriptorSubtype) {
        case USB_DESC_SUBTYPE_AUDIO_CS_HEADER:
            *header_desc = &fd->header;
            if (SHORT_LE_TO_HOST(*(uint_16*)((*header_desc)->bcdCDC)) > 0x0110)
                status = USBERR_INIT_FAILED;
            break;
        case USB_DESC_SUBTYPE_AUDIO_CS_IT:
            *it_desc = &fd->it;
            break;
        case USB_DESC_SUBTYPE_AUDIO_CS_OT:
            *ot_desc = &fd->ot;
            break;
        case USB_DESC_SUBTYPE_AUDIO_CS_FU:
            *fu_desc = &fd->fu;
            break;
        }
        if (status != USB_OK)
            break;
    }

#ifdef _HOST_DEBUG_
    if (!status)
        DEBUG_LOG_TRACE("usb_class_audio_control_get_descriptors, SUCCESSFULL");
    else
        DEBUG_LOG_TRACE("usb_class_audio_control_get_descriptors, FAILED");
#endif

    return status;
}
Beispiel #4
0
/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : usb_host_cntrl_transaction_done
* Returned Value : none
* Comments       :
*     Callback function to process transaction-done events
*     State machine for enumeration/subsequent transactions
*     Between states, the 8-byte buffer in device_instance
*        is used to save the first part of the configuration.
*     Pointer desc in various flavors (uchar_ptr, cfig_ptr)
*        is used to parse this buffer in various ways. 
* 
*END*--------------------------------------------------------------------*/
static void  usb_host_cntrl_transaction_done
   (
      /* [IN] the pipe handle */
      _usb_pipe_handle  handle,

      /* [IN] The user parameter */
      pointer           user_parm,

      /* [IN] the buffer */
      uchar_ptr         buffer,

      /* [IN] The length of the transfer */
      uint_32           length,

      /* [IN] status of the transfer */
      uint_32           status
   )
{ /* Body */
   USB_HOST_STATE_STRUCT_PTR  usb_host_ptr;
   PIPE_DESCRIPTOR_STRUCT_PTR pipe_ptr =
      (PIPE_DESCRIPTOR_STRUCT_PTR)handle;
   DEV_INSTANCE_PTR           dev_inst_ptr =
      (DEV_INSTANCE_PTR)pipe_ptr->DEV_INSTANCE;
   DESCRIPTOR_UNION           desc;
   int_32                     config_size;
   DEV_MEMORY_PTR             dev_mem;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_host_cntrl_transaction_done");
   #endif

   usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)dev_inst_ptr->host;

   switch (status) {
      case USB_OK:
         dev_inst_ptr->ctrl_retries = USBCFG_CTRL_RETRY;
         break;

      case USBERR_TR_FAILED:
         if (buffer != NULL) {
            dev_inst_ptr->ctrl_retries--;
            if (dev_inst_ptr->ctrl_retries) {
               if (dev_inst_ptr->state == DEVSTATE_DEVDESC8) {
                  /* dont jump to DEVSTATE_INITIAL state, get descriptor instead */
                  status = _usb_host_ch9_get_descriptor((pointer)dev_inst_ptr,
                     USB_DESC_TYPE_DEV << 8, 0, 8, 
                     (uchar_ptr)buffer);
                  return;
               }
               else {
                  dev_inst_ptr->state--; /* back to previous enum state */
                  status = USB_OK;
                  _time_delay(100);
               }
            }
         } else
            dev_inst_ptr->state = DEVSTATE_INITIAL;
         break;

      case USBERR_ENDPOINT_STALLED:
         dev_inst_ptr->ctrl_retries--;
         if (dev_inst_ptr->ctrl_retries) {
            status = _usb_host_ch9_clear_feature((pointer)dev_inst_ptr, REQ_TYPE_ENDPOINT, 0, ENDPOINT_HALT);
            if (status == USB_OK)
                _time_delay(100);
         }
         break;

      default:
         dev_inst_ptr->state = DEVSTATE_INITIAL;
         break;
   }

   if (status != USB_OK)
      return;

   /*----------------------------------------------------**
   ** Enumeration state machine -- cases are named after **
   ** the just-completed transactions.                   **
   **----------------------------------------------------*/
   
   switch (dev_inst_ptr->state) {
      case DEVSTATE_INITIAL:      /* initial device state = forever error state */
         break;   
      case DEVSTATE_DEVDESC8:     /* device descriptor [0..7]*/
         /* We must have received the first 8 bytes in 
         ** dev_inst_ptr->dev_descriptor which contains the 
         ** max packet size for this control endpoint 
         */
         pipe_ptr->MAX_PACKET_SIZE = 
            dev_inst_ptr->dev_descriptor.bMaxPacketSize;
            
         /* Notify device driver of MaxPacketSize0 for this device */
         status = _usb_host_update_max_packet_size_call_interface (usb_host_ptr, pipe_ptr);
         
         if (status != USB_OK)
         {
            dev_inst_ptr->state = DEVSTATE_INITIAL;
            break;
         }
         else
         {
            dev_inst_ptr->state = DEVSTATE_ADDR_SET;
         }

         /* Now set the address that we assigned when we initialized 
         ** the device instance struct for this device 
         */
         status = _usb_host_ch9_set_address((pointer)dev_inst_ptr);
         
         if (status != USB_STATUS_TRANSFER_QUEUED)
         {
            dev_inst_ptr->state = DEVSTATE_INITIAL;
            break;
         }

         break;
      case DEVSTATE_ADDR_SET:     /* address set */
         pipe_ptr->DEVICE_ADDRESS = dev_inst_ptr->address;
         
         /* Notify device driver of USB device's new address */
         status = _usb_host_update_device_address_call_interface (usb_host_ptr, pipe_ptr);
         
         if (status != USB_OK)
         {
            dev_inst_ptr->state = DEVSTATE_INITIAL;
            break;
         }

         dev_inst_ptr->state = DEVSTATE_DEV_DESC;

         /* Now get the full descriptor */
         status = _usb_host_ch9_get_descriptor((pointer)dev_inst_ptr,
            USB_DESC_TYPE_DEV << 8, 
            0, 
            USB_DESC_LEN_DEV,
            (uchar_ptr)&dev_inst_ptr->dev_descriptor);
            
         if (status != USB_STATUS_TRANSFER_QUEUED)
         {
            dev_inst_ptr->state = DEVSTATE_INITIAL;
            break;
         }

         break;   
      case DEVSTATE_DEV_DESC:     /* full device descriptor received */
         /* Now lets get the first 9 bytes of the configuration 
         ** descriptor 
         */
         desc.pntr = &dev_inst_ptr->buffer;
         dev_inst_ptr->state = DEVSTATE_GET_CFG9;
         status = _usb_host_ch9_get_descriptor((pointer)dev_inst_ptr,
            USB_DESC_TYPE_CFG << 8, 
            0, 
            sizeof(dev_inst_ptr->buffer),
            desc.bufr);
            
         if (status != USB_STATUS_TRANSFER_QUEUED)
         {
            dev_inst_ptr->state = DEVSTATE_INITIAL;
            break;
         }

         break;
      case DEVSTATE_GET_CFG9:     /* Read 9 bytes of config descriptor */
         dev_inst_ptr->state = DEVSTATE_SET_CFG;
         /* Now select the configuration as specified in the 
         ** descriptor 
         */
         desc.cfig = (CONFIGURATION_DESCRIPTOR_PTR)dev_inst_ptr->buffer;
         config_size = SHORT_LE_TO_HOST(*(uint_16*)desc.cfig->wTotalLength);

         desc.pntr = &dev_inst_ptr->buffer;
         if (USB_OK != usb_dev_list_get_mem(dev_inst_ptr,
            config_size,
            USB_MEMTYPE_CONFIG,
            1,
            &dev_mem))
         {
            #ifdef _HOST_DEBUG_
               DEBUG_LOG_TRACE("usb_host_cntrl_transaction_done");
            #endif
            return;
         }
         /* Move the pointer to the aligned payload */
         desc.pntr = dev_mem->payload.data + dev_mem->offset;
         
#ifdef __USB_OTG__
         dev_inst_ptr->state = DEVSTATE_CHK_OTG;
#else
         dev_inst_ptr->state = DEVSTATE_SET_CFG;
#endif
         /* We can only read one config descriptor at a time */
         status = _usb_host_ch9_get_descriptor((pointer)dev_inst_ptr,
            USB_DESC_TYPE_CFG << 8, 
            0, 
            (uint_16)config_size,
            desc.bufr);
            
         if (status != USB_STATUS_TRANSFER_QUEUED)
         {
            dev_inst_ptr->state = DEVSTATE_INITIAL;
            break;
         }

         break;   

      case DEVSTATE_CHK_OTG:
         /* Point to the memory owned by this device */
         /* FIXME: it is presumed that memlist points to the config descriptor */
         desc.pntr = dev_inst_ptr->memlist->payload.data + dev_inst_ptr->memlist->offset;

         /* We will always start with config desc so update the search pointer */
         config_size = SHORT_LE_TO_HOST(*(uint_16*)desc.cfig->wTotalLength);
         config_size -= desc.cfig->bLength;
         desc.word += desc.cfig->bLength;

         while (config_size) {
            if (desc.otg->bDescriptorType == USB_DESC_TYPE_OTG) {
               /* Found the OTG descriptor */
               break;
            } /* Endif */
            config_size -= desc.intf->bLength;
            desc.word += desc.intf->bLength;
         } /* EndWhile */

         /* Check for an OTG descriptor */
         dev_inst_ptr->state = DEVSTATE_SET_CFG;

         if (config_size && desc.otg->bDescriptorType == USB_DESC_TYPE_OTG &&
            (desc.otg->bmAttributes & OTG_HNP_SUPPORT))
         {
            status = _usb_host_ch9_set_feature(dev_inst_ptr, 0, 0, 4);
            
            if (status != USB_STATUS_TRANSFER_QUEUED)
            {
               dev_inst_ptr->state = DEVSTATE_INITIAL;
               break;
            }
            else
            {
               break;
            }

         } /* Endif */

         /* Fall through */

      case DEVSTATE_SET_CFG:     /* config descriptor [0..8] */

         /* Point to the memory owned by this device */
         /* FIXME: it is presumed that memlist points to the config descriptor */
         desc.pntr = dev_inst_ptr->memlist->payload.data + dev_inst_ptr->memlist->offset;

         dev_inst_ptr->state = DEVSTATE_CFG_READ;
         status = _usb_host_ch9_set_configuration(dev_inst_ptr, 
            desc.cfig->bConfigurationValue);
            
         if (status != USB_STATUS_TRANSFER_QUEUED)
         {
            dev_inst_ptr->state = DEVSTATE_INITIAL;
            break;
         }

         break;   

      case DEVSTATE_CFG_READ:     /* full config desc. read in */
         dev_inst_ptr->state = DEVSTATE_APP_CALL;

         /* Scan the configuration descriptor to find out the total 
         ** number of interfaces available. This will be the upper 
         ** bound for searching through the interface descriptors' 
         ** array
         */
         dev_inst_ptr->num_of_interfaces = 0;

         /* Point to the memory owned by this device */
         /* FIXME: it is presumed that memlist points to the config descriptor */
         desc.pntr = dev_inst_ptr->memlist->payload.data + dev_inst_ptr->memlist->offset;

         /* We will always start with config desc so update the search pointer */
         config_size = SHORT_LE_TO_HOST(*(uint_16*)desc.cfig->wTotalLength);
         config_size -= desc.cfig->bLength;
         desc.word += desc.cfig->bLength;
         
         while (config_size > 0) {
            if (desc.intf->bDescriptorType == USB_DESC_TYPE_IF) {
               /* Found an interface */
               dev_inst_ptr->num_of_interfaces++;
            } /* Endif */
            if (desc.intf->bLength) {
               config_size -= desc.intf->bLength;
               desc.word += desc.intf->bLength;
            } else {
               /* Zero-sized interface found */
               status = USBERR_INVALID_CFIG_NUM;
               break;
            }
         } /* EndWhile */
         if (config_size < 0) {
            /* Error: we have not read the configuration descriptor properly,
            ** some part is missing. Symptom: there is not config descriptor
            ** info left for latest descriptor.
            */
            status = USBERR_INVALID_CFIG_NUM;
         }
         if (status == USBERR_INVALID_CFIG_NUM) {
            /* TODO: Remove config descriptor from memlist and try to re-read. */
            break;
         }

         /* Don't select an interface here. The device driver will 
         ** select the interface 
         */

      case DEVSTATE_APP_CALL:     /* full config desc. read in */
         dev_inst_ptr->state = DEVSTATE_SET_INTF;
         if (dev_inst_ptr->new_config != 0) {
            /* We have just read a new configuration descriptor */
            dev_inst_ptr->new_config = 0;
            usb_hostdev_attach_detach(dev_inst_ptr, USB_CONFIG_EVENT);
         } else {
            usb_hostdev_attach_detach(dev_inst_ptr, USB_ATTACH_EVENT);
         } /* EndIf */
         break;

      case DEVSTATE_SET_INTF:    /* Select interface done */
         dev_inst_ptr->state = DEVSTATE_ENUM_OK;
         usb_hostdev_attach_detach(dev_inst_ptr, USB_INTF_EVENT);
         break;
      default:
         dev_inst_ptr->state = DEVSTATE_ENUM_OK;
         case DEVSTATE_ENUM_OK:   /* enumeration complete */
            if ((dev_inst_ptr->control_callback != NULL))
               dev_inst_ptr->control_callback
                  (handle,
                  user_parm,
                  buffer,
                  length,
                  status);
            break;   
      } /* EndSwitch */

   #ifdef _HOST_DEBUG_
   if (dev_inst_ptr->state == DEVSTATE_INITIAL)
   {
      DEBUG_LOG_TRACE("usb_host_cntrl_transaction_done FAILED");
   }
   else
   {
      DEBUG_LOG_TRACE("usb_host_cntrl_transaction_done SUCCESSFUL");
   }
   #endif
      
} /* EndBody */
Beispiel #5
0
/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : usb_host_ch9_dev_req
* Returned Value : USB_OK, or error status
* Comments       :
*     Function to process standard device requests in Chapter 9.
*        See Table 9-3 p. 250 of USB 2.0 specification.
*     This code does minimal error checking, on the assumption
*        that it is called only from wrappers in this file.
*     It is presumed that this function is called with USB interrupts disabled
* 
*END*--------------------------------------------------------------------*/
static USB_STATUS  usb_host_ch9_dev_req
   (
      /* usb device */
      _usb_device_instance_handle   dev_handle,
         
      /* Device Request to send */
      USB_SETUP_PTR                 devreq_ptr,
         
      /* buffer to send/receive */
      uchar_ptr                     buff_ptr
   )
{ /* Body */
  
   DEV_INSTANCE_PTR           dev_ptr;
   _usb_pipe_handle           pipe_handle;
   TR_INIT_PARAM_STRUCT       tr;
   USB_STATUS                 error;

   #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_host_ch9_dev_req");
   #endif
   
   /* Verify that device handle is valid */
   error = usb_hostdev_validate(dev_handle);

   if (error != USB_OK) 
   {

      #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("usb_host_ch9_dev_req device not found");
      #endif
      return USB_log_error(__FILE__,__LINE__,USBERR_DEVICE_NOT_FOUND);
   } /* Endif */
     
   dev_ptr = (DEV_INSTANCE_PTR)dev_handle;
   pipe_handle = dev_ptr->control_pipe;
   
   /* Initialize the TR with TR index and default control callback 
   ** function if there is one registered 
   */
   usb_hostdev_tr_init(&tr, dev_ptr->control_callback, 
      dev_ptr->control_callback_param);
   
   /* Set buffer length if required */
   switch (devreq_ptr->BREQUEST) {
      case REQ_SET_DESCRIPTOR:
         tr.TX_BUFFER = buff_ptr;
         tr.TX_LENGTH = SHORT_LE_TO_HOST(*(uint_16*)devreq_ptr->WLENGTH);
         break;
      case REQ_GET_CONFIGURATION:
      case REQ_GET_DESCRIPTOR:
      case REQ_GET_INTERFACE:
      case REQ_GET_STATUS:
      case REQ_SYNCH_FRAME:
         tr.RX_BUFFER = buff_ptr;
         tr.RX_LENGTH = SHORT_LE_TO_HOST(*(uint_16*)devreq_ptr->WLENGTH);
         break;
   } /* EndSwitch */

   tr.DEV_REQ_PTR = (uchar_ptr)(devreq_ptr);

   if ((dev_ptr->state < DEVSTATE_ENUM_OK) ||
      (tr.CALLBACK == NULL))
   {
      tr.CALLBACK = usb_host_cntrl_transaction_done;
      tr.CALLBACK_PARAM = NULL;
   } /* Endif */

   #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_host_ch9_dev_req SUCCESSFUL");
   #endif
   error = _usb_host_send_setup(dev_ptr->host, pipe_handle, &tr);
   
   return USB_log_error(__FILE__,__LINE__,error);
} /* EndBody */
Beispiel #6
0
/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : _usb_hostdev_cntrl_request
* Returned Value : USB_OK, or error status
* Comments       :
*     Function to process class- or vendor-specific control pipe device
*     requests.
*
*END*--------------------------------------------------------------------*/
USB_STATUS  _usb_hostdev_cntrl_request
   (
      /* usb device */
      _usb_device_instance_handle   dev_handle,

      /* Device Request to send */
      USB_SETUP_PTR                 devreq,

      /* buffer to send/receive */
      uchar_ptr                     buff_ptr,

      /* callback upon completion */
      tr_callback                   callback,

      /* [IN] the parameter to pass back to the callback function */
      pointer                       callback_param
   )
{ /* Body */

   DEV_INSTANCE_PTR           dev_ptr;
   _usb_pipe_handle           pipe_handle;
   TR_INIT_PARAM_STRUCT       tr;
   USB_STATUS                 error = USB_OK;

   #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_hostdev_cntrl_request");
   #endif
   
   /* Verify that device handle is valid */
   USB_lock();
   error = usb_hostdev_validate(dev_handle);

   if (error != USB_OK) {
      USB_unlock();
      #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("_usb_hostdev_cntrl_request, invalid device handle");
      #endif
      return USB_log_error(__FILE__,__LINE__,USBERR_DEVICE_NOT_FOUND);
   } /* Endif */
      

   dev_ptr = (DEV_INSTANCE_PTR)dev_handle;

   if (dev_ptr->state < DEVSTATE_ENUM_OK) {
      USB_unlock();
      #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("_usb_hostdev_cntrl_request, no device found");
      #endif
      return USB_log_error(__FILE__,__LINE__,USBERR_DEVICE_NOT_FOUND);
   } /* Endif */

   pipe_handle = dev_ptr->control_pipe;

   usb_hostdev_tr_init(&tr, callback, callback_param);

   /* Set TR buffer length as required */
   if ((REQ_TYPE_IN & devreq->BMREQUESTTYPE) != 0) {
      tr.RX_BUFFER = buff_ptr;
      tr.RX_LENGTH = SHORT_LE_TO_HOST(*(uint_16*)devreq->WLENGTH);
   } else {
      tr.TX_BUFFER = buff_ptr;
      tr.TX_LENGTH = SHORT_LE_TO_HOST(*(uint_16*)devreq->WLENGTH);
   } /* EndIf */

   tr.DEV_REQ_PTR = (uchar_ptr)devreq;

   error = _usb_host_send_setup(dev_ptr->host, pipe_handle, &tr);

   USB_unlock();

   #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_hostdev_cntrl_request,SUCCESSFUL");
   #endif
   
   return USB_log_error(__FILE__,__LINE__,error);
} /* EndBody */