0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <linux/kernel.h>
0015 #include <linux/types.h>
0016 #include <linux/errno.h>
0017 #include <linux/slab.h>
0018 #include <linux/list.h>
0019 #include <linux/io.h>
0020 #include <linux/usb.h>
0021 #include <linux/usb/hcd.h>
0022 #include "fhci.h"
0023
0024 #define DUMMY_BD_BUFFER 0xdeadbeef
0025 #define DUMMY2_BD_BUFFER 0xbaadf00d
0026
0027
0028 #define TD_R 0x8000
0029 #define TD_W 0x2000
0030 #define TD_I 0x1000
0031 #define TD_L 0x0800
0032 #define TD_TC 0x0400
0033 #define TD_CNF 0x0200
0034 #define TD_LSP 0x0100
0035 #define TD_PID 0x00c0
0036 #define TD_RXER 0x0020
0037
0038 #define TD_NAK 0x0010
0039 #define TD_STAL 0x0008
0040 #define TD_TO 0x0004
0041 #define TD_UN 0x0002
0042 #define TD_NO 0x0010
0043 #define TD_AB 0x0008
0044 #define TD_CR 0x0004
0045 #define TD_OV 0x0002
0046 #define TD_BOV 0x0001
0047
0048 #define TD_ERRORS (TD_NAK | TD_STAL | TD_TO | TD_UN | \
0049 TD_NO | TD_AB | TD_CR | TD_OV | TD_BOV)
0050
0051 #define TD_PID_DATA0 0x0080
0052 #define TD_PID_DATA1 0x00c0
0053 #define TD_PID_TOGGLE 0x00c0
0054
0055 #define TD_TOK_SETUP 0x0000
0056 #define TD_TOK_OUT 0x4000
0057 #define TD_TOK_IN 0x8000
0058 #define TD_ISO 0x1000
0059 #define TD_ENDP 0x0780
0060 #define TD_ADDR 0x007f
0061
0062 #define TD_ENDP_SHIFT 7
0063
0064 struct usb_td {
0065 __be16 status;
0066 __be16 length;
0067 __be32 buf_ptr;
0068 __be16 extra;
0069 __be16 reserved;
0070 };
0071
0072 static struct usb_td __iomem *next_bd(struct usb_td __iomem *base,
0073 struct usb_td __iomem *td,
0074 u16 status)
0075 {
0076 if (status & TD_W)
0077 return base;
0078 else
0079 return ++td;
0080 }
0081
0082 void fhci_push_dummy_bd(struct endpoint *ep)
0083 {
0084 if (!ep->already_pushed_dummy_bd) {
0085 u16 td_status = in_be16(&ep->empty_td->status);
0086
0087 out_be32(&ep->empty_td->buf_ptr, DUMMY_BD_BUFFER);
0088
0089 ep->empty_td = next_bd(ep->td_base, ep->empty_td, td_status);
0090 ep->already_pushed_dummy_bd = true;
0091 }
0092 }
0093
0094
0095 void fhci_ep0_free(struct fhci_usb *usb)
0096 {
0097 struct endpoint *ep;
0098 int size;
0099
0100 ep = usb->ep0;
0101 if (ep) {
0102 if (ep->td_base)
0103 cpm_muram_free(cpm_muram_offset(ep->td_base));
0104
0105 if (kfifo_initialized(&ep->conf_frame_Q)) {
0106 size = cq_howmany(&ep->conf_frame_Q);
0107 for (; size; size--) {
0108 struct packet *pkt = cq_get(&ep->conf_frame_Q);
0109
0110 kfree(pkt);
0111 }
0112 cq_delete(&ep->conf_frame_Q);
0113 }
0114
0115 if (kfifo_initialized(&ep->empty_frame_Q)) {
0116 size = cq_howmany(&ep->empty_frame_Q);
0117 for (; size; size--) {
0118 struct packet *pkt = cq_get(&ep->empty_frame_Q);
0119
0120 kfree(pkt);
0121 }
0122 cq_delete(&ep->empty_frame_Q);
0123 }
0124
0125 if (kfifo_initialized(&ep->dummy_packets_Q)) {
0126 size = cq_howmany(&ep->dummy_packets_Q);
0127 for (; size; size--) {
0128 u8 *buff = cq_get(&ep->dummy_packets_Q);
0129
0130 kfree(buff);
0131 }
0132 cq_delete(&ep->dummy_packets_Q);
0133 }
0134
0135 kfree(ep);
0136 usb->ep0 = NULL;
0137 }
0138 }
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148 u32 fhci_create_ep(struct fhci_usb *usb, enum fhci_mem_alloc data_mem,
0149 u32 ring_len)
0150 {
0151 struct endpoint *ep;
0152 struct usb_td __iomem *td;
0153 unsigned long ep_offset;
0154 char *err_for = "endpoint PRAM";
0155 int ep_mem_size;
0156 u32 i;
0157
0158
0159 if (!(ring_len > 2)) {
0160 fhci_err(usb->fhci, "illegal TD ring length parameters\n");
0161 return -EINVAL;
0162 }
0163
0164 ep = kzalloc(sizeof(*ep), GFP_KERNEL);
0165 if (!ep)
0166 return -ENOMEM;
0167
0168 ep_mem_size = ring_len * sizeof(*td) + sizeof(struct fhci_ep_pram);
0169 ep_offset = cpm_muram_alloc(ep_mem_size, 32);
0170 if (IS_ERR_VALUE(ep_offset))
0171 goto err;
0172 ep->td_base = cpm_muram_addr(ep_offset);
0173
0174
0175 if (cq_new(&ep->conf_frame_Q, ring_len + 2) ||
0176 cq_new(&ep->empty_frame_Q, ring_len + 2) ||
0177 cq_new(&ep->dummy_packets_Q, ring_len + 2)) {
0178 err_for = "frame_queues";
0179 goto err;
0180 }
0181
0182 for (i = 0; i < (ring_len + 1); i++) {
0183 struct packet *pkt;
0184 u8 *buff;
0185
0186 pkt = kmalloc(sizeof(*pkt), GFP_KERNEL);
0187 if (!pkt) {
0188 err_for = "frame";
0189 goto err;
0190 }
0191
0192 buff = kmalloc_array(1028, sizeof(*buff), GFP_KERNEL);
0193 if (!buff) {
0194 kfree(pkt);
0195 err_for = "buffer";
0196 goto err;
0197 }
0198 cq_put(&ep->empty_frame_Q, pkt);
0199 cq_put(&ep->dummy_packets_Q, buff);
0200 }
0201
0202
0203 ep->ep_pram_ptr = (void __iomem *)ep->td_base + sizeof(*td) * ring_len;
0204
0205 ep->conf_td = ep->td_base;
0206 ep->empty_td = ep->td_base;
0207
0208 ep->already_pushed_dummy_bd = false;
0209
0210
0211 td = ep->td_base;
0212 for (i = 0; i < ring_len; i++) {
0213 out_be32(&td->buf_ptr, 0);
0214 out_be16(&td->status, 0);
0215 out_be16(&td->length, 0);
0216 out_be16(&td->extra, 0);
0217 td++;
0218 }
0219 td--;
0220 out_be16(&td->status, TD_W);
0221 out_be16(&td->length, 0);
0222
0223
0224 usb->ep0 = ep;
0225
0226 return 0;
0227 err:
0228 fhci_ep0_free(usb);
0229 kfree(ep);
0230 fhci_err(usb->fhci, "no memory for the %s\n", err_for);
0231 return -ENOMEM;
0232 }
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242 void fhci_init_ep_registers(struct fhci_usb *usb, struct endpoint *ep,
0243 enum fhci_mem_alloc data_mem)
0244 {
0245 u8 rt;
0246
0247
0248 out_be16(&usb->fhci->regs->usb_usep[0],
0249 USB_TRANS_CTR | USB_EP_MF | USB_EP_RTE);
0250 out_be16(&usb->fhci->pram->ep_ptr[0],
0251 cpm_muram_offset(ep->ep_pram_ptr));
0252
0253 rt = (BUS_MODE_BO_BE | BUS_MODE_GBL);
0254 #ifdef MULTI_DATA_BUS
0255 if (data_mem == MEM_SECONDARY)
0256 rt |= BUS_MODE_DTB;
0257 #endif
0258 out_8(&ep->ep_pram_ptr->rx_func_code, rt);
0259 out_8(&ep->ep_pram_ptr->tx_func_code, rt);
0260 out_be16(&ep->ep_pram_ptr->rx_buff_len, 1028);
0261 out_be16(&ep->ep_pram_ptr->rx_base, 0);
0262 out_be16(&ep->ep_pram_ptr->tx_base, cpm_muram_offset(ep->td_base));
0263 out_be16(&ep->ep_pram_ptr->rx_bd_ptr, 0);
0264 out_be16(&ep->ep_pram_ptr->tx_bd_ptr, cpm_muram_offset(ep->td_base));
0265 out_be32(&ep->ep_pram_ptr->tx_state, 0);
0266 }
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277 static void fhci_td_transaction_confirm(struct fhci_usb *usb)
0278 {
0279 struct endpoint *ep = usb->ep0;
0280 struct packet *pkt;
0281 struct usb_td __iomem *td;
0282 u16 extra_data;
0283 u16 td_status;
0284 u16 td_length;
0285 u32 buf;
0286
0287
0288
0289
0290
0291
0292 while (1) {
0293 td = ep->conf_td;
0294 td_status = in_be16(&td->status);
0295 td_length = in_be16(&td->length);
0296 buf = in_be32(&td->buf_ptr);
0297 extra_data = in_be16(&td->extra);
0298
0299
0300 if (!(!(td_status & TD_R) && ((td_status & ~TD_W) || buf)))
0301 break;
0302
0303 else if ((buf == DUMMY_BD_BUFFER) && !(td_status & ~TD_W))
0304 break;
0305
0306
0307 clrbits16(&td->status, ~TD_W);
0308 out_be16(&td->length, 0);
0309 out_be32(&td->buf_ptr, 0);
0310 out_be16(&td->extra, 0);
0311
0312 ep->conf_td = next_bd(ep->td_base, ep->conf_td, td_status);
0313
0314
0315 if ((buf == DUMMY2_BD_BUFFER) && !(td_status & ~TD_W))
0316 continue;
0317
0318 pkt = cq_get(&ep->conf_frame_Q);
0319 if (!pkt)
0320 fhci_err(usb->fhci, "no frame to confirm\n");
0321
0322 if (td_status & TD_ERRORS) {
0323 if (td_status & TD_RXER) {
0324 if (td_status & TD_CR)
0325 pkt->status = USB_TD_RX_ER_CRC;
0326 else if (td_status & TD_AB)
0327 pkt->status = USB_TD_RX_ER_BITSTUFF;
0328 else if (td_status & TD_OV)
0329 pkt->status = USB_TD_RX_ER_OVERUN;
0330 else if (td_status & TD_BOV)
0331 pkt->status = USB_TD_RX_DATA_OVERUN;
0332 else if (td_status & TD_NO)
0333 pkt->status = USB_TD_RX_ER_NONOCT;
0334 else
0335 fhci_err(usb->fhci, "illegal error "
0336 "occurred\n");
0337 } else if (td_status & TD_NAK)
0338 pkt->status = USB_TD_TX_ER_NAK;
0339 else if (td_status & TD_TO)
0340 pkt->status = USB_TD_TX_ER_TIMEOUT;
0341 else if (td_status & TD_UN)
0342 pkt->status = USB_TD_TX_ER_UNDERUN;
0343 else if (td_status & TD_STAL)
0344 pkt->status = USB_TD_TX_ER_STALL;
0345 else
0346 fhci_err(usb->fhci, "illegal error occurred\n");
0347 } else if ((extra_data & TD_TOK_IN) &&
0348 pkt->len > td_length - CRC_SIZE) {
0349 pkt->status = USB_TD_RX_DATA_UNDERUN;
0350 }
0351
0352 if (extra_data & TD_TOK_IN)
0353 pkt->len = td_length - CRC_SIZE;
0354 else if (pkt->info & PKT_ZLP)
0355 pkt->len = 0;
0356 else
0357 pkt->len = td_length;
0358
0359 fhci_transaction_confirm(usb, pkt);
0360 }
0361 }
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377 u32 fhci_host_transaction(struct fhci_usb *usb,
0378 struct packet *pkt,
0379 enum fhci_ta_type trans_type,
0380 u8 dest_addr,
0381 u8 dest_ep,
0382 enum fhci_tf_mode trans_mode,
0383 enum fhci_speed dest_speed, u8 data_toggle)
0384 {
0385 struct endpoint *ep = usb->ep0;
0386 struct usb_td __iomem *td;
0387 u16 extra_data;
0388 u16 td_status;
0389
0390 fhci_usb_disable_interrupt(usb);
0391
0392 td = ep->empty_td;
0393 td_status = in_be16(&td->status);
0394
0395 if (td_status & TD_R && in_be16(&td->length)) {
0396
0397 fhci_usb_enable_interrupt(usb);
0398 return -1;
0399 }
0400
0401
0402 ep->empty_td = next_bd(ep->td_base, ep->empty_td, td_status);
0403 fhci_usb_enable_interrupt(usb);
0404 pkt->priv_data = td;
0405 out_be32(&td->buf_ptr, virt_to_phys(pkt->data));
0406
0407 extra_data = (dest_ep << TD_ENDP_SHIFT) | dest_addr;
0408 switch (trans_type) {
0409 case FHCI_TA_IN:
0410 extra_data |= TD_TOK_IN;
0411 break;
0412 case FHCI_TA_OUT:
0413 extra_data |= TD_TOK_OUT;
0414 break;
0415 case FHCI_TA_SETUP:
0416 extra_data |= TD_TOK_SETUP;
0417 break;
0418 }
0419 if (trans_mode == FHCI_TF_ISO)
0420 extra_data |= TD_ISO;
0421 out_be16(&td->extra, extra_data);
0422
0423
0424 td_status = ((td_status & TD_W) | TD_R | TD_L | TD_I | TD_CNF);
0425 if (!(pkt->info & PKT_NO_CRC))
0426 td_status |= TD_TC;
0427
0428 switch (trans_type) {
0429 case FHCI_TA_IN:
0430 if (data_toggle)
0431 pkt->info |= PKT_PID_DATA1;
0432 else
0433 pkt->info |= PKT_PID_DATA0;
0434 break;
0435 default:
0436 if (data_toggle) {
0437 td_status |= TD_PID_DATA1;
0438 pkt->info |= PKT_PID_DATA1;
0439 } else {
0440 td_status |= TD_PID_DATA0;
0441 pkt->info |= PKT_PID_DATA0;
0442 }
0443 break;
0444 }
0445
0446 if ((dest_speed == FHCI_LOW_SPEED) &&
0447 (usb->port_status == FHCI_PORT_FULL))
0448 td_status |= TD_LSP;
0449
0450 out_be16(&td->status, td_status);
0451
0452
0453 if (trans_type == FHCI_TA_IN)
0454 out_be16(&td->length, pkt->len + CRC_SIZE);
0455 else
0456 out_be16(&td->length, pkt->len);
0457
0458
0459 cq_put(&ep->conf_frame_Q, pkt);
0460
0461 if (cq_howmany(&ep->conf_frame_Q) == 1)
0462 out_8(&usb->fhci->regs->usb_uscom, USB_CMD_STR_FIFO);
0463
0464 return 0;
0465 }
0466
0467
0468 void fhci_flush_bds(struct fhci_usb *usb)
0469 {
0470 u16 td_status;
0471 struct usb_td __iomem *td;
0472 struct endpoint *ep = usb->ep0;
0473
0474 td = ep->td_base;
0475 while (1) {
0476 td_status = in_be16(&td->status);
0477 in_be32(&td->buf_ptr);
0478 in_be16(&td->extra);
0479
0480
0481 if (td_status & TD_R)
0482 out_be16(&td->status, (td_status & ~TD_R) | TD_TO);
0483
0484 else if (in_be32(&td->buf_ptr) == DUMMY_BD_BUFFER)
0485 out_be32(&td->buf_ptr, DUMMY2_BD_BUFFER);
0486
0487 if (td_status & TD_W)
0488 break;
0489
0490 td++;
0491 }
0492
0493 fhci_td_transaction_confirm(usb);
0494
0495 td = ep->td_base;
0496 do {
0497 out_be16(&td->status, 0);
0498 out_be16(&td->length, 0);
0499 out_be32(&td->buf_ptr, 0);
0500 out_be16(&td->extra, 0);
0501 td++;
0502 } while (!(in_be16(&td->status) & TD_W));
0503 out_be16(&td->status, TD_W);
0504 out_be16(&td->length, 0);
0505 out_be32(&td->buf_ptr, 0);
0506 out_be16(&td->extra, 0);
0507
0508 out_be16(&ep->ep_pram_ptr->tx_bd_ptr,
0509 in_be16(&ep->ep_pram_ptr->tx_base));
0510 out_be32(&ep->ep_pram_ptr->tx_state, 0);
0511 out_be16(&ep->ep_pram_ptr->tx_cnt, 0);
0512 ep->empty_td = ep->td_base;
0513 ep->conf_td = ep->td_base;
0514 }
0515
0516
0517
0518
0519
0520
0521 void fhci_flush_actual_frame(struct fhci_usb *usb)
0522 {
0523 u8 mode;
0524 u16 tb_ptr;
0525 u16 td_status;
0526 u32 buf_ptr;
0527 struct usb_td __iomem *td;
0528 struct endpoint *ep = usb->ep0;
0529
0530
0531 mode = in_8(&usb->fhci->regs->usb_usmod);
0532 out_8(&usb->fhci->regs->usb_usmod, mode & ~USB_MODE_EN);
0533
0534 tb_ptr = in_be16(&ep->ep_pram_ptr->tx_bd_ptr);
0535 td = cpm_muram_addr(tb_ptr);
0536 td_status = in_be16(&td->status);
0537 buf_ptr = in_be32(&td->buf_ptr);
0538 in_be16(&td->extra);
0539 do {
0540 if (td_status & TD_R) {
0541 out_be16(&td->status, (td_status & ~TD_R) | TD_TO);
0542 } else {
0543 out_be32(&td->buf_ptr, 0);
0544 ep->already_pushed_dummy_bd = false;
0545 break;
0546 }
0547
0548
0549 td = next_bd(ep->td_base, td, td_status);
0550 td_status = in_be16(&td->status);
0551 buf_ptr = in_be32(&td->buf_ptr);
0552 in_be16(&td->extra);
0553 } while ((td_status & TD_R) || buf_ptr);
0554
0555 fhci_td_transaction_confirm(usb);
0556
0557 out_be16(&ep->ep_pram_ptr->tx_bd_ptr,
0558 in_be16(&ep->ep_pram_ptr->tx_base));
0559 out_be32(&ep->ep_pram_ptr->tx_state, 0);
0560 out_be16(&ep->ep_pram_ptr->tx_cnt, 0);
0561 ep->empty_td = ep->td_base;
0562 ep->conf_td = ep->td_base;
0563
0564 usb->actual_frame->frame_status = FRAME_TIMER_END_TRANSMISSION;
0565
0566
0567 out_be16(&usb->fhci->regs->usb_usber, 0xffff);
0568
0569 out_8(&usb->fhci->regs->usb_usmod, mode | USB_MODE_EN);
0570 }
0571
0572
0573 void fhci_tx_conf_interrupt(struct fhci_usb *usb)
0574 {
0575 fhci_td_transaction_confirm(usb);
0576
0577
0578
0579
0580
0581 if (((fhci_get_sof_timer_count(usb) < usb->max_frame_usage) ||
0582 (usb->actual_frame->frame_status & FRAME_END_TRANSMISSION)) &&
0583 (list_empty(&usb->actual_frame->tds_list)))
0584 fhci_schedule_transactions(usb);
0585 }
0586
0587 void fhci_host_transmit_actual_frame(struct fhci_usb *usb)
0588 {
0589 u16 tb_ptr;
0590 u16 td_status;
0591 struct usb_td __iomem *td;
0592 struct endpoint *ep = usb->ep0;
0593
0594 tb_ptr = in_be16(&ep->ep_pram_ptr->tx_bd_ptr);
0595 td = cpm_muram_addr(tb_ptr);
0596
0597 if (in_be32(&td->buf_ptr) == DUMMY_BD_BUFFER) {
0598 struct usb_td __iomem *old_td = td;
0599
0600 ep->already_pushed_dummy_bd = false;
0601 td_status = in_be16(&td->status);
0602
0603 td = next_bd(ep->td_base, td, td_status);
0604 tb_ptr = cpm_muram_offset(td);
0605 out_be16(&ep->ep_pram_ptr->tx_bd_ptr, tb_ptr);
0606
0607
0608 if (in_be16(&td->status) & TD_R)
0609 out_8(&usb->fhci->regs->usb_uscom, USB_CMD_STR_FIFO);
0610
0611 if (in_be32(&ep->conf_td->buf_ptr) == DUMMY_BD_BUFFER) {
0612 out_be32(&old_td->buf_ptr, 0);
0613 ep->conf_td = next_bd(ep->td_base, ep->conf_td,
0614 td_status);
0615 } else {
0616 out_be32(&old_td->buf_ptr, DUMMY2_BD_BUFFER);
0617 }
0618 }
0619 }