Ejemplo n.º 1
0
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");
}
Ejemplo n.º 2
0
/* 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;
}
Ejemplo n.º 3
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");
}
Ejemplo n.º 4
0
/**
 * @brief Print out a bunch of debug information on the console
 */
void unipro_info(void)
{
    dump_regs();
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
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;
		}
	}
}
Ejemplo n.º 8
0
static void do_exception(struct irq_regs *regs)
{
	printf("%s\n", exceptions[regs->irq_id]);
	dump_regs(regs);
	hang();
}
Ejemplo n.º 9
0
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;
}
Ejemplo n.º 10
0
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
}