mirror of git://git.sysmocom.de/ofono
udev: Adding PCIe as a subsystem in udev
Adding support for enumerating PCIe types of modems in ofono
This commit is contained in:
parent
b9da075d63
commit
26fb0623dc
178
plugins/udevng.c
178
plugins/udevng.c
|
@ -41,6 +41,7 @@
|
||||||
enum modem_type {
|
enum modem_type {
|
||||||
MODEM_TYPE_USB,
|
MODEM_TYPE_USB,
|
||||||
MODEM_TYPE_SERIAL,
|
MODEM_TYPE_SERIAL,
|
||||||
|
MODEM_TYPE_PCIE,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct modem_info {
|
struct modem_info {
|
||||||
|
@ -1229,26 +1230,47 @@ static gboolean setup_xmm7xxx(struct modem_info *modem)
|
||||||
info->interface, info->number, info->label,
|
info->interface, info->number, info->label,
|
||||||
info->sysattr, info->subsystem);
|
info->sysattr, info->subsystem);
|
||||||
|
|
||||||
if (g_strcmp0(modem->model,"095a") == 0) {
|
if (g_strcmp0(info->subsystem, "pci") == 0) {
|
||||||
if (g_strcmp0(info->subsystem, "tty") == 0) {
|
if ((g_strcmp0(modem->vendor, "0x8086") == 0) &&
|
||||||
if (g_strcmp0(info->number, "00") == 0)
|
(g_strcmp0(modem->model, "0x7560") == 0)) {
|
||||||
mdm = info->devnode;
|
mdm = "/dev/iat";
|
||||||
} else if (g_strcmp0(info->subsystem, "net") == 0) {
|
net = "inm0";
|
||||||
if (g_strcmp0(info->number, "06") == 0)
|
net2 = "inm1";
|
||||||
net = info->devnode;
|
net3 = "inm2";
|
||||||
if (g_strcmp0(info->number, "08") == 0)
|
ofono_modem_set_string(modem->modem,
|
||||||
net2 = info->devnode;
|
"CtrlPath", "/PCIE/IOSM/CTRL/1");
|
||||||
if (g_strcmp0(info->number, "0a") == 0)
|
ofono_modem_set_string(modem->modem, "DataPath",
|
||||||
net3 = info->devnode;
|
"/PCIE/IOSM/IPS/");
|
||||||
}
|
}
|
||||||
} else {
|
} else { /* For USB */
|
||||||
if (g_strcmp0(info->subsystem, "tty") == 0) {
|
if (g_strcmp0(modem->model, "095a") == 0) {
|
||||||
if (g_strcmp0(info->number, "02") == 0)
|
if (g_strcmp0(info->subsystem, "tty") == 0) {
|
||||||
mdm = info->devnode;
|
if (g_strcmp0(info->number, "00") == 0)
|
||||||
} else if (g_strcmp0(info->subsystem, "net") == 0) {
|
mdm = info->devnode;
|
||||||
if (g_strcmp0(info->number, "00") == 0)
|
} else if (g_strcmp0(info->subsystem, "net")
|
||||||
net = info->devnode;
|
== 0) {
|
||||||
|
if (g_strcmp0(info->number, "06") == 0)
|
||||||
|
net = info->devnode;
|
||||||
|
if (g_strcmp0(info->number, "08") == 0)
|
||||||
|
net2 = info->devnode;
|
||||||
|
if (g_strcmp0(info->number, "0a") == 0)
|
||||||
|
net3 = info->devnode;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (g_strcmp0(info->subsystem, "tty") == 0) {
|
||||||
|
if (g_strcmp0(info->number, "02") == 0)
|
||||||
|
mdm = info->devnode;
|
||||||
|
} else if (g_strcmp0(info->subsystem, "net")
|
||||||
|
== 0) {
|
||||||
|
if (g_strcmp0(info->number, "00") == 0)
|
||||||
|
net = info->devnode;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ofono_modem_set_string(modem->modem, "CtrlPath",
|
||||||
|
"/USBCDC/0");
|
||||||
|
ofono_modem_set_string(modem->modem, "DataPath",
|
||||||
|
"/USBHS/NCM/");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1266,9 +1288,6 @@ static gboolean setup_xmm7xxx(struct modem_info *modem)
|
||||||
if (net3)
|
if (net3)
|
||||||
ofono_modem_set_string(modem->modem, "NetworkInterface3", net3);
|
ofono_modem_set_string(modem->modem, "NetworkInterface3", net3);
|
||||||
|
|
||||||
ofono_modem_set_string(modem->modem, "CtrlPath", "/USBCDC/0");
|
|
||||||
ofono_modem_set_string(modem->modem, "DataPath", "/USBHS/NCM/");
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1437,6 +1456,7 @@ static void destroy_modem(gpointer data)
|
||||||
|
|
||||||
switch (modem->type) {
|
switch (modem->type) {
|
||||||
case MODEM_TYPE_USB:
|
case MODEM_TYPE_USB:
|
||||||
|
case MODEM_TYPE_PCIE:
|
||||||
for (list = modem->devices; list; list = list->next) {
|
for (list = modem->devices; list; list = list->next) {
|
||||||
struct device_info *info = list->data;
|
struct device_info *info = list->data;
|
||||||
|
|
||||||
|
@ -1467,6 +1487,7 @@ static gboolean check_remove(gpointer key, gpointer value, gpointer user_data)
|
||||||
|
|
||||||
switch (modem->type) {
|
switch (modem->type) {
|
||||||
case MODEM_TYPE_USB:
|
case MODEM_TYPE_USB:
|
||||||
|
case MODEM_TYPE_PCIE:
|
||||||
for (list = modem->devices; list; list = list->next) {
|
for (list = modem->devices; list; list = list->next) {
|
||||||
struct device_info *info = list->data;
|
struct device_info *info = list->data;
|
||||||
|
|
||||||
|
@ -1599,7 +1620,8 @@ static void add_serial_device(struct udev_device *dev)
|
||||||
|
|
||||||
static void add_device(const char *syspath, const char *devname,
|
static void add_device(const char *syspath, const char *devname,
|
||||||
const char *driver, const char *vendor,
|
const char *driver, const char *vendor,
|
||||||
const char *model, struct udev_device *device)
|
const char *model, struct udev_device *device,
|
||||||
|
enum modem_type type)
|
||||||
{
|
{
|
||||||
struct udev_device *usb_interface;
|
struct udev_device *usb_interface;
|
||||||
const char *devpath, *devnode, *interface, *number;
|
const char *devpath, *devnode, *interface, *number;
|
||||||
|
@ -1612,25 +1634,13 @@ static void add_device(const char *syspath, const char *devname,
|
||||||
if (devpath == NULL)
|
if (devpath == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
devnode = udev_device_get_devnode(device);
|
|
||||||
if (devnode == NULL) {
|
|
||||||
devnode = udev_device_get_property_value(device, "INTERFACE");
|
|
||||||
if (devnode == NULL)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
usb_interface = udev_device_get_parent_with_subsystem_devtype(device,
|
|
||||||
"usb", "usb_interface");
|
|
||||||
if (usb_interface == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
modem = g_hash_table_lookup(modem_list, syspath);
|
modem = g_hash_table_lookup(modem_list, syspath);
|
||||||
if (modem == NULL) {
|
if (modem == NULL) {
|
||||||
modem = g_try_new0(struct modem_info, 1);
|
modem = g_try_new0(struct modem_info, 1);
|
||||||
if (modem == NULL)
|
if (modem == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
modem->type = MODEM_TYPE_USB;
|
modem->type = type;
|
||||||
modem->syspath = g_strdup(syspath);
|
modem->syspath = g_strdup(syspath);
|
||||||
modem->devname = g_strdup(devname);
|
modem->devname = g_strdup(devname);
|
||||||
modem->driver = g_strdup(driver);
|
modem->driver = g_strdup(driver);
|
||||||
|
@ -1642,8 +1652,37 @@ static void add_device(const char *syspath, const char *devname,
|
||||||
g_hash_table_replace(modem_list, modem->syspath, modem);
|
g_hash_table_replace(modem_list, modem->syspath, modem);
|
||||||
}
|
}
|
||||||
|
|
||||||
interface = udev_device_get_property_value(usb_interface, "INTERFACE");
|
if (modem->type == MODEM_TYPE_USB) {
|
||||||
number = udev_device_get_property_value(device, "ID_USB_INTERFACE_NUM");
|
devnode = udev_device_get_devnode(device);
|
||||||
|
if (devnode == NULL) {
|
||||||
|
devnode = udev_device_get_property_value(device,
|
||||||
|
"INTERFACE");
|
||||||
|
if (devnode == NULL)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
usb_interface = udev_device_get_parent_with_subsystem_devtype(
|
||||||
|
device, "usb",
|
||||||
|
"usb_interface");
|
||||||
|
if (usb_interface == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
interface = udev_device_get_property_value(usb_interface,
|
||||||
|
"INTERFACE");
|
||||||
|
number = udev_device_get_property_value(device,
|
||||||
|
"ID_USB_INTERFACE_NUM");
|
||||||
|
|
||||||
|
label = udev_device_get_property_value(device, "OFONO_LABEL");
|
||||||
|
if (!label)
|
||||||
|
label = udev_device_get_property_value(usb_interface,
|
||||||
|
"OFONO_LABEL");
|
||||||
|
} else {
|
||||||
|
devnode = NULL;
|
||||||
|
interface = udev_device_get_property_value(device,
|
||||||
|
"INTERFACE");
|
||||||
|
number = NULL;
|
||||||
|
label = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* If environment variable is not set, get value from attributes (or parent's ones) */
|
/* If environment variable is not set, get value from attributes (or parent's ones) */
|
||||||
if (number == NULL) {
|
if (number == NULL) {
|
||||||
|
@ -1657,11 +1696,6 @@ static void add_device(const char *syspath, const char *devname,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
label = udev_device_get_property_value(device, "OFONO_LABEL");
|
|
||||||
if (!label)
|
|
||||||
label = udev_device_get_property_value(usb_interface,
|
|
||||||
"OFONO_LABEL");
|
|
||||||
|
|
||||||
subsystem = udev_device_get_subsystem(device);
|
subsystem = udev_device_get_subsystem(device);
|
||||||
|
|
||||||
if (modem->sysattr != NULL)
|
if (modem->sysattr != NULL)
|
||||||
|
@ -1855,9 +1889,64 @@ static void check_usb_device(struct udev_device *device)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
add_device(syspath, devname, driver, vendor, model, device);
|
add_device(syspath, devname, driver, vendor, model, device,
|
||||||
|
MODEM_TYPE_USB);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct {
|
||||||
|
const char *driver;
|
||||||
|
const char *drv;
|
||||||
|
const char *vid;
|
||||||
|
const char *pid;
|
||||||
|
} pci_driver_list[] = {
|
||||||
|
{ "xmm7xxx", "imc_ipc", "0x8086", "0x7560"},
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
static void check_pci_device(struct udev_device *device)
|
||||||
|
{
|
||||||
|
const char *syspath, *devname, *driver;
|
||||||
|
const char *vendor = NULL, *model = NULL, *drv = NULL;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
syspath = udev_device_get_syspath(device);
|
||||||
|
|
||||||
|
if (syspath == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
devname = udev_device_get_devnode(device);
|
||||||
|
vendor = udev_device_get_sysattr_value(device, "vendor");
|
||||||
|
model = udev_device_get_sysattr_value(device, "device");
|
||||||
|
driver = udev_device_get_property_value(device, "OFONO_DRIVER");
|
||||||
|
drv = udev_device_get_property_value(device, "DRIVER");
|
||||||
|
DBG("%s [%s:%s]", drv, vendor, model);
|
||||||
|
|
||||||
|
if (vendor == NULL || model == NULL || drv == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; pci_driver_list[i].driver; i++) {
|
||||||
|
if (g_str_equal(pci_driver_list[i].drv, drv) == FALSE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (pci_driver_list[i].vid) {
|
||||||
|
if (!g_str_equal(pci_driver_list[i].vid, vendor))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pci_driver_list[i].pid) {
|
||||||
|
if (!g_str_equal(pci_driver_list[i].pid, model))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
driver = pci_driver_list[i].driver;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (driver == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
add_device(syspath, devname, driver, vendor, model, device,
|
||||||
|
MODEM_TYPE_PCIE);
|
||||||
|
}
|
||||||
static void check_device(struct udev_device *device)
|
static void check_device(struct udev_device *device)
|
||||||
{
|
{
|
||||||
const char *bus;
|
const char *bus;
|
||||||
|
@ -1872,6 +1961,8 @@ static void check_device(struct udev_device *device)
|
||||||
if ((g_str_equal(bus, "usb") == TRUE) ||
|
if ((g_str_equal(bus, "usb") == TRUE) ||
|
||||||
(g_str_equal(bus, "usbmisc") == TRUE))
|
(g_str_equal(bus, "usbmisc") == TRUE))
|
||||||
check_usb_device(device);
|
check_usb_device(device);
|
||||||
|
else if (g_str_equal(bus, "pci") == TRUE)
|
||||||
|
check_pci_device(device);
|
||||||
else
|
else
|
||||||
add_serial_device(device);
|
add_serial_device(device);
|
||||||
|
|
||||||
|
@ -1932,6 +2023,7 @@ static void enumerate_devices(struct udev *context)
|
||||||
udev_enumerate_add_match_subsystem(enumerate, "usbmisc");
|
udev_enumerate_add_match_subsystem(enumerate, "usbmisc");
|
||||||
udev_enumerate_add_match_subsystem(enumerate, "net");
|
udev_enumerate_add_match_subsystem(enumerate, "net");
|
||||||
udev_enumerate_add_match_subsystem(enumerate, "hsi");
|
udev_enumerate_add_match_subsystem(enumerate, "hsi");
|
||||||
|
udev_enumerate_add_match_subsystem(enumerate, "pci");
|
||||||
|
|
||||||
udev_enumerate_scan_devices(enumerate);
|
udev_enumerate_scan_devices(enumerate);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue