static void htifblk_request(struct request_queue *q) { struct htifblk_device *dev; struct request *req; unsigned long flags; int ret; dev = q->queuedata; spin_lock_irqsave(q->queue_lock, flags); if (dev->req != NULL) goto out; while ((req = blk_fetch_request(q)) != NULL) { if (req->cmd_type == REQ_TYPE_FS) { ret = htifblk_segment(dev, req); if (unlikely(ret)) { WARN_ON(__blk_end_request_cur(req, ret)); continue; } blk_stop_queue(q); break; } else { blk_dump_rq_flags(req, DRIVER_NAME ": ignored non-fs request"); __blk_end_request_all(req, -EIO); continue; } } out: spin_unlock_irqrestore(q->queue_lock, flags); }
static void htifblk_request(struct request_queue *q) { struct htifblk_device *dev; struct request *req; int ret; dev = q->queuedata; if (dev->req != NULL) return; while ((req = blk_fetch_request(q)) != NULL) { if (req->cmd_type == REQ_TYPE_FS) { ret = htifblk_segment(dev, req); if (unlikely(ret)) { WARN_ON(__blk_end_request_cur(req, ret)); continue; } blk_stop_queue(q); break; } else { blk_dump_rq_flags(req, DRIVER_NAME ": ignored non-fs request"); __blk_end_request_all(req, -EIO); continue; } } }
void bsg_remove_queue(struct request_queue *q) { struct request *req; int counts; if (!q) return; spin_lock_irq(q->queue_lock); blk_stop_queue(q); while (1) { req = blk_fetch_request(q); counts = q->rq.count[0] + q->rq.count[1] + q->rq.starved[0] + q->rq.starved[1]; spin_unlock_irq(q->queue_lock); if (counts == 0) break; if (req) { req->errors = -ENXIO; blk_end_request_all(req, -ENXIO); } msleep(200); spin_lock_irq(q->queue_lock); } bsg_unregister_queue(q); }
/** * ide_complete_pm_rq - end the current Power Management request * @drive: target drive * @rq: request * * This function cleans up the current PM request and stops the queue * if necessary. */ void ide_complete_pm_rq(ide_drive_t *drive, struct request *rq) { struct request_queue *q = drive->queue; struct request_pm_state *pm = rq->special; unsigned long flags; ide_complete_power_step(drive, rq); if (pm->pm_step != IDE_PM_COMPLETED) return; #ifdef DEBUG_PM #ifdef CONFIG_DEBUG_PRINTK printk("%s: completing PM request, %s\n", drive->name, (rq->cmd_type == REQ_TYPE_PM_SUSPEND) ? "suspend" : "resume"); #else ; #endif #endif spin_lock_irqsave(q->queue_lock, flags); if (rq->cmd_type == REQ_TYPE_PM_SUSPEND) blk_stop_queue(q); else drive->dev_flags &= ~IDE_DFLAG_BLOCKED; spin_unlock_irqrestore(q->queue_lock, flags); drive->hwif->rq = NULL; if (blk_end_request(rq, 0, 0)) BUG(); }
static void skd_timer_tick(ulong arg) { struct skd_device *skdev = (struct skd_device *)arg; u32 timo_slot; u32 overdue_timestamp; unsigned long reqflags; u32 state; if (skdev->state == SKD_DRVR_STATE_FAULT) /* The driver has declared fault, and we want it to * stay that way until driver is reloaded. */ return; spin_lock_irqsave(&skdev->lock, reqflags); state = SKD_READL(skdev, FIT_STATUS); state &= FIT_SR_DRIVE_STATE_MASK; if (state != skdev->drive_state) skd_isr_fwstate(skdev); if (skdev->state != SKD_DRVR_STATE_ONLINE) { skd_timer_tick_not_online(skdev); goto timer_func_out; } skdev->timeout_stamp++; timo_slot = skdev->timeout_stamp & SKD_TIMEOUT_SLOT_MASK; /* * All requests that happened during the previous use of * this slot should be done by now. The previous use was * over 7 seconds ago. */ if (skdev->timeout_slot[timo_slot] == 0) goto timer_func_out; /* Something is overdue */ overdue_timestamp = skdev->timeout_stamp - SKD_N_TIMEOUT_SLOT; pr_debug("%s:%s:%d found %d timeouts, draining busy=%d\n", skdev->name, __func__, __LINE__, skdev->timeout_slot[timo_slot], skdev->in_flight); pr_err("(%s): Overdue IOs (%d), busy %d\n", skd_name(skdev), skdev->timeout_slot[timo_slot], skdev->in_flight); skdev->timer_countdown = SKD_DRAINING_TIMO; skdev->state = SKD_DRVR_STATE_DRAINING_TIMEOUT; skdev->timo_slot = timo_slot; blk_stop_queue(skdev->queue); timer_func_out: mod_timer(&skdev->timer, (jiffies + HZ)); spin_unlock_irqrestore(&skdev->lock, reqflags); }
static void dm_old_stop_queue(struct request_queue *q) { unsigned long flags; spin_lock_irqsave(q->queue_lock, flags); if (!blk_queue_stopped(q)) blk_stop_queue(q); spin_unlock_irqrestore(q->queue_lock, flags); }
void card_queue_suspend(struct card_queue *cq) { struct request_queue *q = cq->queue; unsigned long flags; if (!(cq->flags & CARD_QUEUE_SUSPENDED)) { cq->flags |= CARD_QUEUE_SUSPENDED; spin_lock_irqsave(q->queue_lock, flags); blk_stop_queue(q); spin_unlock_irqrestore(q->queue_lock, flags); down(&cq->thread_sem); } }
/** * mmc_queue_suspend - suspend a MMC request queue * @mq: MMC queue to suspend * * Stop the block request queue, and wait for our thread to * complete any outstanding requests. This ensures that we * won't suspend while a request is being processed. */ void mmc_queue_suspend(struct mmc_queue *mq) { struct request_queue *q = mq->queue; unsigned long flags; if (!mq->suspended) { mq->suspended |= true; spin_lock_irqsave(q->queue_lock, flags); blk_stop_queue(q); spin_unlock_irqrestore(q->queue_lock, flags); down(&mq->thread_sem); } }
/** * mmc_queue_suspend - suspend a MMC request queue * @mq: MMC queue to suspend * * Stop the block request queue, and wait for our thread to * complete any outstanding requests. This ensures that we * won't suspend while a request is being processed. */ void mmc_queue_suspend(struct mmc_queue *mq) { struct request_queue *q = mq->queue; unsigned long flags; if (!(mq->flags & MMC_QUEUE_SUSPENDED)) { mq->flags |= MMC_QUEUE_SUSPENDED; spin_lock_irqsave(q->queue_lock, flags); blk_stop_queue(q); spin_unlock_irqrestore(q->queue_lock, flags); down(&mq->thread_sem); } }
static int null_rq_prep_fn(struct request_queue *q, struct request *req) { struct nullb *nullb = q->queuedata; struct nullb_queue *nq = nullb_to_queue(nullb); struct nullb_cmd *cmd; cmd = alloc_cmd(nq, 0); if (cmd) { cmd->rq = req; req->special = cmd; return BLKPREP_OK; } blk_stop_queue(q); return BLKPREP_DEFER; }
/** * cyasblkdev_queue_suspend - suspend a CyAsBlkDev request queue * @bq: CyAsBlkDev queue to suspend * * Stop the block request queue, and wait for our thread to * complete any outstanding requests. This ensures that we * won't suspend while a request is being processed. */ void cyasblkdev_queue_suspend(struct cyasblkdev_queue *bq) { struct request_queue *q = bq->queue; unsigned long flags; DBGPRN_FUNC_NAME; if (!(bq->flags & CYASBLKDEV_QUEUE_SUSPENDED)) { bq->flags |= CYASBLKDEV_QUEUE_SUSPENDED; spin_lock_irqsave(q->queue_lock, flags); blk_stop_queue(q); spin_unlock_irqrestore(q->queue_lock, flags); down(&bq->thread_sem); } }
/** * bsg_remove_queue - Deletes the bsg dev from the q * @q: the request_queue that is to be torn down. * * Notes: * Before unregistering the queue empty any requests that are blocked */ void bsg_remove_queue(struct request_queue *q) { struct request *req; /* block request */ int counts; /* totals for request_list count and starved */ if (!q) return; /* Stop taking in new requests */ spin_lock_irq(q->queue_lock); blk_stop_queue(q); /* drain all requests in the queue */ while (1) { /* need the lock to fetch a request * this may fetch the same reqeust as the previous pass */ req = blk_fetch_request(q); /* save requests in use and starved */ counts = q->root_rl.count[0] + q->root_rl.count[1] + q->root_rl.starved[0] + q->root_rl.starved[1]; spin_unlock_irq(q->queue_lock); /* any requests still outstanding? */ if (counts == 0) break; /* This may be the same req as the previous iteration, * always send the blk_end_request_all after a prefetch. * It is not okay to not end the request because the * prefetch started the request. */ if (req) { /* return -ENXIO to indicate that this queue is * going away */ req->errors = -ENXIO; blk_end_request_all(req, -ENXIO); } msleep(200); /* allow bsg to possibly finish */ spin_lock_irq(q->queue_lock); } bsg_unregister_queue(q); }
/* * do_blkif_request * read a block; request is in a request queue */ static void do_blkif_request(struct request_queue *rq) { struct blkfront_info *info = NULL; struct request *req; int queued; pr_debug("Entered do_blkif_request\n"); queued = 0; while ((req = blk_peek_request(rq)) != NULL) { info = req->rq_disk->private_data; if (RING_FULL(&info->ring)) goto wait; blk_start_request(req); if (!blk_fs_request(req)) { __blk_end_request_all(req, -EIO); continue; } pr_debug("do_blk_req %p: cmd %p, sec %lx, " "(%u/%u) buffer:%p [%s]\n", req, req->cmd, (unsigned long)blk_rq_pos(req), blk_rq_cur_sectors(req), blk_rq_sectors(req), req->buffer, rq_data_dir(req) ? "write" : "read"); if (blkif_queue_request(req)) { blk_requeue_request(rq, req); wait: /* Avoid pointless unplugs. */ blk_stop_queue(rq); break; } queued++; } if (queued != 0) flush_requests(info); }
/** * ide_complete_pm_request - end the current Power Management request * @drive: target drive * @rq: request * * This function cleans up the current PM request and stops the queue * if necessary. */ static void ide_complete_pm_request (ide_drive_t *drive, struct request *rq) { unsigned long flags; #ifdef DEBUG_PM printk("%s: completing PM request, %s\n", drive->name, blk_pm_suspend_request(rq) ? "suspend" : "resume"); #endif spin_lock_irqsave(&ide_lock, flags); if (blk_pm_suspend_request(rq)) { blk_stop_queue(drive->queue); } else { drive->blocked = 0; blk_start_queue(drive->queue); } HWGROUP(drive)->rq = NULL; if (__blk_end_request(rq, 0, 0)) BUG(); spin_unlock_irqrestore(&ide_lock, flags); }
/** * ide_complete_pm_request - end the current Power Management request * @drive: target drive * @rq: request * * This function cleans up the current PM request and stops the queue * if necessary. */ void ide_complete_pm_request(ide_drive_t *drive, struct request *rq) { struct request_queue *q = drive->queue; unsigned long flags; #ifdef DEBUG_PM printk("%s: completing PM request, %s\n", drive->name, blk_pm_suspend_request(rq) ? "suspend" : "resume"); #endif spin_lock_irqsave(q->queue_lock, flags); if (blk_pm_suspend_request(rq)) blk_stop_queue(q); else drive->dev_flags &= ~IDE_DFLAG_BLOCKED; spin_unlock_irqrestore(q->queue_lock, flags); drive->hwif->rq = NULL; if (blk_end_request(rq, 0, 0)) BUG(); }
static void stop_queue(int index, char *path) { unsigned long flags; struct request_queue *q; bdev[index] = blkdev_get_by_path(path, FMODE_READ, stop_queue); if (IS_ERR(bdev[index])) { pr_err("failed to get block device %s (%ld)\n", path, PTR_ERR(bdev[index])); bdev[index] = NULL; return; } q = bdev_get_queue(bdev[index]); if (!q) { pr_err("queue not found bdev[index]=%d\n", index); return; } spin_lock_irqsave(q->queue_lock, flags); blk_stop_queue(q); spin_unlock_irqrestore(q->queue_lock, flags); }
/* * Generic MMC request handler. This is called for any queue on a * particular host. When the host is not busy, we look for a request * on any queue on this host, and attempt to issue it. This may * not be the queue we were asked to process. */ static void mmc_request(struct request_queue *q) { struct mmc_queue *mq = q->queuedata; struct request *req; int ret; #if 0 if (!mq) { #else //插着USB线(充电姿态),拔插卡,有偶尔死机现象。出现mq->thread为空的现象;modifyed by xbw if (!mq ||!mq->thread) { #endif printk(KERN_ERR "MMC: killing requests for dead queue\n"); while ((req = elv_next_request(q)) != NULL) { do { ret = __blk_end_request(req, -EIO, blk_rq_cur_bytes(req)); } while (ret); } return; } if (!mq->req) wake_up_process(mq->thread); } /** * mmc_init_queue - initialise a queue structure. * @mq: mmc queue * @card: mmc card to attach this queue * @lock: queue lock * * Initialise a MMC card request queue. */ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock) { struct mmc_host *host = card->host; u64 limit = BLK_BOUNCE_ANY ; // BLK_BOUNCE_HIGH; int ret; if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask) limit = *mmc_dev(host)->dma_mask; mq->card = card; mq->queue = blk_init_queue(mmc_request, lock); if (!mq->queue) return -ENOMEM; mq->queue->queuedata = mq; mq->req = NULL; blk_queue_prep_rq(mq->queue, mmc_prep_request); #ifdef CONFIG_MMC_BLOCK_BOUNCE if (host->max_hw_segs == 1) { unsigned int bouncesz; bouncesz = MMC_QUEUE_BOUNCESZ; if (bouncesz > host->max_req_size) bouncesz = host->max_req_size; if (bouncesz > host->max_seg_size) bouncesz = host->max_seg_size; mq->bounce_buf = kmalloc(bouncesz, GFP_KERNEL); if (!mq->bounce_buf) { printk(KERN_WARNING "%s: unable to allocate " "bounce buffer\n", mmc_card_name(card)); } else { blk_queue_bounce_limit(mq->queue, BLK_BOUNCE_HIGH); blk_queue_max_sectors(mq->queue, bouncesz / 512); blk_queue_max_phys_segments(mq->queue, bouncesz / 512); blk_queue_max_hw_segments(mq->queue, bouncesz / 512); blk_queue_max_segment_size(mq->queue, bouncesz); mq->sg = kmalloc(sizeof(struct scatterlist), GFP_KERNEL); if (!mq->sg) { ret = -ENOMEM; goto cleanup_queue; } sg_init_table(mq->sg, 1); mq->bounce_sg = kmalloc(sizeof(struct scatterlist) * bouncesz / 512, GFP_KERNEL); if (!mq->bounce_sg) { ret = -ENOMEM; goto cleanup_queue; } sg_init_table(mq->bounce_sg, bouncesz / 512); } } #endif if (!mq->bounce_buf) { blk_queue_bounce_limit(mq->queue, limit); blk_queue_max_sectors(mq->queue, host->max_req_size / 512); blk_queue_max_phys_segments(mq->queue, host->max_phys_segs); blk_queue_max_hw_segments(mq->queue, host->max_hw_segs); blk_queue_max_segment_size(mq->queue, host->max_seg_size); mq->sg = kmalloc(sizeof(struct scatterlist) * host->max_phys_segs, GFP_KERNEL); if (!mq->sg) { ret = -ENOMEM; goto cleanup_queue; } sg_init_table(mq->sg, host->max_phys_segs); } init_MUTEX(&mq->thread_sem); mq->thread = kthread_run(mmc_queue_thread, mq, "mmcqd"); if (IS_ERR(mq->thread)) { ret = PTR_ERR(mq->thread); goto free_bounce_sg; } return 0; free_bounce_sg: if (mq->bounce_sg) kfree(mq->bounce_sg); mq->bounce_sg = NULL; cleanup_queue: if (mq->sg) kfree(mq->sg); mq->sg = NULL; if (mq->bounce_buf) kfree(mq->bounce_buf); mq->bounce_buf = NULL; blk_cleanup_queue(mq->queue); return ret; } void mmc_cleanup_queue(struct mmc_queue *mq) { struct request_queue *q = mq->queue; unsigned long flags; /* Mark that we should start throwing out stragglers */ spin_lock_irqsave(q->queue_lock, flags); q->queuedata = NULL; spin_unlock_irqrestore(q->queue_lock, flags); /* Make sure the queue isn't suspended, as that will deadlock */ mmc_queue_resume(mq); /* Then terminate our worker thread */ kthread_stop(mq->thread); if (mq->bounce_sg) kfree(mq->bounce_sg); mq->bounce_sg = NULL; kfree(mq->sg); mq->sg = NULL; if (mq->bounce_buf) kfree(mq->bounce_buf); mq->bounce_buf = NULL; blk_cleanup_queue(mq->queue); mq->card = NULL; } EXPORT_SYMBOL(mmc_cleanup_queue); /** * mmc_queue_suspend - suspend a MMC request queue * @mq: MMC queue to suspend * * Stop the block request queue, and wait for our thread to * complete any outstanding requests. This ensures that we * won't suspend while a request is being processed. */ void mmc_queue_suspend(struct mmc_queue *mq) { struct request_queue *q = mq->queue; unsigned long flags; if (!(mq->flags & MMC_QUEUE_SUSPENDED)) { mq->flags |= MMC_QUEUE_SUSPENDED; spin_lock_irqsave(q->queue_lock, flags); blk_stop_queue(q); spin_unlock_irqrestore(q->queue_lock, flags); down(&mq->thread_sem); } } /** * mmc_queue_resume - resume a previously suspended MMC request queue * @mq: MMC queue to resume */ void mmc_queue_resume(struct mmc_queue *mq) { struct request_queue *q = mq->queue; unsigned long flags; if (mq->flags & MMC_QUEUE_SUSPENDED) { mq->flags &= ~MMC_QUEUE_SUSPENDED; up(&mq->thread_sem); spin_lock_irqsave(q->queue_lock, flags); blk_start_queue(q); spin_unlock_irqrestore(q->queue_lock, flags); } } static void copy_sg(struct scatterlist *dst, unsigned int dst_len, struct scatterlist *src, unsigned int src_len) { unsigned int chunk; char *dst_buf, *src_buf; unsigned int dst_size, src_size; dst_buf = NULL; src_buf = NULL; dst_size = 0; src_size = 0; while (src_len) { BUG_ON(dst_len == 0); if (dst_size == 0) { dst_buf = sg_virt(dst); dst_size = dst->length; } if (src_size == 0) { src_buf = sg_virt(src); src_size = src->length; } chunk = min(dst_size, src_size); memcpy(dst_buf, src_buf, chunk); dst_buf += chunk; src_buf += chunk; dst_size -= chunk; src_size -= chunk; if (dst_size == 0) { dst++; dst_len--; } if (src_size == 0) { src++; src_len--; } } }
static void skd_request_fn(struct request_queue *q) { struct skd_device *skdev = q->queuedata; struct skd_fitmsg_context *skmsg = NULL; struct fit_msg_hdr *fmh = NULL; struct skd_request_context *skreq; struct request *req = NULL; struct skd_scsi_request *scsi_req; struct page *page; unsigned long io_flags; int error; u32 lba; u32 count; int data_dir; u32 be_lba; u32 be_count; u64 be_dmaa; u64 cmdctxt; u32 timo_slot; void *cmd_ptr; int flush, fua; if (skdev->state != SKD_DRVR_STATE_ONLINE) { skd_request_fn_not_online(q); return; } if (blk_queue_stopped(skdev->queue)) { if (skdev->skmsg_free_list == NULL || skdev->skreq_free_list == NULL || skdev->in_flight >= skdev->queue_low_water_mark) /* There is still some kind of shortage */ return; queue_flag_clear(QUEUE_FLAG_STOPPED, skdev->queue); } /* * Stop conditions: * - There are no more native requests * - There are already the maximum number of requests in progress * - There are no more skd_request_context entries * - There are no more FIT msg buffers */ for (;; ) { flush = fua = 0; req = blk_peek_request(q); /* Are there any native requests to start? */ if (req == NULL) break; lba = (u32)blk_rq_pos(req); count = blk_rq_sectors(req); data_dir = rq_data_dir(req); io_flags = req->cmd_flags; if (io_flags & REQ_FLUSH) flush++; if (io_flags & REQ_FUA) fua++; pr_debug("%s:%s:%d new req=%p lba=%u(0x%x) " "count=%u(0x%x) dir=%d\n", skdev->name, __func__, __LINE__, req, lba, lba, count, count, data_dir); /* At this point we know there is a request */ /* Are too many requets already in progress? */ if (skdev->in_flight >= skdev->cur_max_queue_depth) { pr_debug("%s:%s:%d qdepth %d, limit %d\n", skdev->name, __func__, __LINE__, skdev->in_flight, skdev->cur_max_queue_depth); break; } /* Is a skd_request_context available? */ skreq = skdev->skreq_free_list; if (skreq == NULL) { pr_debug("%s:%s:%d Out of req=%p\n", skdev->name, __func__, __LINE__, q); break; } SKD_ASSERT(skreq->state == SKD_REQ_STATE_IDLE); SKD_ASSERT((skreq->id & SKD_ID_INCR) == 0); /* Now we check to see if we can get a fit msg */ if (skmsg == NULL) { if (skdev->skmsg_free_list == NULL) { pr_debug("%s:%s:%d Out of msg\n", skdev->name, __func__, __LINE__); break; } } skreq->flush_cmd = 0; skreq->n_sg = 0; skreq->sg_byte_count = 0; skreq->discard_page = 0; /* * OK to now dequeue request from q. * * At this point we are comitted to either start or reject * the native request. Note that skd_request_context is * available but is still at the head of the free list. */ blk_start_request(req); skreq->req = req; skreq->fitmsg_id = 0; /* Either a FIT msg is in progress or we have to start one. */ if (skmsg == NULL) { /* Are there any FIT msg buffers available? */ skmsg = skdev->skmsg_free_list; if (skmsg == NULL) { pr_debug("%s:%s:%d Out of msg skdev=%p\n", skdev->name, __func__, __LINE__, skdev); break; } SKD_ASSERT(skmsg->state == SKD_MSG_STATE_IDLE); SKD_ASSERT((skmsg->id & SKD_ID_INCR) == 0); skdev->skmsg_free_list = skmsg->next; skmsg->state = SKD_MSG_STATE_BUSY; skmsg->id += SKD_ID_INCR; /* Initialize the FIT msg header */ fmh = (struct fit_msg_hdr *)skmsg->msg_buf; memset(fmh, 0, sizeof(*fmh)); fmh->protocol_id = FIT_PROTOCOL_ID_SOFIT; skmsg->length = sizeof(*fmh); } skreq->fitmsg_id = skmsg->id; /* * Note that a FIT msg may have just been started * but contains no SoFIT requests yet. */ /* * Transcode the request, checking as we go. The outcome of * the transcoding is represented by the error variable. */ cmd_ptr = &skmsg->msg_buf[skmsg->length]; memset(cmd_ptr, 0, 32); be_lba = cpu_to_be32(lba); be_count = cpu_to_be32(count); be_dmaa = cpu_to_be64((u64)skreq->sksg_dma_address); cmdctxt = skreq->id + SKD_ID_INCR; scsi_req = cmd_ptr; scsi_req->hdr.tag = cmdctxt; scsi_req->hdr.sg_list_dma_address = be_dmaa; if (data_dir == READ) skreq->sg_data_dir = SKD_DATA_DIR_CARD_TO_HOST; else skreq->sg_data_dir = SKD_DATA_DIR_HOST_TO_CARD; if (io_flags & REQ_DISCARD) { page = alloc_page(GFP_ATOMIC | __GFP_ZERO); if (!page) { pr_err("request_fn:Page allocation failed.\n"); skd_end_request(skdev, skreq, -ENOMEM); break; } skreq->discard_page = 1; req->completion_data = page; skd_prep_discard_cdb(scsi_req, skreq, page, lba, count); } else if (flush == SKD_FLUSH_ZERO_SIZE_FIRST) { skd_prep_zerosize_flush_cdb(scsi_req, skreq); SKD_ASSERT(skreq->flush_cmd == 1); } else { skd_prep_rw_cdb(scsi_req, data_dir, lba, count); } if (fua) scsi_req->cdb[1] |= SKD_FUA_NV; if (!req->bio) goto skip_sg; error = skd_preop_sg_list(skdev, skreq); if (error != 0) { /* * Complete the native request with error. * Note that the request context is still at the * head of the free list, and that the SoFIT request * was encoded into the FIT msg buffer but the FIT * msg length has not been updated. In short, the * only resource that has been allocated but might * not be used is that the FIT msg could be empty. */ pr_debug("%s:%s:%d error Out\n", skdev->name, __func__, __LINE__); skd_end_request(skdev, skreq, error); continue; } skip_sg: scsi_req->hdr.sg_list_len_bytes = cpu_to_be32(skreq->sg_byte_count); /* Complete resource allocations. */ skdev->skreq_free_list = skreq->next; skreq->state = SKD_REQ_STATE_BUSY; skreq->id += SKD_ID_INCR; skmsg->length += sizeof(struct skd_scsi_request); fmh->num_protocol_cmds_coalesced++; /* * Update the active request counts. * Capture the timeout timestamp. */ skreq->timeout_stamp = skdev->timeout_stamp; timo_slot = skreq->timeout_stamp & SKD_TIMEOUT_SLOT_MASK; skdev->timeout_slot[timo_slot]++; skdev->in_flight++; pr_debug("%s:%s:%d req=0x%x busy=%d\n", skdev->name, __func__, __LINE__, skreq->id, skdev->in_flight); /* * If the FIT msg buffer is full send it. */ if (skmsg->length >= SKD_N_FITMSG_BYTES || fmh->num_protocol_cmds_coalesced >= skd_max_req_per_msg) { skd_send_fitmsg(skdev, skmsg); skmsg = NULL; fmh = NULL; } } /* * Is a FIT msg in progress? If it is empty put the buffer back * on the free list. If it is non-empty send what we got. * This minimizes latency when there are fewer requests than * what fits in a FIT msg. */ if (skmsg != NULL) { /* Bigger than just a FIT msg header? */ if (skmsg->length > sizeof(struct fit_msg_hdr)) { pr_debug("%s:%s:%d sending msg=%p, len %d\n", skdev->name, __func__, __LINE__, skmsg, skmsg->length); skd_send_fitmsg(skdev, skmsg); } else { /* * The FIT msg is empty. It means we got started * on the msg, but the requests were rejected. */ skmsg->state = SKD_MSG_STATE_IDLE; skmsg->id += SKD_ID_INCR; skmsg->next = skdev->skmsg_free_list; skdev->skmsg_free_list = skmsg; } skmsg = NULL; fmh = NULL; } /* * If req is non-NULL it means there is something to do but * we are out of a resource. */ if (req) blk_stop_queue(skdev->queue); }