Il giorno mer, 02/08/2006 alle 10.51 +0200, Dario Lesca ha scritto: > produced this structure (see attach): Makefile: > > obj-m += usbatm.o > obj-m += cxacru.o > > PWD := $(shell pwd) > MDIR := /lib/modules/$(shell uname -r) > KDIR := $(MDIR)/build > SUDO := sudo -p 'Sudo Password: ' > > default: > @echo "make {patch|build|install|uninstall|clean|cleanall}" > > #Patch > patch: usbatm.c.orig usbatm.h.orig > patch < usbatm-oam-support.patch > usbatm.c.orig: > test -f usbatm.c.orig && exit 1 > cp -a usbatm.c usbatm.c.orig > usbatm.h.orig: > test -f usbatm.h.orig && exit 1 > cp -a usbatm.h usbatm.h.orig > > #Build > build: usbatm.ko cxacru.ko > > usbatm.ko: usbatm.c > $(MAKE) -C $(KDIR) M=$(PWD) modules > cxacru.ko: cxacru.c > $(MAKE) -C $(KDIR) M=$(PWD) modules > > #Install > install: usbatm.ko cxacru.ko uninstall > $(SUDO) sh -x -c '/sbin/modprobe -rv cxacru;\ > /sbin/modprobe -rv usbatm;\ > cp -a usbatm.ko $(MDIR)/updates/.;\ > cp -a cxacru.ko $(MDIR)/updates/.;\ > /sbin/depmod -a;\ > /sbin/modprobe -v cxacru;\ > /sbin/modprobe -v usbatm' > > uninstall: > $(SUDO) sh -x -c '/sbin/modprobe -rv cxacru;\ > /sbin/modprobe -rv usbatm;\ > /sbin/modprobe -rv cxacru;\ > rm -f $(MDIR)/updates/usbatm.ko;\ > rm -f $(MDIR)/updates/cxacru.ko;\ > /sbin/depmod -a;\ > /sbin/modprobe -v cxacru;\ > /sbin/modprobe -v usbatm' > #Clear files > clear: clean > clean: > rm -fr \ > usbatm.ko usbatm.mod.c usbatm.mod.o usbatm.o \ > .usbatm.ko.cmd .usbatm.mod.o.cmd .usbatm.o.cmd \ > cxacru.ko cxacru.mod.c cxacru.mod.o cxacru.o \ > .cxacru.ko.cmd .cxacru.mod.o.cmd .cxacru.o.cmd \ > Modules.symvers .tmp_versions > > cleanall: clean uninstall > usbatm-oam-support.patch: > diff -u atm.orig/usbatm.c atm/usbatm.c > --- atm.orig/usbatm.c 2006-06-18 03:49:35.000000000 +0200 > +++ atm/usbatm.c 2006-07-25 12:07:28.000000000 +0200 > @@ -92,18 +92,18 @@ > #endif > > #define DRIVER_AUTHOR "Johan Verrept, Duncan Sands <duncan.sands@xxxxxxx>" > -#define DRIVER_VERSION "1.10" > +#define DRIVER_VERSION "1.10-OAM" > #define DRIVER_DESC "Generic USB ATM/DSL I/O, version " DRIVER_VERSION > > static const char usbatm_driver_name[] = "usbatm"; > > #define UDSL_MAX_RCV_URBS 16 > #define UDSL_MAX_SND_URBS 16 > -#define UDSL_MAX_BUF_SIZE 65536 > +#define UDSL_MAX_BUF_SIZE 64 * 1024 /* bytes */ > #define UDSL_DEFAULT_RCV_URBS 4 > #define UDSL_DEFAULT_SND_URBS 4 > -#define UDSL_DEFAULT_RCV_BUF_SIZE 3392 /* 64 * ATM_CELL_SIZE */ > -#define UDSL_DEFAULT_SND_BUF_SIZE 3392 /* 64 * ATM_CELL_SIZE */ > +#define UDSL_DEFAULT_RCV_BUF_SIZE 64 * ATM_CELL_SIZE /* bytes */ > +#define UDSL_DEFAULT_SND_BUF_SIZE 64 * ATM_CELL_SIZE /* bytes */ > > #define ATM_CELL_HEADER (ATM_CELL_SIZE - ATM_CELL_PAYLOAD) > > @@ -135,7 +135,7 @@ > module_param(snd_buf_bytes, uint, S_IRUGO); > MODULE_PARM_DESC(snd_buf_bytes, > "Size of the buffers used for transmission, in bytes (range: 1-" > - __MODULE_STRING(UDSL_MAX_BUF_SIZE) ", default: " > + __MODULE_STRING(UDSL_MAX_SND_BUF_SIZE) ", default: " > __MODULE_STRING(UDSL_DEFAULT_SND_BUF_SIZE) ")"); > > > @@ -183,7 +183,6 @@ > .owner = THIS_MODULE, > }; > > - > /*********** > ** misc ** > ***********/ > @@ -202,12 +201,37 @@ > dev_kfree_skb_any(skb); > } > > +static u16 crc10_table[256] = { > + 0x000, 0x233, 0x255, 0x066, 0x299, 0x0aa, 0x0cc, 0x2ff, 0x301, 0x132, 0x154, 0x367, 0x198, 0x3ab, 0x3cd, 0x1fe, > + 0x031, 0x202, 0x264, 0x057, 0x2a8, 0x09b, 0x0fd, 0x2ce, 0x330, 0x103, 0x165, 0x356, 0x1a9, 0x39a, 0x3fc, 0x1cf, > + 0x062, 0x251, 0x237, 0x004, 0x2fb, 0x0c8, 0x0ae, 0x29d, 0x363, 0x150, 0x136, 0x305, 0x1fa, 0x3c9, 0x3af, 0x19c, > + 0x053, 0x260, 0x206, 0x035, 0x2ca, 0x0f9, 0x09f, 0x2ac, 0x352, 0x161, 0x107, 0x334, 0x1cb, 0x3f8, 0x39e, 0x1ad, > + 0x0c4, 0x2f7, 0x291, 0x0a2, 0x25d, 0x06e, 0x008, 0x23b, 0x3c5, 0x1f6, 0x190, 0x3a3, 0x15c, 0x36f, 0x309, 0x13a, > + 0x0f5, 0x2c6, 0x2a0, 0x093, 0x26c, 0x05f, 0x039, 0x20a, 0x3f4, 0x1c7, 0x1a1, 0x392, 0x16d, 0x35e, 0x338, 0x10b, > + 0x0a6, 0x295, 0x2f3, 0x0c0, 0x23f, 0x00c, 0x06a, 0x259, 0x3a7, 0x194, 0x1f2, 0x3c1, 0x13e, 0x30d, 0x36b, 0x158, > + 0x097, 0x2a4, 0x2c2, 0x0f1, 0x20e, 0x03d, 0x05b, 0x268, 0x396, 0x1a5, 0x1c3, 0x3f0, 0x10f, 0x33c, 0x35a, 0x169, > + 0x188, 0x3bb, 0x3dd, 0x1ee, 0x311, 0x122, 0x144, 0x377, 0x289, 0x0ba, 0x0dc, 0x2ef, 0x010, 0x223, 0x245, 0x076, > + 0x1b9, 0x38a, 0x3ec, 0x1df, 0x320, 0x113, 0x175, 0x346, 0x2b8, 0x08b, 0x0ed, 0x2de, 0x021, 0x212, 0x274, 0x047, > + 0x1ea, 0x3d9, 0x3bf, 0x18c, 0x373, 0x140, 0x126, 0x315, 0x2eb, 0x0d8, 0x0be, 0x28d, 0x072, 0x241, 0x227, 0x014, > + 0x1db, 0x3e8, 0x38e, 0x1bd, 0x342, 0x171, 0x117, 0x324, 0x2da, 0x0e9, 0x08f, 0x2bc, 0x043, 0x270, 0x216, 0x025, > + 0x14c, 0x37f, 0x319, 0x12a, 0x3d5, 0x1e6, 0x180, 0x3b3, 0x24d, 0x07e, 0x018, 0x22b, 0x0d4, 0x2e7, 0x281, 0x0b2, > + 0x17d, 0x34e, 0x328, 0x11b, 0x3e4, 0x1d7, 0x1b1, 0x382, 0x27c, 0x04f, 0x029, 0x21a, 0x0e5, 0x2d6, 0x2b0, 0x083, > + 0x12e, 0x31d, 0x37b, 0x148, 0x3b7, 0x184, 0x1e2, 0x3d1, 0x22f, 0x01c, 0x07a, 0x249, 0x0b6, 0x285, 0x2e3, 0x0d0, > + 0x11f, 0x32c, 0x34a, 0x179, 0x386, 0x1b5, 0x1d3, 0x3e0, 0x21e, 0x02d, 0x04b, 0x278, 0x087, 0x2b4, 0x2d2, 0x0e1, > +}; > + > +static u16 inline crc10(u16 init, u8 *data, int len) > +{ > + while (len--) > + init = ((init << 8) & 0x3ff) ^ crc10_table[(init >> 2) & 0xff] ^ *data++; > + return init; > +} > > /*********** > ** urbs ** > ************/ > > -static struct urb *usbatm_pop_urb(struct usbatm_channel *channel) > +static inline struct urb *usbatm_pop_urb(struct usbatm_channel *channel) > { > struct urb *urb; > > @@ -224,7 +248,7 @@ > return urb; > } > > -static int usbatm_submit_urb(struct urb *urb) > +static inline int usbatm_submit_urb(struct urb *urb) > { > struct usbatm_channel *channel = urb->context; > int ret; > @@ -283,6 +307,42 @@ > tasklet_schedule(&channel->tasklet); > } > > +/* OAM loopback reply (fire-and-forget) */ > +static int usbatm_oam_reply(struct usbatm_data *instance, u8 *source) > +{ > + struct urb *urb; > + u16 crc; > + u8 *buffer; > + > + if (source[ATM_CELL_HEADER] != 0x18 || source[ATM_CELL_HEADER + 1] != 0x01) { > + atm_dbg(instance, "%s: unexpected OAM type/function %x direction %x!\n", > + __func__, source[ATM_CELL_HEADER], source[ATM_CELL_HEADER + 1]); > + return -EPROTO; > + } > + > + if (crc10(0, source + ATM_CELL_HEADER, ATM_CELL_PAYLOAD)) { > + atm_dbg(instance, "%s: OAM CRC10 error!\n", __func__); > + return -EIO; > + } > + > + urb = usbatm_pop_urb(&instance->tx_channel); > + if (!urb) > + return -ENOMEM; > + > + buffer = urb->transfer_buffer; > + memcpy(buffer, source, ATM_CELL_SIZE); > + > + buffer[ATM_CELL_HEADER + 1] = 0; /* update the direction field */ > + > + memset(buffer + ATM_CELL_SIZE - 2, 0, 2); > + > + crc = crc10(0, buffer + ATM_CELL_HEADER, ATM_CELL_PAYLOAD); > + buffer[ATM_CELL_SIZE - 2] = (crc >> 8) & 0x3; > + buffer[ATM_CELL_SIZE - 1] = crc & 0xff; > + > + urb->transfer_buffer_length = instance->tx_channel.stride; > + return usbatm_submit_urb(urb); > +} > > /************* > ** decode ** > @@ -324,12 +384,24 @@ > > vcc = instance->cached_vcc->vcc; > > +// /* OAM F5 end-to-end */ > +// if (pti == ATM_PTI_E2EF5) { > +// if (printk_ratelimit()) > +// atm_warn(instance, "%s: OAM not supported (vpi %d, vci %d)!\n", > +// __func__, vpi, vci); > +// atomic_inc(&vcc->stats->rx_err); > +// return; > +// } > + > /* OAM F5 end-to-end */ > if (pti == ATM_PTI_E2EF5) { > if (printk_ratelimit()) > - atm_warn(instance, "%s: OAM not supported (vpi %d, vci %d)!\n", > + atm_warn(instance, "%s: Trying to support OAM (vpi %d, vci %d)!\n", > __func__, vpi, vci); > - atomic_inc(&vcc->stats->rx_err); > + if (usbatm_oam_reply(instance, source)) { > + atm_dbg(instance, "%s: OAM reply failed (vpi %d, vci %d)!\n", __func__, vpi, vci); > + atomic_inc(&vcc->stats->rx_err); > + } > return; > } > > @@ -823,7 +895,7 @@ > return -EINVAL; > } > > - mutex_lock(&instance->serialize); /* vs self, usbatm_atm_close, usbatm_usb_disconnect */+ down(&instance->serialize); /* vs self, usbatm_atm_close, usbatm_usb_disconnect */ > > if (instance->disconnected) { > atm_dbg(instance, "%s: disconnected!\n", __func__); > @@ -837,7 +909,7 @@ > goto fail; > } > > - if (!(new = kzalloc(sizeof(struct usbatm_vcc_data), GFP_KERNEL))) { > + if (!(new = kmalloc(sizeof(struct usbatm_vcc_data), GFP_KERNEL))) { > atm_err(instance, "%s: no memory for vcc_data!\n", __func__); > ret = -ENOMEM; > goto fail; > @@ -867,7 +939,7 @@ > set_bit(ATM_VF_PARTIAL, &vcc->flags); > set_bit(ATM_VF_READY, &vcc->flags); > > - mutex_unlock(&instance->serialize); > + up(&instance->serialize); > > atm_dbg(instance, "%s: allocated vcc data 0x%p\n", __func__, new); > > @@ -875,7 +947,7 @@ > > fail: > kfree(new); > - mutex_unlock(&instance->serialize); > + up(&instance->serialize); > return ret; > } > > @@ -896,7 +968,7 @@ > > usbatm_cancel_send(instance, vcc); > > - mutex_lock(&instance->serialize); /* vs self, usbatm_atm_open, usbatm_usb_disconnect */ > + down(&instance->serialize); /* vs self, usbatm_atm_open, usbatm_usb_disconnect */ > > tasklet_disable(&instance->rx_channel.tasklet); > if (instance->cached_vcc == vcc_data) { > @@ -919,7 +991,7 @@ > clear_bit(ATM_VF_PARTIAL, &vcc->flags); > clear_bit(ATM_VF_ADDR, &vcc->flags); > > - mutex_unlock(&instance->serialize); > + up(&instance->serialize); > > atm_dbg(instance, "%s successful\n", __func__); > } > @@ -1009,9 +1081,9 @@ > if (!ret) > ret = usbatm_atm_init(instance); > > - mutex_lock(&instance->serialize); > + down(&instance->serialize); > instance->thread_pid = -1; > - mutex_unlock(&instance->serialize); > + up(&instance->serialize); > > complete_and_exit(&instance->thread_exited, ret); > } > @@ -1025,9 +1097,9 @@ > return ret; > } > > - mutex_lock(&instance->serialize); > + down(&instance->serialize); > instance->thread_pid = ret; > - mutex_unlock(&instance->serialize); > + up(&instance->serialize); > > wait_for_completion(&instance->thread_started); > > @@ -1066,7 +1138,7 @@ > intf->altsetting->desc.bInterfaceNumber); > > /* instance init */ > - instance = kzalloc(sizeof(*instance) + sizeof(struct urb *) * (num_rcv_urbs + num_snd_urbs), GFP_KERNEL); > + instance = kmalloc(sizeof(*instance) + sizeof(struct urb *) * (num_rcv_urbs + num_snd_urbs), GFP_KERNEL); > if (!instance) { > dev_err(dev, "%s: no memory for instance data!\n", __func__); > return -ENOMEM; > @@ -1110,7 +1182,7 @@ > /* private fields */ > > kref_init(&instance->refcount); /* dropped in usbatm_usb_disconnect */ > - mutex_init(&instance->serialize); > + init_MUTEX(&instance->serialize); > > instance->thread_pid = -1; > init_completion(&instance->thread_started); > @@ -1186,7 +1258,7 @@ > instance->urbs[i] = urb; > > /* zero the tx padding to avoid leaking information */ > - buffer = kzalloc(channel->buf_size, GFP_KERNEL); > + buffer = kmalloc(channel->buf_size, GFP_KERNEL); > if (!buffer) { > dev_err(dev, "%s: no memory for buffer %d!\n", __func__, i); > error = -ENOMEM; > @@ -1273,18 +1345,18 @@ > > usb_set_intfdata(intf, NULL); > > - mutex_lock(&instance->serialize); > + down(&instance->serialize); > instance->disconnected = 1; > if (instance->thread_pid >= 0) > kill_proc(instance->thread_pid, SIGTERM, 1); > - mutex_unlock(&instance->serialize); > + up(&instance->serialize); > > wait_for_completion(&instance->thread_exited); > > - mutex_lock(&instance->serialize); > + down(&instance->serialize); > list_for_each_entry(vcc_data, &instance->vcc_list, list) > vcc_release_async(vcc_data->vcc, -EPIPE); > - mutex_unlock(&instance->serialize); > + up(&instance->serialize); > > tasklet_disable(&instance->rx_channel.tasklet); > tasklet_disable(&instance->tx_channel.tasklet); > diff -u atm.orig/usbatm.h atm/usbatm.h > --- atm.orig/usbatm.h 2006-06-18 03:49:35.000000000 +0200 > +++ atm/usbatm.h 2006-07-25 12:11:53.000000000 +0200 > @@ -34,7 +34,6 @@ > #include <linux/list.h> > #include <linux/stringify.h> > #include <linux/usb.h> > -#include <linux/mutex.h> > > /* > #define VERBOSE_DEBUG > @@ -172,7 +171,7 @@ > ********************************/ > > struct kref refcount; > - struct mutex serialize; > + struct semaphore serialize; > int disconnected; > > /* heavy init */ -- Dario Lesca <d.lesca@xxxxxxxxxx> -- fedora-devel-list mailing list fedora-devel-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/fedora-devel-list