in core/mspro_block.c [737:795]
static int mspro_block_complete_req(struct memstick_dev *card, int error)
{
struct mspro_block_data *msb = memstick_get_drvdata(card);
int cnt;
bool chunk;
unsigned int t_len = 0;
unsigned long flags;
spin_lock_irqsave(&msb->q_lock, flags);
dev_dbg(&card->dev, "complete %d, %d\n", msb->block_req ? 1 : 0,
error);
if (msb->block_req) {
/* Nothing to do - not really an error */
if (error == -EAGAIN)
error = 0;
if (error || (card->current_mrq.tpc == MSPRO_CMD_STOP)) {
if (msb->data_dir == READ) {
for (cnt = 0; cnt < msb->current_seg; cnt++) {
t_len += msb->req_sg[cnt].length
/ msb->page_size;
if (msb->current_page)
t_len += msb->current_page - 1;
t_len *= msb->page_size;
}
}
} else
t_len = blk_rq_bytes(msb->block_req);
dev_dbg(&card->dev, "transferred %x (%d)\n", t_len, error);
if (error && !t_len)
t_len = blk_rq_cur_bytes(msb->block_req);
chunk = blk_update_request(msb->block_req,
errno_to_blk_status(error), t_len);
if (chunk) {
error = mspro_block_issue_req(card);
if (!error)
goto out;
} else {
__blk_mq_end_request(msb->block_req,
errno_to_blk_status(error));
msb->block_req = NULL;
}
} else {
if (!error)
error = -EAGAIN;
}
card->next_request = h_mspro_block_default_bad;
complete_all(&card->mrq_complete);
out:
spin_unlock_irqrestore(&msb->q_lock, flags);
return error;
}