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 --- |