Changeset 1914


Ignore:
Timestamp:
05/06/07 01:51:17 (6 years ago)
Author:
andrew
Message:

Implement S3C2410A USB Slave controller registered as a USB gadget.
Make usb-gadget endpoints synchronous independently of each other.
Don't use always the configuration 0 - a monitor interface will be needed later for choosing the desired slave configuration.

Location:
trunk/src/host/qemu-neo1973
Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/host/qemu-neo1973/Makefile.target

    r1825 r1914  
    383383VL_OBJS+= ads7846.o sd.o ide.o serial.o nand.o $(AUDIODRV) wm8750.o wm8753.o 
    384384VL_OBJS+= s3c2410.o s3c24xx_gpio.o s3c24xx_lcd.o s3c24xx_mmci.o s3c24xx_rtc.o 
    385 VL_OBJS+= neo1973.o pcf5060x.o jbt6k74.o modem.o 
    386 CPPFLAGS += -DHAS_AUDIO -DHIGH_LATENCY 
     385VL_OBJS+= s3c24xx_udc.o neo1973.o pcf5060x.o jbt6k74.o modem.o 
     386CPPFLAGS += -DHAS_AUDIO 
    387387endif 
    388388ifeq ($(TARGET_BASE_ARCH), sh4) 
  • trunk/src/host/qemu-neo1973/hw/s3c.h

    r1647 r1914  
    3434# define S3C_PIC_SPI0   22 
    3535# define S3C_PIC_UART1  23 
     36# define S3C_PIC_USBD   25 
    3637# define S3C_PIC_USBH   26 
    3738# define S3C_PIC_IIC    27 
     
    152153void s3c_rtc_reset(struct s3c_rtc_state_s *s); 
    153154 
     155/* s3c24xx_udc.c */ 
     156struct s3c_udc_state_s; 
     157struct s3c_udc_state_s *s3c_udc_init(target_phys_addr_t base, void *pic, 
     158                void *dma); 
     159void s3c_udc_reset(struct s3c_udc_state_s *s); 
     160 
    154161/* s3c2410.c */ 
    155162struct s3c_spi_state_s; 
     
    175182    struct s3c_rtc_state_s *rtc; 
    176183    struct s3c_spi_state_s *spi; 
     184    struct s3c_udc_state_s *udc; 
    177185 
    178186    /* Memory controller */ 
  • trunk/src/host/qemu-neo1973/hw/s3c2410.c

    r1673 r1914  
    801801    elapsed = muldiv64(qemu_get_clock(vm_clock) - s->timer[tm].reload, 
    802802                    s->timer[tm].divider, ticks_per_sec); 
    803     if (elapsed > s->timer[tm].count)   /* unlikely() */ 
     803    if (unlikely(elapsed > s->timer[tm].count)) 
    804804        return s->timer[tm].count; 
    805805 
     
    21582158    s3c_rtc_reset(s->rtc); 
    21592159    s3c_spi_reset(s->spi); 
     2160    s3c_udc_reset(s->udc); 
    21602161    s3c_clkpwr_reset(s); 
    21612162    s3c_nand_reset(s); 
     
    22132214    s->timers = s3c_timers_init(0x51000000, s->pic, s->dma); 
    22142215 
    2215     /* USBDevice at 0x52000000 */ 
     2216    s->udc = s3c_udc_init(0x52000000, s->pic, s->dma); 
     2217 
    22162218    /* Watchdog at 0x53000000 */ 
    22172219 
  • trunk/src/host/qemu-neo1973/usb-linux-gadget.c

    r1898 r1914  
    3333struct gadget_state_s { 
    3434    USBPort port; 
     35    uint8_t config_num; 
    3536    int connected; 
    3637    int speed; 
     
    4546        int num; 
    4647        struct gadget_state_s *state; 
     48 
     49        int busy; 
     50        uint8_t buffer[4096]; 
     51        USBPacket packet; 
    4752    } ep[16]; 
    4853 
     
    123128} 
    124129 
     130static void gadget_ep_run(struct ep_s *ep) 
     131{ 
     132    USBDevice *dev = ep->state->port.dev; 
     133    int ret; 
     134 
     135    ret = dev->handle_packet(dev, &ep->packet); 
     136 
     137    if (ret >= 0) { 
     138        ep->packet.len = ret; 
     139        ep->packet.complete_cb(&ep->packet, ep->packet.complete_opaque); 
     140    } else if (ret == USB_RET_STALL) { 
     141        gadget_stall(ep->state, &ep->packet); 
     142    } else if (ret == USB_RET_ASYNC) { 
     143        ep->busy = 1; 
     144    } else { 
     145        fprintf(stderr, "%s: packet unhandled: %i\n", __FUNCTION__, ret); 
     146        if (ret != USB_RET_NAK) 
     147            gadget_detach(ep->state); 
     148    } 
     149} 
     150 
    125151static void gadget_respond(USBPacket *packet, void *opaque) 
    126152{ 
     
    142168{ 
    143169    struct ep_s *ep = (struct ep_s *) opaque; 
    144     if (packet->len > 0) 
    145         write(ep->fd, packet->data, packet->len); 
     170    ep->busy = 0; 
     171    while (write(ep->fd, packet->data, packet->len) < packet->len && 
     172                    errno == EINTR); 
    146173} 
    147174 
     
    161188    struct gadget_state_s *hci = ep->state; 
    162189 
     190    if (ep->busy) 
     191        return; 
     192 
    163193#if 0 
    164194    if (!gadget_ep_poll(opaque)) 
     
    167197 
    168198    /* write() is supposed to not block here */ 
    169     if (write(ep->fd, hci->buffer, 0)) 
     199    if (write(ep->fd, ep->buffer, 0)) 
    170200        return; 
    171201 
    172     if (hci->async_count) { 
    173         fprintf(stderr, "%s: overrun\n", __FUNCTION__); 
    174         gadget_detach(hci); 
    175         return; 
    176     } 
    177  
    178     hci->async_count = 1; 
    179  
    180     hci->packet->pid = USB_TOKEN_IN; 
    181     hci->packet->devaddr = hci->addr; 
    182     hci->packet->devep = ep->num; 
    183     hci->packet->data = hci->buffer; 
    184     hci->packet->len = sizeof(hci->buffer); 
    185     hci->packet->complete_cb = gadget_token_in; 
    186     hci->packet->complete_opaque = ep; 
    187  
    188     gadget_run(0, hci); 
     202    ep->packet.pid = USB_TOKEN_IN; 
     203    ep->packet.devaddr = hci->addr; 
     204    ep->packet.devep = ep->num; 
     205    ep->packet.data = ep->buffer; 
     206    ep->packet.len = sizeof(ep->buffer); 
     207    ep->packet.complete_cb = gadget_token_in; 
     208    ep->packet.complete_opaque = ep; 
     209 
     210    gadget_ep_run(ep); 
    189211} 
    190212 
    191213static void gadget_nop(USBPacket *prev_packet, void *opaque) 
    192214{ 
     215    ((struct ep_s *) opaque)->busy = 0; 
    193216} 
    194217 
     
    199222    int ret; 
    200223 
    201     ret = read(ep->fd, hci->buffer, sizeof(hci->buffer)); 
     224    if (ep->busy) 
     225        return; 
     226 
     227    ret = read(ep->fd, ep->buffer, sizeof(ep->buffer)); 
    202228    if (ret <= 0) 
    203229        return; 
    204230 
    205     if (hci->async_count) { 
    206         fprintf(stderr, "%s: overrun\n", __FUNCTION__); 
    207         gadget_detach(hci); 
    208         return; 
    209     } 
    210  
    211     hci->async_count = 1; 
    212  
    213     hci->packet->pid = USB_TOKEN_OUT; 
    214     hci->packet->devaddr = hci->addr; 
    215     hci->packet->devep = ep->num; 
    216     hci->packet->data = hci->buffer; 
    217     hci->packet->len = ret; 
    218     hci->packet->complete_cb = gadget_nop; 
    219     hci->packet->complete_opaque = ep; 
    220  
    221     gadget_run(0, hci); 
     231    ep->packet.pid = USB_TOKEN_OUT; 
     232    ep->packet.devaddr = hci->addr; 
     233    ep->packet.devep = ep->num; 
     234    ep->packet.data = ep->buffer; 
     235    ep->packet.len = ret; 
     236    ep->packet.complete_cb = gadget_nop; 
     237    ep->packet.complete_opaque = ep; 
     238 
     239    gadget_ep_run(ep); 
    222240} 
    223241 
     
    268286        goto fail; 
    269287    } 
     288 
     289    ep->busy = 0; 
    270290 
    271291    if (desc->bEndpointAddress & USB_DIR_IN) 
     
    472492    req->bRequestType = USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE; 
    473493    req->bRequest = USB_REQ_GET_DESCRIPTOR; 
    474     req->wValue = (USB_DT_CONFIG << 8) | 0; 
     494    req->wValue = (USB_DT_CONFIG << 8) | hci->config_num; 
    475495    req->wIndex = 0x0000; 
    476496    req->wLength = sizeof(hci->buffer); 
     
    496516    int ret, len; 
    497517 
    498     if (!s->connected) 
     518    if (!s->addr) 
    499519        return; 
    500520 
     
    526546        s->async_count = 2; 
    527547 
    528         memcpy(s->buffer, &event.u.setup, 8); 
     548        memcpy(s->buffer, &event.u.setup, sizeof(event.u.setup)); 
    529549        s->packet[1].pid = USB_TOKEN_SETUP; 
    530550        s->packet[1].devaddr = s->addr; 
    531551        s->packet[1].devep = 0; 
    532552        s->packet[1].data = s->buffer; 
    533         s->packet[1].len = 8; 
     553        s->packet[1].len = sizeof(event.u.setup); 
    534554        s->packet[1].complete_cb = gadget_run; 
    535555        s->packet[1].complete_opaque = s; 
     
    718738 
    719739    hci->addr = 0; 
     740    hci->config_num = 0; 
    720741 
    721742    qemu_register_usb_port(&hci->port, hci, USB_INDEX_HOST, gadget_attach); 
  • trunk/src/host/qemu-neo1973/vl.h

    r1898 r1914  
    14601460#include "hw/i2c.h" 
    14611461 
    1462 #define unlikely(cond)  __builtin_expect(cond, 0) 
     1462#define unlikely(cond)  __builtin_expect(!!(cond), 0) 
    14631463 
    14641464#ifdef TARGET_ARM 
Note: See TracChangeset for help on using the changeset viewer.