예제 #1
0
static void
ptstart(struct cam_periph *periph, union ccb *start_ccb)
{
	struct pt_softc *softc;
	struct buf *bp;
	struct bio *bio;

	softc = (struct pt_softc *)periph->softc;

	/*
	 * See if there is a buf with work for us to do..
	 */
	bio = bioq_first(&softc->bio_queue);
	if (periph->immediate_priority <= periph->pinfo.priority) {
		CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE,
				("queuing for immediate ccb\n"));
		start_ccb->ccb_h.ccb_state = PT_CCB_WAITING;
		SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h,
				  periph_links.sle);
		periph->immediate_priority = CAM_PRIORITY_NONE;
		wakeup(&periph->ccb_list);
	} else if (bio == NULL) {
		xpt_release_ccb(start_ccb);
	} else {
		bioq_remove(&softc->bio_queue, bio);
		bp = bio->bio_buf;

		devstat_start_transaction(&softc->device_stats);

		scsi_send_receive(&start_ccb->csio,
				  /*retries*/4,
				  ptdone,
				  MSG_SIMPLE_Q_TAG,
				  (bp->b_cmd == BUF_CMD_READ),
				  /*byte2*/0,
				  bp->b_bcount,
				  bp->b_data,
				  /*sense_len*/SSD_FULL_SIZE,
				  /*timeout*/softc->io_timeout);

		start_ccb->ccb_h.ccb_state = PT_CCB_BUFFER_IO_UA;

		/*
		 * Block out any asyncronous callbacks
		 * while we touch the pending ccb list.
		 */
		LIST_INSERT_HEAD(&softc->pending_ccbs, &start_ccb->ccb_h,
				 periph_links.le);

		start_ccb->ccb_h.ccb_bio = bio;
		bio = bioq_first(&softc->bio_queue);

		xpt_action(start_ccb);
		
		if (bio != NULL) {
			/* Have more work to do, so ensure we stay scheduled */
			xpt_schedule(periph, /* XXX priority */1);
		}
	}
}
예제 #2
0
static void
ptstart(struct cam_periph *periph, union ccb *start_ccb)
{
    struct pt_softc *softc;
    struct bio *bp;

    softc = (struct pt_softc *)periph->softc;

    CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("ptstart\n"));

    /*
     * See if there is a buf with work for us to do..
     */
    bp = bioq_first(&softc->bio_queue);
    if (bp == NULL) {
        xpt_release_ccb(start_ccb);
    } else {
        bioq_remove(&softc->bio_queue, bp);

        devstat_start_transaction_bio(softc->device_stats, bp);

        scsi_send_receive(&start_ccb->csio,
                          /*retries*/4,
                          ptdone,
                          MSG_SIMPLE_Q_TAG,
                          bp->bio_cmd == BIO_READ,
                          /*byte2*/0,
                          bp->bio_bcount,
                          bp->bio_data,
                          /*sense_len*/SSD_FULL_SIZE,
                          /*timeout*/softc->io_timeout);

        start_ccb->ccb_h.ccb_state = PT_CCB_BUFFER_IO_UA;

        /*
         * Block out any asynchronous callbacks
         * while we touch the pending ccb list.
         */
        LIST_INSERT_HEAD(&softc->pending_ccbs, &start_ccb->ccb_h,
                         periph_links.le);

        start_ccb->ccb_h.ccb_bp = bp;
        bp = bioq_first(&softc->bio_queue);

        xpt_action(start_ccb);

        if (bp != NULL) {
            /* Have more work to do, so ensure we stay scheduled */
            xpt_schedule(periph, CAM_PRIORITY_NORMAL);
        }
    }
}