Deleted Added
full compact
scsi_pass.c (58934) scsi_pass.c (59249)
1/*
2 * Copyright (c) 1997, 1998 Justin T. Gibbs.
3 * Copyright (c) 1997, 1998, 1999 Kenneth D. Merry.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 10 unchanged lines hidden (view full) ---

19 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
1/*
2 * Copyright (c) 1997, 1998 Justin T. Gibbs.
3 * Copyright (c) 1997, 1998, 1999 Kenneth D. Merry.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 10 unchanged lines hidden (view full) ---

19 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 * $FreeBSD: head/sys/cam/scsi/scsi_pass.c 58934 2000-04-02 15:24:56Z phk $
27 * $FreeBSD: head/sys/cam/scsi/scsi_pass.c 59249 2000-04-15 05:54:02Z phk $
28 */
29
30#include <sys/param.h>
31#include <sys/systm.h>
32#include <sys/kernel.h>
33#include <sys/types.h>
34#include <sys/buf.h>
35#include <sys/malloc.h>

--- 34 unchanged lines hidden (view full) ---

70
71#define ccb_type ppriv_field0
72#define ccb_bp ppriv_ptr1
73
74struct pass_softc {
75 pass_state state;
76 pass_flags flags;
77 u_int8_t pd_type;
28 */
29
30#include <sys/param.h>
31#include <sys/systm.h>
32#include <sys/kernel.h>
33#include <sys/types.h>
34#include <sys/buf.h>
35#include <sys/malloc.h>

--- 34 unchanged lines hidden (view full) ---

70
71#define ccb_type ppriv_field0
72#define ccb_bp ppriv_ptr1
73
74struct pass_softc {
75 pass_state state;
76 pass_flags flags;
77 u_int8_t pd_type;
78 struct buf_queue_head buf_queue;
78 struct bio_queue_head bio_queue;
79 union ccb saved_ccb;
80 struct devstat device_stats;
81 dev_t dev;
82};
83
84#ifndef MIN
85#define MIN(x,y) ((x<y) ? x : y)
86#endif

--- 88 unchanged lines hidden (view full) ---

175
176}
177
178static void
179passoninvalidate(struct cam_periph *periph)
180{
181 int s;
182 struct pass_softc *softc;
79 union ccb saved_ccb;
80 struct devstat device_stats;
81 dev_t dev;
82};
83
84#ifndef MIN
85#define MIN(x,y) ((x<y) ? x : y)
86#endif

--- 88 unchanged lines hidden (view full) ---

175
176}
177
178static void
179passoninvalidate(struct cam_periph *periph)
180{
181 int s;
182 struct pass_softc *softc;
183 struct buf *q_bp;
183 struct bio *q_bp;
184 struct ccb_setasync csa;
185
186 softc = (struct pass_softc *)periph->softc;
187
188 /*
189 * De-register any async callbacks.
190 */
191 xpt_setup_ccb(&csa.ccb_h, periph->path,

--- 13 unchanged lines hidden (view full) ---

205 */
206 s = splbio();
207
208 /*
209 * Return all queued I/O with ENXIO.
210 * XXX Handle any transactions queued to the card
211 * with XPT_ABORT_CCB.
212 */
184 struct ccb_setasync csa;
185
186 softc = (struct pass_softc *)periph->softc;
187
188 /*
189 * De-register any async callbacks.
190 */
191 xpt_setup_ccb(&csa.ccb_h, periph->path,

--- 13 unchanged lines hidden (view full) ---

205 */
206 s = splbio();
207
208 /*
209 * Return all queued I/O with ENXIO.
210 * XXX Handle any transactions queued to the card
211 * with XPT_ABORT_CCB.
212 */
213 while ((q_bp = bufq_first(&softc->buf_queue)) != NULL){
214 bufq_remove(&softc->buf_queue, q_bp);
215 q_bp->b_resid = q_bp->b_bcount;
216 q_bp->b_error = ENXIO;
217 q_bp->b_ioflags |= BIO_ERROR;
213 while ((q_bp = bioq_first(&softc->bio_queue)) != NULL){
214 bioq_remove(&softc->bio_queue, q_bp);
215 q_bp->bio_resid = q_bp->bio_bcount;
216 q_bp->bio_error = ENXIO;
217 q_bp->bio_flags |= BIO_ERROR;
218 biodone(q_bp);
219 }
220 splx(s);
221
222 if (bootverbose) {
223 xpt_print_path(periph->path);
224 printf("lost device\n");
225 }

--- 84 unchanged lines hidden (view full) ---

310 printf("passregister: Unable to probe new device. "
311 "Unable to allocate softc\n");
312 return(CAM_REQ_CMP_ERR);
313 }
314
315 bzero(softc, sizeof(*softc));
316 softc->state = PASS_STATE_NORMAL;
317 softc->pd_type = SID_TYPE(&cgd->inq_data);
218 biodone(q_bp);
219 }
220 splx(s);
221
222 if (bootverbose) {
223 xpt_print_path(periph->path);
224 printf("lost device\n");
225 }

--- 84 unchanged lines hidden (view full) ---

310 printf("passregister: Unable to probe new device. "
311 "Unable to allocate softc\n");
312 return(CAM_REQ_CMP_ERR);
313 }
314
315 bzero(softc, sizeof(*softc));
316 softc->state = PASS_STATE_NORMAL;
317 softc->pd_type = SID_TYPE(&cgd->inq_data);
318 bufq_init(&softc->buf_queue);
318 bioq_init(&softc->bio_queue);
319
320 periph->softc = softc;
321
322 cam_extend_set(passperiphs, periph->unit_number, periph);
323 /*
324 * We pass in 0 for a blocksize, since we don't
325 * know what the blocksize of this device is, if
326 * it even has a blocksize.

--- 127 unchanged lines hidden (view full) ---

454}
455
456/*
457 * Actually translate the requested transfer into one the physical driver
458 * can understand. The transfer is described by a buf and will include
459 * only one physical transfer.
460 */
461static void
319
320 periph->softc = softc;
321
322 cam_extend_set(passperiphs, periph->unit_number, periph);
323 /*
324 * We pass in 0 for a blocksize, since we don't
325 * know what the blocksize of this device is, if
326 * it even has a blocksize.

--- 127 unchanged lines hidden (view full) ---

454}
455
456/*
457 * Actually translate the requested transfer into one the physical driver
458 * can understand. The transfer is described by a buf and will include
459 * only one physical transfer.
460 */
461static void
462passstrategy(struct buf *bp)
462passstrategy(struct bio *bp)
463{
464 struct cam_periph *periph;
465 struct pass_softc *softc;
466 u_int unit;
467 int s;
468
469 /*
470 * The read/write interface for the passthrough driver doesn't
471 * really work right now. So, we just pass back EINVAL to tell the
472 * user to go away.
473 */
463{
464 struct cam_periph *periph;
465 struct pass_softc *softc;
466 u_int unit;
467 int s;
468
469 /*
470 * The read/write interface for the passthrough driver doesn't
471 * really work right now. So, we just pass back EINVAL to tell the
472 * user to go away.
473 */
474 bp->b_error = EINVAL;
474 bp->bio_error = EINVAL;
475 goto bad;
476
475 goto bad;
476
477 /* unit = dkunit(bp->b_dev); */
477 /* unit = dkunit(bp->bio_dev); */
478 /* XXX KDM fix this */
478 /* XXX KDM fix this */
479 unit = minor(bp->b_dev) & 0xff;
479 unit = minor(bp->bio_dev) & 0xff;
480
481 periph = cam_extend_get(passperiphs, unit);
482 if (periph == NULL) {
480
481 periph = cam_extend_get(passperiphs, unit);
482 if (periph == NULL) {
483 bp->b_error = ENXIO;
483 bp->bio_error = ENXIO;
484 goto bad;
485 }
486 softc = (struct pass_softc *)periph->softc;
487
488 /*
489 * Odd number of bytes or negative offset
490 */
491 /* valid request? */
484 goto bad;
485 }
486 softc = (struct pass_softc *)periph->softc;
487
488 /*
489 * Odd number of bytes or negative offset
490 */
491 /* valid request? */
492 if (bp->b_blkno < 0) {
493 bp->b_error = EINVAL;
492 if (bp->bio_blkno < 0) {
493 bp->bio_error = EINVAL;
494 goto bad;
495 }
496
497 /*
498 * Mask interrupts so that the pack cannot be invalidated until
499 * after we are in the queue. Otherwise, we might not properly
500 * clean up one of the buffers.
501 */
502 s = splbio();
503
494 goto bad;
495 }
496
497 /*
498 * Mask interrupts so that the pack cannot be invalidated until
499 * after we are in the queue. Otherwise, we might not properly
500 * clean up one of the buffers.
501 */
502 s = splbio();
503
504 bufq_insert_tail(&softc->buf_queue, bp);
504 bioq_insert_tail(&softc->bio_queue, bp);
505
506 splx(s);
507
508 /*
509 * Schedule ourselves for performing the work.
510 */
511 xpt_schedule(periph, /* XXX priority */1);
512
513 return;
514bad:
505
506 splx(s);
507
508 /*
509 * Schedule ourselves for performing the work.
510 */
511 xpt_schedule(periph, /* XXX priority */1);
512
513 return;
514bad:
515 bp->b_ioflags |= BIO_ERROR;
515 bp->bio_flags |= BIO_ERROR;
516
517 /*
518 * Correctly set the buf to indicate a completed xfer
519 */
516
517 /*
518 * Correctly set the buf to indicate a completed xfer
519 */
520 bp->b_resid = bp->b_bcount;
520 bp->bio_resid = bp->bio_bcount;
521 biodone(bp);
522 return;
523}
524
525static void
526passstart(struct cam_periph *periph, union ccb *start_ccb)
527{
528 struct pass_softc *softc;
529 int s;
530
531 softc = (struct pass_softc *)periph->softc;
532
533 switch (softc->state) {
534 case PASS_STATE_NORMAL:
535 {
521 biodone(bp);
522 return;
523}
524
525static void
526passstart(struct cam_periph *periph, union ccb *start_ccb)
527{
528 struct pass_softc *softc;
529 int s;
530
531 softc = (struct pass_softc *)periph->softc;
532
533 switch (softc->state) {
534 case PASS_STATE_NORMAL:
535 {
536 struct buf *bp;
536 struct bio *bp;
537
538 s = splbio();
537
538 s = splbio();
539 bp = bufq_first(&softc->buf_queue);
539 bp = bioq_first(&softc->bio_queue);
540 if (periph->immediate_priority <= periph->pinfo.priority) {
541 start_ccb->ccb_h.ccb_type = PASS_CCB_WAITING;
542 SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h,
543 periph_links.sle);
544 periph->immediate_priority = CAM_PRIORITY_NONE;
545 splx(s);
546 wakeup(&periph->ccb_list);
547 } else if (bp == NULL) {
548 splx(s);
549 xpt_release_ccb(start_ccb);
550 } else {
551
540 if (periph->immediate_priority <= periph->pinfo.priority) {
541 start_ccb->ccb_h.ccb_type = PASS_CCB_WAITING;
542 SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h,
543 periph_links.sle);
544 periph->immediate_priority = CAM_PRIORITY_NONE;
545 splx(s);
546 wakeup(&periph->ccb_list);
547 } else if (bp == NULL) {
548 splx(s);
549 xpt_release_ccb(start_ccb);
550 } else {
551
552 bufq_remove(&softc->buf_queue, bp);
552 bioq_remove(&softc->bio_queue, bp);
553
554 devstat_start_transaction(&softc->device_stats);
555
556 /*
557 * XXX JGibbs -
558 * Interpret the contents of the bp as a CCB
559 * and pass it to a routine shared by our ioctl
560 * code and passtart.
561 * For now, just biodone it with EIO so we don't
562 * hang.
563 */
553
554 devstat_start_transaction(&softc->device_stats);
555
556 /*
557 * XXX JGibbs -
558 * Interpret the contents of the bp as a CCB
559 * and pass it to a routine shared by our ioctl
560 * code and passtart.
561 * For now, just biodone it with EIO so we don't
562 * hang.
563 */
564 bp->b_error = EIO;
565 bp->b_ioflags |= BIO_ERROR;
566 bp->b_resid = bp->b_bcount;
564 bp->bio_error = EIO;
565 bp->bio_flags |= BIO_ERROR;
566 bp->bio_resid = bp->bio_bcount;
567 biodone(bp);
567 biodone(bp);
568 bp = bufq_first(&softc->buf_queue);
568 bp = bioq_first(&softc->bio_queue);
569 splx(s);
570
571 xpt_action(start_ccb);
572
573 }
574 if (bp != NULL) {
575 /* Have more work to do, so ensure we stay scheduled */
576 xpt_schedule(periph, /* XXX priority */1);

--- 8 unchanged lines hidden (view full) ---

585 struct pass_softc *softc;
586 struct ccb_scsiio *csio;
587
588 softc = (struct pass_softc *)periph->softc;
589 csio = &done_ccb->csio;
590 switch (csio->ccb_h.ccb_type) {
591 case PASS_CCB_BUFFER_IO:
592 {
569 splx(s);
570
571 xpt_action(start_ccb);
572
573 }
574 if (bp != NULL) {
575 /* Have more work to do, so ensure we stay scheduled */
576 xpt_schedule(periph, /* XXX priority */1);

--- 8 unchanged lines hidden (view full) ---

585 struct pass_softc *softc;
586 struct ccb_scsiio *csio;
587
588 softc = (struct pass_softc *)periph->softc;
589 csio = &done_ccb->csio;
590 switch (csio->ccb_h.ccb_type) {
591 case PASS_CCB_BUFFER_IO:
592 {
593 struct buf *bp;
593 struct bio *bp;
594 cam_status status;
595 u_int8_t scsi_status;
596 devstat_trans_flags ds_flags;
597
598 status = done_ccb->ccb_h.status;
599 scsi_status = done_ccb->csio.scsi_status;
594 cam_status status;
595 u_int8_t scsi_status;
596 devstat_trans_flags ds_flags;
597
598 status = done_ccb->ccb_h.status;
599 scsi_status = done_ccb->csio.scsi_status;
600 bp = (struct buf *)done_ccb->ccb_h.ccb_bp;
600 bp = (struct bio *)done_ccb->ccb_h.ccb_bp;
601 /* XXX handle errors */
602 if (!(((status & CAM_STATUS_MASK) == CAM_REQ_CMP)
603 && (scsi_status == SCSI_STATUS_OK))) {
604 int error;
605
606 if ((error = passerror(done_ccb, 0, 0)) == ERESTART) {
607 /*
608 * A retry was scheuled, so
609 * just return.
610 */
611 return;
612 }
613
614 /*
615 * XXX unfreeze the queue after we complete
616 * the abort process
617 */
601 /* XXX handle errors */
602 if (!(((status & CAM_STATUS_MASK) == CAM_REQ_CMP)
603 && (scsi_status == SCSI_STATUS_OK))) {
604 int error;
605
606 if ((error = passerror(done_ccb, 0, 0)) == ERESTART) {
607 /*
608 * A retry was scheuled, so
609 * just return.
610 */
611 return;
612 }
613
614 /*
615 * XXX unfreeze the queue after we complete
616 * the abort process
617 */
618 bp->b_error = error;
619 bp->b_ioflags |= BIO_ERROR;
618 bp->bio_error = error;
619 bp->bio_flags |= BIO_ERROR;
620 }
621
622 if ((done_ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
623 ds_flags = DEVSTAT_READ;
624 else if ((done_ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
625 ds_flags = DEVSTAT_WRITE;
626 else
627 ds_flags = DEVSTAT_NO_DATA;
628
620 }
621
622 if ((done_ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
623 ds_flags = DEVSTAT_READ;
624 else if ((done_ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
625 ds_flags = DEVSTAT_WRITE;
626 else
627 ds_flags = DEVSTAT_NO_DATA;
628
629 devstat_end_transaction_buf(&softc->device_stats, bp);
629 devstat_end_transaction_bio(&softc->device_stats, bp);
630 biodone(bp);
631 break;
632 }
633 case PASS_CCB_WAITING:
634 {
635 /* Caller will release the CCB */
636 wakeup(&done_ccb->ccb_h.cbfcnp);
637 return;

--- 188 unchanged lines hidden ---
630 biodone(bp);
631 break;
632 }
633 case PASS_CCB_WAITING:
634 {
635 /* Caller will release the CCB */
636 wakeup(&done_ccb->ccb_h.cbfcnp);
637 return;

--- 188 unchanged lines hidden ---