Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usbdev/src/recognise.c

    rfeeac0d rc01987c  
    3434 */
    3535
    36 /** XXX Fix this */
    37 #define _DDF_DATA_IMPLANT
    38 
    39 #include <sys/types.h>
    40 #include <fibril_synch.h>
    41 #include <usb/debug.h>
    42 #include <usb/dev/hub.h>
    4336#include <usb/dev/pipes.h>
    4437#include <usb/dev/recognise.h>
    45 #include <usb/ddfiface.h>
    4638#include <usb/dev/request.h>
    4739#include <usb/classes/classes.h>
     40
     41#include <assert.h>
     42#include <errno.h>
    4843#include <stdio.h>
    49 #include <errno.h>
    50 #include <assert.h>
    51 
    52 /** DDF operations of child devices. */
    53 static ddf_dev_ops_t child_ops = {
    54         .interfaces[USB_DEV_IFACE] = &usb_iface_hub_child_impl
    55 };
     44#include <sys/types.h>
    5645
    5746/** Get integer part from BCD coded number. */
     
    245234                    (int) device_descriptor->product_id,
    246235                    BCD_ARGS(device_descriptor->device_version));
    247                
     236
    248237                /* Next, without release number. */
    249238                ADD_MATCHID_OR_RETURN(matches, 90,
     
    251240                    (int) device_descriptor->vendor_id,
    252241                    (int) device_descriptor->product_id);
    253         }       
    254 
    255         /*
    256          * If the device class points to interface we skip adding
    257          * class directly but we add a multi interface device.
    258          */
    259         if (device_descriptor->device_class != USB_CLASS_USE_INTERFACE) {
    260                 ADD_MATCHID_OR_RETURN(matches, 50, "usb&class=%s",
    261                     usb_str_class(device_descriptor->device_class));
    262         } else {
    263                 ADD_MATCHID_OR_RETURN(matches, 50, "usb&mid");
    264         }
    265        
     242        }
     243
     244        /* Class match id */
     245        ADD_MATCHID_OR_RETURN(matches, 50, "usb&class=%s",
     246            usb_str_class(device_descriptor->device_class));
     247
    266248        /* As a last resort, try fallback driver. */
    267249        ADD_MATCHID_OR_RETURN(matches, 10, "usb&fallback");
     
    305287}
    306288
    307 /** Probe for device kind and register it in devman.
    308  *
    309  * @param[in] ctrl_pipe Control pipe to the device.
    310  * @param[in] parent Parent device.
    311  * @param[in] dev_ops Child device ops. Default child_ops will be used if NULL.
    312  * @param[in] dev_data Arbitrary pointer to be stored in the child
    313  *      as @c driver_data.
    314  * @param[out] child_fun Storage where pointer to allocated child function
    315  *      will be written.
    316  * @return Error code.
    317  *
    318  */
    319 int usb_device_register_child_in_devman(usb_pipe_t *ctrl_pipe,
    320     ddf_dev_t *parent, ddf_dev_ops_t *dev_ops, void *dev_data,
    321     ddf_fun_t **child_fun)
    322 {
    323         if (child_fun == NULL || ctrl_pipe == NULL)
    324                 return EINVAL;
    325        
    326         if (!dev_ops && dev_data) {
    327                 usb_log_warning("Using standard fun ops with arbitrary "
    328                     "driver data. This does not have to work.\n");
    329         }
    330        
    331         /** Index to append after device name for uniqueness. */
    332         static atomic_t device_name_index = {0};
    333         const size_t this_device_name_index =
    334             (size_t) atomic_preinc(&device_name_index);
    335        
    336         ddf_fun_t *child = NULL;
    337         int rc;
    338        
    339         /*
    340          * TODO: Once the device driver framework support persistent
    341          * naming etc., something more descriptive could be created.
    342          */
    343         char child_name[12];  /* The format is: "usbAB_aXYZ", length 11 */
    344         rc = snprintf(child_name, sizeof(child_name),
    345             "usb%02zu_a%d", this_device_name_index, ctrl_pipe->wire->address);
    346         if (rc < 0) {
    347                 goto failure;
    348         }
    349        
    350         child = ddf_fun_create(parent, fun_inner, child_name);
    351         if (child == NULL) {
    352                 rc = ENOMEM;
    353                 goto failure;
    354         }
    355        
    356         if (dev_ops != NULL)
    357                 ddf_fun_set_ops(child, dev_ops);
    358         else
    359                 ddf_fun_set_ops(child, &child_ops);
    360        
    361         ddf_fun_data_implant(child, dev_data);
    362        
    363         /*
    364          * Store the attached device in fun
    365          * driver data if there is no other data
    366          */
    367         if (!dev_data) {
    368                 usb_hub_attached_device_t *new_device = ddf_fun_data_alloc(
    369                     child, sizeof(usb_hub_attached_device_t));
    370                 if (!new_device) {
    371                         rc = ENOMEM;
    372                         goto failure;
    373                 }
    374                
    375                 new_device->address = ctrl_pipe->wire->address;
    376                 new_device->fun = child;
    377         }
    378        
    379         match_id_list_t match_ids;
    380         init_match_ids(&match_ids);
    381         rc = usb_device_create_match_ids(ctrl_pipe, &match_ids);
    382         if (rc != EOK)
    383                 goto failure;
    384        
    385         list_foreach(match_ids.ids, link, match_id_t, match_id) {
    386                 rc = ddf_fun_add_match_id(child, match_id->id, match_id->score);
    387                 if (rc != EOK) {
    388                         clean_match_ids(&match_ids);
    389                         goto failure;
    390                 }
    391         }
    392        
    393         clean_match_ids(&match_ids);
    394        
    395         rc = ddf_fun_bind(child);
    396         if (rc != EOK)
    397                 goto failure;
    398        
    399         *child_fun = child;
    400         return EOK;
    401        
    402 failure:
    403         if (child != NULL) {
    404                 /* This takes care of match_id deallocation as well. */
    405                 ddf_fun_destroy(child);
    406         }
    407        
    408         return rc;
    409 }
    410 
    411289/**
    412290 * @}
Note: See TracChangeset for help on using the changeset viewer.