diff options
author | tzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2007-10-16 19:17:46 +0000 |
---|---|---|
committer | tzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2007-10-16 19:17:46 +0000 |
commit | f314f6fcda2493f0097b4e2af46fd0c305e740d7 (patch) | |
tree | 2a5341d3b22461a73763908d496f896bbeb9ef33 /xpp/utils | |
parent | 963a296c4a3cd7cca0bed3af311ab75b3f75a6ce (diff) |
xpp r4892:
* Zaptel/Hardware perl modules:
- Use sysfs directly. Don't rely on lspci/lsusb.
- Each device has a description and driver name.
- Zaptel::Hardware::drivers() to show the list of required drivers
for this system (see zaptel_drivers).
- zaptel_hardware shows a description and a (suggested?) driver.
* zt_registration sorts by Serial first and only then by connector.
* USB_FW.hex replaces all the USB_11x0.hex .
- Separate USB interface for the management processor.
- Hence fpga_load can now work even with drivers loaded.
* Fix firmware upgrading.
* Fix manual firmware loading while auto-loading.
Merged revisions 3142 via svnmerge from
http://svn.digium.com/svn/zaptel/branches/1.2
git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.4@3143 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'xpp/utils')
-rw-r--r-- | xpp/utils/fpga_load.c | 117 | ||||
-rw-r--r-- | xpp/utils/xpp_fxloader | 12 | ||||
-rwxr-xr-x | xpp/utils/zaptel_drivers | 9 | ||||
-rwxr-xr-x | xpp/utils/zaptel_hardware | 61 | ||||
-rw-r--r-- | xpp/utils/zconf/Zaptel/Hardware.pm | 11 | ||||
-rw-r--r-- | xpp/utils/zconf/Zaptel/Hardware/PCI.pm | 187 | ||||
-rw-r--r-- | xpp/utils/zconf/Zaptel/Hardware/USB.pm | 81 | ||||
-rw-r--r-- | xpp/utils/zconf/Zaptel/Xpp.pm | 4 | ||||
-rw-r--r-- | xpp/utils/zconf/Zaptel/Xpp/Xbus.pm | 7 | ||||
-rwxr-xr-x | xpp/utils/zt_registration | 53 |
10 files changed, 342 insertions, 200 deletions
diff --git a/xpp/utils/fpga_load.c b/xpp/utils/fpga_load.c index c7ce907..e28f9a8 100644 --- a/xpp/utils/fpga_load.c +++ b/xpp/utils/fpga_load.c @@ -33,6 +33,52 @@ static char *progname; #define PACKET_SIZE 512 #define EEPROM_SIZE 16 #define SERIAL_SIZE 8 +#define TIMEOUT 5000 + + +/* My device parameters */ +#define MY_EP_OUT 0x04 +#define MY_EP_IN 0x88 + +#define FPGA_EP_OUT 0x02 +#define FPGA_EP_IN 0x86 + +/* USB firmware types */ +#define USB_11xx 0 +#define USB_FIRMWARE_II 1 + +#define TYPE_ENTRY(t,ni,n,ne,out,in,...) \ + [t] = { \ + .type_code = (t), \ + .num_interfaces = (ni), \ + .my_interface_num = (n), \ + .num_endpoints = (ne), \ + .my_ep_in = (in), \ + .my_ep_out = (out), \ + .name = #t, \ + .endpoints = { __VA_ARGS__ }, \ + } + +static const struct astribank_type { + int type_code; + int num_interfaces; + int my_interface_num; + int num_endpoints; + int my_ep_out; + int my_ep_in; + char *name; + int endpoints[4]; /* for matching */ +} astribank_types[] = { + TYPE_ENTRY(USB_11xx, 1, 0, 4, MY_EP_OUT, MY_EP_IN, + FPGA_EP_OUT, + MY_EP_OUT, + FPGA_EP_IN, + MY_EP_IN), + TYPE_ENTRY(USB_FIRMWARE_II, 2, 1, 2, MY_EP_OUT, MY_EP_IN, + MY_EP_OUT, + MY_EP_IN), +}; +#undef TYPE_ENTRY enum fpga_load_packet_types { PT_STATUS_REPLY = 0x01, @@ -98,6 +144,7 @@ struct my_usb_device { char iInterface[BUFSIZ]; int is_usb2; struct myeeprom eeprom; + const struct astribank_type *abtype; }; const char *load_status2str(enum fpga_load_status s) @@ -191,52 +238,6 @@ int get_usb_string(char *buf, unsigned int len, uint16_t item, usb_dev_handle *h return snprintf(buf, len, "%s", tmp); } -/* My device parameters */ -#define MY_EP_OUT 0x04 -#define MY_EP_IN 0x88 - -#define FPGA_EP_OUT 0x02 -#define FPGA_EP_IN 0x86 - -/* USB firmware types */ -#define USB_11xx 0 -#define USB_FIRMWARE_II 1 - -#define TYPE_ENTRY(t,ni,n,ne,out,in,...) \ - [t] = { \ - .type_code = (t), \ - .num_interfaces = (ni), \ - .my_interface_num = (n), \ - .num_endpoints = (ne), \ - .my_ep_in = (in), \ - .my_ep_out = (out), \ - .name = #t, \ - .endpoints = { __VA_ARGS__ }, \ - } - -static const struct astribank_type { - int type_code; - int num_interfaces; - int my_interface_num; - int num_endpoints; - int my_ep_out; - int my_ep_in; - char *name; - int endpoints[4]; /* for matching */ -} astribank_types[] = { - TYPE_ENTRY(USB_11xx, 1, 0, 4, MY_EP_OUT, MY_EP_IN, - FPGA_EP_OUT, - MY_EP_OUT, - FPGA_EP_IN, - MY_EP_IN), - TYPE_ENTRY(USB_FIRMWARE_II, 2, 1, 2, MY_EP_OUT, MY_EP_IN, - MY_EP_OUT, - MY_EP_IN), -}; -#undef TYPE_ENTRY - -#define TIMEOUT 5000 - void my_usb_device_cleanup(struct my_usb_device *mydev, const struct astribank_type *abtype) { assert(mydev != NULL); @@ -260,6 +261,7 @@ static void show_device_info(const struct my_usb_device *mydev) eeprom = &mydev->eeprom; memset(data, 0, SERIAL_SIZE + 1); memcpy(data, eeprom->serial, SERIAL_SIZE); + printf("USB Firmware Type: [%s]\n", mydev->abtype->name); printf("USB iManufacturer: [%s]\n", mydev->iManufacturer); printf("USB iProduct: [%s]\n", mydev->iProduct); printf("USB iSerialNumber: [%s]\n", mydev->iSerialNumber); @@ -556,10 +558,6 @@ int my_usb_device_init(const char devpath[], struct my_usb_device *mydev, const ERR("usb_claim_interface: %s\n", usb_strerror()); return 0; } - if(usb_reset(mydev->handle) != 0) { - ERR("usb_reset: %s\n", usb_strerror()); - return 0; - } dev_desc = &mydev->dev->descriptor; config_desc = mydev->dev->config; interface = &config_desc->interface[abtype->my_interface_num]; @@ -578,6 +576,7 @@ int my_usb_device_init(const char devpath[], struct my_usb_device *mydev, const } } } + mydev->abtype = abtype; mydev->my_ep_in = abtype->my_ep_in; mydev->my_ep_out = abtype->my_ep_out; ret = get_usb_string(mydev->iManufacturer, BUFSIZ, dev_desc->iManufacturer, mydev->handle); @@ -591,12 +590,12 @@ int my_usb_device_init(const char devpath[], struct my_usb_device *mydev, const mydev->iProduct, mydev->iSerialNumber, mydev->iInterface); - if(usb_resetep(mydev->handle, mydev->my_ep_out) != 0) { - ERR("Failed to reset usb output endpoint: %s\n", usb_strerror()); + if(usb_clear_halt(mydev->handle, mydev->my_ep_out) != 0) { + ERR("Clearing output endpoint: %s\n", usb_strerror()); return 0; } - if(usb_resetep(mydev->handle, mydev->my_ep_in) != 0) { - ERR("Failed to reset usb input endpoint: %s\n", usb_strerror()); + if(usb_clear_halt(mydev->handle, mydev->my_ep_in) != 0) { + ERR("Clearing input endpoint: %s\n", usb_strerror()); return 0; } return 1; @@ -614,6 +613,16 @@ int renumerate_device(struct my_usb_device *mydev, enum fpga_load_packet_types p ret = send_usb("renumerate[W]", mydev, phead, 1, TIMEOUT); if(ret < 0) return ret; +#if 0 + /* + * FIXME: we count on our USB firmware to reset the device... should we? + */ + ret = usb_reset(mydev->handle); + if(ret < 0) { + ERR("usb_reset: %s\n", usb_strerror()); + return -ENODEV; + } +#endif return 0; } diff --git a/xpp/utils/xpp_fxloader b/xpp/utils/xpp_fxloader index 3000718..27eec1c 100644 --- a/xpp/utils/xpp_fxloader +++ b/xpp/utils/xpp_fxloader @@ -71,6 +71,7 @@ FIRM_FXS=$FIRMWARE_DIR/FPGA_FXS.hex REENUM_SLEEP_TIME=3 # only used on manual runs FPGA_LOAD=${FPGA_LOAD:-/usr/sbin/fpga_load} +USB_FW="${USB_FW:-USB_FW.hex}" if [ -r "$DEFAULTS" ]; then . "$DEFAULTS" @@ -182,10 +183,9 @@ reset) xppdetect|load|usb) echo "--------- FIRMWARE LOADING: ($1)" - load_fw 04b4 8613 USB_8613.hex - load_fw e4e4 1130 USB_1130.hex - load_fw e4e4 1140 USB_1140.hex - load_fw e4e4 1150 USB_1150.hex + load_fw e4e4 1130 $USB_FW + load_fw e4e4 1140 $USB_FW + load_fw e4e4 1150 $USB_FW if [ "$1" != 'usb' ] then load_fpga e4e4 1131 FPGA_FXS.hex @@ -225,8 +225,8 @@ then $LOGGER "Trying to find what to do for product $PRODUCT, device $DEVICE" prod_id=`echo "$PRODUCT" | cut -d/ -f2` case "$PRODUCT" in - 4b4/8613/*|e4e4/11[345]0/*) - FIRM_USB="$FIRMWARE_DIR/USB_$prod_id.hex" + e4e4/11[345]0/*) + FIRM_USB="$FIRMWARE_DIR/$USB_FW" $LOGGER "Loading firmware '$FIRM_USB' into '$DEVICE'" do_fxload -D "$DEVICE" -I "$FIRM_USB" ;; diff --git a/xpp/utils/zaptel_drivers b/xpp/utils/zaptel_drivers new file mode 100755 index 0000000..5cd890d --- /dev/null +++ b/xpp/utils/zaptel_drivers @@ -0,0 +1,9 @@ +#! /usr/bin/perl -w +use strict; +use File::Basename; +BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/zconf"); } + +use Zaptel::Hardware; + +Zaptel::Hardware->scan_hardware(); +print join("\n", Zaptel::Hardware->drivers),"\n"; diff --git a/xpp/utils/zaptel_hardware b/xpp/utils/zaptel_hardware index 91fcb2e..473be1f 100755 --- a/xpp/utils/zaptel_hardware +++ b/xpp/utils/zaptel_hardware @@ -33,8 +33,7 @@ sub show_xbus($) { my @xpds = $xbus->xpds; my $serialnum = $xbus->serial(); my $connector = ($xbus->status eq 'CONNECTED') ? $xbus->connector : "MISSING"; - $connector = "(" . $connector . ")"; - printf "%-10s %-20s\n", $serialnum, $connector; + printf " SERIAL=%-10s CONNECTOR=%-20s\n", $serialnum, $connector; foreach my $xpd (sort { $a->num <=> $b->num } @xpds) { my $reg = $xpd->zt_registration; my $span; @@ -53,15 +52,18 @@ sub show_xbus($) { } my %seen; -my $format = "%-20s\t%4s:%4s %-12s "; +my $format = "%-20s %-12s %4s:%4s %s\n"; foreach my $dev (@hardware) { my $xbus = $dev->xbus; my $driver = $dev->driver || ""; - $driver = "[$driver]"; - printf $format, $dev->hardware_name, $dev->vendor, $dev->product, $driver; + my $loaded = $dev->loaded; + die "driver should be '$driver' but is actually '$loaded'" + if defined($loaded) && $driver ne $loaded; + $driver = "$driver" . (($loaded) ? "+" : "-"); + my $description = $dev->description || ""; + printf $format, $dev->hardware_name, $driver, $dev->vendor, $dev->product, $description; if(!$xbus) { - printf "\n"; next; } $seen{$xbus->name} = 1; @@ -78,12 +80,11 @@ foreach my $xbus (Zaptel::Xpp::xbuses('SORT_CONNECTOR')) { } } - __END__ =head1 NAME -zaptel_hardware - Shows Zaptel hardware devices. +zaptel_hardware - Shows Zaptel hardware devices. =head1 SYNOPSIS @@ -91,10 +92,44 @@ zaptel_hardware =head1 DESCRIPTION -Show all zaptel hardware devices, both used and unused. +Show all zaptel hardware devices. Devices are recognized according to +lists of PCI and USB IDs in Zaptel::Hardware::PCI.pm and +Zaptel::Hardware::USB.pm . For PCI it is possible to detect by +sub-vendor and sub-product ID as well. + +The first output column is the connector: a bus specific field that +shows where this device is. + +The second field shows which driver should handle the device. a "-" sign +marks that the device is not yet handled by this driver. A "+" sign +means that the device is handled by the driver. + +For the Xorcom Astribank (and in the future: for other Zaptel devices) +some further information is provided from the driver. Those extra lines +always begin with spaces. + +Example output: + +Without drivers loaded: + + usb:001/002 xpp_usb- e4e4:1152 Astribank-multi FPGA-firmware + usb:001/003 xpp_usb- e4e4:1152 Astribank-multi FPGA-firmware + pci:0000:01:0b.0 wctdm- e159:0001 Wildcard TDM400P REV H + +With drivers loaded: + + usb:001/002 xpp_usb+ e4e4:1152 Astribank-multi FPGA-firmware + SERIAL=[usb:123] CONNECTOR=usb-0000:00:1d.7-1 + XBUS-00/XPD-00: FXS Span 2 + XBUS-00/XPD-10: FXS Span 3 + XBUS-00/XPD-20: FXS Span 4 + XBUS-00/XPD-30: FXS Span 5 + usb:001/003 xpp_usb+ e4e4:1152 Astribank-multi FPGA-firmware + SERIAL=[usb:4567] CONNECTOR=usb-0000:00:1d.7-4 + XBUS-01/XPD-00: FXS Span 6 XPP-SYNC + XBUS-01/XPD-10: FXO Span 7 + XBUS-01/XPD-20: FXO Span 8 + XBUS-01/XPD-30: FXO Span 9 + pci:0000:01:0b.0 wctdm+ e159:0001 Wildcard TDM400P REV E/F -=head1 BUGS -Assumes a bit too much about the output of lspci and sysfs. Currently -the PCI scanning will not work on e.g. CentOS 4. This should be fixed in -Zaptel::Hardware::PCI.pm diff --git a/xpp/utils/zconf/Zaptel/Hardware.pm b/xpp/utils/zconf/Zaptel/Hardware.pm index 39305fb..8423c18 100644 --- a/xpp/utils/zconf/Zaptel/Hardware.pm +++ b/xpp/utils/zconf/Zaptel/Hardware.pm @@ -18,6 +18,7 @@ sub device_detected($$) { my $name = shift || die; warn "Device '$name' already known\n" if grep { $_->hardware_name eq $name } @zaptel_devices; + $dev->{'HARDWARE_NAME'} = $name; push(@zaptel_devices, $dev); } @@ -34,6 +35,16 @@ sub devices($) { return @zaptel_devices; } +sub drivers($) { + my $pack = shift or die "Wasn't called as a class method\n"; + my @devs = $pack->devices(); + my @drvs = map { $_->{DRIVER} } @devs; + # Make unique + my %drivers; + @drivers{@drvs} = 1; + return sort keys %drivers; +} + sub scan_hardware($) { my $pack = shift || die; diff --git a/xpp/utils/zconf/Zaptel/Hardware/PCI.pm b/xpp/utils/zconf/Zaptel/Hardware/PCI.pm index 9e916f6..bd6f6e3 100644 --- a/xpp/utils/zconf/Zaptel/Hardware/PCI.pm +++ b/xpp/utils/zconf/Zaptel/Hardware/PCI.pm @@ -10,29 +10,89 @@ package Zaptel::Hardware::PCI; use strict; use Zaptel::Hardware; -my @idlist = qw( - 0B0B:0206 - 1397:16B8 - 1397:08B4 - 1057:5608 - 10B5:3001 - 10B5:4000 - 10B5:9030 - 10B5:D00D - D161:0800 - D161:2400 - D161:0120 - D161:0205 - D161:0210 - D161:0220 - D161:0405 - D161:0410 - D161:0420 - E159:0001 +our @ISA = qw(Zaptel::Hardware); + +# Lookup algorithm: +# First match 'vendor:product/subvendor:subproduct' key +# Else match 'vendor:product/subvendor' key +# Else match 'vendor:product' key +# Else not a zaptel hardware. +my %pci_ids = ( + # from wct4xxp + '10ee:0314' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE410P/TE405P (1st Gen)' }, + 'd161:0420/0004' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE420 (4th Gen)' }, + 'd161:0410/0004' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE410P (4th Gen)' }, + 'd161:0405/0004' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE405P (4th Gen)' }, + 'd161:0410/0003' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE410P (3rd Gen)' }, + 'd161:0405/0003' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE405P (3rd Gen)' }, + 'd161:0410' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE410P (2nd Gen)' }, + 'd161:0405' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE405P (2nd Gen)' }, + 'd161:0220/0004' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE220 (4th Gen)' }, + 'd161:0205/0004' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE205P (4th Gen)' }, + 'd161:0210/0004' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE210P (4th Gen)' }, + 'd161:0205/0003' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE205P (3rd Gen)' }, + 'd161:0210/0003' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE210P (3rd Gen)' }, + 'd161:0205' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE205P ' }, + 'd161:0210' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE210P ' }, + + # from wctdm24xxp + 'd161:2400' => { DRIVER => 'wctdm24xxp', DESCRIPTION => 'Wildcard TDM2400P' }, + 'd161:0800' => { DRIVER => 'wctdm24xxp', DESCRIPTION => 'Wildcard TDM800P' }, + 'd161:8002' => { DRIVER => 'wctdm24xxp', DESCRIPTION => 'Wildcard AEX800' }, + 'd161:8003' => { DRIVER => 'wctdm24xxp', DESCRIPTION => 'Wildcard AEX2400' }, + + # from pciradio + 'e159:0001/e16b' => { DRIVER => 'pciradio', DESCRIPTION => 'PCIRADIO' }, + + # from wcfxo + 'e159:0001/8085' => { DRIVER => 'wcfxo', DESCRIPTION => 'Wildcard X101P' }, + 'e159:0001/8086' => { DRIVER => 'wcfxo', DESCRIPTION => 'Generic Clone' }, + 'e159:0001/8087' => { DRIVER => 'wcfxo', DESCRIPTION => 'Generic Clone' }, + '1057:5608' => { DRIVER => 'wcfxo', DESCRIPTION => 'Wildcard X100P' }, + + # from wct1xxp + 'e159:0001/6159' => { DRIVER => 'wct1xxp', DESCRIPTION => 'Digium Wildcard T100P T1/PRI or E100P E1/PRA Board' }, + + # from wctdm + 'e159:0001/a159' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard S400P Prototype' }, + 'e159:0001/e159' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard S400P Prototype' }, + 'e159:0001/b100' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard TDM400P REV E/F' }, + 'e159:0001/b1d9' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard TDM400P REV I' }, + 'e159:0001/b118' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard TDM400P REV I' }, + 'e159:0001/b119' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard TDM400P REV I' }, + 'e159:0001/a9fd' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard TDM400P REV H' }, + 'e159:0001/a8fd' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard TDM400P REV H' }, + 'e159:0001/a800' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard TDM400P REV H' }, + 'e159:0001/a801' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard TDM400P REV H' }, + 'e159:0001/a908' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard TDM400P REV H' }, + 'e159:0001/a901' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard TDM400P REV H' }, + #'e159:0001' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard TDM400P REV H' }, + + # from wcte11xp + 'e159:0001/71fe' => { DRIVER => 'wcte11xp', DESCRIPTION => 'Digium Wildcard TE110P T1/E1 Board' }, + 'e159:0001/79fe' => { DRIVER => 'wcte11xp', DESCRIPTION => 'Digium Wildcard TE110P T1/E1 Board' }, + 'e159:0001/795e' => { DRIVER => 'wcte11xp', DESCRIPTION => 'Digium Wildcard TE110P T1/E1 Board' }, + 'e159:0001/79de' => { DRIVER => 'wcte11xp', DESCRIPTION => 'Digium Wildcard TE110P T1/E1 Board' }, + 'e159:0001/797e' => { DRIVER => 'wcte11xp', DESCRIPTION => 'Digium Wildcard TE110P T1/E1 Board' }, + + # from wcte12xp + 'd161:0120' => { DRIVER => 'wcte12xp', DESCRIPTION => 'Wildcard TE12xP' }, + + # from tor2 + '10b5:9030' => { DRIVER => 'tor2', DESCRIPTION => 'PLX 9030' }, + '10b5:3001' => { DRIVER => 'tor2', DESCRIPTION => 'PLX Development Board' }, + '10b5:D00D' => { DRIVER => 'tor2', DESCRIPTION => 'Tormenta 2 Quad T1/PRI or E1/PRA' }, + '10b5:4000' => { DRIVER => 'tor2', DESCRIPTION => 'Tormenta 2 Quad T1/E1 (non-Digium clone)' }, + + # Cologne Chips: + # (Still a partial list) + '1397:08b4/b556' => { DRIVER => 'qozap', DESCRIPTION => 'Junghanns DuoBRI ISDN card' }, + '1397:08b4' => { DRIVER => 'qozap', DESCRIPTION => 'Junghanns QuadBRI ISDN card' }, + '1397:16b8' => { DRIVER => 'qozap', DESCRIPTION => 'Junghanns OctoBRI ISDN card' }, + '1397:2bd0' => { DRIVER => 'zaphfc', DESCRIPTION => 'HFC-S ISDN BRI card' }, ); $ENV{PATH} .= ":/usr/sbin:/sbin:/usr/bin:/bin"; -my $prog = 'lspci'; # Accessors (miniperl does not have Class:Accessor) our $AUTOLOAD; @@ -49,25 +109,16 @@ sub AUTOLOAD { my @devices; -sub pci_sorter() { - return - sprintf("%03d/%03d", $a->bus, $a->dev) cmp - sprintf("%03d/%03d", $b->bus, $b->dev); +sub pci_sorter { + return $a->priv_device_name() cmp $b->priv_device_name(); } sub new($$) { my $pack = shift or die "Wasn't called as a class method\n"; my $self = { @_ }; bless $self, $pack; - my $hardware_name = sprintf("pci:%s:%s:%s", $self->{DOMAIN}, $self->{BUS}, $self->{DEV}); - $self->{HARDWARE_NAME} = $hardware_name; - Zaptel::Hardware::device_detected($self, $hardware_name); - my $sysfile = sprintf "/sys/bus/pci/devices/%s:%s:%s/driver/module", $self->{DOMAIN}, $self->{BUS}, $self->{DEV}; - my $module = readlink($sysfile); - if(defined $module) { - $module =~ s:^.*/::; - $self->{DRIVER} = $module; - } + Zaptel::Hardware::device_detected($self, + sprintf("pci:%s", $self->{PRIV_DEVICE_NAME})); return $self; } @@ -76,38 +127,58 @@ sub devices($) { return sort pci_sorter @devices; } -my $domain_support = 1; # Optimistic... +my %pci_devs; + +sub readfile($) { + my $name = shift || die; + open(F, $name) || die "Failed to open '$name': $!"; + my $str = <F>; + close F; + chomp($str); + return $str; +} sub scan_devices($) { - my $pack = shift || die; - if(!open(F, "$prog -Dn 2> /dev/null |")) { - $domain_support = 0; - open(F, "$prog -n|") || die "$0: Failed running $prog: $!"; + while(</sys/bus/pci/devices/*>) { + m,([^/]+)$,,; + my $name = $1; + my $l = readlink $_ || die; + $pci_devs{$name}{PRIV_DEVICE_NAME} = $name; + $pci_devs{$name}{DEVICE} = $l; + $pci_devs{$name}{VENDOR} = readfile "$_/vendor"; + $pci_devs{$name}{PRODUCT} = readfile "$_/device"; + $pci_devs{$name}{SUBVENDOR} = readfile "$_/subsystem_vendor"; + $pci_devs{$name}{SUBPRODUCT} = readfile "$_/subsystem_device"; + my $dev = $pci_devs{$name}; + grep(s/0x//, $dev->{VENDOR}, $dev->{PRODUCT}, $dev->{SUBVENDOR}, $dev->{SUBPRODUCT}); + $pci_devs{$name}{DRIVER} = ''; } - while(<F>) { - chomp; - my ($phys,$id) = (split(/\s+/))[0,2]; - my $domain; - my $bus; - my $dev; - if($domain_support) { - ($domain,$bus,$dev) = split(/:/, $phys); - } else { - ($bus,$dev) = split(/:/, $phys); - $domain = '0000'; - } - next unless grep { uc($id) eq $_ } @idlist; - my($vendor,$product) = split(/:/, $id); + + while(</sys/bus/pci/drivers/*/[0-9]*>) { + m,([^/]+)/([^/]+)$,,; + $pci_devs{$2}{LOADED} = $1; + } + foreach (sort keys %pci_devs) { + my $dev = $pci_devs{$_}; + my $key; + # Try to match + $key = "$dev->{VENDOR}:$dev->{PRODUCT}/$dev->{SUBVENDOR}:$dev->{SUBPRODUCT}"; + $key = "$dev->{VENDOR}:$dev->{PRODUCT}/$dev->{SUBVENDOR}" if !defined($pci_ids{$key}); + $key = "$dev->{VENDOR}:$dev->{PRODUCT}" if !defined($pci_ids{$key}); + next unless defined $pci_ids{$key}; + my $d = Zaptel::Hardware::PCI->new( - DOMAIN => $domain, - BUS => $bus, - DEV => $dev, - VENDOR => $vendor, - PRODUCT => $product, + PRIV_DEVICE_NAME => $dev->{PRIV_DEVICE_NAME}, + VENDOR => $dev->{VENDOR}, + PRODUCT => $dev->{PRODUCT}, + SUBVENDOR => $dev->{SUBVENDOR}, + SUBPRODUCT => $dev->{SUBPRODUCT}, + LOADED => $dev->{LOADED}, + DRIVER => $pci_ids{$key}{DRIVER}, + DESCRIPTION => $pci_ids{$key}{DESCRIPTION}, ); push(@devices, $d); } - close F; } 1; diff --git a/xpp/utils/zconf/Zaptel/Hardware/USB.pm b/xpp/utils/zconf/Zaptel/Hardware/USB.pm index bbf00fe..0f2024b 100644 --- a/xpp/utils/zconf/Zaptel/Hardware/USB.pm +++ b/xpp/utils/zconf/Zaptel/Hardware/USB.pm @@ -12,21 +12,28 @@ use Zaptel::Hardware; use Zaptel::Xpp; use Zaptel::Xpp::Xbus; -my @idlist = qw( - e4e4:1130 - e4e4:1131 - e4e4:1132 - e4e4:1140 - e4e4:1141 - e4e4:1142 - e4e4:1150 - e4e4:1151 - e4e4:1152 +our @ISA = qw(Zaptel::Hardware); + +my %usb_ids = ( + # from wcusb + '06e6:831c' => { DRIVER => 'wcusb', DESCRIPTION => 'Wildcard S100U USB FXS Interface' }, + '06e6:831e' => { DRIVER => 'wcusb2', DESCRIPTION => 'Wildcard S110U USB FXS Interface' }, + '06e6:b210' => { DRIVER => 'wc_usb_phone', DESCRIPTION => 'Wildcard Phone Test driver' }, + + # from xpp_usb + 'e4e4:1130' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-8/16 no-firmware' }, + 'e4e4:1131' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-8/16 USB-firmware' }, + 'e4e4:1132' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-8/16 FPGA-firmware' }, + 'e4e4:1140' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-BRI no-firmware' }, + 'e4e4:1141' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-BRI USB-firmware' }, + 'e4e4:1142' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-BRI FPGA-firmware' }, + 'e4e4:1150' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-multi no-firmware' }, + 'e4e4:1151' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-multi USB-firmware' }, + 'e4e4:1152' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-multi FPGA-firmware' }, ); $ENV{PATH} .= ":/usr/sbin:/sbin:/usr/bin:/bin"; -my $prog = 'lsusb'; # Accessors (miniperl does not have Class:Accessor) our $AUTOLOAD; @@ -45,21 +52,14 @@ my @devices; my @xbuses = Zaptel::Xpp::xbuses('SORT_CONNECTOR'); sub usb_sorter() { - return - sprintf("%03d/%03d", $a->bus, $a->dev) cmp - sprintf("%03d/%03d", $b->bus, $b->dev); + return $a->hardware_name cmp $b->hardware_name; } -sub xbus_of_usb($$) { - my $bus = shift; +sub xbus_of_usb($) { + my $priv_device_name = shift; my $dev = shift; - my ($wanted) = grep { - my $b = $_->usb_bus; - my $d = $_->usb_dev; - defined($b) && $b == $bus && - defined($d) && $d == $dev - } @xbuses; + my ($wanted) = grep { $priv_device_name eq $_->usb_devname } @xbuses; return $wanted; } @@ -67,14 +67,13 @@ sub new($$) { my $pack = shift or die "Wasn't called as a class method\n"; my $self = { @_ }; bless $self, $pack; - my $xbus = xbus_of_usb($self->bus, $self->dev); + my $xbus = xbus_of_usb($self->priv_device_name); if(defined $xbus) { $self->{XBUS} = $xbus; - $self->{DRIVER} = 'xpp_usb'; + $self->{LOADED} = 'xpp_usb'; } - my $hardware_name = sprintf("usb:%03d/%03d", $self->{BUS}, $self->{DEV}); - $self->{HARDWARE_NAME} = $hardware_name; - Zaptel::Hardware::device_detected($self, $hardware_name); + Zaptel::Hardware::device_detected($self, + sprintf("usb:%s", $self->{PRIV_DEVICE_NAME})); return $self; } @@ -85,20 +84,24 @@ sub devices($) { sub scan_devices($) { my $pack = shift || die; - open(F, "$prog|") || die "$0: Failed running $prog: $!"; + my $usb_device_list = "/proc/bus/usb/devices"; + open(F, $usb_device_list) || die "Failed to open $usb_device_list: $!"; + $/ = ''; while(<F>) { - chomp; - my ($bus,$dev,$id) = (split(/\s+/))[1,3,5]; - $dev =~ s/://; - $bus =~ s/^0*//; - $dev =~ s/^0*//; - next unless grep { lc($id) eq $_ } @idlist; - my($vendor,$product) = split(/:/, $id); + my @lines = split(/\n/); + my ($tline) = grep(/^T/, @lines); + my ($pline) = grep(/^P/, @lines); + my ($busnum,$devnum) = ($tline =~ /Bus=(\w+)\W.*Dev#=\s*(\w+)\W/); + my $devname = sprintf("%03d/%03d", $busnum, $devnum); + my ($vendor,$product) = ($pline =~ /Vendor=(\w+)\W.*ProdID=(\w+)\W/); + my $model = $usb_ids{"$vendor:$product"}; + next unless defined $model; my $d = Zaptel::Hardware::USB->new( - BUS => $bus, - DEV => $dev, - VENDOR => $vendor, - PRODUCT => $product, + PRIV_DEVICE_NAME => $devname, + VENDOR => $vendor, + PRODUCT => $product, + DESCRIPTION => $model->{DESCRIPTION}, + DRIVER => $model->{DRIVER}, ); push(@devices, $d); } diff --git a/xpp/utils/zconf/Zaptel/Xpp.pm b/xpp/utils/zconf/Zaptel/Xpp.pm index ff0008a..db9add6 100644 --- a/xpp/utils/zconf/Zaptel/Xpp.pm +++ b/xpp/utils/zconf/Zaptel/Xpp.pm @@ -24,7 +24,9 @@ sub by_connector { } sub by_serial { - return $a->serial cmp $b->serial; + my $cmp = $a->serial cmp $b->serial; + return $cmp if $cmp != 0; + return $a->connector cmp $b->connector; } sub xbuses { diff --git a/xpp/utils/zconf/Zaptel/Xpp/Xbus.pm b/xpp/utils/zconf/Zaptel/Xpp/Xbus.pm index 0dd6d84..7951d98 100644 --- a/xpp/utils/zconf/Zaptel/Xpp/Xbus.pm +++ b/xpp/utils/zconf/Zaptel/Xpp/Xbus.pm @@ -70,12 +70,7 @@ sub new($$) { chomp $head; close F; $head =~ s/^device: +([^, ]+)/$1/i or die; - my ($usb_bus, $usb_dev) = split('/', $head); - die unless defined($usb_bus) && defined($usb_dev); - $usb_bus =~ s/^0*//; - $usb_dev =~ s/^0*//; - $self->{USB_BUS} = $usb_bus; - $self->{USB_DEV} = $usb_dev; + $self->{USB_DEVNAME} = $head; } @{$self->{XPDS}} = (); foreach my $fqn (glob "$prefix/XPD-??") { diff --git a/xpp/utils/zt_registration b/xpp/utils/zt_registration index fdcf33e..1b26f74 100755 --- a/xpp/utils/zt_registration +++ b/xpp/utils/zt_registration @@ -74,11 +74,16 @@ zt_registration [on|off] =head1 DESCRIPTION -Without parameters, show all connected XPDs sorted by physical connector order. -Each one is show to be unregistered (off), or registered to a specific zaptel span -(the span number is shown). +Without parameters, show all connected XPDs sorted by serial number and +physical connector order. Each one is show to be unregistered (off), or +registered to a specific zaptel span (the span number is shown). -All registerations/deregisterations are sorted by physical connector string. +All registerations/deregisterations are sorted by serial number and +(lacking that) physical connector string. + +Span registration should generally always succeed. Span unregistration may +fail if channels from the span are in use by e.g. asterisk. In such a case +you'll also see those channels as '(In use)' in the output of lszaptel(8). =head2 Parameters @@ -88,22 +93,27 @@ on -- registers all XPD's to zaptel. =head2 Sample Output - $ zt_registration - XBUS-02 usb-0000:00:1d.7-3 - XBUS-02/XPD-00: on Span 9 - XBUS-02/XPD-10: on Span 10 - XBUS-02/XPD-20: on Span 11 - XBUS-02/XPD-30: on Span 12 - XBUS-01 usb-0000:00:1d.7-4 - XBUS-01/XPD-00: on Span 13 - XBUS-01/XPD-10: on Span 14 - XBUS-01/XPD-20: on Span 15 - XBUS-01/XPD-30: on Span 16 - XBUS-00 usb-0000:00:1d.7-5 - XBUS-00/XPD-00: on Span 17 - XBUS-00/XPD-10: on Span 18 - XBUS-00/XPD-20: on Span 19 - XBUS-00/XPD-30: on Span 20 +An example of the output of zt_registration for some registered +Astribanks: + + $ zt_registration + XBUS-02 [] usb-0000:00:1d.7-4 + XBUS-00/XPD-00: on Span 1 + XBUS-00/XPD-10: on Span 2 + XBUS-00 [usb:00000126] usb-0000:00:1d.7-2 + XBUS-02/XPD-00: on Span 3 + XBUS-02/XPD-10: on Span 4 + XBUS-02/XPD-20: on Span 5 + XBUS-02/XPD-30: on Span 6 + XBUS-01 [usb:00000128] usb-0000:00:1d.7-1 + XBUS-01/XPD-00: on Span 7 + XBUS-01/XPD-10: on Span 8 + XBUS-01/XPD-20: on Span 9 + XBUS-01/XPD-30: on Span 10 + +In this example the XBUS-02 has an empty serial number and thus +becomes the first Astribank. The other two are sorted according to their +serial numbers. =head1 FILES @@ -117,7 +127,4 @@ registered. Writing to it 0 or 1 registers / unregisters the device. This should allow you to register / unregister a specific XPD rather than all of them. -Unregistering an XPD will fail if the span is in use (has some channels -that are in use by e.g. Asterisk). - =back |