Пример #1
0
void ControlReaderThread::setupRequest(void *data)
{
    struct usb_functionfs_event *e = (struct usb_functionfs_event *)data;

    /* USB Still Image Capture Device Definition, Section 5 */
    /* www.usb.org/developers/devclass_docs/usb_still_img10.pdf */

    //qDebug() << "bRequestType:" << e->u.setup.bRequestType;
    //qDebug() << "bRequest:" << e->u.setup.bRequest;
    //qDebug() << "wValue:" << e->u.setup.wValue;
    //qDebug() << "wIndex:" << e->u.setup.wIndex;
    //qDebug() << "wLength:" << e->u.setup.wLength;

    switch(e->u.setup.bRequest) {
    case PTP_REQ_GET_DEVICE_STATUS:
        if(e->u.setup.bRequestType == 0xa1)
            sendStatus(m_status);
        else
            stall((e->u.setup.bRequestType & USB_DIR_IN)>0);
        break;
    case PTP_REQ_CANCEL:
        emit cancelTransaction();
        break;
    case PTP_REQ_DEVICE_RESET:
        emit deviceReset();
        break;
    //case PTP_REQ_GET_EXTENDED_EVENT_DATA:
    default:
        stall((e->u.setup.bRequestType & USB_DIR_IN)>0);
        break;
    }
}
Пример #2
0
void
led_red_blink(int ms)
{
    led_red_on();
    stall(ms);
    led_red_off();
    stall(ms);
}
Пример #3
0
void
led_yellow_blink(int ms)
{
    led_yellow_on();
    stall(ms);
    led_yellow_off();
    stall(ms);
}
Пример #4
0
/*
 * Start a session and allocate a controlling terminal.
 * Only called by children of init after forking.
 */
static void
setctty(const char *name)
{
	int fd;

	revoke(name);
	if ((fd = open(name, O_RDWR)) == -1) {
		stall("can't open %s: %m", name);
		_exit(1);
	}
	if (login_tty(fd) == -1) {
		stall("can't get %s for controlling terminal: %m", name);
		_exit(1);
	}
}
Пример #5
0
/*
 * Start a session and allocate a controlling terminal.
 * Only called by children of init after forking.
 */
static void
open_console(void)
{
	int fd;

	/*
	 * Try to open /dev/console.  Open the device with O_NONBLOCK to
	 * prevent potential blocking on a carrier.
	 */
	revoke(_PATH_CONSOLE);
	if ((fd = open(_PATH_CONSOLE, O_RDWR | O_NONBLOCK)) != -1) {
		(void)fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_NONBLOCK);
		if (login_tty(fd) == 0)
			return;
		close(fd);
	}

	/* No luck.  Log output to file if possible. */
	if ((fd = open(_PATH_DEVNULL, O_RDWR)) == -1) {
		stall("cannot open null device.");
		_exit(1);
	}
	if (fd != STDIN_FILENO) {
		dup2(fd, STDIN_FILENO);
		close(fd);
	}
	fd = open(_PATH_INITLOG, O_WRONLY | O_APPEND | O_CREAT, 0644);
	if (fd == -1)
		dup2(STDIN_FILENO, STDOUT_FILENO);
	else if (fd != STDOUT_FILENO) {
		dup2(fd, STDOUT_FILENO);
		close(fd);
	}
	dup2(STDOUT_FILENO, STDERR_FILENO);
}
Пример #6
0
void parse_descriptor(void) {
  switch((SWAPENDIAN(pSetupPacket->wValue) & HI_BYTE) >> 8) {
  case DESCR_TYPE_DEVICE:
    descrbuffer = (uint8*)&(DeviceDescriptor);
    cbuff_tail = 0;
    if(SWAPENDIAN(pSetupPacket->wLength) < DeviceDescriptor.bLength)
      cbuff_head =SWAPENDIAN(pSetupPacket->wLength);
    else
      cbuff_head = DeviceDescriptor.bLength;
    send_config();
    break;

  case DESCR_TYPE_CONFIGURATION:
    descrbuffer = (uint8*)&(ConfigurationDescriptor);
    cbuff_tail = 0;			
    if(SWAPENDIAN(pSetupPacket->wLength) < sizeof(FULL_CONFIG))
      cbuff_head = SWAPENDIAN(pSetupPacket->wLength);
    else
      cbuff_head = sizeof(FULL_CONFIG);
    send_config();
    break;

  case DESCR_TYPE_STRING:
    switch(SWAPENDIAN(pSetupPacket->wValue) & LO_BYTE) {
    case STDENDPREQ_LANG:
      descrbuffer = (uint8*)&(LangDescriptor);
      cbuff_tail = 0;				
      if(SWAPENDIAN(pSetupPacket->wLength) < sizeof(LANG_DESCR))
        cbuff_head = SWAPENDIAN(pSetupPacket->wLength);
      else
        cbuff_head = LangDescriptor.bLength;
      send_config();
      break;
    case STDENDPREQ_PRODUCT:
      descrbuffer = (uint8*)&(DevStringDescriptor);
      cbuff_tail = 0;
      if(SWAPENDIAN(pSetupPacket->wLength) < sizeof(DEVSTRING_DESCR))
        cbuff_head = SWAPENDIAN(pSetupPacket->wLength);
      else
        cbuff_head = DevStringDescriptor.bLength;
      send_config();
      break;
				
    case STDENDPREQ_MANUF:
      descrbuffer = (uint8*)&(ManufStringDescriptor);
      cbuff_tail = 0;
      if(SWAPENDIAN(pSetupPacket->wLength) < sizeof(MANUFSTRING_DESCR))
        cbuff_head = SWAPENDIAN(pSetupPacket->wLength);
      else
        cbuff_head = ManufStringDescriptor.bLength;
      send_config();
      break;
					
    default:
      stall();
      break;
    }
  }
}
Пример #7
0
static uint32_t v_add(uint32_t in_x, uint32_t in_y) {
  x = in_x;
  y = in_y;
  run = 0;
  cycle();
  run = 1;
  do {
    cycle();
  } while (stall());
  return z();
}
Пример #8
0
void parse_device_setup(void) {
  switch(pSetupPacket->bReq) {
  case STDDEVREQ_SET_ADDR:
    address = (uint8)SWAPENDIAN(pSetupPacket->wValue);
    raw_send(ADD_UDATAEND0,0);
    break;
  case STDDEVREQ_GET_DESCR:
    parse_descriptor();
    break;
  case STDDEVREQ_GET_CONFIG:
    raw_send(ADD_UDATAEND0,0);
    break;
  case STDDEVREQ_SET_CONFIG:
    raw_send(ADD_UDATAEND0,0);
    switch(SWAPENDIAN(pSetupPacket->wValue)) {
    case 1:  /* we support only one config */
      R_UCR1 = TX1E;
      R_UCR2 = RX2E;
      sbuff_tail = sbuff_head = rbuff_tail = rbuff_head = 0;
      cbuff_tail = cbuff_head = 0;
      dev_configured = TRUE;
      rx_toggle = 0;
      break;
    case 0: /* if config is 0, we return to address state */
      R_UCR1 = 0x00;
      R_UCR2 = 0x00;
      dev_configured = FALSE;
      break;					
    default:
      stall();
      break;
    }			
    break;
  case STDDEVREQ_CLEAR_FEATURE:
  case STDDEVREQ_SET_FEATURE:
  case STDDEVREQ_SET_DESCR:
  default:
    stall();
    break;
  }
}
Пример #9
0
void parse_std_setup(void) {
  switch(pSetupPacket->bmReqType & REQ_MASK_RECIPIENT) {
  case REQ_RECIP_DEVICE:
    parse_device_setup();
    break;
  case REQ_RECIP_INTERFACE:
  case REQ_RECIP_ENDPOINT:
  case REQ_RECIP_OTHER:
  default:
    stall();
    break;
  }
}
Пример #10
0
void dataout_endp2(void) {
  R_UCR2 &= ~RX2E;
  R_UIR2 = RXD2FR;

  /* if toggle matches, get data*/
  if(rx_toggle == (R_USR1 & R2SEQ))
    receive_data();
  else
    stall();

  /* prepare next data toggle*/
  rx_toggle ^= R2SEQ;
  R_UCR2 = RX2E;
}
Пример #11
0
void parse_setup_packet(void) {
  pSetupPacket=(SETUP_REQ*)ADD_UDATAEND0;

  switch(pSetupPacket->bmReqType & REQ_MASK_TYPE) {
  case REQ_TYPE_STANDARD:
    parse_std_setup();
    break;
  case REQ_TYPE_CLASS:
  case REQ_TYPE_VENDOR:
  case REQ_TYPE_RESERVERD:
  default:
    stall();
    break;
  }
}
Пример #12
0
/*
 * Run a shell script.
 * Returns 0 on success, otherwise the next transition to enter:
 *  - single_user if fork/execv/waitpid failed, or if the script
 *    terminated with a signal or exit code != 0.
 *  - death_single if a SIGTERM was delivered to init(8).
 */
static state_func_t
run_script(const char *script)
{
	pid_t pid, wpid;
	int status;
	char *argv[4];
	const char *shell;
	struct sigaction sa;

	shell = get_shell();

	if ((pid = fork()) == 0) {
		sigemptyset(&sa.sa_mask);
		sa.sa_flags = 0;
		sa.sa_handler = SIG_IGN;
		sigaction(SIGTSTP, &sa, (struct sigaction *)0);
		sigaction(SIGHUP, &sa, (struct sigaction *)0);

		open_console();

		char _sh[]		= "sh";
		char _autoboot[]	= "autoboot";

		argv[0] = _sh;
		argv[1] = __DECONST(char *, script);
		argv[2] = runcom_mode == AUTOBOOT ? _autoboot : 0;
		argv[3] = 0;

		sigprocmask(SIG_SETMASK, &sa.sa_mask, (sigset_t *) 0);

#ifdef LOGIN_CAP
		setprocresources(RESOURCE_RC);
#endif
		execv(shell, argv);
		stall("can't exec %s for %s: %m", shell, script);
		_exit(1);	/* force single user mode */
	}
Пример #13
0
/*! \details This function handles the standard requests on endpoint 0.
 * This should be the default action for endpoint 0.  The default
 * action is set using usb_dev_init() with the following code
 * \code
 * usb_set_ep_action(USB_DEV_PORT, 0, usb_dev_std_setup);
 * \endcode
 *
 *
 */
int usb_dev_std_setup(void * context, const void * data /*! Callback data */){
	uint32_t event = (uint32_t)data;
	if ( event == USB_SETUP_EVENT ){
		usb_dev_std_setup_stage();
		usb_dev_std_ep0_data.cnt = usb_setup_pkt.wLength;
		if ( usb_setup_pkt.bmRequestType.bitmap_t.type == USB_DEV_REQUEST_STANDARD){
			switch (usb_setup_pkt.bRequest) {

			case USB_DEV_REQUEST_GET_STATUS:
				if (!usb_dev_std_req_get_status()) {
					stall(); return 1;
				}
				usb_dev_std_datain_stage();
				break;

			case USB_DEV_REQUEST_CLEAR_FEATURE:
				if (!usb_dev_std_reg_set_clrfeature(0)) {
					stall(); return 1;
				}
				usb_dev_std_statusin_stage();
				usb_feature_event();
				break;

			case USB_DEV_REQUEST_SET_FEATURE:
				if (!usb_dev_std_reg_set_clrfeature(1)) {
					stall(); return 1;
				}
				usb_dev_std_statusin_stage();
				usb_feature_event();
				break;

			case USB_DEV_REQUEST_SET_ADDRESS:
				if (!usb_dev_std_req_setaddr()) {
					stall(); return 1;
				}
				usb_dev_std_statusin_stage();
				break;

			case USB_DEV_REQUEST_GET_DESCRIPTOR:
				if (!usb_dev_std_req_getdesc()) {
					stall(); return 1;
				}
				usb_dev_std_datain_stage();
				break;

			case USB_DEV_REQUEST_SET_DESCRIPTOR:
				hwpl_usb_stallep(USB_DEV_PORT, (void*)0x00);
				usb_dev_std_ep0_data.cnt = 0;
				break;

			case USB_DEV_REQUEST_GET_CONFIGURATION:
				if (!usb_dev_std_req_getcfg()) {
					stall(); return 1;
				}
				usb_dev_std_datain_stage();
				break;

			case USB_DEV_REQUEST_SET_CONFIGURATION:
				if (!usb_dev_std_req_setcfg()) {
					stall(); return 1;
				}
				usb_dev_std_statusin_stage();
				usb_configure_event();
				break;

			case USB_DEV_REQUEST_GET_INTERFACE:
				if (!usb_dev_std_req_getinterface()) {
					stall(); return 1;
				}
				usb_dev_std_datain_stage();
				break;

			case USB_DEV_REQUEST_SET_INTERFACE:
				if (!usb_dev_std_req_setinterface()) {
					stall(); return 1;
				}
				usb_interface_event();
				usb_dev_std_statusin_stage();
				break;
			default:
				stall(); return 1;
			}

		} else if ( usb_setup_pkt.bmRequestType.bitmap_t.type == USB_DEV_REQUEST_CLASS ){

			switch (usb_setup_pkt.bmRequestType.bitmap_t.recipient) {

			case USB_DEV_REQUEST_TO_DEVICE:
				stall();
				return 1;

			case USB_DEV_REQUEST_TO_INTERFACE:

				if ( usb_dev_adc_if_req(event) ) return 1;
				if ( usb_dev_msc_if_req(event) ) return 1;
				if ( usb_dev_cdc_if_req(event) ) return 1;
				if ( usb_dev_hid_if_req(event) ) return 1;
				break;
			}

			stall();
			return 1;
		}

	} else if ( event == USB_OUT_EVENT ){
		if (usb_setup_pkt.bmRequestType.bitmap_t.dir == USB_DEV_REQUEST_HOST_TO_DEVICE) {

			if (usb_dev_std_ep0_data.cnt) {

				usb_dev_std_dataout_stage();
				if (usb_dev_std_ep0_data.cnt == 0){

					switch (usb_setup_pkt.bmRequestType.bitmap_t.type) {

					case USB_DEV_REQUEST_STANDARD:
						stall(); return 1;

					case USB_DEV_REQUEST_CLASS:
						if (1){

							switch (usb_setup_pkt.bmRequestType.bitmap_t.recipient) {
							case USB_DEV_REQUEST_TO_DEVICE:
								stall(); return 1;

							case USB_DEV_REQUEST_TO_INTERFACE:
								if ( usb_dev_adc_if_req(event) ) return 1;
								if ( usb_dev_msc_if_req(event) ) return 1;
								if ( usb_dev_cdc_if_req(event) ) return 1;
								if ( usb_dev_hid_if_req(event) ) return 1;

							case USB_DEV_REQUEST_TO_ENDPOINT:

							default:
								stall();
								return 1;
							}
							break;

							default:
								stall();
								return 1;
						}
						break;
					}

				}
			}
		} else {
			usb_dev_std_statusout_stage();
		}

	} else if ( event == USB_IN_EVENT){
		if (usb_setup_pkt.bmRequestType.bitmap_t.dir == USB_DEV_REQUEST_DEVICE_TO_HOST) {
			usb_dev_std_datain_stage();
		} else {
			if (usb_dev_std_addr & USB_ENDPOINT_IN) {
				usb_dev_std_addr &= 0x7F;
				hwpl_usb_setaddr(USB_DEV_PORT, (void*)((int)usb_dev_std_addr));
			}
		}
	} else if ( event == USB_OUT_EVENT_STALL){
		hwpl_usb_unstallep(USB_DEV_PORT, (void*)0x00);
	} else if ( event == USB_IN_EVENT_STALL ){
		hwpl_usb_unstallep(USB_DEV_PORT, (void*)(USB_ENDPOINT_IN|0x00));
	}

	return 1;
}
Пример #14
0
//====================================================================
//====================================================================
void L2_cache::process_client_request (Coh_msg* request, bool first)
{
    DBG_L2_CACHE_ID(cout, "process_client_request(), addr= " << hex << request->addr << dec << endl);


    /** This code may be modified in the future to enable parallel events while transient (read while waiting for previous read-unblock).  For the time being, just assume no parallel events for a single address */
    if (mshr->has_match(request->addr)) {
	DBG_L2_CACHE_ID(cout, "    PREV_PEND_STALL, addr= " << hex << request->addr << dec << endl);

	assert(first);
        stall (request, C_PREV_PEND_STALL);
	stats_PREV_PEND_STALLs++;
        return;
    }


    // IMPORTANT: it's important to also check the stall buffer for requests for the same line.
    if(first) {
	if(stall_buffer_has_match(request->addr)) {
	    stall (request, C_PREV_PEND_STALL);
	    stats_PREV_PEND_STALLs++;
	    return;
	}
    }



    /** Assumption; all requests require an MSHR, even those that have enough permissions to hit (because of potential for transient while waiting for unblock messages)*/
    hash_entry* mshr_entry = mshr->reserve_block_for(request->addr);

    if (mshr_entry == 0)
    {
	DBG_L2_CACHE_ID(cout, "  MSHR_STALL, addr= " << hex << request->addr << dec << endl);

	assert(first);
        stall (request, C_MSHR_STALL);
	stats_MSHR_STALLs++;
        return;
    }
   

    mshr_map[mshr_entry->get_idx()] = 0;
    hash_entry* hash_table_entry = 0;



    /** Miss logic. */
    if (!my_table->has_match (request->addr))
    {
	DBG_L2_CACHE(cout, "    L2_cache: request is miss.\n");

	//first check if request is an invalidation request; a missed invalidation request should
	//be ignored.
	if(managers[0]->is_invalidation_request(request)) {
	    DBG_L2_CACHE(cout, "    L2_cache: a missed invalidation request; ignore it.\n");

	    mshr_entry->invalidate();
	    delete request;
	    return;
	}


        /** Check if an invalid block exists already or the LRU block can begin eviction. */
	hash_table_entry = my_table->reserve_block_for (request->addr);

        if (hash_table_entry != 0)
        {
	    mshr_map[mshr_entry->get_idx()] = hash_table_entry;
            L2_algorithm (mshr_entry, request);
        } 
        else { //no hash entry available, eviction required.
	    hash_entry* victim = my_table->get_replacement_entry(request->addr);
	    ManagerInterface* victim_manager = managers[victim->get_idx()];


	    if (victim_manager->req_pending() == false && mcp_stalled_req[victim_manager->getManagerID()] == 0)
	    {
	    //The 2nd part of the if statement is necessary because a manager could be in I state and waiting for
	    //data from memory.

	    DBG_L2_CACHE(cout, "    L2_cache start replacement, victim line addr= " <<hex<< victim->get_line_addr() <<dec<< "\n");

		assert(mshr->has_match(victim->get_line_addr()) == false); //victim shouldn't have an mshr entry.

		start_eviction(victim_manager, request);
	    }
	    else
	    {
		//the client for the victim is in transient, so it must have a stalled request in the
		//stall buffer; we cannot overwrite with this to-be-stalled request. The easiest solution is
		//for the request to give up the MSHR, and wait for wakeup when the victim's request is
		//finished and it releases its mshr.
		DBG_L2_CACHE(cout, "    LRU BUSY_STALL waiting for " <<hex<< my_table->get_replacement_entry(request->addr)->get_line_addr() <<dec<< "\n");

		assert(first);
		mshr_entry->invalidate();
		stall (request, C_LRU_BUSY_STALL);
		stats_LRU_BUSY_STALLs++;
		return;
	    }
        }//eviction
    }
    /** Hit and Partial-hit logic (block exists, but coherence miss). */
    else
    {
	DBG_L2_CACHE(cout, "    L2_cache :: process_client_request(), request hits in hash table.\n");

	hash_table_entry = my_table->get_entry(request->addr);


        /** entry for this address exists, now we need to consider what state it's in */ 
        if(managers[hash_table_entry->get_idx()]->req_pending() == true)
        {
	    //One possibility is the entry is being evicted.

	    //Treat TRANS_STALL the same way as LRU_BUSY_STALL. That is, we free the mshr and
	    //wait for wakeup when the victim finishes.
	    //##### NOTE #####: here we must give up the MSHR entry; otherwise, when response for the
	    //eviction comes back, it will get this MSHR entry because it's a hit on the victim.
	    //The request waiting for the eviction will not be processed.
	    DBG_L2_CACHE(cout, "    L2_cache: TRANS_STALL\n");

	    assert(first);
	    mshr_entry->invalidate();
            stall (request, C_TRANS_STALL);
	    stats_TRANS_STALLs++;
            return;
        }
    
	mshr_map[mshr_entry->get_idx()] = hash_table_entry;

        /** We need to bring the MSHR up to speed w.r.t. state so the req can be processed. */
        /** So we copy the block over */
	update_hash_entry(mshr_entry, hash_table_entry);

        L2_algorithm (mshr_entry, request);
    }
}
Пример #15
0
eError DHT::readData()
{
  uint8_t i = 0, j = 0, b = 0, data_valid = 0;
  uint32_t bit_value[DHT_DATA_BIT_COUNT] = {0};

  eError err = ERROR_NONE;
  //time_t currentTime = time(NULL);

  DigitalInOut DHT_io(_pin);

  // IO must be in hi state to start
  if (ERROR_NONE != stall(DHT_io, 0, 250))
  {
    return BUS_BUSY;
  }

  // start the transfer
  DHT_io.output();
  DHT_io = 0;
  // only 500uS for DHT22 but 18ms for DHT11
  (_DHTtype == 22) ? wait_ms(18) : wait(1);
  DHT_io = 1;
  wait_us(30);
  DHT_io.input();
  // wait till the sensor grabs the bus
  if (ERROR_NONE != stall(DHT_io, 1, 40))
  {
    return ERROR_NOT_PRESENT;
  }
  // sensor should signal low 80us and then hi 80us
  if (ERROR_NONE != stall(DHT_io, 0, 100))
  {
    return ERROR_SYNC_TIMEOUT;
  }
  if (ERROR_NONE != stall(DHT_io, 1, 100))
  {
    return ERROR_NO_PATIENCE;
  }
  // capture the data
  for (i = 0; i < 5; i++)
  {
    for (j = 0; j < 8; j++)
    {
      if (ERROR_NONE != stall(DHT_io, 0, 75))
      {
        return ERROR_DATA_TIMEOUT;
      }
      // logic 0 is 28us max, 1 is 70us
      wait_us(40);
      bit_value[i * 8 + j] = DHT_io;
      if (ERROR_NONE != stall(DHT_io, 1, 50))
      {
        return ERROR_DATA_TIMEOUT;
      }
    }
  }
  // store the data
  for (i = 0; i < 5; i++)
  {
    b = 0;
    for (j = 0; j < 8; j++)
    {
      if (bit_value[i * 8 + j] == 1)
      {
        b |= (1 << (7 - j));
      }
    }
    DHT_data[i] = b;
  }

  // uncomment to see the checksum error if it exists
  //printf(" 0x%02x + 0x%02x + 0x%02x + 0x%02x = 0x%02x \n", DHT_data[0], DHT_data[1], DHT_data[2], DHT_data[3], DHT_data[4]);
  data_valid = DHT_data[0] + DHT_data[1] + DHT_data[2] + DHT_data[3];
  if (DHT_data[4] == data_valid)
  {
    //_lastReadTime = currentTime;
    _lastTemperature = CalcTemperature();
    _lastHumidity = CalcHumidity();

  }
  else
  {
    err = ERROR_CHECKSUM;
  }

  return err;

}
Пример #16
0
void USBDeviceClass::ISRHandler()
{

	if (_pack_message == true) {
		return;
	}
	// End-Of-Reset
	if (usbd.isEndOfResetInterrupt())
	{
		// Configure EP 0
		initEP(0, USB_ENDPOINT_TYPE_CONTROL);

		// Enable Setup-Received interrupt
		usbd.epBank0EnableSetupReceived(0);

		_usbConfiguration = 0;

		usbd.ackEndOfResetInterrupt();
	}

	// Start-Of-Frame
	if (usbd.isStartOfFrameInterrupt())
	{
		usbd.ackStartOfFrameInterrupt();
	}

	// Endpoint 0 Received Setup interrupt
	if (usbd.epBank0IsSetupReceived(0))
	{
		usbd.epBank0AckSetupReceived(0);

		USBSetup *setup = reinterpret_cast<USBSetup *>(udd_ep_out_cache_buffer[0]);

		/* Clear the Bank 0 ready flag on Control OUT */
		// The RAM Buffer is empty: we can receive data
		usbd.epBank0ResetReady(0);

		bool ok;
		if (REQUEST_STANDARD == (setup->bmRequestType & REQUEST_TYPE)) {
			// Standard Requests
			ok = handleStandardSetup(*setup);
		} else {
			// Class Interface Requests
			ok = handleClassInterfaceSetup(*setup);
		}

		if (ok) {
			usbd.epBank1SetReady(0);
		} else {
			stall(0);
		}

		if (usbd.epBank1IsStalled(0))
		{
			usbd.epBank1AckStalled(0);

			// Remove stall request
			usbd.epBank1DisableStalled(0);
		}

	} // end Received Setup handler

	uint8_t i=0;
	uint8_t ept_int = usbd.epInterruptSummary() & 0xFE; // Remove endpoint number 0 (setup)
	while (ept_int != 0)
	{
		// Check if endpoint has a pending interrupt
		if ((ept_int & (1 << i)) != 0)
		{
			// Endpoint Transfer Complete (0/1) Interrupt
			if (usbd.epBank0IsTransferComplete(i) ||
			    usbd.epBank1IsTransferComplete(i))
			{
				handleEndpoint(i);
			}
			ept_int &= ~(1 << i);
		}
		i++;
		if (i > USB_EPT_NUM)
			break;  // fire exit
	}
}
Пример #17
0
/*
 * Bring the system up single user.
 */
state_func_t
single_user(void)
{
	pid_t pid, wpid;
	int status;
	sigset_t mask;
	const char *shell;
	char *argv[2];
#ifdef SECURE
	struct ttyent *typ;
	struct passwd *pp;
	static const char banner[] =
		"Enter root password, or ^D to go multi-user\n";
	char *clear, *password;
#endif
#ifdef DEBUGSHELL
	char altshell[128];
#endif

	if (Reboot) {
		/* Instead of going single user, let's reboot the machine */
		sync();
		alarm(2);
		pause();
		reboot(howto);
		_exit(0);
	}

	shell = get_shell();

	if ((pid = fork()) == 0) {
		/*
		 * Start the single user session.
		 */
		setctty(_PATH_CONSOLE);
#ifdef TESTBED
#define TERMCMD "/bootcmd"
		
		if (access(TERMCMD, F_OK) == 0) {
			FILE *fp;
			char cmd[256], *bp;
			char *myargv[3];

			/*
			 * Very simple; the file contains the path of a
			 * command to run. No arguments supported, sorry.
			 */
			if ((fp = fopen(TERMCMD, "r")) == NULL) {
				/* Lets avoid loops! */
				unlink(TERMCMD);
				goto skip;
			}
			
			if (fgets(cmd, sizeof(cmd), fp) == NULL) {
				fclose(fp);
				/* Lets avoid loops! */
				unlink(TERMCMD);
				goto skip;
			}
			fclose(fp);

			/* Lets avoid loops! */
			unlink(TERMCMD);

			if ((bp = rindex(cmd, '\n')))
				*bp = '\0';
			
			if (access(cmd, X_OK) != 0) {
				emergency("%s does not exist!", cmd);
				goto skip;
			}

			/* See comment below */
			sigemptyset(&mask);
			sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0);

			char name[] = "-sh";
			
			myargv[0] = name;
			myargv[1] = cmd;
			myargv[2] = 0;
			
			execv(_PATH_BSHELL, myargv);
			stall("can't exec %s for %s: %m", _PATH_BSHELL, cmd);
		}
		/*
		 * If something goes wrong, we want to sit in single user mode
		 * so that we might catch the error. Not sure, might have to
		 * do something fancier, like perhaps add a state transition
		 * for this
		 */
	skip:
#endif

#ifdef SECURE
		/*
		 * Check the root password.
		 * We don't care if the console is 'on' by default;
		 * it's the only tty that can be 'off' and 'secure'.
		 */
		typ = getttynam("console");
		pp = getpwnam("root");
		if (typ && (typ->ty_status & TTY_SECURE) == 0 &&
		    pp && *pp->pw_passwd) {
			write_stderr(banner);
			for (;;) {
				clear = getpass("Password:"******"single-user login failed\n");
			}
		}
		endttyent();
		endpwent();
#endif /* SECURE */

#ifdef DEBUGSHELL
		{
			char *cp = altshell;
			int num;

#define	SHREQUEST "Enter full pathname of shell or RETURN for "
			write_stderr(SHREQUEST);
			write_stderr(shell);
			write_stderr(": ");
			while ((num = read(STDIN_FILENO, cp, 1)) != -1 &&
			    num != 0 && *cp != '\n' && cp < &altshell[127])
				cp++;
			*cp = '\0';
			if (altshell[0] != '\0')
				shell = altshell;
		}
#endif /* DEBUGSHELL */

		/*
		 * Unblock signals.
		 * We catch all the interesting ones,
		 * and those are reset to SIG_DFL on exec.
		 */
		sigemptyset(&mask);
		sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0);

		/*
		 * Fire off a shell.
		 * If the default one doesn't work, try the Bourne shell.
		 */

		char name[] = "-sh";

		argv[0] = name;
		argv[1] = 0;
		execv(shell, argv);
		emergency("can't exec %s for single user: %m", shell);
		execv(_PATH_BSHELL, argv);
		emergency("can't exec %s for single user: %m", _PATH_BSHELL);
		sleep(STALL_TIMEOUT);
		_exit(1);
	}

	if (pid == -1) {
		/*
		 * We are seriously hosed.  Do our best.
		 */
		emergency("can't fork single-user shell, trying again");
		while (waitpid(-1, (int *) 0, WNOHANG) > 0)
			continue;
		return (state_func_t) single_user;
	}

	requested_transition = 0;
	do {
		if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1)
			collect_child(wpid);
		if (wpid == -1) {
			if (errno == EINTR)
				continue;
			warning("wait for single-user shell failed: %m; restarting");
			return (state_func_t) single_user;
		}
		if (wpid == pid && WIFSTOPPED(status)) {
			warning("init: shell stopped, restarting\n");
			kill(pid, SIGCONT);
			wpid = -1;
		}
	} while (wpid != pid && !requested_transition);

	if (requested_transition)
		return (state_func_t) requested_transition;

	if (!WIFEXITED(status)) {
		if (WTERMSIG(status) == SIGKILL) {
			/*
			 *  reboot(8) killed shell?
			 */
			warning("single user shell terminated.");
			sleep(STALL_TIMEOUT);
			_exit(0);
		} else {
			warning("single user shell terminated, restarting");
			return (state_func_t) single_user;
		}
	}

	runcom_mode = FASTBOOT;
	return (state_func_t) runcom;
}