#define MYDRVNAME "visorbus"
-/* module parameters */
-static int visorbus_forcenomatch;
-
/* Display string that is guaranteed to be no longer the 99 characters*/
#define LINESIZE 99
#define CURRENT_FILE_PC VISOR_BUS_PC_visorbus_main_c
#define POLLJIFFIES_NORMALCHANNEL 10
+static bool initialized; /* stores whether bus_registration was successful */
static struct dentry *visorbus_debugfs_dir;
/*
dev = to_visor_device(xdev);
guid = visorchannel_get_uuid(dev->visorchannel);
- if (add_uevent_var(env, "MODALIAS=visorbus:%pUl", &guid))
- return -ENOMEM;
- return 0;
+ return add_uevent_var(env, "MODALIAS=visorbus:%pUl", &guid);
}
/*
drv = to_visor_driver(xdrv);
channel_type = visorchannel_get_uuid(dev->visorchannel);
- if (visorbus_forcenomatch)
- return 0;
if (!drv->channel_types)
return 0;
u32 chipset_bus_no = dev->chipset_bus_no;
u32 chipset_dev_no = dev->chipset_dev_no;
- POSTCODE_LINUX(DEVICE_CREATE_ENTRY_PC, chipset_dev_no, chipset_bus_no,
- DIAG_SEVERITY_PRINT);
-
mutex_init(&dev->visordriver_callback_lock);
dev->device.bus = &visorbus_type;
dev->device.groups = visorbus_channel_groups;
* (NOT bus instance). That's why we need to include the bus
* number within the name.
*/
- dev_set_name(&dev->device, "vbus%u:dev%u",
- chipset_bus_no, chipset_dev_no);
+ err = dev_set_name(&dev->device, "vbus%u:dev%u",
+ chipset_bus_no, chipset_dev_no);
+ if (err)
+ goto err_put;
/*
* device_add does this:
* bus_type.klist_devices regardless (use bus_for_each_dev).
*/
err = device_add(&dev->device);
- if (err < 0) {
- POSTCODE_LINUX(DEVICE_ADD_PC, 0, chipset_bus_no,
- DIAG_SEVERITY_ERR);
+ if (err < 0)
goto err_put;
- }
list_add_tail(&dev->list_all, &list_all_device_instances);
return 0; /* success: reference kept via unmatched get_device() */
err_put:
put_device(&dev->device);
+ dev_err(&dev->device, "Creating visor device failed. %d\n", err);
return err;
}
get_vbus_header_info(struct visorchannel *chan,
struct spar_vbus_headerinfo *hdr_info)
{
+ int err;
+
if (!spar_check_channel(visorchannel_get_header(chan),
spar_vbus_channel_protocol_uuid,
"vbus",
SPAR_VBUS_CHANNEL_PROTOCOL_SIGNATURE))
return -EINVAL;
- if (visorchannel_read(chan, sizeof(struct channel_header), hdr_info,
- sizeof(*hdr_info)) < 0) {
- return -EIO;
- }
+ err = visorchannel_read(chan, sizeof(struct channel_header), hdr_info,
+ sizeof(*hdr_info));
+ if (err < 0)
+ return err;
+
if (hdr_info->struct_bytes < sizeof(struct spar_vbus_headerinfo))
return -EINVAL;
if (hdr_info->device_info_struct_bytes <
- sizeof(struct ultra_vbus_deviceinfo)) {
+ sizeof(struct ultra_vbus_deviceinfo))
return -EINVAL;
- }
+
return 0;
}
*/
int visorbus_register_visor_driver(struct visor_driver *drv)
{
- int rc = 0;
+ if (!initialized)
+ return -ENODEV; /* can't register on a nonexistent bus */
drv->driver.name = drv->name;
drv->driver.bus = &visorbus_type;
* dev.drv = NULL
*/
- rc = driver_register(&drv->driver);
- if (rc < 0)
- driver_unregister(&drv->driver);
- return rc;
+ return driver_register(&drv->driver);
}
EXPORT_SYMBOL_GPL(visorbus_register_visor_driver);
* via a callback function; see pause_state_change_complete() and
* resume_state_change_complete().
*/
-static void
+static int
initiate_chipset_device_pause_resume(struct visor_device *dev, bool is_pause)
{
- int rc;
+ int err;
struct visor_driver *drv = NULL;
- void (*notify_func)(struct visor_device *dev, int response) = NULL;
-
- if (is_pause)
- notify_func = device_pause_response;
- else
- notify_func = device_resume_response;
- if (!notify_func)
- return;
drv = to_visor_driver(dev->device.driver);
- if (!drv) {
- (*notify_func)(dev, -ENODEV);
- return;
- }
+ if (!drv)
+ return -ENODEV;
- if (dev->pausing || dev->resuming) {
- (*notify_func)(dev, -EBUSY);
- return;
- }
+ if (dev->pausing || dev->resuming)
+ return -EBUSY;
if (is_pause) {
- if (!drv->pause) {
- (*notify_func)(dev, -EINVAL);
- return;
- }
+ if (!drv->pause)
+ return -EINVAL;
dev->pausing = true;
- rc = drv->pause(dev, pause_state_change_complete);
+ err = drv->pause(dev, pause_state_change_complete);
} else {
- /* This should be done at BUS resume time, but an
- * existing problem prevents us from ever getting a bus
- * resume... This hack would fail to work should we
- * ever have a bus that contains NO devices, since we
- * would never even get here in that case.
+ /* The vbus_dev_info structure in the channel was been
+ * cleared, make sure it is valid.
*/
fix_vbus_dev_info(dev);
- if (!drv->resume) {
- (*notify_func)(dev, -EINVAL);
- return;
- }
+ if (!drv->resume)
+ return -EINVAL;
dev->resuming = true;
- rc = drv->resume(dev, resume_state_change_complete);
- }
- if (rc < 0) {
- if (is_pause)
- dev->pausing = false;
- else
- dev->resuming = false;
- (*notify_func)(dev, -EINVAL);
+ err = drv->resume(dev, resume_state_change_complete);
}
+
+ return err;
}
/**
* that device. Success/failure result is returned asynchronously
* via a callback function; see pause_state_change_complete().
*/
-void
+int
chipset_device_pause(struct visor_device *dev_info)
{
- initiate_chipset_device_pause_resume(dev_info, true);
+ int err;
+
+ err = initiate_chipset_device_pause_resume(dev_info, true);
+
+ if (err < 0) {
+ dev_info->pausing = false;
+ return err;
+ }
+
+ return 0;
}
/**
* that device. Success/failure result is returned asynchronously
* via a callback function; see resume_state_change_complete().
*/
-void
+int
chipset_device_resume(struct visor_device *dev_info)
{
- initiate_chipset_device_pause_resume(dev_info, false);
+ int err;
+
+ err = initiate_chipset_device_pause_resume(dev_info, false);
+
+ if (err < 0) {
+ dev_info->resuming = false;
+ return err;
+ }
+
+ return 0;
}
int
POSTCODE_LINUX(BUS_CREATE_ENTRY_PC, 0, 0, DIAG_SEVERITY_ERR);
goto error;
}
+ initialized = true;
bus_device_info_init(&chipset_driverinfo, "chipset", "visorchipset");
}
bus_unregister(&visorbus_type);
+ initialized = false;
debugfs_remove_recursive(visorbus_debugfs_dir);
}
-
-module_param_named(forcenomatch, visorbus_forcenomatch, int, 0444);
-MODULE_PARM_DESC(visorbus_forcenomatch,
- "1 to force an UNsuccessful dev <--> drv match");