ChangeSet 1.975, 2003/01/31 15:26:33+11:00, [EMAIL PROTECTED]
[PATCH] USB speedtouch: add a new speedtouch encoding function
speedtouch: add a new encoding function, atmsar_encode. Calling it amounts to doing
atmsar_encode_aal5 followed by atmsar_encode_rawcell in one fell swoop. It
eliminates
the need for intermediate buffers and reduces memory movement. The following patches
use it to simplify the send logic (and get rid of those annoying little oopsen).
diff -Nru a/drivers/usb/misc/atmsar.c b/drivers/usb/misc/atmsar.c
--- a/drivers/usb/misc/atmsar.c Tue Feb 4 15:17:29 2003
+++ b/drivers/usb/misc/atmsar.c Tue Feb 4 15:17:29 2003
@@ -381,6 +381,83 @@
**
***********************/
+/* encapsulate in an AAL5 frame, which is then split into ATM cells */
+unsigned int atmsar_encode (struct atmsar_vcc_data *ctx, char *source, char *target,
+unsigned int pdu_length)
+{
+ unsigned int num_cells = (pdu_length + ATM_AAL5_TRAILER + ATM_CELL_PAYLOAD -
+1) / ATM_CELL_PAYLOAD;
+ unsigned int num_pdu_cells = pdu_length / ATM_CELL_PAYLOAD + 1;
+ unsigned int aal5_length = num_cells * ATM_CELL_PAYLOAD;
+ unsigned int zero_padding = aal5_length - pdu_length - ATM_AAL5_TRAILER;
+ unsigned int final_length = num_cells * ATM_CELL_SIZE;
+ unsigned char aal5_trailer [ATM_AAL5_TRAILER];
+ unsigned char cell_header [ATM_CELL_HEADER];
+ u32 crc;
+ int i;
+
+ PDEBUG ("atmsar_encode entered\n");
+
+ PDEBUG ("pdu_length %d, num_cells %d, num_pdu_cells %d, aal5_length %d,
+zero_padding %d, final_length %d\n", pdu_length, num_cells, num_pdu_cells,
+aal5_length, zero_padding, final_length);
+
+ PDEBUG ("source 0x=%p, target 0x%p\n", source, target);
+
+ aal5_trailer [0] = 0; /* UU = 0 */
+ aal5_trailer [1] = 0; /* CPI = 0 */
+ aal5_trailer [2] = pdu_length >> 8;
+ aal5_trailer [3] = pdu_length;
+
+ crc = crc32 (~0, source, pdu_length);
+ for (i = 0; i < zero_padding; i++)
+ crc = CRC32 (0, crc);
+ crc = crc32 (crc, aal5_trailer, 4);
+ crc = ~crc;
+
+ aal5_trailer [4] = crc >> 24;
+ aal5_trailer [5] = crc >> 16;
+ aal5_trailer [6] = crc >> 8;
+ aal5_trailer [7] = crc;
+
+ cell_header [0] = ctx->atmHeader >> 24;
+ cell_header [1] = ctx->atmHeader >> 16;
+ cell_header [2] = ctx->atmHeader >> 8;
+ cell_header [3] = ctx->atmHeader;
+ cell_header [4] = 0xec;
+
+ for (i = 1; i < num_pdu_cells; i++) {
+ memcpy (target, cell_header, ATM_CELL_HEADER);
+ target += ATM_CELL_HEADER;
+ memcpy (target, source, ATM_CELL_PAYLOAD);
+ target += ATM_CELL_PAYLOAD;
+ source += ATM_CELL_PAYLOAD;
+ PDEBUG ("source 0x=%p, target 0x%p\n", source, target);
+ }
+ memcpy (target, cell_header, ATM_CELL_HEADER);
+ target += ATM_CELL_HEADER;
+ memcpy (target, source, pdu_length % ATM_CELL_PAYLOAD);
+ target += pdu_length % ATM_CELL_PAYLOAD;
+ if (num_pdu_cells < num_cells) {
+ memset (target, 0, zero_padding + ATM_AAL5_TRAILER - ATM_CELL_PAYLOAD);
+ target += zero_padding + ATM_AAL5_TRAILER - ATM_CELL_PAYLOAD;
+ memcpy (target, cell_header, ATM_CELL_HEADER);
+ target += ATM_CELL_HEADER;
+ zero_padding = ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER;
+ }
+ memset (target, 0, zero_padding);
+ target += zero_padding;
+ memcpy (target, aal5_trailer, ATM_AAL5_TRAILER);
+
+ /* set pti bit in last cell */
+ *(target + ATM_AAL5_TRAILER + 3 - ATM_CELL_SIZE) |= 0x2;
+
+ /* update stats */
+ if (ctx->stats)
+ atomic_inc (&ctx->stats->tx);
+
+ if (ctx->stats && (ctx->type <= ATMSAR_TYPE_AAL1))
+ atomic_add (num_cells, &(ctx->stats->tx));
+
+ return final_length;
+}
+
struct sk_buff *atmsar_encode_rawcell (struct atmsar_vcc_data *ctx, struct sk_buff
*skb)
{
int number_of_cells = (skb->len) / 48;
diff -Nru a/drivers/usb/misc/atmsar.h b/drivers/usb/misc/atmsar.h
--- a/drivers/usb/misc/atmsar.h Tue Feb 4 15:17:29 2003
+++ b/drivers/usb/misc/atmsar.h Tue Feb 4 15:17:29 2003
@@ -33,6 +33,7 @@
#define ATMSAR_USE_53BYTE_CELL 0x1L
#define ATMSAR_SET_PTI 0x2L
+#define ATM_CELL_HEADER (ATM_CELL_SIZE - ATM_CELL_PAYLOAD)
/* types */
#define ATMSAR_TYPE_AAL0 ATM_AAL0
@@ -88,5 +89,7 @@
struct sk_buff *atmsar_decode_aal5 (struct atmsar_vcc_data *ctx, struct sk_buff *skb);
struct sk_buff *atmsar_alloc_tx (struct atmsar_vcc_data *vcc, unsigned int size);
+
+unsigned int atmsar_encode (struct atmsar_vcc_data *ctx, char *source, char *target,
+unsigned int pdu_length);
#endif /* _ATMSAR_H_ */
-------------------------------------------------------
This SF.NET email is sponsored by:
SourceForge Enterprise Edition + IBM + LinuxWorld = Something 2 See!
http://www.vasoftware.com
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel