Thread: Re: [RTnet-developers] arcnet driver
Brought to you by:
bet-frogger,
kiszka
|
From: LIGHTCAP,CHRISTOPHER A <ca...@uf...> - 2006-07-13 18:11:32
|
Jan,
Thanks for such a quick response! We've made good progress with
the RTnet Arcnet driver but have a few questions about code which
doesn't quite match up to the existing examples.
And I have little experience with designing network drivers (or
any driver!) .. therefore the questions might seem basic.
1.) The original arcnet driver does not call alloc_etherdev but
rather alloc_netdev (shown below). Can I still change this
function call like suggested in your porting documenation? What
effect will this have on the program?
BEFORE
struct net_device *alloc_arcdev(char *name)
{
struct net_device *dev;
dev = alloc_netdev(sizeof(struct arcnet_local),
name && *name ? name : "arc%d", arcdev_setup);
if(dev) {
struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
spin_lock_init(&lp->lock);
}
return dev;
}
AFTER
struct rtnet_device *alloc_arcdev(char *name)
{
struct rtnet_device *dev;
/*** RTnet ***/
dev = rt_alloc_etherdev(sizeof(struct arcnet_local)); //
etherdev?
rtdev_alloc_name(dev, "rtarc%d");
rt_rtdev_connect(dev, &RTDEV_manager);
RTNET_SET_MODULE_OWNER(dev);
dev->vers = RTDEV_VERS_2_0;
/*** RTnet ***/
if(dev) {
struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
rtdm_lock_init(&lp->lock); /*** RTnet ***/
}
return dev;
}
2.) In your example, you initialize the skb_pool in the probe
function and if the return value is less than twice the ring size
then you release the skb_pool and call a few 'cleanup' functions.
e.g. pci_free_consistent(lp->pci_dev, sizeof(*lp), lp,
lp->dma_addr);
I'm not sure how it works, but I cannot this function because
the struct arcnet_local does not have a field called 'dma_addr'.
So my question is .. is dma_addr disguised under another name in
the arcnet_local struct? and if not do I even need to call this
function?
static int __devinit com20020pci_probe(struct pci_dev *pdev, const
struct pci_device_id *id)
{
struct rtnet_device *dev;
struct arcnet_local *lp;
int ioaddr, err;
/*** RTnet ***/
cards_found++;
if (cards[cards_found] == 0)
return -ENODEV;
/*** RTnet ***/
if (pci_enable_device(pdev))
return -EIO;
dev = alloc_arcdev(device);
if (!dev)
return -ENOMEM;
lp = dev->priv;
pci_set_drvdata(pdev, dev);
// SOHARD needs PCI base addr 4
if (pdev->vendor==0x10B5) {
BUGMSG(D_NORMAL, "SOHARD\n");
ioaddr = pci_resource_start(pdev, 4);
}
else {
BUGMSG(D_NORMAL, "Contemporary Controls\n");
ioaddr = pci_resource_start(pdev, 2);
}
if (!request_region(ioaddr, ARCNET_TOTAL_SIZE, "com20020-pci"))
{
BUGMSG(D_INIT, "IO region %xh-%xh already allocated.\n",
ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1);
err = -EBUSY;
goto out_dev;
}
/*** RTnet ***/
if (rtskb_pool_init(&lp->skb_pool, RX_RING_SIZE*2) <
RX_RING_SIZE*2) {
rtskb_pool_release(&lp->skb_pool);
---------> // pci_free_consistent(lp->pci_dev, sizeof(*lp), lp,
lp->dma_addr);
release_region(ioaddr, ARCNET_TOTAL_SIZE);
rtdev_free(dev);
return -ENOMEM;
}
/*** RTnet ***/
// Dummy access after Reset
// ARCNET controller needs this access to detect bustype
outb(0x00,ioaddr+1);
inb(ioaddr+1);
dev->base_addr = ioaddr;
dev->irq = pdev->irq;
dev->dev_addr[0] = node;
lp->card_name = "PCI COM20020";
lp->card_flags = id->driver_data;
lp->backplane = backplane;
lp->clockp = clockp & 7;
lp->clockm = clockm & 3;
lp->timeout = timeout;
lp->hw.owner = THIS_MODULE;
if (ASTATUS() == 0xFF) {
BUGMSG(D_NORMAL, "IO address %Xh was reported by PCI BIOS, "
"but seems empty!\n", ioaddr);
err = -EIO;
goto out_port;
}
if (com20020_check(dev)) {
err = -EIO;
goto out_port;
}
if ((err = com20020_found(dev, SA_SHIRQ)) != 0)
goto out_port;
return 0;
out_port:
release_region(ioaddr, ARCNET_TOTAL_SIZE);
out_dev:
rtdev_free(dev);
return err;
}
here's a snapshot of the arcnet_local struct ...
struct arcnet_local {
struct net_device_stats stats;
uint8_t config, /* current value of CONFIG register */
timeout, /* Extended timeout for COM20020 */
backplane, /* Backplane flag for COM20020 */
clockp, /* COM20020 clock divider */
clockm, /* COM20020 clock multiplier flag */
setup, /* Contents of setup1 register */
setup2, /* Contents of setup2 register */
intmask; /* current value of INTMASK register */
uint8_t default_proto[256]; /* default encap to use for each host
*/
int cur_tx, /* buffer used by current transmit, or -1 */
next_tx, /* buffer where a packet is ready to send */
cur_rx; /* current receive buffer */
int lastload_dest, /* can last loaded packet be acked? */
lasttrans_dest; /* can last TX'd packet be acked? */
int timed_out; /* need to process TX timeout and drop packet */
unsigned long last_timeout; /* time of last reported timeout */
char *card_name; /* card ident string */
int card_flags; /* special card features */
/*** RTnet ***/
struct rtskb *tx_skbuff[TX_RING_SIZE];
struct rtskb *rx_skbuff[RX_RING_SIZE];
struct rtskb_queue skb_pool;
rtdm_irq_t irq_handle;
/*** RTnet ***/
/* On preemtive and SMB a lock is needed */
rtdm_lock_t lock;
/*
* Buffer management: an ARCnet card has 4 x 512-byte buffers,
each of
* which can be used for either sending or receiving. The new
dynamic
* buffer management routines use a simple circular queue of
available
* buffers, and take them as they're needed. This way, we
simplify
* situations in which we (for example) want to pre-load a
transmit
* buffer, or start receiving while we copy a received packet to
* memory.
*
* The rules: only the interrupt handler is allowed to _add_
buffers to
* the queue; thus, this doesn't require a lock. Both the
interrupt
* handler and the transmit function will want to _remove_
buffers, so
* we need to handle the situation where they try to do it at the
same
* time.
*
* If next_buf == first_free_buf, the queue is empty. Since
there are
* only four possible buffers, the queue should never be full.
*/
atomic_t buf_lock;
int buf_queue[5];
int next_buf, first_free_buf;
/* network "reconfiguration" handling */
time_t first_recon, /* time of "first" RECON message to count
*/
last_recon; /* time of most recent RECON */
int num_recons; /* number of RECONs between first and last. */
bool network_down; /* do we think the network is down? */
bool excnak_pending; /* We just got an excesive nak interrupt */
struct {
uint16_t sequence; /* sequence number (incs with each packet)
*/
uint16_t aborted_seq;
struct Incoming incoming[256]; /* one from each address */
} rfc1201;
/* really only used by rfc1201, but we'll pretend it's not */
struct Outgoing outgoing; /* packet currently being sent */
/* hardware-specific functions */
struct {
struct module *owner;
void (*command) (struct rtnet_device * dev, int cmd);
int (*status) (struct rtnet_device * dev);
void (*intmask) (struct rtnet_device * dev, int mask);
bool (*reset) (struct rtnet_device * dev, bool really_reset);
void (*open) (struct rtnet_device * dev);
void (*close) (struct rtnet_device * dev);
void (*copy_to_card) (struct rtnet_device * dev, int bufnum, int
offset,
void *buf, int count);
void (*copy_from_card) (struct rtnet_device * dev, int bufnum,
int offset,
void *buf, int count);
} hw;
void __iomem *mem_start; /* pointer to ioremap'ed MMIO */
};
and if you're curious com20020_found looks like this ...
/* Set up the struct rtnet_device associated with this card.
Called after
* probing succeeds.
*/
int com20020_found(struct rtnet_device *dev, int shared)
{
struct arcnet_local *lp;
int ioaddr = dev->base_addr;
int retval;
/* Initialize the rest of the device structure. */
lp = dev->priv;
lp->hw.owner = THIS_MODULE;
lp->hw.command = com20020_command;
lp->hw.status = com20020_status;
lp->hw.intmask = com20020_setmask;
lp->hw.reset = com20020_reset;
lp->hw.copy_to_card = com20020_copy_to_card;
lp->hw.copy_from_card = com20020_copy_from_card;
lp->hw.close = com20020_close;
// dev->set_multicast_list = com20020_set_mc_list; /*** RTNET
***/
if (!dev->dev_addr[0])
dev->dev_addr[0] = inb(ioaddr + BUS_ALIGN*8); /* FIXME: do this
some other way! (not written by me - Chris) */
SET_SUBADR(SUB_SETUP1);
outb(lp->setup, _XREG);
if (lp->card_flags & ARC_CAN_10MBIT)
{
SET_SUBADR(SUB_SETUP2);
outb(lp->setup2, _XREG);
/* must now write the magic "restart operation" command */
mdelay(1);
outb(0x18, _COMMAND);
}
lp->config = 0x20 | (lp->timeout << 3) | (lp->backplane << 2) |
1;
/* Default 0x38 + register: Node ID */
SETCONF;
outb(dev->dev_addr[0], _XREG);
/*** RTnet ***/
/* reserve the irq */
/*if (request_irq(dev->irq, &arcnet_interrupt, shared,
"arcnet (COM20020)", dev)) {
BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq);
return -ENODEV;
}*/
if (dev->irq == 0)
return -EAGAIN;
rt_stack_connect(dev, &STACK_manager);
retval = rtdm_irq_request(&lp->irq_handle, dev->irq,
arcnet_interrupt, 0,
"rt_arcnet", dev);
if (retval)
return retval;
rtdm_irq_enable(&lp->irq_handle);
/*** RTnet ***/
dev->base_addr = ioaddr;
BUGMSG(D_NORMAL, "%s: station %02Xh found at %03lXh, IRQ %d.\n",
lp->card_name, dev->dev_addr[0], dev->base_addr,
dev->irq);
if (lp->backplane)
BUGMSG(D_NORMAL, "Using backplane mode.\n");
if (lp->timeout != 3)
BUGMSG(D_NORMAL, "Using extended timeout value of %d.\n",
lp->timeout);
BUGMSG(D_NORMAL, "Using CKP %d - data rate %s.\n",
lp->setup >> 1,
clockrates[3 - ((lp->setup2 & 0xF0) >> 4) + ((lp->setup &
0x0F) >> 1)]);
/*** RTnet ***/
/*if (register_netdev(dev)) {
free_irq(dev->irq, dev);
return -EIO;
}*/
if (rt_register_rtnetdev(dev))
{
rtdm_irq_free(&lp->irq_handle);
return -EIO;
}
/*** RTnet ***/
return 0;
}
3.) Ok. last question. It seems like I have a problem with module
dependencies. The arcnet driver is set up to be loaded as four
separate modules: arcnet.ko (the foundation), arc-rawmode.ko
(provides rawmode encapsulation), com20020.ko (support for
chipset), and com20020-pci.ko (support for pci-board).
I've done my homework and created four rt modules that compile and
load into the kernel.. but the problem is that I cannot get them
to load with 'rtnet start'. How do I specify dependencies in the
'rtnet.conf' file? My dilemna is that if I specify com20020-pci
without any extra work.. the program will not run because it
cannot load the module without its dependencies.. BUT I cannot
load rt_arcnet.ko and rt_com20020.ko before running 'rtnet start'
because they both depend on the module rtnet!!
So I feel like I'm in a bit of a catch-22. Please tell me how to
get around this problem.
Thank you so much for your help.
Chris Lightcap
University of Florida
On Tue Jul 11 04:03:33 EDT 2006, Jan Kiszka <jan...@we...>
wrote:
> Chris Lightcap wrote:
>> Hello all,
>>
>> I'd like to implement a real-time arcnet driver to communicate
>> with
>> our mitsubishi PA-10 robot using RTAI and RTnet. I found in the
>
> You are welcome!
>
>> mailing list archive that there was some interest in this topic
>> about
>> a year ago.
>>
>> .. Has anyone made progress with a real-time arcnet driver? is it
>
> I'm personally not aware of any effort.
>
>> possible to simply modify the existing driver as explained in the
>> porting documentation? are there any additional problems I should
>> know of beforehand?
>
> I think to remember once browsing through the Linux arcnet stack
> without
> finding anything that's fundamentally different from the "normal"
> networking stack. So all the pattern of RTnet /should/ apply to
> arcnet
> as well. If you encounter something that doesn't fit on first
> sight,
> feel free to discuss it here.
>
> Please build your port on top of latest RTnet and only use RTDM
> for
> interfacing the real-time Linux services - this will help to
> integrate
> your work into the official version later.
>
> Jan
>
>
--
LIGHTCAP,CHRISTOPHER A
|
|
From: Chris L. <ca...@uf...> - 2006-07-14 16:16:41
|
Hi Jan,
I made the changes you suggested in your last response. I've
exported the rtdev_alloc so that I can use that with arcdev_setup
in my driver. (code shown below)
/* Setup a struct device for ARCnet. */
static void arcdev_setup(struct rtnet_device *dev)
{
dev->type = ARPHRD_ARCNET;
dev->hard_header_len = sizeof(struct archdr);
dev->mtu = choose_mtu();
dev->get_mtu = rt_hard_mtu; // RTNET
dev->addr_len = ARCNET_ALEN;
// dev->tx_queue_len = 100; // RTNET
// dev->watchdog_timeo = TX_TIMEOUT;
dev->broadcast[0] = 0x00; // for us, broadcasts are address 0
// New-style flags.
dev->flags = IFF_BROADCAST;
// Put in this stuff here, so we don't have to export the symbols
to
// the chipset drivers.
dev->open = arcnet_open;
dev->stop = arcnet_close;
dev->hard_start_xmit = arcnet_send_packet;
// dev->tx_timeout = arcnet_timeout;
// dev->get_stats = arcnet_get_stats;
dev->hard_header = arcnet_header;
dev->rebuild_header = arcnet_rebuild_header;
}
struct rtnet_device *rt_alloc_arcdev(char *name)
{
struct rtnet_device *dev;
/*** RTnet ***/
dev = rtdev_alloc(sizeof(struct arcnet_local)); // <-------
if (!dev)
return NULL;
arcdev_setup(dev);
memset(dev->broadcast, 0xFF, ARCNET_ALEN);
strcpy(dev->name, "rteth%d");
rtdev_alloc_name(dev, "rtarc%d");
rt_rtdev_connect(dev, &RTDEV_manager);
RTNET_SET_MODULE_OWNER(dev);
dev->vers = RTDEV_VERS_2_0;
/*** RTnet ***/
if(dev) {
struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
rtdm_lock_init(&lp->lock); /*** RTnet ***/
}
return dev;
}
We're not planning to run RTmac/TDMA over our RT arcnet so we've
decided to scratch the rtnet startup script and load the required
modules in our own script. Is there anything more that has to be
done to load rtnet?
mknod /dev/rtnet c 10 240
ifconfig lo down
ifconfig arc0 down
insmod /usr/local/rtnet/modules/rtnet.ko
insmod /usr/local/rtnet/modules/rtipv4.ko
insmod /usr/local/rtnet/modules/rtpacket.ko
insmod /usr/local/rtnet/modules/rt_loopback.ko
insmod /usr/local/rtnet/modules/rt_arcnet.ko
insmod /usr/local/rtnet/modules/rt_com20020.ko
insmod /usr/local/rtnet/modules/rt_com20020-pci.ko
insmod /usr/local/rtnet/modules/rt_arc-rawmode.ko
/usr/local/rtnet/sbin/rtifconfig rtarc0 up 10.1.1.1
/usr/local/rtnet/sbin/rtifconfig rtlo up 127.0.0.1
It seems like everything loaded ok (no error messages) and here's
the output from dmesg | tail .. is the station address 00 a
looming problem? can I change this in the source file?
lightcap@borelli:/usr/local/rtnet/sbin$ dmesg | tail
[4299263.969000] rt-arcnet: COM20020 PCI support
[4299263.970000] ACPI: PCI Interrupt 0000:04:02.0[A] -> GSI 18
(level, low) -> IRQ 21
[4299263.970000] rtarc0: Contemporary Controls
[4299264.272000] rtarc0: PCI COM20020: station 00h found at CC70h,
IRQ 21.
[4299264.280000] rtarc0: Using CKP 64 - data rate 2.5 Mb/s.
[4299264.280000] RTnet: registered rtarc0
[4300094.481000] initializing loopback...
[4300094.481000] RTnet: registered rtlo
[4300094.511000] rt-arcnet: raw mode (`r') encapsulation support
loaded.
[4300094.512000] rtarc0: WARNING! Station address 00 is reserved
for broadcasts!
and surprisingly!
lightcap@borelli:/usr/local/rtnet/sbin$ sudo ./rtifconfig -a
rtarc0 Medium: unknown (7)
IP address: 10.1.1.1 Broadcast address: 10.255.255.255
UP BROADCAST RUNNING MTU: 508
rtlo Medium: Local Loopback
IP address: 127.0.0.1
UP LOOPBACK RUNNING MTU: 1500
Here is the interesting part! I have a worst case rtt of 0.0 us
when I ping the local loopback. This can't be right. Even more
strange is that I can ping the arcnet card, which I thought was
only possible for TCP/IP devices. What should I set for the IP
address of my arcnet card; should I leave it empty? And the big
question is how can I test the performance of the new arcnet
driver without implementing it in our robot control software? I
have Ethereal but I it would be helpful if you had an example
program.
lightcap@borelli:/usr/local/rtnet/sbin$ sudo ./rtping 127.0.0.1
Real-time PING 127.0.0.1 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 time=0.0 us
64 bytes from 127.0.0.1: icmp_seq=2 time=0.0 us
64 bytes from 127.0.0.1: icmp_seq=3 time=0.0 us
64 bytes from 127.0.0.1: icmp_seq=4 time=0.0 us
64 bytes from 127.0.0.1: icmp_seq=5 time=0.0 us
64 bytes from 127.0.0.1: icmp_seq=6 time=0.0 us
64 bytes from 127.0.0.1: icmp_seq=7 time=0.0 us
64 bytes from 127.0.0.1: icmp_seq=8 time=0.0 us
64 bytes from 127.0.0.1: icmp_seq=9 time=0.0 us
64 bytes from 127.0.0.1: icmp_seq=10 time=0.0 us
64 bytes from 127.0.0.1: icmp_seq=11 time=0.0 us
--- 127.0.0.1 rtping statistics ---
11 packets transmitted, 11 received, 0% packet loss
worst case rtt = 0.0 us
lightcap@borelli:/usr/local/rtnet/sbin$ sudo ./rtping 10.1.1.1
Real-time PING 10.1.1.1 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 time=0.0 us
64 bytes from 127.0.0.1: icmp_seq=2 time=0.0 us
64 bytes from 127.0.0.1: icmp_seq=3 time=0.0 us
64 bytes from 127.0.0.1: icmp_seq=4 time=0.0 us
64 bytes from 127.0.0.1: icmp_seq=5 time=0.0 us
64 bytes from 127.0.0.1: icmp_seq=6 time=0.0 us
64 bytes from 127.0.0.1: icmp_seq=7 time=0.0 us
64 bytes from 127.0.0.1: icmp_seq=8 time=0.0 us
64 bytes from 127.0.0.1: icmp_seq=9 time=0.0 us
--- 10.1.1.1 rtping statistics ---
9 packets transmitted, 9 received, 0% packet loss
worst case rtt = 0.0 us
Thanks again! I'm making great process thanks to your quick
responses.
Chris Lightcap
University of Florida
On Thu Jul 13 17:56:12 EDT 2006, Jan Kiszka <jan...@we...>
wrote:
> Hi Christoper,
>
> LIGHTCAP,CHRISTOPHER A wrote:
>>
>> Jan,
>>
>> Thanks for such a quick response! We've made good progress with
>> the
>
> Indeed, I'm impressed!
>
>> RTnet Arcnet driver but have a few questions about code which
>> doesn't
>> quite match up to the existing examples.
>>
>> And I have little experience with designing network drivers (or
>> any
>> driver!) .. therefore the questions might seem basic.
>>
>> 1.) The original arcnet driver does not call alloc_etherdev but
>> rather
>> alloc_netdev (shown below). Can I still change this function
>> call like
>> suggested in your porting documenation? What effect will this
>> have on
>> the program?
>>
>> BEFORE
>>
>> struct net_device *alloc_arcdev(char *name)
>> {
>> struct net_device *dev;
>>
>> dev = alloc_netdev(sizeof(struct arcnet_local),
>> name && *name ? name : "arc%d", arcdev_setup);
>> if(dev) {
>> struct arcnet_local *lp = (struct arcnet_local *)
>> dev->priv;
>> spin_lock_init(&lp->lock);
>> }
>>
>> return dev;
>> }
>>
>> AFTER
>>
>> struct rtnet_device *alloc_arcdev(char *name)
>> {
>> struct rtnet_device *dev;
>>
>> /*** RTnet ***/
>> dev = rt_alloc_etherdev(sizeof(struct arcnet_local)); //
>> etherdev?
>> rtdev_alloc_name(dev, "rtarc%d");
>> rt_rtdev_connect(dev, &RTDEV_manager);
>> RTNET_SET_MODULE_OWNER(dev);
>> dev->vers = RTDEV_VERS_2_0;
>> /*** RTnet ***/
>>
>> if(dev) {
>> struct arcnet_local *lp = (struct arcnet_local *)
>> dev->priv;
>> rtdm_lock_init(&lp->lock); /*** RTnet ***/
>> }
>>
>> return dev;
>> }
>
> We have rtdev_alloc instead, but that's not exported so far. If
> you need
> it, it's trivial to add such an export (i.e. feel free to add
> this to
> your patch). In this case, you will likely have to do a similar
> initialisation of the device structure like it is now done in
> rt_alloc_etherdev for Ethernet. I guess your handler arcdev_setup
> is
> responsible for this in the original driver.
>
>>
>> 2.) In your example, you initialize the skb_pool in the probe
>> function
>
> Which example do you mean?
>
>> and if the return value is less than twice the ring size then you
>> release the skb_pool and call a few 'cleanup' functions.
>>
>> e.g. pci_free_consistent(lp->pci_dev, sizeof(*lp), lp,
>> lp->dma_addr);
>>
>> I'm not sure how it works, but I cannot this function because
>> the
>> struct arcnet_local does not have a field called 'dma_addr'. So
>> my
>> question is .. is dma_addr disguised under another name in the
>> arcnet_local struct? and if not do I even need to call this
>> function?
>
> That's definitely driver-specific. If you did not request this
> kind of
> resource earlier, you do not have to release it here on error.
> Rather
> check your driver carefully what might have to be cleaned up when
> something fails.
>
>> [...]
>>
>> 3.) Ok. last question. It seems like I have a problem with module
>> dependencies. The arcnet driver is set up to be loaded as four
>> separate
>> modules: arcnet.ko (the foundation), arc-rawmode.ko (provides
>> rawmode
>> encapsulation), com20020.ko (support for chipset), and
>> com20020-pci.ko
>> (support for pci-board).
>>
>> I've done my homework and created four rt modules that compile
>> and load
>> into the kernel.. but the problem is that I cannot get them to
>> load with
>> 'rtnet start'. How do I specify dependencies in the 'rtnet.conf'
>> file?
>> My dilemna is that if I specify com20020-pci without any extra
>> work..
>> the program will not run because it cannot load the module
>> without its
>> dependencies.. BUT I cannot load rt_arcnet.ko and rt_com20020.ko
>> before
>> running 'rtnet start' because they both depend on the module
>> rtnet!!
>
> Yeah, I see. This actually reminds me of the fact that the
> installation
> process and, as a result, the startup scripting need some
> renovation.
> The way it is now dates back to the days where RT applications
> where
> typically kernel modules as well. In fact we should have the same
> problem with the recently added RT-WLAN driver as well. Daniel
> just
> didn't test a full RTnet setup yet as far as I heard.
>
> If we assume that modules go to
> /lib/modules/<kernel-version>/rtnet by
> default e.g. and that depmod will be executed (or we trigger its
> execution), then modprobe could be used in the startup script,
> and
> missing components will get dragged in automatically - kind of
> standard...
>
>>
>> So I feel like I'm in a bit of a catch-22. Please tell me how to
>> get
>> around this problem.
>
> Well, as an intermediate solution we could add another variable
> to
> rtnet.conf, let's say RT_ADDON_MODULES, that lists all modules
> that have
> to be loaded after rtnet.ko but before the driver. This could
> also
> include rtpacket.ko, thus making this component optional wrt the
> rtnet
> start script. A simple
>
> for mod in $RT_ADDON_MODULES; do insmod
> $RTNET_MOD/$mod$MODULE_EXT; done
>
> would take care of the list in the script. Do you have scripting
> experiences to add this?
>
> But we definitely need refactoring of the installation process
> and the
> startup script. Many people already asked for multi-device setup,
> something that is not addressed by the current script design. I
> have no
> ideas on this yet, though.
>
>
> Hmm, BTW, do you actually *need* the start script as it is at
> all???
> Will you run RTmac/TDMA over ARCNET (because that is what the
> script is
> mostly about!)? Maybe it's an even easier way for you to write
> your own
> startup/cleanup script then, just by picking up the interesting
> pieces
> from existing code and docs.
>
>>
>> Thank you so much for your help.
>>
>> Chris Lightcap
>> University of Florida
>>
>
> Looking forward to hear about the first successful experiments!
>
> Jan
>
>
|
|
From: Jan K. <jan...@we...> - 2006-07-14 16:36:48
Attachments:
signature.asc
|
Chris Lightcap wrote:
>=20
> Hi Jan,
>=20
> I made the changes you suggested in your last response. I've exported
> the rtdev_alloc so that I can use that with arcdev_setup in my driver.
> (code shown below)
>=20
> /* Setup a struct device for ARCnet. */
>=20
> static void arcdev_setup(struct rtnet_device *dev)
> {
> dev->type =3D ARPHRD_ARCNET;
> dev->hard_header_len =3D sizeof(struct archdr);
> dev->mtu =3D choose_mtu();
> dev->get_mtu =3D rt_hard_mtu; // RTNET
>=20
> dev->addr_len =3D ARCNET_ALEN;
>=20
> // dev->tx_queue_len =3D 100; // RTNET
> // dev->watchdog_timeo =3D TX_TIMEOUT;
>=20
> dev->broadcast[0] =3D 0x00; // for us, broadcasts are address 0
> =20
> // New-style flags.
>=20
> dev->flags =3D IFF_BROADCAST;
> =20
> // Put in this stuff here, so we don't have to export the symbols t=
o
> // the chipset drivers.
> =20
> dev->open =3D arcnet_open;
> dev->stop =3D arcnet_close;
> dev->hard_start_xmit =3D arcnet_send_packet;
>=20
> // dev->tx_timeout =3D arcnet_timeout;
> // dev->get_stats =3D arcnet_get_stats;
>=20
> dev->hard_header =3D arcnet_header;
> dev->rebuild_header =3D arcnet_rebuild_header;
> }
>=20
> struct rtnet_device *rt_alloc_arcdev(char *name)
> {
> struct rtnet_device *dev;
>=20
> /*** RTnet ***/
> =20
> dev =3D rtdev_alloc(sizeof(struct arcnet_local)); // <-------
> if (!dev)
> return NULL;
>=20
> arcdev_setup(dev);
>=20
> memset(dev->broadcast, 0xFF, ARCNET_ALEN);
> strcpy(dev->name, "rteth%d");
> =20
> rtdev_alloc_name(dev, "rtarc%d");
> rt_rtdev_connect(dev, &RTDEV_manager);
> RTNET_SET_MODULE_OWNER(dev);
> dev->vers =3D RTDEV_VERS_2_0;
>=20
> /*** RTnet ***/
>=20
> if(dev) {
> struct arcnet_local *lp =3D (struct arcnet_local *) dev->priv;
> rtdm_lock_init(&lp->lock); /*** RTnet ***/
> }
>=20
> return dev;
> }
>=20
> We're not planning to run RTmac/TDMA over our RT arcnet so we've decide=
d
> to scratch the rtnet startup script and load the required modules in ou=
r
> own script. Is there anything more that has to be done to load rtnet?
Yes and no. Explanation follows below.
>=20
> mknod /dev/rtnet c 10 240
>=20
> ifconfig lo down
> ifconfig arc0 down
>=20
> insmod /usr/local/rtnet/modules/rtnet.ko
> insmod /usr/local/rtnet/modules/rtipv4.ko
> insmod /usr/local/rtnet/modules/rtpacket.ko
> insmod /usr/local/rtnet/modules/rt_loopback.ko
>=20
> insmod /usr/local/rtnet/modules/rt_arcnet.ko
> insmod /usr/local/rtnet/modules/rt_com20020.ko
> insmod /usr/local/rtnet/modules/rt_com20020-pci.ko
> insmod /usr/local/rtnet/modules/rt_arc-rawmode.ko
>=20
> /usr/local/rtnet/sbin/rtifconfig rtarc0 up 10.1.1.1
> /usr/local/rtnet/sbin/rtifconfig rtlo up 127.0.0.1
>=20
> It seems like everything loaded ok (no error messages) and here's the
> output from dmesg | tail .. is the station address 00 a looming problem=
?
> can I change this in the source file?
That looks arcnet-specific to me, and this is something I cannot comment
on due to lacking experience. I would compare the output with standard
Linux. Of course, understanding how the station addresses are normally
used will be even better. ;)
>=20
> lightcap@borelli:/usr/local/rtnet/sbin$ dmesg | tail
> [4299263.969000] rt-arcnet: COM20020 PCI support
> [4299263.970000] ACPI: PCI Interrupt 0000:04:02.0[A] -> GSI 18 (level,
> low) -> IRQ 21
> [4299263.970000] rtarc0: Contemporary Controls
> [4299264.272000] rtarc0: PCI COM20020: station 00h found at CC70h, IRQ =
21.
> [4299264.280000] rtarc0: Using CKP 64 - data rate 2.5 Mb/s.
> [4299264.280000] RTnet: registered rtarc0
> [4300094.481000] initializing loopback...
> [4300094.481000] RTnet: registered rtlo
> [4300094.511000] rt-arcnet: raw mode (`r') encapsulation support loaded=
=2E
> [4300094.512000] rtarc0: WARNING! Station address 00 is reserved for
> broadcasts!
>=20
> and surprisingly!
>=20
> lightcap@borelli:/usr/local/rtnet/sbin$ sudo ./rtifconfig -a
> rtarc0 Medium: unknown (7)
^^^^^^^
Hah, this still needs fixing! :o>
(see tools/rtifconfig.c)
> IP address: 10.1.1.1 Broadcast address: 10.255.255.255
> UP BROADCAST RUNNING MTU: 508
>=20
> rtlo Medium: Local Loopback
> IP address: 127.0.0.1
> UP LOOPBACK RUNNING MTU: 1500
>=20
> Here is the interesting part! I have a worst case rtt of 0.0 us when I
> ping the local loopback. This can't be right. Even more strange is that=
Let me guess: you run this over RTAI? Then you did not start the system
timer /somehow/. Normally, this is done by rtcfg.ko or tdma.ko. If those
modules aren't loaded, your application has to do this. But as you do
not have any application yet: simply insmod rtcfg.ko. This will start
the timer while rtcfg remains passive otherwise.
> I can ping the arcnet card, which I thought was only possible for TCP/I=
P
> devices. What should I set for the IP address of my arcnet card; should=
> I leave it empty? And the big question is how can I test the performanc=
e
> of the new arcnet driver without implementing it in our robot control
> software? I have Ethereal but I it would be helpful if you had an
> example program.
Well, if it is transparent to the rest of the RTnet stack (and this
seems to be the case), rtping would be a good start. Another performance
tester are the rtt-* examples under examples/xenomai/posix. Teresa
Noviello started a RTAI port recently, but I don't know the current statu=
s.
>=20
> lightcap@borelli:/usr/local/rtnet/sbin$ sudo ./rtping 127.0.0.1
> Real-time PING 127.0.0.1 56(84) bytes of data.
> 64 bytes from 127.0.0.1: icmp_seq=3D1 time=3D0.0 us
> 64 bytes from 127.0.0.1: icmp_seq=3D2 time=3D0.0 us
> 64 bytes from 127.0.0.1: icmp_seq=3D3 time=3D0.0 us
> 64 bytes from 127.0.0.1: icmp_seq=3D4 time=3D0.0 us
> 64 bytes from 127.0.0.1: icmp_seq=3D5 time=3D0.0 us
> 64 bytes from 127.0.0.1: icmp_seq=3D6 time=3D0.0 us
> 64 bytes from 127.0.0.1: icmp_seq=3D7 time=3D0.0 us
> 64 bytes from 127.0.0.1: icmp_seq=3D8 time=3D0.0 us
> 64 bytes from 127.0.0.1: icmp_seq=3D9 time=3D0.0 us
> 64 bytes from 127.0.0.1: icmp_seq=3D10 time=3D0.0 us
> 64 bytes from 127.0.0.1: icmp_seq=3D11 time=3D0.0 us
>=20
> --- 127.0.0.1 rtping statistics ---
> 11 packets transmitted, 11 received, 0% packet loss
> worst case rtt =3D 0.0 us
>=20
> lightcap@borelli:/usr/local/rtnet/sbin$ sudo ./rtping 10.1.1.1
> Real-time PING 10.1.1.1 56(84) bytes of data.
> 64 bytes from 127.0.0.1: icmp_seq=3D1 time=3D0.0 us
> 64 bytes from 127.0.0.1: icmp_seq=3D2 time=3D0.0 us
> 64 bytes from 127.0.0.1: icmp_seq=3D3 time=3D0.0 us
> 64 bytes from 127.0.0.1: icmp_seq=3D4 time=3D0.0 us
> 64 bytes from 127.0.0.1: icmp_seq=3D5 time=3D0.0 us
> 64 bytes from 127.0.0.1: icmp_seq=3D6 time=3D0.0 us
> 64 bytes from 127.0.0.1: icmp_seq=3D7 time=3D0.0 us
> 64 bytes from 127.0.0.1: icmp_seq=3D8 time=3D0.0 us
> 64 bytes from 127.0.0.1: icmp_seq=3D9 time=3D0.0 us
>=20
> --- 10.1.1.1 rtping statistics ---
> 9 packets transmitted, 9 received, 0% packet loss
> worst case rtt =3D 0.0 us
>=20
>=20
> Thanks again! I'm making great process thanks to your quick responses.
I'm just eagerly awaiting your patches... :)
Jan
|
|
From: Chris L. <ca...@uf...> - 2006-07-17 22:15:13
|
Hi Jan,
I've modified a simple arcnet communication program to support the
new real-time driver.. but I'm having a problem opening the socket
(the first step, i know!) where the function returns an integer
value of -97? The original program called the socket function with
the following socket type and protocol and I've modified it as
shown below.
int sockfd = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ALL)); //
the original
int sockfd = rt_dev_socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
// the modified
I know that SOCK_PACKET is an outdated socket type but the
alternative SOCK_RAW will not work either. I found in the
rt_pci32.c driver that the arguments AF_INET and SOCK_DGRAM work
but I need to use header information in the arcnet packets.
Any suggestions?
Thanks for all of the help,
Chris Lightcap
University of Florida
On Fri Jul 14 12:31:27 EDT 2006, Jan Kiszka <jan...@we...>
wrote:
> Chris Lightcap wrote:
>>
>> Hi Jan,
>>
>> I made the changes you suggested in your last response. I've
>> exported
>> the rtdev_alloc so that I can use that with arcdev_setup in my
>> driver.
>> (code shown below)
>>
>> /* Setup a struct device for ARCnet. */
>>
>> static void arcdev_setup(struct rtnet_device *dev)
>> {
>> dev->type = ARPHRD_ARCNET;
>> dev->hard_header_len = sizeof(struct archdr);
>> dev->mtu = choose_mtu();
>> dev->get_mtu = rt_hard_mtu; // RTNET
>>
>> dev->addr_len = ARCNET_ALEN;
>>
>> // dev->tx_queue_len = 100; // RTNET
>> // dev->watchdog_timeo = TX_TIMEOUT;
>>
>> dev->broadcast[0] = 0x00; // for us, broadcasts are
>> address 0
>> // New-style flags.
>>
>> dev->flags = IFF_BROADCAST;
>> // Put in this stuff here, so we don't have to export
>> the symbols to
>> // the chipset drivers.
>> dev->open = arcnet_open;
>> dev->stop = arcnet_close;
>> dev->hard_start_xmit = arcnet_send_packet;
>>
>> // dev->tx_timeout = arcnet_timeout;
>> // dev->get_stats = arcnet_get_stats;
>>
>> dev->hard_header = arcnet_header;
>> dev->rebuild_header = arcnet_rebuild_header;
>> }
>>
>> struct rtnet_device *rt_alloc_arcdev(char *name)
>> {
>> struct rtnet_device *dev;
>>
>> /*** RTnet ***/
>> dev = rtdev_alloc(sizeof(struct arcnet_local)); //
>> <-------
>> if (!dev)
>> return NULL;
>>
>> arcdev_setup(dev);
>>
>> memset(dev->broadcast, 0xFF, ARCNET_ALEN);
>> strcpy(dev->name, "rteth%d");
>> rtdev_alloc_name(dev, "rtarc%d");
>> rt_rtdev_connect(dev, &RTDEV_manager);
>> RTNET_SET_MODULE_OWNER(dev);
>> dev->vers = RTDEV_VERS_2_0;
>>
>> /*** RTnet ***/
>>
>> if(dev) {
>> struct arcnet_local *lp = (struct arcnet_local *)
>> dev->priv;
>> rtdm_lock_init(&lp->lock); /*** RTnet ***/
>> }
>>
>> return dev;
>> }
>>
>> We're not planning to run RTmac/TDMA over our RT arcnet so we've
>> decided
>> to scratch the rtnet startup script and load the required
>> modules in our
>> own script. Is there anything more that has to be done to load
>> rtnet?
>
> Yes and no. Explanation follows below.
>
>>
>> mknod /dev/rtnet c 10 240
>>
>> ifconfig lo down
>> ifconfig arc0 down
>>
>> insmod /usr/local/rtnet/modules/rtnet.ko
>> insmod /usr/local/rtnet/modules/rtipv4.ko
>> insmod /usr/local/rtnet/modules/rtpacket.ko
>> insmod /usr/local/rtnet/modules/rt_loopback.ko
>>
>> insmod /usr/local/rtnet/modules/rt_arcnet.ko
>> insmod /usr/local/rtnet/modules/rt_com20020.ko
>> insmod /usr/local/rtnet/modules/rt_com20020-pci.ko
>> insmod /usr/local/rtnet/modules/rt_arc-rawmode.ko
>>
>> /usr/local/rtnet/sbin/rtifconfig rtarc0 up 10.1.1.1
>> /usr/local/rtnet/sbin/rtifconfig rtlo up 127.0.0.1
>>
>> It seems like everything loaded ok (no error messages) and
>> here's the
>> output from dmesg | tail .. is the station address 00 a looming
>> problem?
>> can I change this in the source file?
>
> That looks arcnet-specific to me, and this is something I cannot
> comment
> on due to lacking experience. I would compare the output with
> standard
> Linux. Of course, understanding how the station addresses are
> normally
> used will be even better. ;)
>
>>
>> lightcap@borelli:/usr/local/rtnet/sbin$ dmesg | tail
>> [4299263.969000] rt-arcnet: COM20020 PCI support
>> [4299263.970000] ACPI: PCI Interrupt 0000:04:02.0[A] -> GSI 18
>> (level,
>> low) -> IRQ 21
>> [4299263.970000] rtarc0: Contemporary Controls
>> [4299264.272000] rtarc0: PCI COM20020: station 00h found at
>> CC70h, IRQ 21.
>> [4299264.280000] rtarc0: Using CKP 64 - data rate 2.5 Mb/s.
>> [4299264.280000] RTnet: registered rtarc0
>> [4300094.481000] initializing loopback...
>> [4300094.481000] RTnet: registered rtlo
>> [4300094.511000] rt-arcnet: raw mode (`r') encapsulation support
>> loaded.
>> [4300094.512000] rtarc0: WARNING! Station address 00 is
>> reserved for
>> broadcasts!
>>
>> and surprisingly!
>>
>> lightcap@borelli:/usr/local/rtnet/sbin$ sudo ./rtifconfig -a
>> rtarc0 Medium: unknown (7)
> ^^^^^^^
> Hah, this still needs fixing! :o>
> (see tools/rtifconfig.c)
>
>> IP address: 10.1.1.1 Broadcast address: 10.255.255.255
>> UP BROADCAST RUNNING MTU: 508
>>
>> rtlo Medium: Local Loopback
>> IP address: 127.0.0.1
>> UP LOOPBACK RUNNING MTU: 1500
>>
>> Here is the interesting part! I have a worst case rtt of 0.0 us
>> when I
>> ping the local loopback. This can't be right. Even more strange
>> is that
>
> Let me guess: you run this over RTAI? Then you did not start the
> system
> timer /somehow/. Normally, this is done by rtcfg.ko or tdma.ko.
> If those
> modules aren't loaded, your application has to do this. But as
> you do
> not have any application yet: simply insmod rtcfg.ko. This will
> start
> the timer while rtcfg remains passive otherwise.
>
>> I can ping the arcnet card, which I thought was only possible
>> for TCP/IP
>> devices. What should I set for the IP address of my arcnet card;
>> should
>> I leave it empty? And the big question is how can I test the
>> performance
>> of the new arcnet driver without implementing it in our robot
>> control
>> software? I have Ethereal but I it would be helpful if you had an
>> example program.
>
> Well, if it is transparent to the rest of the RTnet stack (and
> this
> seems to be the case), rtping would be a good start. Another
> performance
> tester are the rtt-* examples under examples/xenomai/posix.
> Teresa
> Noviello started a RTAI port recently, but I don't know the
> current status.
>
>>
>> lightcap@borelli:/usr/local/rtnet/sbin$ sudo ./rtping 127.0.0.1
>> Real-time PING 127.0.0.1 56(84) bytes of data.
>> 64 bytes from 127.0.0.1: icmp_seq=1 time=0.0 us
>> 64 bytes from 127.0.0.1: icmp_seq=2 time=0.0 us
>> 64 bytes from 127.0.0.1: icmp_seq=3 time=0.0 us
>> 64 bytes from 127.0.0.1: icmp_seq=4 time=0.0 us
>> 64 bytes from 127.0.0.1: icmp_seq=5 time=0.0 us
>> 64 bytes from 127.0.0.1: icmp_seq=6 time=0.0 us
>> 64 bytes from 127.0.0.1: icmp_seq=7 time=0.0 us
>> 64 bytes from 127.0.0.1: icmp_seq=8 time=0.0 us
>> 64 bytes from 127.0.0.1: icmp_seq=9 time=0.0 us
>> 64 bytes from 127.0.0.1: icmp_seq=10 time=0.0 us
>> 64 bytes from 127.0.0.1: icmp_seq=11 time=0.0 us
>>
>> --- 127.0.0.1 rtping statistics ---
>> 11 packets transmitted, 11 received, 0% packet loss
>> worst case rtt = 0.0 us
>>
>> lightcap@borelli:/usr/local/rtnet/sbin$ sudo ./rtping 10.1.1.1
>> Real-time PING 10.1.1.1 56(84) bytes of data.
>> 64 bytes from 127.0.0.1: icmp_seq=1 time=0.0 us
>> 64 bytes from 127.0.0.1: icmp_seq=2 time=0.0 us
>> 64 bytes from 127.0.0.1: icmp_seq=3 time=0.0 us
>> 64 bytes from 127.0.0.1: icmp_seq=4 time=0.0 us
>> 64 bytes from 127.0.0.1: icmp_seq=5 time=0.0 us
>> 64 bytes from 127.0.0.1: icmp_seq=6 time=0.0 us
>> 64 bytes from 127.0.0.1: icmp_seq=7 time=0.0 us
>> 64 bytes from 127.0.0.1: icmp_seq=8 time=0.0 us
>> 64 bytes from 127.0.0.1: icmp_seq=9 time=0.0 us
>>
>> --- 10.1.1.1 rtping statistics ---
>> 9 packets transmitted, 9 received, 0% packet loss
>> worst case rtt = 0.0 us
>>
>>
>> Thanks again! I'm making great process thanks to your quick
>> responses.
>
> I'm just eagerly awaiting your patches... :)
>
> Jan
>
>
>
--
LIGHTCAP,CHRISTOPHER A
|
|
From: Jan K. <jan...@we...> - 2006-07-18 06:29:54
Attachments:
signature.asc
|
Chris Lightcap wrote: > Hi Jan, >=20 > I've modified a simple arcnet communication program to support the=20 > new real-time driver.. but I'm having a problem opening the socket=20 > (the first step, i know!) where the function returns an integer=20 > value of -97? The original program called the socket function with=20 > the following socket type and protocol and I've modified it as=20 > shown below. >=20 > int sockfd =3D socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ALL)); //=20 > the original >=20 > int sockfd =3D rt_dev_socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));=20 > // the modified >=20 > I know that SOCK_PACKET is an outdated socket type but the=20 > alternative SOCK_RAW will not work either. I found in the=20 > rt_pci32.c driver that the arguments AF_INET and SOCK_DGRAM work=20 > but I need to use header information in the arcnet packets. >=20 > Any suggestions? >=20 Depends on what you really need for your arcnet app: RTnet's rtpacket currently provide PF_PACKET:SOCK_DGRAM, i.e. "cooked" access to some networking device. And this access is limited to a per-protocol basis, which means no ETH_P_ALL. Moreover, it's a bit Ethernet-specific, see rt_packet_recvmsg(). Some generalisation of the rtpacket socket interface will therefore be required. Whether you also have to add ETH_P_ALL support, depends on your application design. Currently, the core would demux incoming arcnet protocols for you and and distribute them to different sockets (registered via socket(PF_PACKET, SOCK_DGRAM, <protocol>)). ETH_P_ALL would require exclusive device access because RTnet has currently no means to clone incoming packets for multiple receivers. SOCK_RAW might be necessary if there is no clean way to get all required arcnet header informations through the SOCK_DGRAM interface. Re-check your situation and suggest what you think it's best for your scenario. Then we can see how to generalise your usage scenario and integrate it cleanly. Jan |
|
From: Jan K. <jan...@we...> - 2006-07-13 21:56:46
Attachments:
signature.asc
|
Hi Christoper,
LIGHTCAP,CHRISTOPHER A wrote:
>=20
> Jan,
>=20
> Thanks for such a quick response! We've made good progress with the
Indeed, I'm impressed!
> RTnet Arcnet driver but have a few questions about code which doesn't
> quite match up to the existing examples.
>=20
> And I have little experience with designing network drivers (or any
> driver!) .. therefore the questions might seem basic.
>=20
> 1.) The original arcnet driver does not call alloc_etherdev but rather
> alloc_netdev (shown below). Can I still change this function call like
> suggested in your porting documenation? What effect will this have on
> the program?
>=20
> BEFORE
>=20
> struct net_device *alloc_arcdev(char *name)
> {
> struct net_device *dev;
>=20
> dev =3D alloc_netdev(sizeof(struct arcnet_local),
> name && *name ? name : "arc%d", arcdev_setup);
> if(dev) {
> struct arcnet_local *lp =3D (struct arcnet_local *) dev->priv;
> spin_lock_init(&lp->lock);
> }
>=20
> return dev;
> }
>=20
> AFTER
>=20
> struct rtnet_device *alloc_arcdev(char *name)
> {
> struct rtnet_device *dev;
>=20
> /*** RTnet ***/
> dev =3D rt_alloc_etherdev(sizeof(struct arcnet_local)); // etherdev=
?
> =20
> rtdev_alloc_name(dev, "rtarc%d");
> rt_rtdev_connect(dev, &RTDEV_manager);
> RTNET_SET_MODULE_OWNER(dev);
> dev->vers =3D RTDEV_VERS_2_0;
> /*** RTnet ***/
>=20
> if(dev) {
> struct arcnet_local *lp =3D (struct arcnet_local *) dev->priv;
> rtdm_lock_init(&lp->lock); /*** RTnet ***/
> }
>=20
> return dev;
> }
We have rtdev_alloc instead, but that's not exported so far. If you need
it, it's trivial to add such an export (i.e. feel free to add this to
your patch). In this case, you will likely have to do a similar
initialisation of the device structure like it is now done in
rt_alloc_etherdev for Ethernet. I guess your handler arcdev_setup is
responsible for this in the original driver.
>=20
> 2.) In your example, you initialize the skb_pool in the probe function
Which example do you mean?
> and if the return value is less than twice the ring size then you
> release the skb_pool and call a few 'cleanup' functions.
>=20
> e.g. pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr=
);
>=20
> I'm not sure how it works, but I cannot this function because the
> struct arcnet_local does not have a field called 'dma_addr'. So my
> question is .. is dma_addr disguised under another name in the
> arcnet_local struct? and if not do I even need to call this function?
That's definitely driver-specific. If you did not request this kind of
resource earlier, you do not have to release it here on error. Rather
check your driver carefully what might have to be cleaned up when
something fails.
> [...]
>=20
> 3.) Ok. last question. It seems like I have a problem with module
> dependencies. The arcnet driver is set up to be loaded as four separate=
> modules: arcnet.ko (the foundation), arc-rawmode.ko (provides rawmode
> encapsulation), com20020.ko (support for chipset), and com20020-pci.ko
> (support for pci-board).
>=20
> I've done my homework and created four rt modules that compile and load=
> into the kernel.. but the problem is that I cannot get them to load wit=
h
> 'rtnet start'. How do I specify dependencies in the 'rtnet.conf' file?
> My dilemna is that if I specify com20020-pci without any extra work..
> the program will not run because it cannot load the module without its
> dependencies.. BUT I cannot load rt_arcnet.ko and rt_com20020.ko before=
> running 'rtnet start' because they both depend on the module rtnet!!
Yeah, I see. This actually reminds me of the fact that the installation
process and, as a result, the startup scripting need some renovation.
The way it is now dates back to the days where RT applications where
typically kernel modules as well. In fact we should have the same
problem with the recently added RT-WLAN driver as well. Daniel just
didn't test a full RTnet setup yet as far as I heard.
If we assume that modules go to /lib/modules/<kernel-version>/rtnet by
default e.g. and that depmod will be executed (or we trigger its
execution), then modprobe could be used in the startup script, and
missing components will get dragged in automatically - kind of standard..=
=2E
>=20
> So I feel like I'm in a bit of a catch-22. Please tell me how to get
> around this problem.
Well, as an intermediate solution we could add another variable to
rtnet.conf, let's say RT_ADDON_MODULES, that lists all modules that have
to be loaded after rtnet.ko but before the driver. This could also
include rtpacket.ko, thus making this component optional wrt the rtnet
start script. A simple
for mod in $RT_ADDON_MODULES; do insmod $RTNET_MOD/$mod$MODULE_EXT; done
would take care of the list in the script. Do you have scripting
experiences to add this?
But we definitely need refactoring of the installation process and the
startup script. Many people already asked for multi-device setup,
something that is not addressed by the current script design. I have no
ideas on this yet, though.
Hmm, BTW, do you actually *need* the start script as it is at all???
Will you run RTmac/TDMA over ARCNET (because that is what the script is
mostly about!)? Maybe it's an even easier way for you to write your own
startup/cleanup script then, just by picking up the interesting pieces
from existing code and docs.
>=20
> Thank you so much for your help.
>=20
> Chris Lightcap
> University of Florida
>=20
Looking forward to hear about the first successful experiments!
Jan
|