sunrpc: Include missing smp_lock.h
[linux-2.6-block.git] / drivers / usb / host / fhci-tds.c
1 /*
2  * Freescale QUICC Engine USB Host Controller Driver
3  *
4  * Copyright (c) Freescale Semicondutor, Inc. 2006.
5  *               Shlomi Gridish <gridish@freescale.com>
6  *               Jerry Huang <Chang-Ming.Huang@freescale.com>
7  * Copyright (c) Logic Product Development, Inc. 2007
8  *               Peter Barada <peterb@logicpd.com>
9  * Copyright (c) MontaVista Software, Inc. 2008.
10  *               Anton Vorontsov <avorontsov@ru.mvista.com>
11  *
12  * This program is free software; you can redistribute  it and/or modify it
13  * under  the terms of  the GNU General  Public License as published by the
14  * Free Software Foundation;  either version 2 of the  License, or (at your
15  * option) any later version.
16  */
17
18 #include <linux/kernel.h>
19 #include <linux/types.h>
20 #include <linux/errno.h>
21 #include <linux/list.h>
22 #include <linux/io.h>
23 #include <linux/usb.h>
24 #include "../core/hcd.h"
25 #include "fhci.h"
26
27 #define DUMMY_BD_BUFFER  0xdeadbeef
28 #define DUMMY2_BD_BUFFER 0xbaadf00d
29
30 /* Transaction Descriptors bits */
31 #define TD_R            0x8000 /* ready bit */
32 #define TD_W            0x2000 /* wrap bit */
33 #define TD_I            0x1000 /* interrupt on completion */
34 #define TD_L            0x0800 /* last */
35 #define TD_TC           0x0400 /* transmit CRC */
36 #define TD_CNF          0x0200 /* CNF - Must be always 1 */
37 #define TD_LSP          0x0100 /* Low-speed transaction */
38 #define TD_PID          0x00c0 /* packet id */
39 #define TD_RXER         0x0020 /* Rx error or not */
40
41 #define TD_NAK          0x0010 /* No ack. */
42 #define TD_STAL         0x0008 /* Stall recieved */
43 #define TD_TO           0x0004 /* time out */
44 #define TD_UN           0x0002 /* underrun */
45 #define TD_NO           0x0010 /* Rx Non Octet Aligned Packet */
46 #define TD_AB           0x0008 /* Frame Aborted */
47 #define TD_CR           0x0004 /* CRC Error */
48 #define TD_OV           0x0002 /* Overrun */
49 #define TD_BOV          0x0001 /* Buffer Overrun */
50
51 #define TD_ERRORS       (TD_NAK | TD_STAL | TD_TO | TD_UN | \
52                          TD_NO | TD_AB | TD_CR | TD_OV | TD_BOV)
53
54 #define TD_PID_DATA0    0x0080 /* Data 0 toggle */
55 #define TD_PID_DATA1    0x00c0 /* Data 1 toggle */
56 #define TD_PID_TOGGLE   0x00c0 /* Data 0/1 toggle mask */
57
58 #define TD_TOK_SETUP    0x0000
59 #define TD_TOK_OUT      0x4000
60 #define TD_TOK_IN       0x8000
61 #define TD_ISO          0x1000
62 #define TD_ENDP         0x0780
63 #define TD_ADDR         0x007f
64
65 #define TD_ENDP_SHIFT 7
66
67 struct usb_td {
68         __be16 status;
69         __be16 length;
70         __be32 buf_ptr;
71         __be16 extra;
72         __be16 reserved;
73 };
74
75 static struct usb_td __iomem *next_bd(struct usb_td __iomem *base,
76                                       struct usb_td __iomem *td,
77                                       u16 status)
78 {
79         if (status & TD_W)
80                 return base;
81         else
82                 return ++td;
83 }
84
85 void fhci_push_dummy_bd(struct endpoint *ep)
86 {
87         if (ep->already_pushed_dummy_bd == false) {
88                 u16 td_status = in_be16(&ep->empty_td->status);
89
90                 out_be32(&ep->empty_td->buf_ptr, DUMMY_BD_BUFFER);
91                 /* get the next TD in the ring */
92                 ep->empty_td = next_bd(ep->td_base, ep->empty_td, td_status);
93                 ep->already_pushed_dummy_bd = true;
94         }
95 }
96
97 /* destroy an USB endpoint */
98 void fhci_ep0_free(struct fhci_usb *usb)
99 {
100         struct endpoint *ep;
101         int size;
102
103         ep = usb->ep0;
104         if (ep) {
105                 if (ep->td_base)
106                         cpm_muram_free(cpm_muram_offset(ep->td_base));
107
108                 if (kfifo_initialized(&ep->conf_frame_Q)) {
109                         size = cq_howmany(&ep->conf_frame_Q);
110                         for (; size; size--) {
111                                 struct packet *pkt = cq_get(&ep->conf_frame_Q);
112
113                                 kfree(pkt);
114                         }
115                         cq_delete(&ep->conf_frame_Q);
116                 }
117
118                 if (kfifo_initialized(&ep->empty_frame_Q)) {
119                         size = cq_howmany(&ep->empty_frame_Q);
120                         for (; size; size--) {
121                                 struct packet *pkt = cq_get(&ep->empty_frame_Q);
122
123                                 kfree(pkt);
124                         }
125                         cq_delete(&ep->empty_frame_Q);
126                 }
127
128                 if (kfifo_initialized(&ep->dummy_packets_Q)) {
129                         size = cq_howmany(&ep->dummy_packets_Q);
130                         for (; size; size--) {
131                                 u8 *buff = cq_get(&ep->dummy_packets_Q);
132
133                                 kfree(buff);
134                         }
135                         cq_delete(&ep->dummy_packets_Q);
136                 }
137
138                 kfree(ep);
139                 usb->ep0 = NULL;
140         }
141 }
142
143 /*
144  * create the endpoint structure
145  *
146  * arguments:
147  * usb          A pointer to the data structure of the USB
148  * data_mem     The data memory partition(BUS)
149  * ring_len     TD ring length
150  */
151 u32 fhci_create_ep(struct fhci_usb *usb, enum fhci_mem_alloc data_mem,
152                            u32 ring_len)
153 {
154         struct endpoint *ep;
155         struct usb_td __iomem *td;
156         unsigned long ep_offset;
157         char *err_for = "enpoint PRAM";
158         int ep_mem_size;
159         u32 i;
160
161         /* we need at least 3 TDs in the ring */
162         if (!(ring_len > 2)) {
163                 fhci_err(usb->fhci, "illegal TD ring length parameters\n");
164                 return -EINVAL;
165         }
166
167         ep = kzalloc(sizeof(*ep), GFP_KERNEL);
168         if (!ep)
169                 return -ENOMEM;
170
171         ep_mem_size = ring_len * sizeof(*td) + sizeof(struct fhci_ep_pram);
172         ep_offset = cpm_muram_alloc(ep_mem_size, 32);
173         if (IS_ERR_VALUE(ep_offset))
174                 goto err;
175         ep->td_base = cpm_muram_addr(ep_offset);
176
177         /* zero all queue pointers */
178         if (cq_new(&ep->conf_frame_Q, ring_len + 2) ||
179             cq_new(&ep->empty_frame_Q, ring_len + 2) ||
180             cq_new(&ep->dummy_packets_Q, ring_len + 2)) {
181                 err_for = "frame_queues";
182                 goto err;
183         }
184
185         for (i = 0; i < (ring_len + 1); i++) {
186                 struct packet *pkt;
187                 u8 *buff;
188
189                 pkt = kmalloc(sizeof(*pkt), GFP_KERNEL);
190                 if (!pkt) {
191                         err_for = "frame";
192                         goto err;
193                 }
194
195                 buff = kmalloc(1028 * sizeof(*buff), GFP_KERNEL);
196                 if (!buff) {
197                         kfree(pkt);
198                         err_for = "buffer";
199                         goto err;
200                 }
201                 cq_put(&ep->empty_frame_Q, pkt);
202                 cq_put(&ep->dummy_packets_Q, buff);
203         }
204
205         /* we put the endpoint parameter RAM right behind the TD ring */
206         ep->ep_pram_ptr = (void __iomem *)ep->td_base + sizeof(*td) * ring_len;
207
208         ep->conf_td = ep->td_base;
209         ep->empty_td = ep->td_base;
210
211         ep->already_pushed_dummy_bd = false;
212
213         /* initialize tds */
214         td = ep->td_base;
215         for (i = 0; i < ring_len; i++) {
216                 out_be32(&td->buf_ptr, 0);
217                 out_be16(&td->status, 0);
218                 out_be16(&td->length, 0);
219                 out_be16(&td->extra, 0);
220                 td++;
221         }
222         td--;
223         out_be16(&td->status, TD_W); /* for last TD set Wrap bit */
224         out_be16(&td->length, 0);
225
226         /* endpoint structure has been created */
227         usb->ep0 = ep;
228
229         return 0;
230 err:
231         fhci_ep0_free(usb);
232         kfree(ep);
233         fhci_err(usb->fhci, "no memory for the %s\n", err_for);
234         return -ENOMEM;
235 }
236
237 /*
238  * initialize the endpoint register according to the given parameters
239  *
240  * artuments:
241  * usb          A pointer to the data strucutre of the USB
242  * ep           A pointer to the endpoint structre
243  * data_mem     The data memory partition(BUS)
244  */
245 void fhci_init_ep_registers(struct fhci_usb *usb, struct endpoint *ep,
246                             enum fhci_mem_alloc data_mem)
247 {
248         u8 rt;
249
250         /* set the endpoint registers according to the endpoint */
251         out_be16(&usb->fhci->regs->usb_ep[0],
252                  USB_TRANS_CTR | USB_EP_MF | USB_EP_RTE);
253         out_be16(&usb->fhci->pram->ep_ptr[0],
254                  cpm_muram_offset(ep->ep_pram_ptr));
255
256         rt = (BUS_MODE_BO_BE | BUS_MODE_GBL);
257 #ifdef MULTI_DATA_BUS
258         if (data_mem == MEM_SECONDARY)
259                 rt |= BUS_MODE_DTB;
260 #endif
261         out_8(&ep->ep_pram_ptr->rx_func_code, rt);
262         out_8(&ep->ep_pram_ptr->tx_func_code, rt);
263         out_be16(&ep->ep_pram_ptr->rx_buff_len, 1028);
264         out_be16(&ep->ep_pram_ptr->rx_base, 0);
265         out_be16(&ep->ep_pram_ptr->tx_base, cpm_muram_offset(ep->td_base));
266         out_be16(&ep->ep_pram_ptr->rx_bd_ptr, 0);
267         out_be16(&ep->ep_pram_ptr->tx_bd_ptr, cpm_muram_offset(ep->td_base));
268         out_be32(&ep->ep_pram_ptr->tx_state, 0);
269 }
270
271 /*
272  * Collect the submitted frames and inform the application about them
273  * It is also prepearing the TDs for new frames. If the Tx interrupts
274  * are diabled, the application should call that routine to get
275  * confirmation about the submitted frames. Otherwise, the routine is
276  * called frome the interrupt service routine during the Tx interrupt.
277  * In that case the application is informed by calling the application
278  * specific 'fhci_transaction_confirm' routine
279  */
280 static void fhci_td_transaction_confirm(struct fhci_usb *usb)
281 {
282         struct endpoint *ep = usb->ep0;
283         struct packet *pkt;
284         struct usb_td __iomem *td;
285         u16 extra_data;
286         u16 td_status;
287         u16 td_length;
288         u32 buf;
289
290         /*
291          * collect transmitted BDs from the chip. The routine clears all BDs
292          * with R bit = 0 and the pointer to data buffer is not NULL, that is
293          * BDs which point to the transmitted data buffer
294          */
295         while (1) {
296                 td = ep->conf_td;
297                 td_status = in_be16(&td->status);
298                 td_length = in_be16(&td->length);
299                 buf = in_be32(&td->buf_ptr);
300                 extra_data = in_be16(&td->extra);
301
302                 /* check if the TD is empty */
303                 if (!(!(td_status & TD_R) && ((td_status & ~TD_W) || buf)))
304                         break;
305                 /* check if it is a dummy buffer */
306                 else if ((buf == DUMMY_BD_BUFFER) && !(td_status & ~TD_W))
307                         break;
308
309                 /* mark TD as empty */
310                 clrbits16(&td->status, ~TD_W);
311                 out_be16(&td->length, 0);
312                 out_be32(&td->buf_ptr, 0);
313                 out_be16(&td->extra, 0);
314                 /* advance the TD pointer */
315                 ep->conf_td = next_bd(ep->td_base, ep->conf_td, td_status);
316
317                 /* check if it is a dummy buffer(type2) */
318                 if ((buf == DUMMY2_BD_BUFFER) && !(td_status & ~TD_W))
319                         continue;
320
321                 pkt = cq_get(&ep->conf_frame_Q);
322                 if (!pkt)
323                         fhci_err(usb->fhci, "no frame to confirm\n");
324
325                 if (td_status & TD_ERRORS) {
326                         if (td_status & TD_RXER) {
327                                 if (td_status & TD_CR)
328                                         pkt->status = USB_TD_RX_ER_CRC;
329                                 else if (td_status & TD_AB)
330                                         pkt->status = USB_TD_RX_ER_BITSTUFF;
331                                 else if (td_status & TD_OV)
332                                         pkt->status = USB_TD_RX_ER_OVERUN;
333                                 else if (td_status & TD_BOV)
334                                         pkt->status = USB_TD_RX_DATA_OVERUN;
335                                 else if (td_status & TD_NO)
336                                         pkt->status = USB_TD_RX_ER_NONOCT;
337                                 else
338                                         fhci_err(usb->fhci, "illegal error "
339                                                  "occured\n");
340                         } else if (td_status & TD_NAK)
341                                 pkt->status = USB_TD_TX_ER_NAK;
342                         else if (td_status & TD_TO)
343                                 pkt->status = USB_TD_TX_ER_TIMEOUT;
344                         else if (td_status & TD_UN)
345                                 pkt->status = USB_TD_TX_ER_UNDERUN;
346                         else if (td_status & TD_STAL)
347                                 pkt->status = USB_TD_TX_ER_STALL;
348                         else
349                                 fhci_err(usb->fhci, "illegal error occured\n");
350                 } else if ((extra_data & TD_TOK_IN) &&
351                                 pkt->len > td_length - CRC_SIZE) {
352                         pkt->status = USB_TD_RX_DATA_UNDERUN;
353                 }
354
355                 if (extra_data & TD_TOK_IN)
356                         pkt->len = td_length - CRC_SIZE;
357                 else if (pkt->info & PKT_ZLP)
358                         pkt->len = 0;
359                 else
360                         pkt->len = td_length;
361
362                 fhci_transaction_confirm(usb, pkt);
363         }
364 }
365
366 /*
367  * Submitting a data frame to a specified endpoint of a USB device
368  * The frame is put in the driver's transmit queue for this endpoint
369  *
370  * Arguments:
371  * usb          A pointer to the USB structure
372  * pkt          A pointer to the user frame structure
373  * trans_type   Transaction tyep - IN,OUT or SETUP
374  * dest_addr    Device address - 0~127
375  * dest_ep      Endpoint number of the device - 0~16
376  * trans_mode   Pipe type - ISO,Interrupt,bulk or control
377  * dest_speed   USB speed - Low speed or FULL speed
378  * data_toggle  Data sequence toggle - 0 or 1
379  */
380 u32 fhci_host_transaction(struct fhci_usb *usb,
381                           struct packet *pkt,
382                           enum fhci_ta_type trans_type,
383                           u8 dest_addr,
384                           u8 dest_ep,
385                           enum fhci_tf_mode trans_mode,
386                           enum fhci_speed dest_speed, u8 data_toggle)
387 {
388         struct endpoint *ep = usb->ep0;
389         struct usb_td __iomem *td;
390         u16 extra_data;
391         u16 td_status;
392
393         fhci_usb_disable_interrupt(usb);
394         /* start from the next BD that should be filled */
395         td = ep->empty_td;
396         td_status = in_be16(&td->status);
397
398         if (td_status & TD_R && in_be16(&td->length)) {
399                 /* if the TD is not free */
400                 fhci_usb_enable_interrupt(usb);
401                 return -1;
402         }
403
404         /* get the next TD in the ring */
405         ep->empty_td = next_bd(ep->td_base, ep->empty_td, td_status);
406         fhci_usb_enable_interrupt(usb);
407         pkt->priv_data = td;
408         out_be32(&td->buf_ptr, virt_to_phys(pkt->data));
409         /* sets up transaction parameters - addr,endp,dir,and type */
410         extra_data = (dest_ep << TD_ENDP_SHIFT) | dest_addr;
411         switch (trans_type) {
412         case FHCI_TA_IN:
413                 extra_data |= TD_TOK_IN;
414                 break;
415         case FHCI_TA_OUT:
416                 extra_data |= TD_TOK_OUT;
417                 break;
418         case FHCI_TA_SETUP:
419                 extra_data |= TD_TOK_SETUP;
420                 break;
421         }
422         if (trans_mode == FHCI_TF_ISO)
423                 extra_data |= TD_ISO;
424         out_be16(&td->extra, extra_data);
425
426         /* sets up the buffer descriptor */
427         td_status = ((td_status & TD_W) | TD_R | TD_L | TD_I | TD_CNF);
428         if (!(pkt->info & PKT_NO_CRC))
429                 td_status |= TD_TC;
430
431         switch (trans_type) {
432         case FHCI_TA_IN:
433                 if (data_toggle)
434                         pkt->info |= PKT_PID_DATA1;
435                 else
436                         pkt->info |= PKT_PID_DATA0;
437                 break;
438         default:
439                 if (data_toggle) {
440                         td_status |= TD_PID_DATA1;
441                         pkt->info |= PKT_PID_DATA1;
442                 } else {
443                         td_status |= TD_PID_DATA0;
444                         pkt->info |= PKT_PID_DATA0;
445                 }
446                 break;
447         }
448
449         if ((dest_speed == FHCI_LOW_SPEED) &&
450             (usb->port_status == FHCI_PORT_FULL))
451                 td_status |= TD_LSP;
452
453         out_be16(&td->status, td_status);
454
455         /* set up buffer length */
456         if (trans_type == FHCI_TA_IN)
457                 out_be16(&td->length, pkt->len + CRC_SIZE);
458         else
459                 out_be16(&td->length, pkt->len);
460
461         /* put the frame to the confirmation queue */
462         cq_put(&ep->conf_frame_Q, pkt);
463
464         if (cq_howmany(&ep->conf_frame_Q) == 1)
465                 out_8(&usb->fhci->regs->usb_comm, USB_CMD_STR_FIFO);
466
467         return 0;
468 }
469
470 /* Reset the Tx BD ring */
471 void fhci_flush_bds(struct fhci_usb *usb)
472 {
473         u16 extra_data;
474         u16 td_status;
475         u32 buf;
476         struct usb_td __iomem *td;
477         struct endpoint *ep = usb->ep0;
478
479         td = ep->td_base;
480         while (1) {
481                 td_status = in_be16(&td->status);
482                 buf = in_be32(&td->buf_ptr);
483                 extra_data = in_be16(&td->extra);
484
485                 /* if the TD is not empty - we'll confirm it as Timeout */
486                 if (td_status & TD_R)
487                         out_be16(&td->status, (td_status & ~TD_R) | TD_TO);
488                 /* if this TD is dummy - let's skip this TD */
489                 else if (in_be32(&td->buf_ptr) == DUMMY_BD_BUFFER)
490                         out_be32(&td->buf_ptr, DUMMY2_BD_BUFFER);
491                 /* if this is the last TD - break */
492                 if (td_status & TD_W)
493                         break;
494
495                 td++;
496         }
497
498         fhci_td_transaction_confirm(usb);
499
500         td = ep->td_base;
501         do {
502                 out_be16(&td->status, 0);
503                 out_be16(&td->length, 0);
504                 out_be32(&td->buf_ptr, 0);
505                 out_be16(&td->extra, 0);
506                 td++;
507         } while (!(in_be16(&td->status) & TD_W));
508         out_be16(&td->status, TD_W); /* for last TD set Wrap bit */
509         out_be16(&td->length, 0);
510         out_be32(&td->buf_ptr, 0);
511         out_be16(&td->extra, 0);
512
513         out_be16(&ep->ep_pram_ptr->tx_bd_ptr,
514                  in_be16(&ep->ep_pram_ptr->tx_base));
515         out_be32(&ep->ep_pram_ptr->tx_state, 0);
516         out_be16(&ep->ep_pram_ptr->tx_cnt, 0);
517         ep->empty_td = ep->td_base;
518         ep->conf_td = ep->td_base;
519 }
520
521 /*
522  * Flush all transmitted packets from TDs in the actual frame.
523  * This routine is called when something wrong with the controller and
524  * we want to get rid of the actual frame and start again next frame
525  */
526 void fhci_flush_actual_frame(struct fhci_usb *usb)
527 {
528         u8 mode;
529         u16 tb_ptr;
530         u16 extra_data;
531         u16 td_status;
532         u32 buf_ptr;
533         struct usb_td __iomem *td;
534         struct endpoint *ep = usb->ep0;
535
536         /* disable the USB controller */
537         mode = in_8(&usb->fhci->regs->usb_mod);
538         out_8(&usb->fhci->regs->usb_mod, mode & ~USB_MODE_EN);
539
540         tb_ptr = in_be16(&ep->ep_pram_ptr->tx_bd_ptr);
541         td = cpm_muram_addr(tb_ptr);
542         td_status = in_be16(&td->status);
543         buf_ptr = in_be32(&td->buf_ptr);
544         extra_data = in_be16(&td->extra);
545         do {
546                 if (td_status & TD_R) {
547                         out_be16(&td->status, (td_status & ~TD_R) | TD_TO);
548                 } else {
549                         out_be32(&td->buf_ptr, 0);
550                         ep->already_pushed_dummy_bd = false;
551                         break;
552                 }
553
554                 /* advance the TD pointer */
555                 td = next_bd(ep->td_base, td, td_status);
556                 td_status = in_be16(&td->status);
557                 buf_ptr = in_be32(&td->buf_ptr);
558                 extra_data = in_be16(&td->extra);
559         } while ((td_status & TD_R) || buf_ptr);
560
561         fhci_td_transaction_confirm(usb);
562
563         out_be16(&ep->ep_pram_ptr->tx_bd_ptr,
564                  in_be16(&ep->ep_pram_ptr->tx_base));
565         out_be32(&ep->ep_pram_ptr->tx_state, 0);
566         out_be16(&ep->ep_pram_ptr->tx_cnt, 0);
567         ep->empty_td = ep->td_base;
568         ep->conf_td = ep->td_base;
569
570         usb->actual_frame->frame_status = FRAME_TIMER_END_TRANSMISSION;
571
572         /* reset the event register */
573         out_be16(&usb->fhci->regs->usb_event, 0xffff);
574         /* enable the USB controller */
575         out_8(&usb->fhci->regs->usb_mod, mode | USB_MODE_EN);
576 }
577
578 /* handles Tx confirm and Tx error interrupt */
579 void fhci_tx_conf_interrupt(struct fhci_usb *usb)
580 {
581         fhci_td_transaction_confirm(usb);
582
583         /*
584          * Schedule another transaction to this frame only if we have
585          * already confirmed all transaction in the frame.
586          */
587         if (((fhci_get_sof_timer_count(usb) < usb->max_frame_usage) ||
588              (usb->actual_frame->frame_status & FRAME_END_TRANSMISSION)) &&
589             (list_empty(&usb->actual_frame->tds_list)))
590                 fhci_schedule_transactions(usb);
591 }
592
593 void fhci_host_transmit_actual_frame(struct fhci_usb *usb)
594 {
595         u16 tb_ptr;
596         u16 td_status;
597         struct usb_td __iomem *td;
598         struct endpoint *ep = usb->ep0;
599
600         tb_ptr = in_be16(&ep->ep_pram_ptr->tx_bd_ptr);
601         td = cpm_muram_addr(tb_ptr);
602
603         if (in_be32(&td->buf_ptr) == DUMMY_BD_BUFFER) {
604                 struct usb_td __iomem *old_td = td;
605
606                 ep->already_pushed_dummy_bd = false;
607                 td_status = in_be16(&td->status);
608                 /* gets the next TD in the ring */
609                 td = next_bd(ep->td_base, td, td_status);
610                 tb_ptr = cpm_muram_offset(td);
611                 out_be16(&ep->ep_pram_ptr->tx_bd_ptr, tb_ptr);
612
613                 /* start transmit only if we have something in the TDs */
614                 if (in_be16(&td->status) & TD_R)
615                         out_8(&usb->fhci->regs->usb_comm, USB_CMD_STR_FIFO);
616
617                 if (in_be32(&ep->conf_td->buf_ptr) == DUMMY_BD_BUFFER) {
618                         out_be32(&old_td->buf_ptr, 0);
619                         ep->conf_td = next_bd(ep->td_base, ep->conf_td,
620                                               td_status);
621                 } else {
622                         out_be32(&old_td->buf_ptr, DUMMY2_BD_BUFFER);
623                 }
624         }
625 }