static void isp_update_otg(struct isp1301 *isp, u8 stat) { u8 isp_stat, isp_bstat; enum usb_otg_state state = isp->otg.state; if (stat & INTR_BDIS_ACON) pr_debug("OTG: BDIS_ACON, %s\n", state_name(isp)); /* start certain state transitions right away */ isp_stat = isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE); if (isp_stat & INTR_ID_GND) { if (isp->otg.default_a) { switch (state) { case OTG_STATE_B_IDLE: a_idle(isp, "idle"); /* FALLTHROUGH */ case OTG_STATE_A_IDLE: enable_vbus_source(isp); /* FALLTHROUGH */ case OTG_STATE_A_WAIT_VRISE: /* we skip over OTG_STATE_A_WAIT_BCON, since * the HC will transition to A_HOST (or * A_SUSPEND!) without our noticing except * when HNP is used. */ if (isp_stat & INTR_VBUS_VLD) isp->otg.state = OTG_STATE_A_HOST; break; case OTG_STATE_A_WAIT_VFALL: if (!(isp_stat & INTR_SESS_VLD)) a_idle(isp, "vfell"); break; default: if (!(isp_stat & INTR_VBUS_VLD)) isp->otg.state = OTG_STATE_A_VBUS_ERR; break; } isp_bstat = isp1301_get_u8(isp, ISP1301_OTG_STATUS); } else { switch (state) { case OTG_STATE_B_PERIPHERAL: case OTG_STATE_B_HOST: case OTG_STATE_B_WAIT_ACON: usb_gadget_vbus_disconnect(isp->otg.gadget); break; default: break; } if (state != OTG_STATE_A_IDLE) a_idle(isp, "id"); if (isp->otg.host && state == OTG_STATE_A_IDLE) isp1301_defer_work(isp, WORK_HOST_RESUME); isp_bstat = 0; } } else { /* if user unplugged mini-A end of cable, * don't bypass A_WAIT_VFALL. */ if (isp->otg.default_a) { switch (state) { default: isp->otg.state = OTG_STATE_A_WAIT_VFALL; break; case OTG_STATE_A_WAIT_VFALL: state = OTG_STATE_A_IDLE; /* khubd may take a while to notice and * handle this disconnect, so don't go * to B_IDLE quite yet. */ break; case OTG_STATE_A_IDLE: host_suspend(isp); isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_BDIS_ACON_EN); isp->otg.state = OTG_STATE_B_IDLE; OTG_CTRL_REG &= OTG_CTRL_REG & OTG_CTRL_MASK & ~OTG_CTRL_BITS; break; case OTG_STATE_B_IDLE: break; } } isp_bstat = isp1301_get_u8(isp, ISP1301_OTG_STATUS); switch (isp->otg.state) { case OTG_STATE_B_PERIPHERAL: case OTG_STATE_B_WAIT_ACON: case OTG_STATE_B_HOST: if (likely(isp_bstat & OTG_B_SESS_VLD)) break; enable_vbus_draw(isp, 0); #ifndef CONFIG_USB_OTG /* UDC driver will clear OTG_BSESSVLD */ isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_DP_PULLDOWN); isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_DP_PULLUP); dump_regs(isp, __FUNCTION__); #endif /* FALLTHROUGH */ case OTG_STATE_B_SRP_INIT: b_idle(isp, __FUNCTION__); OTG_CTRL_REG &= OTG_CTRL_REG & OTG_XCEIV_OUTPUTS; /* FALLTHROUGH */ case OTG_STATE_B_IDLE: if (isp->otg.gadget && (isp_bstat & OTG_B_SESS_VLD)) { #ifdef CONFIG_USB_OTG update_otg1(isp, isp_stat); update_otg2(isp, isp_bstat); #endif b_peripheral(isp); } else if (!(isp_stat & (INTR_VBUS_VLD|INTR_SESS_VLD))) isp_bstat |= OTG_B_SESS_END; break; case OTG_STATE_A_WAIT_VFALL: break; default: pr_debug("otg: unsupported b-device %s\n", state_name(isp)); break; } } if (state != isp->otg.state) pr_debug(" isp, %s -> %s\n", state_string(state), state_name(isp)); #ifdef CONFIG_USB_OTG /* update the OTG controller state to match the isp1301; may * trigger OPRT_CHG irqs for changes going to the isp1301. */ update_otg1(isp, isp_stat); update_otg2(isp, isp_bstat); check_state(isp, __FUNCTION__); #endif dump_regs(isp, "isp1301->otg"); }
/* no error returns, they'd just make bus scanning stop */ static int isp1301_probe(struct i2c_adapter *bus, int address, int kind) { int status; struct isp1301 *isp; struct i2c_client *i2c; if (the_transceiver) return 0; isp = kcalloc(1, sizeof *isp, GFP_KERNEL); if (!isp) return 0; INIT_WORK(&isp->work, isp1301_work, isp); init_timer(&isp->timer); isp->timer.function = isp1301_timer; isp->timer.data = (unsigned long) isp; isp->irq = -1; isp->client.addr = address; i2c_set_clientdata(&isp->client, isp); isp->client.adapter = bus; isp->client.driver = &isp1301_driver; strlcpy(isp->client.name, DRIVER_NAME, I2C_NAME_SIZE); i2c = &isp->client; /* if this is a true probe, verify the chip ... */ if (kind < 0) { status = isp1301_get_u16(isp, ISP1301_VENDOR_ID); if (status != I2C_VENDOR_ID_PHILIPS) { dev_dbg(&bus->dev, "addr %d not philips id: %d\n", address, status); goto fail1; } status = isp1301_get_u16(isp, ISP1301_PRODUCT_ID); if (status != I2C_PRODUCT_ID_PHILIPS_1301) { dev_dbg(&bus->dev, "%d not isp1301, %d\n", address, status); goto fail1; } } status = i2c_attach_client(i2c); if (status < 0) { dev_dbg(&bus->dev, "can't attach %s to device %d, err %d\n", DRIVER_NAME, address, status); fail1: kfree(isp); return 0; } isp->i2c_release = i2c->dev.release; i2c->dev.release = isp1301_release; /* initial development used chiprev 2.00 */ status = i2c_smbus_read_word_data(i2c, ISP1301_BCD_DEVICE); dev_info(&i2c->dev, "chiprev %x.%02x, driver " DRIVER_VERSION "\n", status >> 8, status & 0xff); /* make like power-on reset */ isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_MASK); isp1301_set_bits(isp, ISP1301_MODE_CONTROL_2, MC2_BI_DI); isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_2, ~MC2_BI_DI); isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_DM_PULLDOWN | OTG1_DP_PULLDOWN); isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, ~(OTG1_DM_PULLDOWN | OTG1_DP_PULLDOWN)); isp1301_clear_bits(isp, ISP1301_INTERRUPT_LATCH, ~0); isp1301_clear_bits(isp, ISP1301_INTERRUPT_FALLING, ~0); isp1301_clear_bits(isp, ISP1301_INTERRUPT_RISING, ~0); #ifdef CONFIG_USB_OTG status = otg_bind(isp); if (status < 0) { dev_dbg(&i2c->dev, "can't bind OTG\n"); goto fail2; } #endif if (machine_is_omap_h2()) { /* full speed signaling by default */ isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_SPEED_REG); isp1301_set_bits(isp, ISP1301_MODE_CONTROL_2, MC2_SPD_SUSP_CTRL); /* IRQ wired at M14 */ omap_cfg_reg(M14_1510_GPIO2); isp->irq = OMAP_GPIO_IRQ(2); omap_request_gpio(2); omap_set_gpio_direction(2, 1); omap_set_gpio_edge_ctrl(2, OMAP_GPIO_FALLING_EDGE); } status = request_irq(isp->irq, isp1301_irq, SA_SAMPLE_RANDOM, DRIVER_NAME, isp); if (status < 0) { dev_dbg(&i2c->dev, "can't get IRQ %d, err %d\n", isp->irq, status); #ifdef CONFIG_USB_OTG fail2: #endif i2c_detach_client(i2c); goto fail1; } isp->otg.dev = &isp->client.dev; isp->otg.label = DRIVER_NAME; isp->otg.set_host = isp1301_set_host, isp->otg.set_peripheral = isp1301_set_peripheral, isp->otg.set_power = isp1301_set_power, isp->otg.start_srp = isp1301_start_srp, isp->otg.start_hnp = isp1301_start_hnp, enable_vbus_draw(isp, 0); power_down(isp); the_transceiver = isp; #ifdef CONFIG_USB_OTG update_otg1(isp, isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE)); update_otg2(isp, isp1301_get_u8(isp, ISP1301_OTG_STATUS)); #endif dump_regs(isp, __FUNCTION__); #ifdef VERBOSE mod_timer(&isp->timer, jiffies + TIMER_JIFFIES); dev_dbg(&i2c->dev, "scheduled timer, %d min\n", TIMER_MINUTES); #endif status = otg_set_transceiver(&isp->otg); if (status < 0) dev_err(&i2c->dev, "can't register transceiver, %d\n", status); return 0; }
/* inputs going to ISP1301 */ static void otg_update_isp(struct isp1301 *isp) { u32 otg_ctrl, otg_change; u8 set = OTG1_DM_PULLDOWN, clr = OTG1_DM_PULLUP; otg_ctrl = OTG_CTRL_REG; otg_change = otg_ctrl ^ isp->last_otg_ctrl; isp->last_otg_ctrl = otg_ctrl; otg_ctrl = otg_ctrl & OTG_XCEIV_INPUTS; switch (isp->otg.state) { case OTG_STATE_B_IDLE: case OTG_STATE_B_PERIPHERAL: case OTG_STATE_B_SRP_INIT: if (!(otg_ctrl & OTG_PULLUP)) { // if (otg_ctrl & OTG_B_HNPEN) { if (isp->otg.gadget->b_hnp_enable) { isp->otg.state = OTG_STATE_B_WAIT_ACON; pr_debug(" --> b_wait_acon\n"); } goto pulldown; } pullup: set |= OTG1_DP_PULLUP; clr |= OTG1_DP_PULLDOWN; break; case OTG_STATE_A_SUSPEND: case OTG_STATE_A_PERIPHERAL: if (otg_ctrl & OTG_PULLUP) goto pullup; /* FALLTHROUGH */ // case OTG_STATE_B_WAIT_ACON: default: pulldown: set |= OTG1_DP_PULLDOWN; clr |= OTG1_DP_PULLUP; break; } # define toggle(OTG,ISP) do { \ if (otg_ctrl & OTG) set |= ISP; \ else clr |= ISP; \ } while (0) if (!(isp->otg.host)) otg_ctrl &= ~OTG_DRV_VBUS; switch (isp->otg.state) { case OTG_STATE_A_SUSPEND: if (otg_ctrl & OTG_DRV_VBUS) { set |= OTG1_VBUS_DRV; break; } /* HNP failed for some reason (A_AIDL_BDIS timeout) */ notresponding(isp); /* FALLTHROUGH */ case OTG_STATE_A_VBUS_ERR: isp->otg.state = OTG_STATE_A_WAIT_VFALL; pr_debug(" --> a_wait_vfall\n"); /* FALLTHROUGH */ case OTG_STATE_A_WAIT_VFALL: /* FIXME usbcore thinks port power is still on ... */ clr |= OTG1_VBUS_DRV; break; case OTG_STATE_A_IDLE: if (otg_ctrl & OTG_DRV_VBUS) { isp->otg.state = OTG_STATE_A_WAIT_VRISE; pr_debug(" --> a_wait_vrise\n"); } /* FALLTHROUGH */ default: toggle(OTG_DRV_VBUS, OTG1_VBUS_DRV); } toggle(OTG_PU_VBUS, OTG1_VBUS_CHRG); toggle(OTG_PD_VBUS, OTG1_VBUS_DISCHRG); # undef toggle isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, set); isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, clr); /* HNP switch to host or peripheral; and SRP */ if (otg_change & OTG_PULLUP) { switch (isp->otg.state) { case OTG_STATE_B_IDLE: if (clr & OTG1_DP_PULLUP) break; isp->otg.state = OTG_STATE_B_PERIPHERAL; pr_debug(" --> b_peripheral\n"); break; case OTG_STATE_A_SUSPEND: if (clr & OTG1_DP_PULLUP) break; isp->otg.state = OTG_STATE_A_PERIPHERAL; pr_debug(" --> a_peripheral\n"); break; default: break; } OTG_CTRL_REG |= OTG_PULLUP; } check_state(isp, __FUNCTION__); dump_regs(isp, "otg->isp1301"); }
/** * @brief Print out a bunch of debug information on the console */ void unipro_info(void) { dump_regs(); }
static void isp1301_work(void *data) { struct isp1301 *isp = data; int stop; /* implicit lock: we're the only task using this device */ isp->working = 1; do { stop = test_bit(WORK_STOP, &isp->todo); #ifdef CONFIG_USB_OTG /* transfer state from otg engine to isp1301 */ if (test_and_clear_bit(WORK_UPDATE_ISP, &isp->todo)) { otg_update_isp(isp); put_device(&isp->client.dev); } #endif /* transfer state from isp1301 to otg engine */ if (test_and_clear_bit(WORK_UPDATE_OTG, &isp->todo)) { u8 stat = isp1301_clear_latch(isp); isp_update_otg(isp, stat); put_device(&isp->client.dev); } if (test_and_clear_bit(WORK_HOST_RESUME, &isp->todo)) { u32 otg_ctrl; /* * skip A_WAIT_VRISE; hc transitions invisibly * skip A_WAIT_BCON; same. */ switch (isp->otg.state) { case OTG_STATE_A_WAIT_BCON: case OTG_STATE_A_WAIT_VRISE: isp->otg.state = OTG_STATE_A_HOST; pr_debug(" --> a_host\n"); otg_ctrl = OTG_CTRL_REG; otg_ctrl |= OTG_A_BUSREQ; otg_ctrl &= ~(OTG_BUSDROP|OTG_B_BUSREQ) & OTG_CTRL_MASK; OTG_CTRL_REG = otg_ctrl; break; case OTG_STATE_B_WAIT_ACON: isp->otg.state = OTG_STATE_B_HOST; pr_debug(" --> b_host (acon)\n"); break; case OTG_STATE_B_HOST: case OTG_STATE_B_IDLE: case OTG_STATE_A_IDLE: break; default: pr_debug(" host resume in %s\n", state_name(isp)); } host_resume(isp); // mdelay(10); put_device(&isp->client.dev); } if (test_and_clear_bit(WORK_TIMER, &isp->todo)) { #ifdef VERBOSE dump_regs(isp, "timer"); if (!stop) mod_timer(&isp->timer, jiffies + TIMER_JIFFIES); #endif put_device(&isp->client.dev); } if (isp->todo) dev_vdbg(&isp->client.dev, "work done, todo = 0x%lx\n", isp->todo); if (stop) { dev_dbg(&isp->client.dev, "stop\n"); break; } } while (isp->todo); isp->working = 0; }
/*----------------------------------------------------------------------*/ void send_handler(struct event_control *lecb) { extern fd_set *rdfds, *wrfds; const struct event *evt = 0; int rc = 0; int event_processed = 1; int save_errno = 0; int sd; struct info *ip; int called_explicitly = 0; int events; int evt_count; int fake_events = 0; int trace_fd = 0; static int init_done = 0; int i; int buf_index = -1; int listen_sd = -1; if (!init_done) { for (i = 0; i < EVT_BUFS_MAX; i++) { saved_tail[i] = -1; } init_done = 1; } if (options.send_loop) { should_process_sds = 1; } else { should_process_sds = 0; } consecutive = 0; send_handler_evts_done = 0; in_handler = 1; /* turn off notification while processing the event */ ecb->notify = SIG_GRP; if (lecb == NULL) { called_explicitly = 1; PRINT_TIME(NOFD, &tnow, &tprev, "---> send_handler: entered handler explicitly"); lecb = ecb; DEBG(MSG_SEND, "send_handler: lecb was NULL\n"); DEBG(MSG_SEND, "send_handler: lecb now = %p\n", lecb); DEBG(MSG_SEND, "send_handler: lecb->regs = %p\n", lecb->regs); for (i = 0; i < EVT_BUFS; i++) { DEBG(MSG_SEND, "send_handler: lecb->head[%d] = %d lecb->tail[%d] = %d\n", i, lecb->head[i], i, lecb->tail[i]); } t = bogus_regs; num_send_handler_calls++; } else { PRINT_TIME(NOFD, &tnow, &tprev, "---> send_handler: entered thru interrupt"); for (i = 0; i < EVT_BUFS; i++) { DEBG(MSG_SEND, "send_handler: lecb->head[%d] = %d lecb->tail[%d] = %d\n", i, lecb->head[i], i, lecb->tail[i]); } DEBG(MSG_SEND, "send_handler: lecb->regs = %p\n", lecb->regs); num_send_handler_interrupts++; t = lecb->regs; } /* Changed to permit calling handler explicitly */ DEBG(MSG_SEND, "send_handler: setting lecb->regs = 0xffffffff\n"); lecb->regs = (void *) 0xffffffff; save_errno = errno; if (t != bogus_regs && t != 0) { if (t->reason > 0 && t->eax < 0) { DEBG(MSG_SEND, "send_handler: syscall failure: reason = %i\n", t->reason); dump_regs(t); dump_stack(t); } send_errno = (int) t->eax; } else { send_errno = 0; } DEBG(MSG_SEND, "send_handler: send_errno = %d\n", send_errno); /* either entering a critical section or in one so we just leave handler */ if ((entering_cs || in_cs) && (!called_explicitly)) { PRINT_TIME(NOFD, &tnow, &tprev, "<--- send_handler: race detected\n"); num_sigio_races++; send_intrs_to_handle++; goto get_out; } if ((!new_connections_on || sigio_blocked) && (!called_explicitly)) { PRINT_TIME(NOFD, &tnow, &tprev, "<--- send_handler: race detected - new connections not on\n"); num_sigio_false++; send_intrs_to_handle++; goto get_out; } if (num_idle <= options.free_fd_thold) { DEBG(MSG_SEND, "WARNING! send_handler: entered num_idle = %d and " "thold = %d\n", num_idle, options.free_fd_thold); } for (i = 0; i < EVT_BUFS_MAX; i++) { saved_tail[i] = lecb->tail[i]; } consecutive = 0; while (!(bufs_empty())) { /* decide which of the event buffers to process */ buf_index = which_buf_to_process(buf_index); while ((!buf_is_empty(buf_index)) && (event_processed)) { PRINT_TIME(NOFD, &tnow, &tprev, "send_handler: at top of loop"); event_processed = 0; conns_off_if_needed(); evt_count = num_evts_array(); PRINT_TIME(NOFD, &tnow, &tprev, "send_handler: evt_count = %d", evt_count); for (i = 0; i < EVT_BUFS; i++) { PRINT_TIME(NOFD, &tnow, &tprev, "send_handler: head[%d] = %d tail[%d] = %d", i, lecb->head[i], i, lecb->tail[i]); } PRINT_TIME(NOFD, &tnow, &tprev, "send_handler: missed = %d", ecb->missed_events); #ifdef ONE_LISTENER #ifdef TBB_KINFO if (kinfo) { PRINT_TIME(NOFD, &tnow, &tprev, "send_handler: " "kinfo->qlen_young = %d kinfo->qlen = %d", kinfo->qlen_young, kinfo->qlen); PRINT_TIME(NOFD, &tnow, &tprev, "send_handler: syscall " "qlen_young = %d qlen = %d", qlen_young(server_sd), qlen(server_sd)); PRINT_TIME(NOFD, &tnow, &tprev, "send_handler: qlen_listenq = %d", qlen_listenq(server_sd)); } #endif /* TBB_KINFO */ #endif /* ONE_LISTENER */ evt = get_next_event(lecb, &buf_index); #ifdef DEBUG_ON verify_evt_array(evt, buf_index); #endif if ((MSG_MASK & MSG_TIME) || (MSG_MASK & MSG_SEND)) { print_event(evt, t); } #ifdef ARRAY_OF_BUFS num_events[buf_index]++; #else num_events++; #endif /* ARRAY_OF_BUFS */ switch (evt->type) { case EVT_SIG: /* XXX: for now - turn off notification and delivery */ /* because we are just going to print out some stats and exit */ ecb->notify = 0; ecb->queue = 0; num_evt_sig++; event_processed = 1; PRINT_TIME(NOFD, &tnow, &tprev, "send_handler: Processing EVT_SIG"); DEBG(MSG_SEND, "send_handler: Processing EVT_SIG\n"); DEBG(MSG_SEND, "send_handler: Received event: type = %d " "id = %d\n", evt->type, evt->event_id); if (t != bogus_regs) { PRINT_TIME(NOFD, &tnow, &tprev, "send_handler: eip = %p", t->eip); DEBG(MSG_SEND, "send_handler: Received event: eip = %p\n", t->eip); } if (sigs[evt->event_id] && sigs[evt->event_id] != (sighandlerfn_t) (-1)) { PRINT_TIME(NOFD, &tnow, &tprev, "send_handler: signal = %d calling handler", evt->event_id); sigs[evt->event_id] (0, evt); } else if (sigs[evt->event_id] != (sighandlerfn_t) (-1)) { DEBG(MSG_SEND, "send_handler: No handler for %i\n", evt->event_id); printf("send_handler: No handler for %i\n", evt->event_id); fflush(stdout); event_processed = 1; if (t) { dump_regs(t); } print_event(evt, t); exit(1); } else { printf("send_handler: evt->event_id = %d " "sigs[evt->event_id] = %p\n", evt->event_id, sigs[evt->event_id]); fflush(stdout); /* event_processed = 1; */ if (t) { dump_regs(t); } print_event(evt, t); exit(1); } break; case EVT_MSG: num_evt_msg++; DEBG(MSG_SEND, "send_handler: Processing message from: %i\n", evt->event_id); /* * A previous read call failed (EAGAIN) even though the event * was generated saying that the socket was ready. * So for now this is a work around where we've been * sent a message saying that we need to re-read * from the socket indicated in the msg. */ if ((int) evt->data.msg.data > 0) { sd = (int) evt->data.msg.data; ip = info_ptr(sd); assert(ip); fake_events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLREADRETRY; rc = send_do_io(sd, ip, fake_events); } event_processed = 1; break; case EVT_IPACCEPT: num_evt_ipaccept++; /* TODO: not sure this is in the right place? */ PRINT_TIME(NOFD, &tnow, &tprev, "send_handler: consecutive = %d num_idle = %d", consecutive, num_idle); sd = evt->data.ipa.fd; num_accept_calls++; PRINT_TIME(NOFD, &tnow, &tprev, "send_handler: Processing EVT_IPACCEPT sd = %d", sd); if (sd < 0) { /* In this case the sd contains the negated errno */ process_accept_errs(sd, -sd); event_processed = 1; } else { events = evt->data.io.events; if (events & POLLFIN) { /* * We are going to bypass doing a bunch of work * on a socket that has already been closed by * the client. So first we have to do a bit of * setup that subsequent code depends on (preconditions) */ ip = info_add(sd); ip->sd = sd; set_fsm_state(ip, FSM_CONNECTING); num_connections++; num_accept_successful++; num_idle--; if (num_idle == options.free_fd_thold) { PRINT_TIME(sd, &tnow, &tprev, "send_handler: ATTENTION: NUM_IDLE == %d", options.free_fd_thold); } PRINT_TIME(sd, &tnow, &tprev, "send_handler: POLL_FIN " "calling do_close"); num_close_send_early_fin++; rc = do_close(ip, REASON_SEND_POLL_FIN); event_processed = 1; } else { assert(sd <= max_fds); assert(sd > min_usable_sd); ip = info_add(sd); ip->sd = sd; set_fsm_state(ip, FSM_CONNECTING); /* Eventually we should add this to SEND */ /* listen_sd = evt->data.ipa.parent_fd; */ listen_sd = SOCK_LISTENER_USE_UNKNOWN; event_processed = send_handle_new_conn(evt, listen_sd, sd, should_process_sds); #ifdef NOT_SURE if ((options.do_multiaccept == 0 && consecutive == 1) || ((options.multiaccept_max != OPT_MULTIACCEPT_MAX_UNLIMITED) && (consecutive >= options.multiaccept_max))) { PRINT_TIME(NOFD, &tnow, &tprev, "send_handler: reached max accepts"); socket_new_conn_off(); } #endif /* if the socket is has data to be read go ahead and * read it */ if (!options.accepts_only && should_process_sds) { if (event_processed && evt->data.io.events & POLLIN) { /* TODO: this may be wrong as the event has been * processed * event_processed = * send_do_io(sd, ip, evt->data.io.events); */ rc = send_do_io(sd, ip, evt->data.io.events); } } } /* else */ } /* else */ break; case EVT_IOREADY: num_evt_ioready++; /* TODO: not sure this is in the right place? */ PRINT_TIME(NOFD, &tnow, &tprev, "send_handler: consecutive = %d num_idle = %d", consecutive, num_idle); sd = evt->data.io.fd; events = evt->data.io.events; PRINT_TIME(sd, &tnow, &tprev, "send_handler: Processing EVT_IOREADY"); if (sd < 0) { PRINT_TIME(sd, &tnow, &tprev, "send_handler: Processing EVT_IOREADY"); printf("send_handler: got negative sd on EVT_IOREADY\n"); print_event(evt, t); event_processed = 1; } else if (sock_is_listener(sd)) { if (events & POLLIN) { listen_sd = sd; ip = info_add(sd); event_processed = send_handle_new_conn(evt, listen_sd, sd, should_process_sds); /* TODO: This is just to test if it changes anything */ /* send_async_setup(sd); */ } else { PRINT_TIME(sd, &tnow, &tprev, "send_handler: listener_sd EVT_IOREADY but POLLIN " "is not set events = 0x%x", events); /* is pollhint set and nothing else */ if ((events | POLLHINT) == POLLHINT) { PRINT_TIME(sd, &tnow, &tprev, "send_handler: listener_sd no POLLIN but POLLHINT"); num_pollhint_server_consumed++; } event_processed = 1; } } else { if (!options.accepts_only && should_process_sds) { ip = info_ptr(sd); assert(ip); event_processed = send_do_io(sd, ip, events); if (!event_processed) { printf("send_handler: event not processed\n"); print_event(evt, t); exit(1); } } else { PRINT_TIME(sd, &tnow, &tprev, "send_handler: skipping events 0x%x", events); PRINT_TIME(sd, &tnow, &tprev, "send_handler: accepts_only = %d " "should_process_sds = %d", options.accepts_only, should_process_sds); event_processed = 1; } } if (!event_processed) { printf("send_handler: event not processed\n"); print_event(evt, t); exit(1); } break; case EVT_DISPATCH: num_evt_dispatch++; DEBG(MSG_SEND, "send_handler: Processing EVT_DISPATCH\n"); case EVT_SYNCH: num_evt_synch++; DEBG(MSG_SEND, "send_handler: Processing EVT_SYNCH\n"); default: num_evt_unknown++; PRINT_TIME(NOFD, &tnow, &tprev, "send_handler: doing event"); DEBG(MSG_SEND, "send_handler: lecb->head[%d] = %d " "lecb->tail[%d] = %d lecb->event_list_size[%d] = %d\n", buf_index, lecb->head[buf_index], buf_index, lecb->tail[buf_index], buf_index, lecb->event_list_size[buf_index]); DEBG(MSG_SEND, "send_handler: evt->type = %d\n", evt->type); DEBG(MSG_SEND, "send_handler: Fell down into default\n"); print_event(evt, t); exit(1); break; } /* switch */ /* NEW */ /* Did not process the event this time around */ /* so leave it in the buffer/queue to be processed later */ if (event_processed) { /* num_events++; */ send_handler_evts_done++; ++lecb->head[buf_index]; DEBG(MSG_SEND, "send_handler: event processed head for %d now = %d\n", buf_index, lecb->head[buf_index]); /* evt->type= (u32) - 1; */ send_need_to_check_events = 0; } else { DEBG(MSG_SEND, "send_handler: event not processed head for %d still = %d\n", buf_index, lecb->head[buf_index]); PRINT_TIME(NOFD, &tnow, &tprev, "send_handler: event not processed head for %d still = %d\n", buf_index, lecb->head[buf_index]); printf("send_handler: event not processed head for %d still = %d\n", buf_index, lecb->head[buf_index]); send_need_to_check_events = 1; printf("send_handler: if EVT_IPACCEPT fd = %d\n", evt->data.ipa.fd); printf("send_handler: if EVT_IOREADY fd = %d\n", evt->data.io.fd); printf("send_handler: calling exit\n"); print_event(evt, t); exit(1); } DEBG(MSG_SEND, "send_handler: send_need_to_check_events = %d\n", send_need_to_check_events); PRINT_TIME(NOFD, &tnow, &tprev, "send_handler: at bottom of loop buf_index = %d " "head = %d tail = %d", buf_index, ecb->head[buf_index], ecb->tail[buf_index]); } /* while */ } /* while */ if (consecutive > num_max_consecutive_accepts) { num_max_consecutive_accepts = consecutive; } get_out: if (consecutive > 0) { if (options.use_memcpy) { memcpy(readable, rdfds, sizeof(fd_set)); memcpy(writable, wrfds, sizeof(fd_set)); } else { *readable = *rdfds; *writable = *wrfds; } if (options.process_sds_order == OPT_PROCESS_SDS_LIFO) { q_sync(Q_ADD_TO_FRONT); } else if (options.process_sds_order == OPT_PROCESS_SDS_FIFO) { q_sync(Q_ADD_TO_REAR); } } /* Changed to allow handler to be called explicitly. */ lecb->regs = NULL; if (t != bogus_regs) { if (t->reason > 0 && t->eax < 0) { DEBG(MSG_SEND, "send_handler: Syscall failure: %i\n", t->reason); dump_regs(t); dump_stack(t); exit(1); } send_errno = (int) t->eax; } else { send_errno = 0; } /* DEBG(MSG_SEND, "send_handler: About to do restore\n"); */ DEBG(MSG_SEND, "send_handler: send_errno = %d\n", send_errno); DEBG(MSG_SEND, "send_handler: save_errno = %d\n", save_errno); DEBG(MSG_SEND, "send_handler: send_need_to_check_events = %d\n", send_need_to_check_events); PRINT_TIME(NOFD, &tnow, &tprev, "send_handler: consecutive = %d evts_done = %d", consecutive, send_handler_evts_done); /* This was used for debugging */ /* memcpy(&old_regs, t, sizeof(old_regs)); */ /* old_regs_addr = t; */ errno = save_errno; if (t != bogus_regs) { PRINT_TIME(NOFD, &tnow, &tprev, "restore_thread: eip = %p", t->eip); PRINT_TIME(NOFD, &tnow, &tprev, "restore_thread: flags = %p", t->flags); TRACE(EVT_SENDHANDLER, trace_fd = 0; rc = send_handler_evts_done;);
/** * smc911x_eeprom - our application's main() function */ int smc911x_eeprom(int argc, char *argv[]) { /* Avoid initializing on stack as gcc likes to call memset() */ struct eth_device dev; dev.iobase = CONFIG_SMC911X_BASE; /* Print the ABI version */ app_startup(argv); if (XF_VERSION != get_version()) { printf("Expects ABI version %d\n", XF_VERSION); printf("Actual U-Boot ABI version %lu\n", get_version()); printf("Can't run\n\n"); return 1; } /* Initialize the MAC/EEPROM somewhat */ puts("\n"); if (smc911x_init(&dev)) return 1; /* Dump helpful usage information */ puts("\n"); usage(); puts("\n"); while (1) { char *line; /* Send the prompt and wait for a line */ puts("eeprom> "); line = getline(); /* Got a ctrl+c */ if (!line) return 0; /* Eat leading space */ line = skip_space(line); /* Empty line, try again */ if (!line[0]) continue; /* Only accept 1 letter commands */ if (line[0] && line[1] && line[1] != ' ' && line[1] != '\t') goto unknown_cmd; /* Now parse the command */ switch (line[0]) { case 'W': write_stuff(&dev, line); break; case 'D': dump_eeprom(&dev); break; case 'M': dump_regs(&dev); break; case 'C': copy_from_eeprom(&dev); break; case 'P': print_macaddr(&dev); break; unknown_cmd: default: puts("ERROR: Unknown command!\n\n"); case '?': case 'H': usage(); break; case 'Q': return 0; } } }
static void do_exception(struct irq_regs *regs) { printf("%s\n", exceptions[regs->irq_id]); dump_regs(regs); hang(); }
static int __devinit isp1301_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { int status; struct isp1301 *isp; if (the_transceiver) return 0; isp = kzalloc(sizeof *isp, GFP_KERNEL); if (!isp) return 0; INIT_WORK(&isp->work, isp1301_work); init_timer(&isp->timer); isp->timer.function = isp1301_timer; isp->timer.data = (unsigned long) isp; i2c_set_clientdata(i2c, isp); isp->client = i2c; /* verify the chip (shouldn't be necessary) */ status = isp1301_get_u16(isp, ISP1301_VENDOR_ID); if (status != I2C_VENDOR_ID_PHILIPS) { dev_dbg(&i2c->dev, "not philips id: %d\n", status); goto fail; } status = isp1301_get_u16(isp, ISP1301_PRODUCT_ID); if (status != I2C_PRODUCT_ID_PHILIPS_1301) { dev_dbg(&i2c->dev, "not isp1301, %d\n", status); goto fail; } isp->i2c_release = i2c->dev.release; i2c->dev.release = isp1301_release; /* initial development used chiprev 2.00 */ status = i2c_smbus_read_word_data(i2c, ISP1301_BCD_DEVICE); dev_info(&i2c->dev, "chiprev %x.%02x, driver " DRIVER_VERSION "\n", status >> 8, status & 0xff); /* make like power-on reset */ isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_MASK); isp1301_set_bits(isp, ISP1301_MODE_CONTROL_2, MC2_BI_DI); isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_2, ~MC2_BI_DI); isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_DM_PULLDOWN | OTG1_DP_PULLDOWN); isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, ~(OTG1_DM_PULLDOWN | OTG1_DP_PULLDOWN)); isp1301_clear_bits(isp, ISP1301_INTERRUPT_LATCH, ~0); isp1301_clear_bits(isp, ISP1301_INTERRUPT_FALLING, ~0); isp1301_clear_bits(isp, ISP1301_INTERRUPT_RISING, ~0); #ifdef CONFIG_USB_OTG status = otg_bind(isp); if (status < 0) { dev_dbg(&i2c->dev, "can't bind OTG\n"); goto fail; } #endif if (machine_is_omap_h2()) { /* full speed signaling by default */ isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_SPEED); isp1301_set_bits(isp, ISP1301_MODE_CONTROL_2, MC2_SPD_SUSP_CTRL); /* IRQ wired at M14 */ omap_cfg_reg(M14_1510_GPIO2); if (gpio_request(2, "isp1301") == 0) gpio_direction_input(2); isp->irq_type = IRQF_TRIGGER_FALLING; } isp->irq_type |= IRQF_SAMPLE_RANDOM; status = request_irq(i2c->irq, isp1301_irq, isp->irq_type, DRIVER_NAME, isp); if (status < 0) { dev_dbg(&i2c->dev, "can't get IRQ %d, err %d\n", i2c->irq, status); goto fail; } isp->otg.dev = &i2c->dev; isp->otg.label = DRIVER_NAME; isp->otg.set_host = isp1301_set_host, isp->otg.set_peripheral = isp1301_set_peripheral, isp->otg.set_power = isp1301_set_power, isp->otg.start_srp = isp1301_start_srp, isp->otg.start_hnp = isp1301_start_hnp, enable_vbus_draw(isp, 0); power_down(isp); the_transceiver = isp; #ifdef CONFIG_USB_OTG update_otg1(isp, isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE)); update_otg2(isp, isp1301_get_u8(isp, ISP1301_OTG_STATUS)); #endif dump_regs(isp, __func__); #ifdef VERBOSE mod_timer(&isp->timer, jiffies + TIMER_JIFFIES); dev_dbg(&i2c->dev, "scheduled timer, %d min\n", TIMER_MINUTES); #endif status = otg_set_transceiver(&isp->otg); if (status < 0) dev_err(&i2c->dev, "can't register transceiver, %d\n", status); return 0; fail: kfree(isp); return -ENODEV; }
static int isp1301_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget) { struct isp1301 *isp = container_of(otg, struct isp1301, otg); #ifndef CONFIG_USB_OTG u32 l; #endif if (!otg || isp != the_transceiver) return -ENODEV; if (!gadget) { omap_writew(0, OTG_IRQ_EN); if (!isp->otg.default_a) enable_vbus_draw(isp, 0); usb_gadget_vbus_disconnect(isp->otg.gadget); isp->otg.gadget = NULL; power_down(isp); return 0; } #ifdef CONFIG_USB_OTG isp->otg.gadget = gadget; dev_dbg(&isp->client->dev, "registered gadget\n"); /* gadget driver may be suspended until vbus_connect () */ if (isp->otg.host) return isp1301_otg_enable(isp); return 0; #elif !defined(CONFIG_USB_OHCI_HCD) && !defined(CONFIG_USB_OHCI_HCD_MODULE) isp->otg.gadget = gadget; // FIXME update its refcount l = omap_readl(OTG_CTRL) & OTG_CTRL_MASK; l &= ~(OTG_XCEIV_OUTPUTS|OTG_CTRL_BITS); l |= OTG_ID; omap_writel(l, OTG_CTRL); power_up(isp); isp->otg.state = OTG_STATE_B_IDLE; if (machine_is_omap_h2() || machine_is_omap_h3()) isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0); isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING, INTR_SESS_VLD); isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, INTR_VBUS_VLD); dev_info(&isp->client->dev, "B-Peripheral sessions ok\n"); dump_regs(isp, __func__); /* If this has a Mini-AB connector, this mode is highly * nonstandard ... but can be handy for testing, so long * as you don't plug a Mini-A cable into the jack. */ if (isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE) & INTR_VBUS_VLD) b_peripheral(isp); return 0; #else dev_dbg(&isp->client->dev, "peripheral sessions not allowed\n"); return -EINVAL; #endif }