/* * Some broken devices add unnecessary zero-length * packets to the end of their data transfers. * Such packets show up as 0-length CSWs. If we * encounter such a thing, try to read the CSW again. */ if (++cmd->stat_count >= 4) { printk(KERN_NOTICE "%s: unable to get CSW\n", sc->name); goto Bad_End; } __ub_state_stat(sc, cmd); 
ub_state_stat_counted(sc, cmd); 
static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd){	struct urb *urb = &sc->work_urb;	struct bulk_cs_wrap *bcs;	int pipe;	int rc;	if (atomic_read(&sc->poison)) {		/* A little too simplistic, I feel... */		goto Bad_End;	}	if (cmd->state == UB_CMDST_CLEAR) {		if (urb->status == -EPIPE) {			/*			 * STALL while clearning STALL.			 * The control pipe clears itself - nothing to do.			 * XXX Might try to reset the device here and retry.			 */			printk(KERN_NOTICE "%s: stall on control pipe\n",			    sc->name);			goto Bad_End;		}		/*		 * We ignore the result for the halt clear.		 */		/* reset the endpoint toggle */		usb_settoggle(sc->dev, usb_pipeendpoint(sc->last_pipe),			usb_pipeout(sc->last_pipe), 0);		ub_state_sense(sc, cmd);	} else if (cmd->state == UB_CMDST_CLR2STS) {		if (urb->status == -EPIPE) {			/*			 * STALL while clearning STALL.			 * The control pipe clears itself - nothing to do.			 * XXX Might try to reset the device here and retry.			 */			printk(KERN_NOTICE "%s: stall on control pipe\n",			    sc->name);			goto Bad_End;		}		/*		 * We ignore the result for the halt clear.		 */		/* reset the endpoint toggle */		usb_settoggle(sc->dev, usb_pipeendpoint(sc->last_pipe),			usb_pipeout(sc->last_pipe), 0);		ub_state_stat(sc, cmd);	} else if (cmd->state == UB_CMDST_CMD) {		if (urb->status == -EPIPE) {			rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe);			if (rc != 0) {				printk(KERN_NOTICE "%s: "				    "unable to submit clear (%d)\n",				    sc->name, rc);				/*				 * This is typically ENOMEM or some other such shit.				 * Retrying is pointless. Just do Bad End on it...				 */				goto Bad_End;			}			cmd->state = UB_CMDST_CLEAR;			ub_cmdtr_state(sc, cmd);			return;		}		if (urb->status != 0) {			printk("ub: cmd #%d cmd status (%d)\n", cmd->tag, urb->status); /* P3 */			goto Bad_End;		}		if (urb->actual_length != US_BULK_CB_WRAP_LEN) {			printk("ub: cmd #%d xferred %d\n", cmd->tag, urb->actual_length); /* P3 */			/* XXX Must do reset here to unconfuse the device */			goto Bad_End;		}		if (cmd->dir == UB_DIR_NONE) {			ub_state_stat(sc, cmd);			return;		}		UB_INIT_COMPLETION(sc->work_done);		if (cmd->dir == UB_DIR_READ)			pipe = sc->recv_bulk_pipe;		else			pipe = sc->send_bulk_pipe;		sc->last_pipe = pipe;		usb_fill_bulk_urb(&sc->work_urb, sc->dev, pipe,		    cmd->data, cmd->len, ub_urb_complete, sc);		sc->work_urb.transfer_flags = URB_ASYNC_UNLINK;		sc->work_urb.actual_length = 0;		sc->work_urb.error_count = 0;		sc->work_urb.status = 0;		if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) {			/* XXX Clear stalls */			printk("ub: data #%d submit failed (%d)\n", cmd->tag, rc); /* P3 */			ub_complete(&sc->work_done);			ub_state_done(sc, cmd, rc);			return;		}		sc->work_timer.expires = jiffies + UB_DATA_TIMEOUT;		add_timer(&sc->work_timer);		cmd->state = UB_CMDST_DATA;		ub_cmdtr_state(sc, cmd);	} else if (cmd->state == UB_CMDST_DATA) {		if (urb->status == -EPIPE) {			rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe);			if (rc != 0) {				printk(KERN_NOTICE "%s: "				    "unable to submit clear (%d)\n",				    sc->name, rc);				/*				 * This is typically ENOMEM or some other such shit.				 * Retrying is pointless. Just do Bad End on it...				 */				goto Bad_End;			}			cmd->state = UB_CMDST_CLR2STS;			ub_cmdtr_state(sc, cmd);			return;		}		if (urb->status == -EOVERFLOW) {			/*			 * A babble? Failure, but we must transfer CSW now.			 */			cmd->error = -EOVERFLOW;	/* A cheap trick... */		} else {			if (urb->status != 0)				goto Bad_End;		}		cmd->act_len = urb->actual_length;		ub_cmdtr_act_len(sc, cmd);		ub_state_stat(sc, cmd);	} else if (cmd->state == UB_CMDST_STAT) {		if (urb->status == -EPIPE) {			rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe);			if (rc != 0) {				printk(KERN_NOTICE "%s: "				    "unable to submit clear (%d)\n",				    sc->name, rc);				/*				 * This is typically ENOMEM or some other such shit.				 * Retrying is pointless. Just do Bad End on it...				 */				goto Bad_End;			}			cmd->state = UB_CMDST_CLEAR;			ub_cmdtr_state(sc, cmd);			return;		}		if (urb->status != 0)			goto Bad_End;		if (urb->actual_length == 0) {			/*			 * Some broken devices add unnecessary zero-length			 * packets to the end of their data transfers.			 * Such packets show up as 0-length CSWs. If we			 * encounter such a thing, try to read the CSW again.			 */			if (++cmd->stat_count >= 4) {				printk(KERN_NOTICE "%s: unable to get CSW\n",				    sc->name);				goto Bad_End;			}			__ub_state_stat(sc, cmd);			return;		}		/*		 * Check the returned Bulk protocol status.		 */		bcs = &sc->work_bcs;		rc = le32_to_cpu(bcs->Residue);		if (rc != cmd->len - cmd->act_len) {			/*			 * It is all right to transfer less, the caller has			 * to check. But it's not all right if the device			 * counts disagree with our counts.			 */			/* P3 */ printk("%s: resid %d len %d act %d\n",			    sc->name, rc, cmd->len, cmd->act_len);			goto Bad_End;		}#if 0		if (bcs->Signature != cpu_to_le32(US_BULK_CS_SIGN) &&		    bcs->Signature != cpu_to_le32(US_BULK_CS_OLYMPUS_SIGN)) {			/* Windows ignores signatures, so do we. */		}#endif		if (bcs->Tag != cmd->tag) {			/*			 * This usually happens when we disagree with the			 * device's microcode about something. For instance,			 * a few of them throw this after timeouts. They buffer			 * commands and reply at commands we timed out before.			 * Without flushing these replies we loop forever.			 */			if (++cmd->stat_count >= 4) {				printk(KERN_NOTICE "%s: "				    "tag mismatch orig 0x%x reply 0x%x\n",				    sc->name, cmd->tag, bcs->Tag);				goto Bad_End;			}			__ub_state_stat(sc, cmd);			return;		}		switch (bcs->Status) {		case US_BULK_STAT_OK:			break;		case US_BULK_STAT_FAIL:			ub_state_sense(sc, cmd);			return;		case US_BULK_STAT_PHASE:			/* XXX We must reset the transport here */			/* P3 */ printk("%s: status PHASE\n", sc->name);			goto Bad_End;		default:			printk(KERN_INFO "%s: unknown CSW status 0x%x\n",			    sc->name, bcs->Status);			goto Bad_End;		}		/* Not zeroing error to preserve a babble indicator */		cmd->state = UB_CMDST_DONE;		ub_cmdtr_state(sc, cmd);		ub_cmdq_pop(sc);		(*cmd->done)(sc, cmd);	} else if (cmd->state == UB_CMDST_SENSE) {		ub_state_done(sc, cmd, -EIO);	} else {		printk(KERN_WARNING "%s: "		    "wrong command state %d\n",		    sc->name, cmd->state);		goto Bad_End;	}	return;Bad_End: /* Little Excel is dead */	ub_state_done(sc, cmd, -EIO);}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/1872bcebbcd6ad7ddd99e92fb1e4f3d19e73919c/ub.c/clean/drivers/block/ub.c