Re: strange problem with "usb_submit_urb"

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> And what does the code look like for the whole driver?

Here I am pasting the callback and related code.

Please find the code execution path in which usb_submit_urb() is failing.

common_callback()->common_check_for_fail_status()->usb_stor_clear_halt()->usb_stor_control_msg()->my_usb_stor_msg_common()->usb_submit_urb().



//Main call back routine
void common_callback(struct urb *urb)
{
	if(urb->status == 0)
	{

		doProcessCallBack(urb);
	}
	else
	{      //This is the path whare usb_submit_urb();is failing
               //submission has been failed retry submitting urb
		common_check_for_fail_status(urb);
	}	

}

void common_check_for_fail_status(struct urb *urb)
{
	struct urb_context *current_urb_context = NULL;
	int result = 0;

	current_urb_context = (struct urb_context*)urb->context;

	result =  usb_interpret_urb_result(current_urb_context->stat_bulkin_pipe,
						USB_BULK_LEN, urb->status,	urb->actual_length);

	if(result == USB_STOR_CLEAR_HALT)
	{
		//This is the path whare usb_submit_urb();is failing		
		usb_stor_clear_halt(urb, current_urb_context->stat_bulkin_pipe);

		return ;
	}

	if(result == USB_STOR_XFER_SHORT && urb->actual_length == 0)
	{		
		PRINTK("in:Received 0-length ; retrying...\n");

		usb_fill_bulk_urb(urb, current_urb_context->pusb_dev,
current_urb_context->stat_bulkin_pipe, urb->transfer_buffer,
				USB_BULK_LEN,	common_callback,(void*)current_urb_context);

		result = my_usb_stor_msg_common(urb);
					
		return ;
	}
	else if(result == USB_STOR_XFER_STALLED)
	{	
		PRINTK("in:Attempting to get (2nd try)...\n");

		usb_fill_bulk_urb(urb, current_urb_context->pusb_dev,
current_urb_context->stat_bulkin_pipe, urb->transfer_buffer,
				USB_BULK_LEN,	common_callback,(void*)current_urb_context);

		result = my_usb_stor_msg_common(urb);
			
		return ;
	}
}

int usb_stor_clear_halt(struct urb *urb, unsigned int pipe)
{
	int result;
	
	struct urb_context *current_urb_context = (struct urb_context*)urb->context;
	int endp = usb_pipeendpoint(pipe);

	if (usb_pipein (pipe))
		endp |= USB_DIR_IN;

	//This is the path whare usb_submit_urb();is failing
	result = usb_stor_control_msg(urb, current_urb_context->send_ctrl_pipe,
		USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT,
		USB_ENDPOINT_HALT, endp,
		NULL, 0, 3*HZ);

	return result;
	
}

int usb_stor_control_msg(struct urb *urb, unsigned int pipe,
		 u8 request, u8 requesttype, u16 value, u16 index,
		 void *data, u16 size, int timeout)
{
	int status;

	struct urb_context *current_urb_context = (struct urb_context*)urb->context;

	US_DEBUGP("%s: rq=%02x rqtype=%02x value=%04x index=%02x len=%u\n",
			__func__, request, requesttype,
			value, index, size);

	/* fill in the devrequest structure */
	current_urb_context->cr->bRequestType = requesttype;
	current_urb_context->cr->bRequest = request;
	current_urb_context->cr->wValue = cpu_to_le16(value);
	current_urb_context->cr->wIndex = cpu_to_le16(index);
	current_urb_context->cr->wLength = cpu_to_le16(size);

	/* fill and submit the URB */
	usb_fill_control_urb(urb, current_urb_context->pusb_dev, pipe,
			 (unsigned char*) current_urb_context->cr, data, size,
			 usb_stor_clear_halt_callback, (void*)current_urb_context);

	status = my_usb_stor_msg_common(urb);

	return 0;
}

int my_usb_stor_msg_common(struct urb *current_urb)
{
	struct urb_context *current_urb_context = NULL;		
	int status;
	unsigned long flags;
	
	current_urb_context = (struct urb_context*)current_urb->context;
		
	/* don't submit URBs during abort processing */
	if (test_bit(US_FLIDX_ABORTING, current_urb_context->dflags))
		return -EIO;

	/* set up data structures for the wakeup system */

	/* fill the common fields in the URB */
	
	current_urb->actual_length = 0;
	current_urb->error_count = 0;
	current_urb->status = 0;

	current_urb->transfer_flags = URB_NO_SETUP_DMA_MAP;
	current_urb->setup_dma = current_urb_context->cr_dma;

	/* submit the URB */

	//This is the path whare usb_submit_urb();is failing
	
	status = usb_submit_urb(current_urb, GFP_ATOMIC);

	if (status) {
		/* something went wrong */
		printk("<%s> The Status after usb_submit_urb is %d\n", __func__, status);
		return status;
	}

	set_bit(US_FLIDX_URB_ACTIVE, current_urb_context->dflags);

	/* did an abort occur during the submission? */
	if (test_bit(US_FLIDX_ABORTING, current_urb_context->dflags))
	{
		/* cancel the URB, if it hasn't been cancelled already */
		if (test_and_clear_bit(US_FLIDX_URB_ACTIVE, current_urb_context->dflags))
		{
			US_DEBUGP("-- cancelling URB\n");
			usb_unlink_urb(current_urb);
		}
	}

	/* wait for the completion of the URB */

	clear_bit(US_FLIDX_URB_ACTIVE, current_urb_context->dflags);

	/* return the URB status */
	return status;
}


-Aditya
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux