scsi_pt.c (164906) | scsi_pt.c (168752) |
---|---|
1/*- 2 * Implementation of SCSI Processor Target Peripheral driver for CAM. 3 * 4 * Copyright (c) 1998 Justin T. Gibbs. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 13 unchanged lines hidden (view full) --- 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> | 1/*- 2 * Implementation of SCSI Processor Target Peripheral driver for CAM. 3 * 4 * Copyright (c) 1998 Justin T. Gibbs. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 13 unchanged lines hidden (view full) --- 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> |
30__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_pt.c 164906 2006-12-05 07:45:28Z mjacob $"); | 30__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_pt.c 168752 2007-04-15 08:49:19Z scottl $"); |
31 32#include <sys/param.h> 33#include <sys/queue.h> 34#include <sys/systm.h> 35#include <sys/kernel.h> 36#include <sys/types.h> 37#include <sys/bio.h> 38#include <sys/devicestat.h> --- 75 unchanged lines hidden (view full) --- 114 TAILQ_HEAD_INITIALIZER(ptdriver.units), /* generation */ 0 115}; 116 117PERIPHDRIVER_DECLARE(pt, ptdriver); 118 119 120static struct cdevsw pt_cdevsw = { 121 .d_version = D_VERSION, | 31 32#include <sys/param.h> 33#include <sys/queue.h> 34#include <sys/systm.h> 35#include <sys/kernel.h> 36#include <sys/types.h> 37#include <sys/bio.h> 38#include <sys/devicestat.h> --- 75 unchanged lines hidden (view full) --- 114 TAILQ_HEAD_INITIALIZER(ptdriver.units), /* generation */ 0 115}; 116 117PERIPHDRIVER_DECLARE(pt, ptdriver); 118 119 120static struct cdevsw pt_cdevsw = { 121 .d_version = D_VERSION, |
122 .d_flags = D_NEEDGIANT, | 122 .d_flags = 0, |
123 .d_open = ptopen, 124 .d_close = ptclose, 125 .d_read = physread, 126 .d_write = physwrite, 127 .d_ioctl = ptioctl, 128 .d_strategy = ptstrategy, 129 .d_name = "pt", 130}; 131 132#ifndef SCSI_PT_DEFAULT_TIMEOUT 133#define SCSI_PT_DEFAULT_TIMEOUT 60 134#endif 135 136static int 137ptopen(struct cdev *dev, int flags, int fmt, struct thread *td) 138{ 139 struct cam_periph *periph; 140 struct pt_softc *softc; | 123 .d_open = ptopen, 124 .d_close = ptclose, 125 .d_read = physread, 126 .d_write = physwrite, 127 .d_ioctl = ptioctl, 128 .d_strategy = ptstrategy, 129 .d_name = "pt", 130}; 131 132#ifndef SCSI_PT_DEFAULT_TIMEOUT 133#define SCSI_PT_DEFAULT_TIMEOUT 60 134#endif 135 136static int 137ptopen(struct cdev *dev, int flags, int fmt, struct thread *td) 138{ 139 struct cam_periph *periph; 140 struct pt_softc *softc; |
141 int unit; 142 int error; 143 int s; | 141 int error = 0; |
144 | 142 |
145 unit = minor(dev); | |
146 periph = (struct cam_periph *)dev->si_drv1; | 143 periph = (struct cam_periph *)dev->si_drv1; |
147 if (periph == NULL) | 144 if (cam_periph_acquire(periph) != CAM_REQ_CMP) |
148 return (ENXIO); 149 150 softc = (struct pt_softc *)periph->softc; 151 | 145 return (ENXIO); 146 147 softc = (struct pt_softc *)periph->softc; 148 |
152 s = splsoftcam(); | 149 cam_periph_lock(periph); |
153 if (softc->flags & PT_FLAG_DEVICE_INVALID) { | 150 if (softc->flags & PT_FLAG_DEVICE_INVALID) { |
154 splx(s); | 151 cam_periph_unlock(periph); 152 cam_periph_release(periph); |
155 return(ENXIO); 156 } 157 | 153 return(ENXIO); 154 } 155 |
158 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, 159 ("ptopen: dev=%s (unit %d)\n", devtoname(dev), unit)); 160 161 if ((error = cam_periph_lock(periph, PRIBIO|PCATCH)) != 0) { 162 splx(s); 163 return (error); /* error code from tsleep */ | 156 if ((softc->flags & PT_FLAG_OPEN) == 0) 157 softc->flags |= PT_FLAG_OPEN; 158 else { 159 error = EBUSY; 160 cam_periph_release(periph); |
164 } 165 | 161 } 162 |
166 splx(s); | 163 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, 164 ("ptopen: dev=%s\n", devtoname(dev))); |
167 | 165 |
168 if ((softc->flags & PT_FLAG_OPEN) == 0) { 169 if (cam_periph_acquire(periph) != CAM_REQ_CMP) 170 error = ENXIO; 171 else 172 softc->flags |= PT_FLAG_OPEN; 173 } else 174 error = EBUSY; 175 | |
176 cam_periph_unlock(periph); 177 return (error); 178} 179 180static int 181ptclose(struct cdev *dev, int flag, int fmt, struct thread *td) 182{ 183 struct cam_periph *periph; 184 struct pt_softc *softc; | 166 cam_periph_unlock(periph); 167 return (error); 168} 169 170static int 171ptclose(struct cdev *dev, int flag, int fmt, struct thread *td) 172{ 173 struct cam_periph *periph; 174 struct pt_softc *softc; |
185 int error; | |
186 187 periph = (struct cam_periph *)dev->si_drv1; 188 if (periph == NULL) 189 return (ENXIO); 190 191 softc = (struct pt_softc *)periph->softc; 192 | 175 176 periph = (struct cam_periph *)dev->si_drv1; 177 if (periph == NULL) 178 return (ENXIO); 179 180 softc = (struct pt_softc *)periph->softc; 181 |
193 if ((error = cam_periph_lock(periph, PRIBIO)) != 0) 194 return (error); /* error code from tsleep */ | 182 cam_periph_lock(periph); |
195 196 softc->flags &= ~PT_FLAG_OPEN; 197 cam_periph_unlock(periph); 198 cam_periph_release(periph); 199 return (0); 200} 201 202/* 203 * Actually translate the requested transfer into one the physical driver 204 * can understand. The transfer is described by a buf and will include 205 * only one physical transfer. 206 */ 207static void 208ptstrategy(struct bio *bp) 209{ 210 struct cam_periph *periph; 211 struct pt_softc *softc; | 183 184 softc->flags &= ~PT_FLAG_OPEN; 185 cam_periph_unlock(periph); 186 cam_periph_release(periph); 187 return (0); 188} 189 190/* 191 * Actually translate the requested transfer into one the physical driver 192 * can understand. The transfer is described by a buf and will include 193 * only one physical transfer. 194 */ 195static void 196ptstrategy(struct bio *bp) 197{ 198 struct cam_periph *periph; 199 struct pt_softc *softc; |
212 int s; | |
213 214 periph = (struct cam_periph *)bp->bio_dev->si_drv1; 215 bp->bio_resid = bp->bio_bcount; 216 if (periph == NULL) { 217 biofinish(bp, NULL, ENXIO); 218 return; 219 } | 200 201 periph = (struct cam_periph *)bp->bio_dev->si_drv1; 202 bp->bio_resid = bp->bio_bcount; 203 if (periph == NULL) { 204 biofinish(bp, NULL, ENXIO); 205 return; 206 } |
207 cam_periph_lock(periph); |
|
220 softc = (struct pt_softc *)periph->softc; 221 222 /* | 208 softc = (struct pt_softc *)periph->softc; 209 210 /* |
223 * Mask interrupts so that the pack cannot be invalidated until 224 * after we are in the queue. Otherwise, we might not properly 225 * clean up one of the buffers. 226 */ 227 s = splbio(); 228 229 /* | |
230 * If the device has been made invalid, error out 231 */ 232 if ((softc->flags & PT_FLAG_DEVICE_INVALID)) { | 211 * If the device has been made invalid, error out 212 */ 213 if ((softc->flags & PT_FLAG_DEVICE_INVALID)) { |
233 splx(s); | 214 cam_periph_unlock(periph); |
234 biofinish(bp, NULL, ENXIO); 235 return; 236 } 237 238 /* 239 * Place it in the queue of disk activities for this disk 240 */ 241 bioq_insert_tail(&softc->bio_queue, bp); 242 | 215 biofinish(bp, NULL, ENXIO); 216 return; 217 } 218 219 /* 220 * Place it in the queue of disk activities for this disk 221 */ 222 bioq_insert_tail(&softc->bio_queue, bp); 223 |
243 splx(s); 244 | |
245 /* 246 * Schedule ourselves for performing the work. 247 */ 248 xpt_schedule(periph, /* XXX priority */1); | 224 /* 225 * Schedule ourselves for performing the work. 226 */ 227 xpt_schedule(periph, /* XXX priority */1); |
228 cam_periph_unlock(periph); |
|
249 250 return; 251} 252 253static void 254ptinit(void) 255{ 256 cam_status status; --- 90 unchanged lines hidden (view full) --- 347 xpt_announce_periph(periph, NULL); 348 349 return(CAM_REQ_CMP); 350} 351 352static void 353ptoninvalidate(struct cam_periph *periph) 354{ | 229 230 return; 231} 232 233static void 234ptinit(void) 235{ 236 cam_status status; --- 90 unchanged lines hidden (view full) --- 327 xpt_announce_periph(periph, NULL); 328 329 return(CAM_REQ_CMP); 330} 331 332static void 333ptoninvalidate(struct cam_periph *periph) 334{ |
355 int s; | |
356 struct pt_softc *softc; 357 struct ccb_setasync csa; 358 359 softc = (struct pt_softc *)periph->softc; 360 361 /* 362 * De-register any async callbacks. 363 */ 364 xpt_setup_ccb(&csa.ccb_h, periph->path, 365 /* priority */ 5); 366 csa.ccb_h.func_code = XPT_SASYNC_CB; 367 csa.event_enable = 0; 368 csa.callback = ptasync; 369 csa.callback_arg = periph; 370 xpt_action((union ccb *)&csa); 371 372 softc->flags |= PT_FLAG_DEVICE_INVALID; 373 374 /* | 335 struct pt_softc *softc; 336 struct ccb_setasync csa; 337 338 softc = (struct pt_softc *)periph->softc; 339 340 /* 341 * De-register any async callbacks. 342 */ 343 xpt_setup_ccb(&csa.ccb_h, periph->path, 344 /* priority */ 5); 345 csa.ccb_h.func_code = XPT_SASYNC_CB; 346 csa.event_enable = 0; 347 csa.callback = ptasync; 348 csa.callback_arg = periph; 349 xpt_action((union ccb *)&csa); 350 351 softc->flags |= PT_FLAG_DEVICE_INVALID; 352 353 /* |
375 * Although the oninvalidate() routines are always called at 376 * splsoftcam, we need to be at splbio() here to keep the buffer 377 * queue from being modified while we traverse it. 378 */ 379 s = splbio(); 380 381 /* | |
382 * Return all queued I/O with ENXIO. 383 * XXX Handle any transactions queued to the card 384 * with XPT_ABORT_CCB. 385 */ 386 bioq_flush(&softc->bio_queue, NULL, ENXIO); 387 | 354 * Return all queued I/O with ENXIO. 355 * XXX Handle any transactions queued to the card 356 * with XPT_ABORT_CCB. 357 */ 358 bioq_flush(&softc->bio_queue, NULL, ENXIO); 359 |
388 splx(s); 389 | |
390 xpt_print(periph->path, "lost device\n"); 391} 392 393static void 394ptdtor(struct cam_periph *periph) 395{ 396 struct pt_softc *softc; 397 --- 42 unchanged lines hidden (view full) --- 440 "due to status 0x%x\n", status); 441 break; 442 } 443 case AC_SENT_BDR: 444 case AC_BUS_RESET: 445 { 446 struct pt_softc *softc; 447 struct ccb_hdr *ccbh; | 360 xpt_print(periph->path, "lost device\n"); 361} 362 363static void 364ptdtor(struct cam_periph *periph) 365{ 366 struct pt_softc *softc; 367 --- 42 unchanged lines hidden (view full) --- 410 "due to status 0x%x\n", status); 411 break; 412 } 413 case AC_SENT_BDR: 414 case AC_BUS_RESET: 415 { 416 struct pt_softc *softc; 417 struct ccb_hdr *ccbh; |
448 int s; | |
449 450 softc = (struct pt_softc *)periph->softc; | 418 419 softc = (struct pt_softc *)periph->softc; |
451 s = splsoftcam(); | |
452 /* 453 * Don't fail on the expected unit attention 454 * that will occur. 455 */ 456 softc->flags |= PT_FLAG_RETRY_UA; 457 LIST_FOREACH(ccbh, &softc->pending_ccbs, periph_links.le) 458 ccbh->ccb_state |= PT_CCB_RETRY_UA; | 420 /* 421 * Don't fail on the expected unit attention 422 * that will occur. 423 */ 424 softc->flags |= PT_FLAG_RETRY_UA; 425 LIST_FOREACH(ccbh, &softc->pending_ccbs, periph_links.le) 426 ccbh->ccb_state |= PT_CCB_RETRY_UA; |
459 splx(s); | |
460 } 461 /* FALLTHROUGH */ 462 default: 463 cam_periph_async(periph, code, path, arg); 464 break; 465 } 466} 467 468static void 469ptstart(struct cam_periph *periph, union ccb *start_ccb) 470{ 471 struct pt_softc *softc; 472 struct bio *bp; | 427 } 428 /* FALLTHROUGH */ 429 default: 430 cam_periph_async(periph, code, path, arg); 431 break; 432 } 433} 434 435static void 436ptstart(struct cam_periph *periph, union ccb *start_ccb) 437{ 438 struct pt_softc *softc; 439 struct bio *bp; |
473 int s; | |
474 475 softc = (struct pt_softc *)periph->softc; 476 477 /* 478 * See if there is a buf with work for us to do.. 479 */ | 440 441 softc = (struct pt_softc *)periph->softc; 442 443 /* 444 * See if there is a buf with work for us to do.. 445 */ |
480 s = splbio(); | |
481 bp = bioq_first(&softc->bio_queue); 482 if (periph->immediate_priority <= periph->pinfo.priority) { 483 CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE, 484 ("queuing for immediate ccb\n")); 485 start_ccb->ccb_h.ccb_state = PT_CCB_WAITING; 486 SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h, 487 periph_links.sle); 488 periph->immediate_priority = CAM_PRIORITY_NONE; | 446 bp = bioq_first(&softc->bio_queue); 447 if (periph->immediate_priority <= periph->pinfo.priority) { 448 CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE, 449 ("queuing for immediate ccb\n")); 450 start_ccb->ccb_h.ccb_state = PT_CCB_WAITING; 451 SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h, 452 periph_links.sle); 453 periph->immediate_priority = CAM_PRIORITY_NONE; |
489 splx(s); | |
490 wakeup(&periph->ccb_list); 491 } else if (bp == NULL) { | 454 wakeup(&periph->ccb_list); 455 } else if (bp == NULL) { |
492 splx(s); | |
493 xpt_release_ccb(start_ccb); 494 } else { | 456 xpt_release_ccb(start_ccb); 457 } else { |
495 int oldspl; 496 | |
497 bioq_remove(&softc->bio_queue, bp); 498 499 devstat_start_transaction_bio(softc->device_stats, bp); 500 501 scsi_send_receive(&start_ccb->csio, 502 /*retries*/4, 503 ptdone, 504 MSG_SIMPLE_Q_TAG, --- 5 unchanged lines hidden (view full) --- 510 /*timeout*/softc->io_timeout); 511 512 start_ccb->ccb_h.ccb_state = PT_CCB_BUFFER_IO_UA; 513 514 /* 515 * Block out any asyncronous callbacks 516 * while we touch the pending ccb list. 517 */ | 458 bioq_remove(&softc->bio_queue, bp); 459 460 devstat_start_transaction_bio(softc->device_stats, bp); 461 462 scsi_send_receive(&start_ccb->csio, 463 /*retries*/4, 464 ptdone, 465 MSG_SIMPLE_Q_TAG, --- 5 unchanged lines hidden (view full) --- 471 /*timeout*/softc->io_timeout); 472 473 start_ccb->ccb_h.ccb_state = PT_CCB_BUFFER_IO_UA; 474 475 /* 476 * Block out any asyncronous callbacks 477 * while we touch the pending ccb list. 478 */ |
518 oldspl = splcam(); | |
519 LIST_INSERT_HEAD(&softc->pending_ccbs, &start_ccb->ccb_h, 520 periph_links.le); | 479 LIST_INSERT_HEAD(&softc->pending_ccbs, &start_ccb->ccb_h, 480 periph_links.le); |
521 splx(oldspl); | |
522 523 start_ccb->ccb_h.ccb_bp = bp; 524 bp = bioq_first(&softc->bio_queue); | 481 482 start_ccb->ccb_h.ccb_bp = bp; 483 bp = bioq_first(&softc->bio_queue); |
525 splx(s); | |
526 527 xpt_action(start_ccb); 528 529 if (bp != NULL) { 530 /* Have more work to do, so ensure we stay scheduled */ 531 xpt_schedule(periph, /* XXX priority */1); 532 } 533 } --- 7 unchanged lines hidden (view full) --- 541 542 softc = (struct pt_softc *)periph->softc; 543 csio = &done_ccb->csio; 544 switch (csio->ccb_h.ccb_state) { 545 case PT_CCB_BUFFER_IO: 546 case PT_CCB_BUFFER_IO_UA: 547 { 548 struct bio *bp; | 484 485 xpt_action(start_ccb); 486 487 if (bp != NULL) { 488 /* Have more work to do, so ensure we stay scheduled */ 489 xpt_schedule(periph, /* XXX priority */1); 490 } 491 } --- 7 unchanged lines hidden (view full) --- 499 500 softc = (struct pt_softc *)periph->softc; 501 csio = &done_ccb->csio; 502 switch (csio->ccb_h.ccb_state) { 503 case PT_CCB_BUFFER_IO: 504 case PT_CCB_BUFFER_IO_UA: 505 { 506 struct bio *bp; |
549 int oldspl; | |
550 551 bp = (struct bio *)done_ccb->ccb_h.ccb_bp; 552 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 553 int error; | 507 508 bp = (struct bio *)done_ccb->ccb_h.ccb_bp; 509 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 510 int error; |
554 int s; | |
555 int sf; 556 557 if ((csio->ccb_h.ccb_state & PT_CCB_RETRY_UA) != 0) 558 sf = SF_RETRY_UA; 559 else 560 sf = 0; 561 562 error = pterror(done_ccb, CAM_RETRY_SELTO, sf); 563 if (error == ERESTART) { 564 /* 565 * A retry was scheuled, so 566 * just return. 567 */ 568 return; 569 } 570 if (error != 0) { | 511 int sf; 512 513 if ((csio->ccb_h.ccb_state & PT_CCB_RETRY_UA) != 0) 514 sf = SF_RETRY_UA; 515 else 516 sf = 0; 517 518 error = pterror(done_ccb, CAM_RETRY_SELTO, sf); 519 if (error == ERESTART) { 520 /* 521 * A retry was scheuled, so 522 * just return. 523 */ 524 return; 525 } 526 if (error != 0) { |
571 s = splbio(); 572 | |
573 if (error == ENXIO) { 574 /* 575 * Catastrophic error. Mark our device 576 * as invalid. 577 */ 578 xpt_print(periph->path, 579 "Invalidating device\n"); 580 softc->flags |= PT_FLAG_DEVICE_INVALID; 581 } 582 583 /* 584 * return all queued I/O with EIO, so that 585 * the client can retry these I/Os in the 586 * proper order should it attempt to recover. 587 */ 588 bioq_flush(&softc->bio_queue, NULL, EIO); | 527 if (error == ENXIO) { 528 /* 529 * Catastrophic error. Mark our device 530 * as invalid. 531 */ 532 xpt_print(periph->path, 533 "Invalidating device\n"); 534 softc->flags |= PT_FLAG_DEVICE_INVALID; 535 } 536 537 /* 538 * return all queued I/O with EIO, so that 539 * the client can retry these I/Os in the 540 * proper order should it attempt to recover. 541 */ 542 bioq_flush(&softc->bio_queue, NULL, EIO); |
589 splx(s); | |
590 bp->bio_error = error; 591 bp->bio_resid = bp->bio_bcount; 592 bp->bio_flags |= BIO_ERROR; 593 } else { 594 bp->bio_resid = csio->resid; 595 bp->bio_error = 0; 596 if (bp->bio_resid != 0) { 597 /* Short transfer ??? */ --- 11 unchanged lines hidden (view full) --- 609 if (bp->bio_resid != 0) 610 bp->bio_flags |= BIO_ERROR; 611 } 612 613 /* 614 * Block out any asyncronous callbacks 615 * while we touch the pending ccb list. 616 */ | 543 bp->bio_error = error; 544 bp->bio_resid = bp->bio_bcount; 545 bp->bio_flags |= BIO_ERROR; 546 } else { 547 bp->bio_resid = csio->resid; 548 bp->bio_error = 0; 549 if (bp->bio_resid != 0) { 550 /* Short transfer ??? */ --- 11 unchanged lines hidden (view full) --- 562 if (bp->bio_resid != 0) 563 bp->bio_flags |= BIO_ERROR; 564 } 565 566 /* 567 * Block out any asyncronous callbacks 568 * while we touch the pending ccb list. 569 */ |
617 oldspl = splcam(); | |
618 LIST_REMOVE(&done_ccb->ccb_h, periph_links.le); | 570 LIST_REMOVE(&done_ccb->ccb_h, periph_links.le); |
619 splx(oldspl); | |
620 621 biofinish(bp, softc->device_stats, 0); 622 break; 623 } 624 case PT_CCB_WAITING: 625 /* Caller will release the CCB */ 626 wakeup(&done_ccb->ccb_h.cbfcnp); 627 return; --- 14 unchanged lines hidden (view full) --- 642 &softc->saved_ccb)); 643} 644 645static int 646ptioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td) 647{ 648 struct cam_periph *periph; 649 struct pt_softc *softc; | 571 572 biofinish(bp, softc->device_stats, 0); 573 break; 574 } 575 case PT_CCB_WAITING: 576 /* Caller will release the CCB */ 577 wakeup(&done_ccb->ccb_h.cbfcnp); 578 return; --- 14 unchanged lines hidden (view full) --- 593 &softc->saved_ccb)); 594} 595 596static int 597ptioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td) 598{ 599 struct cam_periph *periph; 600 struct pt_softc *softc; |
650 int error; | 601 int error = 0; |
651 652 periph = (struct cam_periph *)dev->si_drv1; 653 if (periph == NULL) 654 return(ENXIO); 655 656 softc = (struct pt_softc *)periph->softc; 657 | 602 603 periph = (struct cam_periph *)dev->si_drv1; 604 if (periph == NULL) 605 return(ENXIO); 606 607 softc = (struct pt_softc *)periph->softc; 608 |
658 if ((error = cam_periph_lock(periph, PRIBIO|PCATCH)) != 0) { 659 return (error); /* error code from tsleep */ 660 } | 609 cam_periph_lock(periph); |
661 662 switch(cmd) { 663 case PTIOCGETTIMEOUT: 664 if (softc->io_timeout >= 1000) 665 *(int *)addr = softc->io_timeout / 1000; 666 else 667 *(int *)addr = 0; 668 break; 669 case PTIOCSETTIMEOUT: | 610 611 switch(cmd) { 612 case PTIOCGETTIMEOUT: 613 if (softc->io_timeout >= 1000) 614 *(int *)addr = softc->io_timeout / 1000; 615 else 616 *(int *)addr = 0; 617 break; 618 case PTIOCSETTIMEOUT: |
670 { 671 int s; 672 | |
673 if (*(int *)addr < 1) { 674 error = EINVAL; 675 break; 676 } 677 | 619 if (*(int *)addr < 1) { 620 error = EINVAL; 621 break; 622 } 623 |
678 s = splsoftcam(); | |
679 softc->io_timeout = *(int *)addr * 1000; | 624 softc->io_timeout = *(int *)addr * 1000; |
680 splx(s); | |
681 682 break; | 625 626 break; |
683 } | |
684 default: 685 error = cam_periph_ioctl(periph, cmd, addr, pterror); 686 break; 687 } 688 689 cam_periph_unlock(periph); 690 691 return(error); --- 28 unchanged lines hidden --- | 627 default: 628 error = cam_periph_ioctl(periph, cmd, addr, pterror); 629 break; 630 } 631 632 cam_periph_unlock(periph); 633 634 return(error); --- 28 unchanged lines hidden --- |