isp_freebsd.c (64176) | isp_freebsd.c (65140) |
---|---|
1/* $FreeBSD: head/sys/dev/isp/isp_freebsd.c 64176 2000-08-03 03:05:50Z mjacob $ */ | 1/* $FreeBSD: head/sys/dev/isp/isp_freebsd.c 65140 2000-08-27 23:38:44Z mjacob $ */ |
2/* 3 * Platform (FreeBSD) dependent common attachment code for Qlogic adapters. 4 * | 2/* 3 * Platform (FreeBSD) dependent common attachment code for Qlogic adapters. 4 * |
5 *--------------------------------------- 6 * Copyright (c) 1997, 1998, 1999 by Matthew Jacob 7 * NASA/Ames Research Center 8 * All rights reserved. 9 *--------------------------------------- | 5 * Copyright (c) 1997, 1998, 1999, 2000 by Matthew Jacob |
10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice immediately at the beginning of the file, without modification, 16 * this list of conditions, and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. | 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice immediately at the beginning of the file, without modification, 12 * this list of conditions, and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. |
20 * 3. The name of the author may not be used to endorse or promote products 21 * derived from this software without specific prior written permission. | |
22 * 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 27 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) --- 129 unchanged lines hidden (view full) --- 159 } 160} 161 162static void 163isp_intr_enable(void *arg) 164{ 165 struct ispsoftc *isp = arg; 166 ENABLE_INTS(isp); | 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) --- 129 unchanged lines hidden (view full) --- 153 } 154} 155 156static void 157isp_intr_enable(void *arg) 158{ 159 struct ispsoftc *isp = arg; 160 ENABLE_INTS(isp); |
161#ifdef SERVICING_INTERRUPT |
|
167 isp->isp_osinfo.intsok = 1; | 162 isp->isp_osinfo.intsok = 1; |
163#endif |
|
168 /* Release our hook so that the boot can continue. */ 169 config_intrhook_disestablish(&isp->isp_osinfo.ehook); 170} 171 172/* 173 * Put the target mode functions here, because some are inlines 174 */ 175 --- 218 unchanged lines hidden (view full) --- 394 395static void 396isp_en_lun(struct ispsoftc *isp, union ccb *ccb) 397{ 398 const char *lfmt = "Lun now %sabled for target mode\n"; 399 struct ccb_en_lun *cel = &ccb->cel; 400 tstate_t *tptr; 401 u_int16_t rstat; | 164 /* Release our hook so that the boot can continue. */ 165 config_intrhook_disestablish(&isp->isp_osinfo.ehook); 166} 167 168/* 169 * Put the target mode functions here, because some are inlines 170 */ 171 --- 218 unchanged lines hidden (view full) --- 390 391static void 392isp_en_lun(struct ispsoftc *isp, union ccb *ccb) 393{ 394 const char *lfmt = "Lun now %sabled for target mode\n"; 395 struct ccb_en_lun *cel = &ccb->cel; 396 tstate_t *tptr; 397 u_int16_t rstat; |
402 int bus; | 398 int bus, frozen = 0; |
403 lun_id_t lun; 404 target_id_t tgt; 405 406 407 bus = XS_CHANNEL(ccb); 408 tgt = ccb->ccb_h.target_id; 409 lun = ccb->ccb_h.target_lun; 410 411 /* | 399 lun_id_t lun; 400 target_id_t tgt; 401 402 403 bus = XS_CHANNEL(ccb); 404 tgt = ccb->ccb_h.target_id; 405 lun = ccb->ccb_h.target_lun; 406 407 /* |
412 * First, check to see if we're enabling on fibre channel 413 * and don't yet have a notion of who the heck we are (no | 408 * Do some sanity checking first. 409 */ 410 411 if (lun < 0 || lun >= (lun_id_t) isp->isp_maxluns) { 412 ccb->ccb_h.status = CAM_LUN_INVALID; 413 return; 414 } 415 if (IS_SCSI(isp)) { 416 if (tgt != CAM_TARGET_WILDCARD && 417 tgt != ((sdparam *) isp->isp_param)->isp_initiator_id) { 418 ccb->ccb_h.status = CAM_TID_INVALID; 419 return; 420 } 421 } else { 422 if (tgt != CAM_TARGET_WILDCARD && 423 tgt != ((fcparam *) isp->isp_param)->isp_loopid) { 424 ccb->ccb_h.status = CAM_TID_INVALID; 425 return; 426 } 427 } 428 429 /* 430 * If Fibre Channel, stop and drain all activity to this bus. 431 */ 432 if (IS_FC(isp)) { 433 ISP_LOCK(isp); 434 frozen = 1; 435 xpt_freeze_simq(isp->isp_sim, 1); 436 isp->isp_osinfo.drain = 1; 437 /* ISP_UNLOCK(isp); XXX NEED CV_WAIT HERE XXX */ 438 while (isp->isp_osinfo.drain) { 439 tsleep(&isp->isp_osinfo.drain, PRIBIO, "ispdrain", 0); 440 } 441 ISP_UNLOCK(isp); 442 } 443 444 /* 445 * Check to see if we're enabling on fibre channel and 446 * don't yet have a notion of who the heck we are (no |
414 * loop yet). 415 */ 416 if (IS_FC(isp) && cel->enable && 417 (isp->isp_osinfo.tmflags & TM_TMODE_ENABLED) == 0) { 418 int rv= 2 * 1000000; 419 fcparam *fcp = isp->isp_param; 420 421 ISP_LOCK(isp); 422 rv = isp_control(isp, ISPCTL_FCLINK_TEST, &rv); 423 ISP_UNLOCK(isp); 424 if (rv || fcp->isp_fwstate != FW_READY) { 425 xpt_print_path(ccb->ccb_h.path); 426 printf("link status not good yet\n"); 427 ccb->ccb_h.status = CAM_REQ_CMP_ERR; | 447 * loop yet). 448 */ 449 if (IS_FC(isp) && cel->enable && 450 (isp->isp_osinfo.tmflags & TM_TMODE_ENABLED) == 0) { 451 int rv= 2 * 1000000; 452 fcparam *fcp = isp->isp_param; 453 454 ISP_LOCK(isp); 455 rv = isp_control(isp, ISPCTL_FCLINK_TEST, &rv); 456 ISP_UNLOCK(isp); 457 if (rv || fcp->isp_fwstate != FW_READY) { 458 xpt_print_path(ccb->ccb_h.path); 459 printf("link status not good yet\n"); 460 ccb->ccb_h.status = CAM_REQ_CMP_ERR; |
461 if (frozen) 462 xpt_release_simq(isp->isp_sim, 1); |
|
428 return; 429 } 430 ISP_LOCK(isp); 431 rv = isp_control(isp, ISPCTL_PDB_SYNC, NULL); 432 ISP_UNLOCK(isp); 433 if (rv || fcp->isp_fwstate != FW_READY) { 434 xpt_print_path(ccb->ccb_h.path); 435 printf("could not get a good port database read\n"); 436 ccb->ccb_h.status = CAM_REQ_CMP_ERR; | 463 return; 464 } 465 ISP_LOCK(isp); 466 rv = isp_control(isp, ISPCTL_PDB_SYNC, NULL); 467 ISP_UNLOCK(isp); 468 if (rv || fcp->isp_fwstate != FW_READY) { 469 xpt_print_path(ccb->ccb_h.path); 470 printf("could not get a good port database read\n"); 471 ccb->ccb_h.status = CAM_REQ_CMP_ERR; |
472 if (frozen) 473 xpt_release_simq(isp->isp_sim, 1); |
|
437 return; 438 } 439 } 440 441 442 /* 443 * Next check to see whether this is a target/lun wildcard action. 444 * 445 * If so, we enable/disable target mode but don't do any lun enabling. 446 */ 447 if (lun == CAM_LUN_WILDCARD && tgt == CAM_TARGET_WILDCARD) { 448 int av; 449 tptr = &isp->isp_osinfo.tsdflt; 450 if (cel->enable) { 451 if (isp->isp_osinfo.tmflags & TM_TMODE_ENABLED) { 452 ccb->ccb_h.status = CAM_LUN_ALRDY_ENA; | 474 return; 475 } 476 } 477 478 479 /* 480 * Next check to see whether this is a target/lun wildcard action. 481 * 482 * If so, we enable/disable target mode but don't do any lun enabling. 483 */ 484 if (lun == CAM_LUN_WILDCARD && tgt == CAM_TARGET_WILDCARD) { 485 int av; 486 tptr = &isp->isp_osinfo.tsdflt; 487 if (cel->enable) { 488 if (isp->isp_osinfo.tmflags & TM_TMODE_ENABLED) { 489 ccb->ccb_h.status = CAM_LUN_ALRDY_ENA; |
490 if (frozen) 491 xpt_release_simq(isp->isp_sim, 1); |
|
453 return; 454 } 455 ccb->ccb_h.status = 456 xpt_create_path(&tptr->owner, NULL, 457 xpt_path_path_id(ccb->ccb_h.path), 458 xpt_path_target_id(ccb->ccb_h.path), 459 xpt_path_lun_id(ccb->ccb_h.path)); 460 if (ccb->ccb_h.status != CAM_REQ_CMP) { | 492 return; 493 } 494 ccb->ccb_h.status = 495 xpt_create_path(&tptr->owner, NULL, 496 xpt_path_path_id(ccb->ccb_h.path), 497 xpt_path_target_id(ccb->ccb_h.path), 498 xpt_path_lun_id(ccb->ccb_h.path)); 499 if (ccb->ccb_h.status != CAM_REQ_CMP) { |
500 if (frozen) 501 xpt_release_simq(isp->isp_sim, 1); |
|
461 return; 462 } 463 SLIST_INIT(&tptr->atios); 464 SLIST_INIT(&tptr->inots); 465 av = 1; 466 ISP_LOCK(isp); 467 av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av); 468 if (av) { 469 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; 470 xpt_free_path(tptr->owner); 471 ISP_UNLOCK(isp); | 502 return; 503 } 504 SLIST_INIT(&tptr->atios); 505 SLIST_INIT(&tptr->inots); 506 av = 1; 507 ISP_LOCK(isp); 508 av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av); 509 if (av) { 510 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; 511 xpt_free_path(tptr->owner); 512 ISP_UNLOCK(isp); |
513 if (frozen) 514 xpt_release_simq(isp->isp_sim, 1); |
|
472 return; 473 } 474 isp->isp_osinfo.tmflags |= TM_TMODE_ENABLED; 475 ISP_UNLOCK(isp); 476 } else { 477 if ((isp->isp_osinfo.tmflags & TM_TMODE_ENABLED) == 0) { 478 ccb->ccb_h.status = CAM_LUN_INVALID; | 515 return; 516 } 517 isp->isp_osinfo.tmflags |= TM_TMODE_ENABLED; 518 ISP_UNLOCK(isp); 519 } else { 520 if ((isp->isp_osinfo.tmflags & TM_TMODE_ENABLED) == 0) { 521 ccb->ccb_h.status = CAM_LUN_INVALID; |
522 if (frozen) 523 xpt_release_simq(isp->isp_sim, 1); |
|
479 return; 480 } 481 if (are_any_luns_enabled(isp)) { 482 ccb->ccb_h.status = CAM_SCSI_BUSY; | 524 return; 525 } 526 if (are_any_luns_enabled(isp)) { 527 ccb->ccb_h.status = CAM_SCSI_BUSY; |
528 if (frozen) 529 xpt_release_simq(isp->isp_sim, 1); |
|
483 return; 484 } 485 av = 0; 486 ISP_LOCK(isp); 487 av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av); 488 if (av) { 489 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; 490 ISP_UNLOCK(isp); | 530 return; 531 } 532 av = 0; 533 ISP_LOCK(isp); 534 av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av); 535 if (av) { 536 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; 537 ISP_UNLOCK(isp); |
538 if (frozen) 539 xpt_release_simq(isp->isp_sim, 1); |
|
491 return; 492 } 493 isp->isp_osinfo.tmflags &= ~TM_TMODE_ENABLED; 494 ISP_UNLOCK(isp); 495 ccb->ccb_h.status = CAM_REQ_CMP; 496 } 497 xpt_print_path(ccb->ccb_h.path); 498 printf(lfmt, (cel->enable) ? "en" : "dis"); | 540 return; 541 } 542 isp->isp_osinfo.tmflags &= ~TM_TMODE_ENABLED; 543 ISP_UNLOCK(isp); 544 ccb->ccb_h.status = CAM_REQ_CMP; 545 } 546 xpt_print_path(ccb->ccb_h.path); 547 printf(lfmt, (cel->enable) ? "en" : "dis"); |
548 if (frozen) 549 xpt_release_simq(isp->isp_sim, 1); |
|
499 return; 500 } 501 502 /* | 550 return; 551 } 552 553 /* |
503 * Do some sanity checking first. | 554 * We can move along now... |
504 */ 505 | 555 */ 556 |
506 if (lun < 0 || lun >= (lun_id_t) isp->isp_maxluns) { 507 ccb->ccb_h.status = CAM_LUN_INVALID; 508 return; 509 } 510 if (IS_SCSI(isp)) { 511 if (tgt != CAM_TARGET_WILDCARD && 512 tgt != ((sdparam *) isp->isp_param)->isp_initiator_id) { 513 ccb->ccb_h.status = CAM_TID_INVALID; 514 return; 515 } 516 } else { 517 if (tgt != CAM_TARGET_WILDCARD && 518 tgt != ((fcparam *) isp->isp_param)->isp_loopid) { 519 ccb->ccb_h.status = CAM_TID_INVALID; 520 return; 521 } 522 } | 557 if (frozen) 558 xpt_release_simq(isp->isp_sim, 1); |
523 524 525 if (cel->enable) { 526 ccb->ccb_h.status = 527 create_lun_state(isp, ccb->ccb_h.path, &tptr); 528 if (ccb->ccb_h.status != CAM_REQ_CMP) { 529 return; 530 } --- 881 unchanged lines hidden (view full) --- 1412 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("isp_action\n")); 1413 1414 isp = (struct ispsoftc *)cam_sim_softc(sim); 1415 ccb->ccb_h.sim_priv.entries[0].field = 0; 1416 ccb->ccb_h.sim_priv.entries[1].ptr = isp; 1417 if (isp->isp_state != ISP_RUNSTATE && 1418 ccb->ccb_h.func_code == XPT_SCSI_IO) { 1419 ISP_LOCK(isp); | 559 560 561 if (cel->enable) { 562 ccb->ccb_h.status = 563 create_lun_state(isp, ccb->ccb_h.path, &tptr); 564 if (ccb->ccb_h.status != CAM_REQ_CMP) { 565 return; 566 } --- 881 unchanged lines hidden (view full) --- 1448 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("isp_action\n")); 1449 1450 isp = (struct ispsoftc *)cam_sim_softc(sim); 1451 ccb->ccb_h.sim_priv.entries[0].field = 0; 1452 ccb->ccb_h.sim_priv.entries[1].ptr = isp; 1453 if (isp->isp_state != ISP_RUNSTATE && 1454 ccb->ccb_h.func_code == XPT_SCSI_IO) { 1455 ISP_LOCK(isp); |
1420 DISABLE_INTS(isp); | |
1421 isp_init(isp); 1422 if (isp->isp_state != ISP_INITSTATE) { 1423 ISP_UNLOCK(isp); 1424 /* 1425 * Lie. Say it was a selection timeout. 1426 */ 1427 ccb->ccb_h.status = CAM_SEL_TIMEOUT | CAM_DEV_QFRZN; 1428 xpt_freeze_devq(ccb->ccb_h.path, 1); 1429 xpt_done(ccb); 1430 return; 1431 } 1432 isp->isp_state = ISP_RUNSTATE; | 1456 isp_init(isp); 1457 if (isp->isp_state != ISP_INITSTATE) { 1458 ISP_UNLOCK(isp); 1459 /* 1460 * Lie. Say it was a selection timeout. 1461 */ 1462 ccb->ccb_h.status = CAM_SEL_TIMEOUT | CAM_DEV_QFRZN; 1463 xpt_freeze_devq(ccb->ccb_h.path, 1); 1464 xpt_done(ccb); 1465 return; 1466 } 1467 isp->isp_state = ISP_RUNSTATE; |
1433 ENABLE_INTS(isp); | |
1434 ISP_UNLOCK(isp); 1435 } 1436 isp_prt(isp, ISP_LOGDEBUG2, "isp_action code %x", ccb->ccb_h.func_code); 1437 1438 switch (ccb->ccb_h.func_code) { 1439 case XPT_SCSI_IO: /* Execute the requested I/O operation */ 1440 /* 1441 * Do a couple of preliminary checks... --- 802 unchanged lines hidden --- | 1468 ISP_UNLOCK(isp); 1469 } 1470 isp_prt(isp, ISP_LOGDEBUG2, "isp_action code %x", ccb->ccb_h.func_code); 1471 1472 switch (ccb->ccb_h.func_code) { 1473 case XPT_SCSI_IO: /* Execute the requested I/O operation */ 1474 /* 1475 * Do a couple of preliminary checks... --- 802 unchanged lines hidden --- |