isp_pci.c (171057) | isp_pci.c (196008) |
---|---|
1/*- | 1/*- |
2 * Copyright (c) 1997-2006 by Matthew Jacob | 2 * Copyright (c) 1997-2008 by Matthew Jacob |
3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice immediately at the beginning of the file, without modification, 10 * this list of conditions, and the following disclaimer. --- 12 unchanged lines hidden (view full) --- 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26/* 27 * PCI specific probe and attach routines for Qlogic ISP SCSI adapters. 28 * FreeBSD Version. 29 */ 30#include <sys/cdefs.h> | 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice immediately at the beginning of the file, without modification, 10 * this list of conditions, and the following disclaimer. --- 12 unchanged lines hidden (view full) --- 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26/* 27 * PCI specific probe and attach routines for Qlogic ISP SCSI adapters. 28 * FreeBSD Version. 29 */ 30#include <sys/cdefs.h> |
31__FBSDID("$FreeBSD: head/sys/dev/isp/isp_pci.c 171057 2007-06-26 23:08:57Z mjacob $"); | 31__FBSDID("$FreeBSD: head/sys/dev/isp/isp_pci.c 196008 2009-08-01 01:04:26Z mjacob $"); |
32 33#include <sys/param.h> 34#include <sys/systm.h> 35#include <sys/kernel.h> 36#include <sys/module.h> | 32 33#include <sys/param.h> 34#include <sys/systm.h> 35#include <sys/kernel.h> 36#include <sys/module.h> |
37#if __FreeBSD_version >= 700000 | |
38#include <sys/linker.h> 39#include <sys/firmware.h> | 37#include <sys/linker.h> 38#include <sys/firmware.h> |
40#endif | |
41#include <sys/bus.h> | 39#include <sys/bus.h> |
42#if __FreeBSD_version < 500000 43#include <pci/pcireg.h> 44#include <pci/pcivar.h> 45#include <machine/bus_memio.h> 46#include <machine/bus_pio.h> 47#else | |
48#include <sys/stdint.h> 49#include <dev/pci/pcireg.h> 50#include <dev/pci/pcivar.h> | 40#include <sys/stdint.h> 41#include <dev/pci/pcireg.h> 42#include <dev/pci/pcivar.h> |
51#endif | |
52#include <machine/bus.h> 53#include <machine/resource.h> 54#include <sys/rman.h> 55#include <sys/malloc.h> | 43#include <machine/bus.h> 44#include <machine/resource.h> 45#include <sys/rman.h> 46#include <sys/malloc.h> |
47#include <sys/uio.h> |
|
56 57#include <dev/isp/isp_freebsd.h> 58 | 48 49#include <dev/isp/isp_freebsd.h> 50 |
59#if __FreeBSD_version < 500000 60#define BUS_PROBE_DEFAULT 0 61#endif 62 | |
63static uint32_t isp_pci_rd_reg(ispsoftc_t *, int); 64static void isp_pci_wr_reg(ispsoftc_t *, int, uint32_t); 65static uint32_t isp_pci_rd_reg_1080(ispsoftc_t *, int); 66static void isp_pci_wr_reg_1080(ispsoftc_t *, int, uint32_t); 67static uint32_t isp_pci_rd_reg_2400(ispsoftc_t *, int); 68static void isp_pci_wr_reg_2400(ispsoftc_t *, int, uint32_t); | 51static uint32_t isp_pci_rd_reg(ispsoftc_t *, int); 52static void isp_pci_wr_reg(ispsoftc_t *, int, uint32_t); 53static uint32_t isp_pci_rd_reg_1080(ispsoftc_t *, int); 54static void isp_pci_wr_reg_1080(ispsoftc_t *, int, uint32_t); 55static uint32_t isp_pci_rd_reg_2400(ispsoftc_t *, int); 56static void isp_pci_wr_reg_2400(ispsoftc_t *, int, uint32_t); |
69static int 70isp_pci_rd_isr(ispsoftc_t *, uint32_t *, uint16_t *, uint16_t *); 71static int 72isp_pci_rd_isr_2300(ispsoftc_t *, uint32_t *, uint16_t *, uint16_t *); 73static int 74isp_pci_rd_isr_2400(ispsoftc_t *, uint32_t *, uint16_t *, uint16_t *); | 57static int isp_pci_rd_isr(ispsoftc_t *, uint32_t *, uint16_t *, uint16_t *); 58static int isp_pci_rd_isr_2300(ispsoftc_t *, uint32_t *, uint16_t *, uint16_t *); 59static int isp_pci_rd_isr_2400(ispsoftc_t *, uint32_t *, uint16_t *, uint16_t *); |
75static int isp_pci_mbxdma(ispsoftc_t *); | 60static int isp_pci_mbxdma(ispsoftc_t *); |
76static int 77isp_pci_dmasetup(ispsoftc_t *, XS_T *, ispreq_t *, uint32_t *, uint32_t); | 61static int isp_pci_dmasetup(ispsoftc_t *, XS_T *, void *); |
78 79 80static void isp_pci_reset0(ispsoftc_t *); 81static void isp_pci_reset1(ispsoftc_t *); 82static void isp_pci_dumpregs(ispsoftc_t *, const char *); 83 84static struct ispmdvec mdvec = { 85 isp_pci_rd_isr, --- 80 unchanged lines hidden (view full) --- 166 isp_pci_mbxdma, 167 isp_pci_dmasetup, 168 isp_common_dmateardown, 169 isp_pci_reset0, 170 isp_pci_reset1, 171 NULL 172}; 173 | 62 63 64static void isp_pci_reset0(ispsoftc_t *); 65static void isp_pci_reset1(ispsoftc_t *); 66static void isp_pci_dumpregs(ispsoftc_t *, const char *); 67 68static struct ispmdvec mdvec = { 69 isp_pci_rd_isr, --- 80 unchanged lines hidden (view full) --- 150 isp_pci_mbxdma, 151 isp_pci_dmasetup, 152 isp_common_dmateardown, 153 isp_pci_reset0, 154 isp_pci_reset1, 155 NULL 156}; 157 |
158static struct ispmdvec mdvec_2500 = { 159 isp_pci_rd_isr_2400, 160 isp_pci_rd_reg_2400, 161 isp_pci_wr_reg_2400, 162 isp_pci_mbxdma, 163 isp_pci_dmasetup, 164 isp_common_dmateardown, 165 isp_pci_reset0, 166 isp_pci_reset1, 167 NULL 168}; 169 |
|
174#ifndef PCIM_CMD_INVEN 175#define PCIM_CMD_INVEN 0x10 176#endif 177#ifndef PCIM_CMD_BUSMASTEREN 178#define PCIM_CMD_BUSMASTEREN 0x0004 179#endif 180#ifndef PCIM_CMD_PERRESPEN 181#define PCIM_CMD_PERRESPEN 0x0040 --- 72 unchanged lines hidden (view full) --- 254#ifndef PCI_PRODUCT_QLOGIC_ISP2422 255#define PCI_PRODUCT_QLOGIC_ISP2422 0x2422 256#endif 257 258#ifndef PCI_PRODUCT_QLOGIC_ISP2432 259#define PCI_PRODUCT_QLOGIC_ISP2432 0x2432 260#endif 261 | 170#ifndef PCIM_CMD_INVEN 171#define PCIM_CMD_INVEN 0x10 172#endif 173#ifndef PCIM_CMD_BUSMASTEREN 174#define PCIM_CMD_BUSMASTEREN 0x0004 175#endif 176#ifndef PCIM_CMD_PERRESPEN 177#define PCIM_CMD_PERRESPEN 0x0040 --- 72 unchanged lines hidden (view full) --- 250#ifndef PCI_PRODUCT_QLOGIC_ISP2422 251#define PCI_PRODUCT_QLOGIC_ISP2422 0x2422 252#endif 253 254#ifndef PCI_PRODUCT_QLOGIC_ISP2432 255#define PCI_PRODUCT_QLOGIC_ISP2432 0x2432 256#endif 257 |
258#ifndef PCI_PRODUCT_QLOGIC_ISP2532 259#define PCI_PRODUCT_QLOGIC_ISP2532 0x2532 260#endif 261 |
|
262#ifndef PCI_PRODUCT_QLOGIC_ISP6312 263#define PCI_PRODUCT_QLOGIC_ISP6312 0x6312 264#endif 265 266#ifndef PCI_PRODUCT_QLOGIC_ISP6322 267#define PCI_PRODUCT_QLOGIC_ISP6322 0x6322 268#endif 269 --- 32 unchanged lines hidden (view full) --- 302 ((PCI_PRODUCT_QLOGIC_ISP2322 << 16) | PCI_VENDOR_QLOGIC) 303 304#define PCI_QLOGIC_ISP2422 \ 305 ((PCI_PRODUCT_QLOGIC_ISP2422 << 16) | PCI_VENDOR_QLOGIC) 306 307#define PCI_QLOGIC_ISP2432 \ 308 ((PCI_PRODUCT_QLOGIC_ISP2432 << 16) | PCI_VENDOR_QLOGIC) 309 | 262#ifndef PCI_PRODUCT_QLOGIC_ISP6312 263#define PCI_PRODUCT_QLOGIC_ISP6312 0x6312 264#endif 265 266#ifndef PCI_PRODUCT_QLOGIC_ISP6322 267#define PCI_PRODUCT_QLOGIC_ISP6322 0x6322 268#endif 269 --- 32 unchanged lines hidden (view full) --- 302 ((PCI_PRODUCT_QLOGIC_ISP2322 << 16) | PCI_VENDOR_QLOGIC) 303 304#define PCI_QLOGIC_ISP2422 \ 305 ((PCI_PRODUCT_QLOGIC_ISP2422 << 16) | PCI_VENDOR_QLOGIC) 306 307#define PCI_QLOGIC_ISP2432 \ 308 ((PCI_PRODUCT_QLOGIC_ISP2432 << 16) | PCI_VENDOR_QLOGIC) 309 |
310#define PCI_QLOGIC_ISP2532 \ 311 ((PCI_PRODUCT_QLOGIC_ISP2532 << 16) | PCI_VENDOR_QLOGIC) 312 |
|
310#define PCI_QLOGIC_ISP6312 \ 311 ((PCI_PRODUCT_QLOGIC_ISP6312 << 16) | PCI_VENDOR_QLOGIC) 312 313#define PCI_QLOGIC_ISP6322 \ 314 ((PCI_PRODUCT_QLOGIC_ISP6322 << 16) | PCI_VENDOR_QLOGIC) 315 316/* 317 * Odd case for some AMI raid cards... We need to *not* attach to this. --- 14 unchanged lines hidden (view full) --- 332#define ISP_PCD(isp) ((struct isp_pcisoftc *)isp)->pci_dev 333struct isp_pcisoftc { 334 ispsoftc_t pci_isp; 335 device_t pci_dev; 336 struct resource * pci_reg; 337 void * ih; 338 int16_t pci_poff[_NREG_BLKS]; 339 bus_dma_tag_t dmat; | 313#define PCI_QLOGIC_ISP6312 \ 314 ((PCI_PRODUCT_QLOGIC_ISP6312 << 16) | PCI_VENDOR_QLOGIC) 315 316#define PCI_QLOGIC_ISP6322 \ 317 ((PCI_PRODUCT_QLOGIC_ISP6322 << 16) | PCI_VENDOR_QLOGIC) 318 319/* 320 * Odd case for some AMI raid cards... We need to *not* attach to this. --- 14 unchanged lines hidden (view full) --- 335#define ISP_PCD(isp) ((struct isp_pcisoftc *)isp)->pci_dev 336struct isp_pcisoftc { 337 ispsoftc_t pci_isp; 338 device_t pci_dev; 339 struct resource * pci_reg; 340 void * ih; 341 int16_t pci_poff[_NREG_BLKS]; 342 bus_dma_tag_t dmat; |
340#if __FreeBSD_version > 700025 | |
341 int msicount; | 343 int msicount; |
342#endif | |
343}; 344 345 346static device_method_t isp_pci_methods[] = { 347 /* Device interface */ 348 DEVMETHOD(device_probe, isp_pci_probe), 349 DEVMETHOD(device_attach, isp_pci_attach), 350 DEVMETHOD(device_detach, isp_pci_detach), 351 { 0, 0 } 352}; 353 354static driver_t isp_pci_driver = { 355 "isp", isp_pci_methods, sizeof (struct isp_pcisoftc) 356}; 357static devclass_t isp_devclass; 358DRIVER_MODULE(isp, pci, isp_pci_driver, isp_devclass, 0, 0); | 344}; 345 346 347static device_method_t isp_pci_methods[] = { 348 /* Device interface */ 349 DEVMETHOD(device_probe, isp_pci_probe), 350 DEVMETHOD(device_attach, isp_pci_attach), 351 DEVMETHOD(device_detach, isp_pci_detach), 352 { 0, 0 } 353}; 354 355static driver_t isp_pci_driver = { 356 "isp", isp_pci_methods, sizeof (struct isp_pcisoftc) 357}; 358static devclass_t isp_devclass; 359DRIVER_MODULE(isp, pci, isp_pci_driver, isp_devclass, 0, 0); |
359#if __FreeBSD_version < 700000 360extern ispfwfunc *isp_get_firmware_p; 361#endif | |
362 363static int 364isp_pci_probe(device_t dev) 365{ | 360 361static int 362isp_pci_probe(device_t dev) 363{ |
366 switch ((pci_get_device(dev) << 16) | (pci_get_vendor(dev))) { | 364 switch ((pci_get_device(dev) << 16) | (pci_get_vendor(dev))) { |
367 case PCI_QLOGIC_ISP1020: 368 device_set_desc(dev, "Qlogic ISP 1020/1040 PCI SCSI Adapter"); 369 break; 370 case PCI_QLOGIC_ISP1080: 371 device_set_desc(dev, "Qlogic ISP 1080 PCI SCSI Adapter"); 372 break; 373 case PCI_QLOGIC_ISP1240: 374 device_set_desc(dev, "Qlogic ISP 1240 PCI SCSI Adapter"); --- 26 unchanged lines hidden (view full) --- 401 device_set_desc(dev, "Qlogic ISP 2322 PCI FC-AL Adapter"); 402 break; 403 case PCI_QLOGIC_ISP2422: 404 device_set_desc(dev, "Qlogic ISP 2422 PCI FC-AL Adapter"); 405 break; 406 case PCI_QLOGIC_ISP2432: 407 device_set_desc(dev, "Qlogic ISP 2432 PCI FC-AL Adapter"); 408 break; | 365 case PCI_QLOGIC_ISP1020: 366 device_set_desc(dev, "Qlogic ISP 1020/1040 PCI SCSI Adapter"); 367 break; 368 case PCI_QLOGIC_ISP1080: 369 device_set_desc(dev, "Qlogic ISP 1080 PCI SCSI Adapter"); 370 break; 371 case PCI_QLOGIC_ISP1240: 372 device_set_desc(dev, "Qlogic ISP 1240 PCI SCSI Adapter"); --- 26 unchanged lines hidden (view full) --- 399 device_set_desc(dev, "Qlogic ISP 2322 PCI FC-AL Adapter"); 400 break; 401 case PCI_QLOGIC_ISP2422: 402 device_set_desc(dev, "Qlogic ISP 2422 PCI FC-AL Adapter"); 403 break; 404 case PCI_QLOGIC_ISP2432: 405 device_set_desc(dev, "Qlogic ISP 2432 PCI FC-AL Adapter"); 406 break; |
407 case PCI_QLOGIC_ISP2532: 408 device_set_desc(dev, "Qlogic ISP 2532 PCI FC-AL Adapter"); 409 break; |
|
409 case PCI_QLOGIC_ISP6312: 410 device_set_desc(dev, "Qlogic ISP 6312 PCI FC-AL Adapter"); 411 break; 412 case PCI_QLOGIC_ISP6322: 413 device_set_desc(dev, "Qlogic ISP 6322 PCI FC-AL Adapter"); 414 break; 415 default: 416 return (ENXIO); --- 7 unchanged lines hidden (view full) --- 424 } 425 /* 426 * XXXX: Here is where we might load the f/w module 427 * XXXX: (or increase a reference count to it). 428 */ 429 return (BUS_PROBE_DEFAULT); 430} 431 | 410 case PCI_QLOGIC_ISP6312: 411 device_set_desc(dev, "Qlogic ISP 6312 PCI FC-AL Adapter"); 412 break; 413 case PCI_QLOGIC_ISP6322: 414 device_set_desc(dev, "Qlogic ISP 6322 PCI FC-AL Adapter"); 415 break; 416 default: 417 return (ENXIO); --- 7 unchanged lines hidden (view full) --- 425 } 426 /* 427 * XXXX: Here is where we might load the f/w module 428 * XXXX: (or increase a reference count to it). 429 */ 430 return (BUS_PROBE_DEFAULT); 431} 432 |
432#if __FreeBSD_version < 500000 | |
433static void | 433static void |
434isp_get_generic_options(device_t dev, ispsoftc_t *isp) | 434isp_get_generic_options(device_t dev, ispsoftc_t *isp, int *nvp) |
435{ | 435{ |
436 int bitmap, unit; 437 438 unit = device_get_unit(dev); 439 if (getenv_int("isp_disable", &bitmap)) { 440 if (bitmap & (1 << unit)) { 441 isp->isp_osinfo.disabled = 1; 442 return; 443 } 444 } 445 if (getenv_int("isp_no_fwload", &bitmap)) { 446 if (bitmap & (1 << unit)) 447 isp->isp_confopts |= ISP_CFG_NORELOAD; 448 } 449 if (getenv_int("isp_fwload", &bitmap)) { 450 if (bitmap & (1 << unit)) 451 isp->isp_confopts &= ~ISP_CFG_NORELOAD; 452 } 453 if (getenv_int("isp_no_nvram", &bitmap)) { 454 if (bitmap & (1 << unit)) 455 isp->isp_confopts |= ISP_CFG_NONVRAM; 456 } 457 if (getenv_int("isp_nvram", &bitmap)) { 458 if (bitmap & (1 << unit)) 459 isp->isp_confopts &= ~ISP_CFG_NONVRAM; 460 } 461 462 bitmap = 0; 463 (void) getenv_int("isp_debug", &bitmap); 464 if (bitmap) { 465 isp->isp_dblev = bitmap; 466 } else { 467 isp->isp_dblev = ISP_LOGWARN|ISP_LOGERR; 468 } 469 if (bootverbose) { 470 isp->isp_dblev |= ISP_LOGCONFIG|ISP_LOGINFO; 471 } 472 473 bitmap = 0; 474 if (getenv_int("role", &bitmap)) { 475 isp->isp_role = bitmap; 476 } else { 477 isp->isp_role = ISP_DEFAULT_ROLES; 478 } 479 480} 481 482static void 483isp_get_pci_options(device_t dev, int *m1, int *m2) 484{ 485 int bitmap; 486 int unit = device_get_unit(dev); 487 488 *m1 = PCIM_CMD_MEMEN; 489 *m2 = PCIM_CMD_PORTEN; 490 if (getenv_int("isp_mem_map", &bitmap)) { 491 if (bitmap & (1 << unit)) { 492 *m1 = PCIM_CMD_MEMEN; 493 *m2 = PCIM_CMD_PORTEN; 494 } 495 } 496 bitmap = 0; 497 if (getenv_int("isp_io_map", &bitmap)) { 498 if (bitmap & (1 << unit)) { 499 *m1 = PCIM_CMD_PORTEN; 500 *m2 = PCIM_CMD_MEMEN; 501 } 502 } 503} 504 505static void 506isp_get_specific_options(device_t dev, ispsoftc_t *isp) 507{ 508 uint64_t wwn; 509 int bitmap; 510 int unit = device_get_unit(dev); 511 512 513 if (IS_SCSI(isp)) { 514 return; 515 } 516 517 if (getenv_int("isp_fcduplex", &bitmap)) { 518 if (bitmap & (1 << unit)) 519 isp->isp_confopts |= ISP_CFG_FULL_DUPLEX; 520 } 521 if (getenv_int("isp_no_fcduplex", &bitmap)) { 522 if (bitmap & (1 << unit)) 523 isp->isp_confopts &= ~ISP_CFG_FULL_DUPLEX; 524 } 525 if (getenv_int("isp_nport", &bitmap)) { 526 if (bitmap & (1 << unit)) 527 isp->isp_confopts |= ISP_CFG_NPORT; 528 } 529 530 /* 531 * Because the resource_*_value functions can neither return 532 * 64 bit integer values, nor can they be directly coerced 533 * to interpret the right hand side of the assignment as 534 * you want them to interpret it, we have to force WWN 535 * hint replacement to specify WWN strings with a leading 536 * 'w' (e..g w50000000aaaa0001). Sigh. 537 */ 538 if (getenv_quad("isp_portwwn", &wwn)) { 539 isp->isp_osinfo.default_port_wwn = wwn; 540 isp->isp_confopts |= ISP_CFG_OWNWWPN; 541 } 542 if (isp->isp_osinfo.default_port_wwn == 0) { 543 isp->isp_osinfo.default_port_wwn = 0x400000007F000009ull; 544 } 545 546 if (getenv_quad("isp_nodewwn", &wwn)) { 547 isp->isp_osinfo.default_node_wwn = wwn; 548 isp->isp_confopts |= ISP_CFG_OWNWWNN; 549 } 550 if (isp->isp_osinfo.default_node_wwn == 0) { 551 isp->isp_osinfo.default_node_wwn = 0x400000007F000009ull; 552 } 553 554 bitmap = 0; 555 (void) getenv_int("isp_fabric_hysteresis", &bitmap); 556 if (bitmap >= 0 && bitmap < 256) { 557 isp->isp_osinfo.hysteresis = bitmap; 558 } else { 559 isp->isp_osinfo.hysteresis = isp_fabric_hysteresis; 560 } 561 562 bitmap = 0; 563 (void) getenv_int("isp_loop_down_limit", &bitmap); 564 if (bitmap >= 0 && bitmap < 0xffff) { 565 isp->isp_osinfo.loop_down_limit = bitmap; 566 } else { 567 isp->isp_osinfo.loop_down_limit = isp_loop_down_limit; 568 } 569 570 bitmap = 0; 571 (void) getenv_int("isp_gone_device_time", &bitmap); 572 if (bitmap >= 0 && bitmap < 0xffff) { 573 isp->isp_osinfo.gone_device_time = bitmap; 574 } else { 575 isp->isp_osinfo.gone_device_time = isp_gone_device_time; 576 } 577#ifdef ISP_FW_CRASH_DUMP 578 bitmap = 0; 579 if (getenv_int("isp_fw_dump_enable", &bitmap)) { 580 if (bitmap & (1 << unit) { 581 size_t amt = 0; 582 if (IS_2200(isp)) { 583 amt = QLA2200_RISC_IMAGE_DUMP_SIZE; 584 } else if (IS_23XX(isp)) { 585 amt = QLA2300_RISC_IMAGE_DUMP_SIZE; 586 } 587 if (amt) { 588 FCPARAM(isp)->isp_dump_data = 589 malloc(amt, M_DEVBUF, M_WAITOK); 590 memset(FCPARAM(isp)->isp_dump_data, 0, amt); 591 } else { 592 device_printf(dev, 593 "f/w crash dumps not supported for card\n"); 594 } 595 } 596 } 597#endif 598} 599#else 600static void 601isp_get_generic_options(device_t dev, ispsoftc_t *isp) 602{ | |
603 int tval; 604 605 /* 606 * Figure out if we're supposed to skip this one. 607 */ 608 tval = 0; | 436 int tval; 437 438 /* 439 * Figure out if we're supposed to skip this one. 440 */ 441 tval = 0; |
609 if (resource_int_value(device_get_name(dev), device_get_unit(dev), 610 "disable", &tval) == 0 && tval) { | 442 if (resource_int_value(device_get_name(dev), device_get_unit(dev), "disable", &tval) == 0 && tval) { |
611 device_printf(dev, "disabled at user request\n"); 612 isp->isp_osinfo.disabled = 1; 613 return; 614 } 615 | 443 device_printf(dev, "disabled at user request\n"); 444 isp->isp_osinfo.disabled = 1; 445 return; 446 } 447 |
616 tval = -1; 617 if (resource_int_value(device_get_name(dev), device_get_unit(dev), 618 "role", &tval) == 0 && tval != -1) { 619 tval &= (ISP_ROLE_INITIATOR|ISP_ROLE_TARGET); 620 isp->isp_role = tval; 621 device_printf(dev, "setting role to 0x%x\n", isp->isp_role); 622 } else { 623#ifdef ISP_TARGET_MODE 624 isp->isp_role = ISP_ROLE_TARGET; 625#else 626 isp->isp_role = ISP_DEFAULT_ROLES; 627#endif 628 } 629 | |
630 tval = 0; | 448 tval = 0; |
631 if (resource_int_value(device_get_name(dev), device_get_unit(dev), 632 "fwload_disable", &tval) == 0 && tval != 0) { | 449 if (resource_int_value(device_get_name(dev), device_get_unit(dev), "fwload_disable", &tval) == 0 && tval != 0) { |
633 isp->isp_confopts |= ISP_CFG_NORELOAD; 634 } 635 tval = 0; | 450 isp->isp_confopts |= ISP_CFG_NORELOAD; 451 } 452 tval = 0; |
636 if (resource_int_value(device_get_name(dev), device_get_unit(dev), 637 "ignore_nvram", &tval) == 0 && tval != 0) { | 453 if (resource_int_value(device_get_name(dev), device_get_unit(dev), "ignore_nvram", &tval) == 0 && tval != 0) { |
638 isp->isp_confopts |= ISP_CFG_NONVRAM; 639 } | 454 isp->isp_confopts |= ISP_CFG_NONVRAM; 455 } |
640 | |
641 tval = 0; | 456 tval = 0; |
642 (void) resource_int_value(device_get_name(dev), device_get_unit(dev), 643 "debug", &tval); | 457 (void) resource_int_value(device_get_name(dev), device_get_unit(dev), "debug", &tval); |
644 if (tval) { 645 isp->isp_dblev = tval; 646 } else { 647 isp->isp_dblev = ISP_LOGWARN|ISP_LOGERR; 648 } 649 if (bootverbose) { 650 isp->isp_dblev |= ISP_LOGCONFIG|ISP_LOGINFO; 651 } | 458 if (tval) { 459 isp->isp_dblev = tval; 460 } else { 461 isp->isp_dblev = ISP_LOGWARN|ISP_LOGERR; 462 } 463 if (bootverbose) { 464 isp->isp_dblev |= ISP_LOGCONFIG|ISP_LOGINFO; 465 } |
466 (void) resource_int_value(device_get_name(dev), device_get_unit(dev), "vports", &tval); 467 if (tval > 0 && tval < 127) { 468 *nvp = tval; 469 } else { 470 *nvp = 0; 471 } 472 tval = 1; 473 (void) resource_int_value(device_get_name(dev), device_get_unit(dev), "autoconfig", &tval); 474 isp_autoconfig = tval; 475 tval = 7; 476 (void) resource_int_value(device_get_name(dev), device_get_unit(dev), "quickboot_time", &tval); 477 isp_quickboot_time = tval; |
|
652 | 478 |
479 tval = 0; 480 if (resource_int_value(device_get_name(dev), device_get_unit(dev), "forcemulti", &tval) == 0 && tval != 0) { 481 isp->isp_osinfo.forcemulti = 1; 482 } |
|
653} 654 655static void 656isp_get_pci_options(device_t dev, int *m1, int *m2) 657{ 658 int tval; 659 /* 660 * Which we should try first - memory mapping or i/o mapping? 661 * 662 * We used to try memory first followed by i/o on alpha, otherwise 663 * the reverse, but we should just try memory first all the time now. 664 */ 665 *m1 = PCIM_CMD_MEMEN; 666 *m2 = PCIM_CMD_PORTEN; 667 668 tval = 0; | 483} 484 485static void 486isp_get_pci_options(device_t dev, int *m1, int *m2) 487{ 488 int tval; 489 /* 490 * Which we should try first - memory mapping or i/o mapping? 491 * 492 * We used to try memory first followed by i/o on alpha, otherwise 493 * the reverse, but we should just try memory first all the time now. 494 */ 495 *m1 = PCIM_CMD_MEMEN; 496 *m2 = PCIM_CMD_PORTEN; 497 498 tval = 0; |
669 if (resource_int_value(device_get_name(dev), device_get_unit(dev), 670 "prefer_iomap", &tval) == 0 && tval != 0) { | 499 if (resource_int_value(device_get_name(dev), device_get_unit(dev), "prefer_iomap", &tval) == 0 && tval != 0) { |
671 *m1 = PCIM_CMD_PORTEN; 672 *m2 = PCIM_CMD_MEMEN; 673 } 674 tval = 0; | 500 *m1 = PCIM_CMD_PORTEN; 501 *m2 = PCIM_CMD_MEMEN; 502 } 503 tval = 0; |
675 if (resource_int_value(device_get_name(dev), device_get_unit(dev), 676 "prefer_memmap", &tval) == 0 && tval != 0) { | 504 if (resource_int_value(device_get_name(dev), device_get_unit(dev), "prefer_memmap", &tval) == 0 && tval != 0) { |
677 *m1 = PCIM_CMD_MEMEN; 678 *m2 = PCIM_CMD_PORTEN; 679 } 680} 681 682static void | 505 *m1 = PCIM_CMD_MEMEN; 506 *m2 = PCIM_CMD_PORTEN; 507 } 508} 509 510static void |
683isp_get_specific_options(device_t dev, ispsoftc_t *isp) | 511isp_get_specific_options(device_t dev, int chan, ispsoftc_t *isp) |
684{ 685 const char *sptr; 686 int tval; 687 | 512{ 513 const char *sptr; 514 int tval; 515 |
688 isp->isp_osinfo.default_id = -1; 689 if (resource_int_value(device_get_name(dev), device_get_unit(dev), 690 "iid", &tval) == 0) { 691 isp->isp_osinfo.default_id = tval; 692 isp->isp_confopts |= ISP_CFG_OWNLOOPID; 693 } 694 if (isp->isp_osinfo.default_id == -1) { | 516 if (resource_int_value(device_get_name(dev), device_get_unit(dev), "iid", &tval)) { |
695 if (IS_FC(isp)) { | 517 if (IS_FC(isp)) { |
696 isp->isp_osinfo.default_id = 109; | 518 ISP_FC_PC(isp, chan)->default_id = 109 - chan; |
697 } else { | 519 } else { |
698 isp->isp_osinfo.default_id = 7; | 520 ISP_SPI_PC(isp, chan)->iid = 7; |
699 } | 521 } |
522 } else { 523 if (IS_FC(isp)) { 524 ISP_FC_PC(isp, chan)->default_id = tval - chan; 525 } else { 526 ISP_SPI_PC(isp, chan)->iid = tval; 527 } 528 isp->isp_confopts |= ISP_CFG_OWNLOOPID; |
|
700 } 701 | 529 } 530 |
531 tval = -1; 532 if (resource_int_value(device_get_name(dev), device_get_unit(dev), "role", &tval) == 0) { 533 switch (tval) { 534 case ISP_ROLE_NONE: 535 case ISP_ROLE_INITIATOR: 536 case ISP_ROLE_TARGET: 537 case ISP_ROLE_INITIATOR|ISP_ROLE_TARGET: 538 device_printf(dev, "setting role to 0x%x\n", tval); 539 break; 540 default: 541 tval = -1; 542 break; 543 } 544 } 545 if (tval == -1) { 546 tval = ISP_DEFAULT_ROLES; 547 } 548 |
|
702 if (IS_SCSI(isp)) { | 549 if (IS_SCSI(isp)) { |
550 ISP_SPI_PC(isp, chan)->role = tval; |
|
703 return; 704 } | 551 return; 552 } |
553 ISP_FC_PC(isp, chan)->role = tval; |
|
705 706 tval = 0; | 554 555 tval = 0; |
707 if (resource_int_value(device_get_name(dev), device_get_unit(dev), 708 "fullduplex", &tval) == 0 && tval != 0) { | 556 if (resource_int_value(device_get_name(dev), device_get_unit(dev), "fullduplex", &tval) == 0 && tval != 0) { |
709 isp->isp_confopts |= ISP_CFG_FULL_DUPLEX; 710 } | 557 isp->isp_confopts |= ISP_CFG_FULL_DUPLEX; 558 } |
711#ifdef ISP_FW_CRASH_DUMP 712 tval = 0; 713 if (resource_int_value(device_get_name(dev), device_get_unit(dev), 714 "fw_dump_enable", &tval) == 0 && tval != 0) { 715 size_t amt = 0; 716 if (IS_2200(isp)) { 717 amt = QLA2200_RISC_IMAGE_DUMP_SIZE; 718 } else if (IS_23XX(isp)) { 719 amt = QLA2300_RISC_IMAGE_DUMP_SIZE; 720 } 721 if (amt) { 722 FCPARAM(isp)->isp_dump_data = 723 malloc(amt, M_DEVBUF, M_WAITOK | M_ZERO); 724 } else { 725 device_printf(dev, 726 "f/w crash dumps not supported for this model\n"); 727 } 728 } 729#endif | |
730 sptr = 0; | 559 sptr = 0; |
731 if (resource_string_value(device_get_name(dev), device_get_unit(dev), 732 "topology", (const char **) &sptr) == 0 && sptr != 0) { | 560 if (resource_string_value(device_get_name(dev), device_get_unit(dev), "topology", (const char **) &sptr) == 0 && sptr != 0) { |
733 if (strcmp(sptr, "lport") == 0) { 734 isp->isp_confopts |= ISP_CFG_LPORT; 735 } else if (strcmp(sptr, "nport") == 0) { 736 isp->isp_confopts |= ISP_CFG_NPORT; 737 } else if (strcmp(sptr, "lport-only") == 0) { 738 isp->isp_confopts |= ISP_CFG_LPORT_ONLY; 739 } else if (strcmp(sptr, "nport-only") == 0) { 740 isp->isp_confopts |= ISP_CFG_NPORT_ONLY; --- 4 unchanged lines hidden (view full) --- 745 * Because the resource_*_value functions can neither return 746 * 64 bit integer values, nor can they be directly coerced 747 * to interpret the right hand side of the assignment as 748 * you want them to interpret it, we have to force WWN 749 * hint replacement to specify WWN strings with a leading 750 * 'w' (e..g w50000000aaaa0001). Sigh. 751 */ 752 sptr = 0; | 561 if (strcmp(sptr, "lport") == 0) { 562 isp->isp_confopts |= ISP_CFG_LPORT; 563 } else if (strcmp(sptr, "nport") == 0) { 564 isp->isp_confopts |= ISP_CFG_NPORT; 565 } else if (strcmp(sptr, "lport-only") == 0) { 566 isp->isp_confopts |= ISP_CFG_LPORT_ONLY; 567 } else if (strcmp(sptr, "nport-only") == 0) { 568 isp->isp_confopts |= ISP_CFG_NPORT_ONLY; --- 4 unchanged lines hidden (view full) --- 573 * Because the resource_*_value functions can neither return 574 * 64 bit integer values, nor can they be directly coerced 575 * to interpret the right hand side of the assignment as 576 * you want them to interpret it, we have to force WWN 577 * hint replacement to specify WWN strings with a leading 578 * 'w' (e..g w50000000aaaa0001). Sigh. 579 */ 580 sptr = 0; |
753 tval = resource_string_value(device_get_name(dev), device_get_unit(dev), 754 "portwwn", (const char **) &sptr); | 581 tval = resource_string_value(device_get_name(dev), device_get_unit(dev), "portwwn", (const char **) &sptr); |
755 if (tval == 0 && sptr != 0 && *sptr++ == 'w') { 756 char *eptr = 0; | 582 if (tval == 0 && sptr != 0 && *sptr++ == 'w') { 583 char *eptr = 0; |
757 isp->isp_osinfo.default_port_wwn = strtouq(sptr, &eptr, 16); 758 if (eptr < sptr + 16 || isp->isp_osinfo.default_port_wwn == 0) { | 584 ISP_FC_PC(isp, chan)->def_wwpn = strtouq(sptr, &eptr, 16); 585 if (eptr < sptr + 16 || ISP_FC_PC(isp, chan)->def_wwpn == -1) { |
759 device_printf(dev, "mangled portwwn hint '%s'\n", sptr); | 586 device_printf(dev, "mangled portwwn hint '%s'\n", sptr); |
760 isp->isp_osinfo.default_port_wwn = 0; 761 } else { 762 isp->isp_confopts |= ISP_CFG_OWNWWPN; | 587 ISP_FC_PC(isp, chan)->def_wwpn = 0; |
763 } 764 } | 588 } 589 } |
765 if (isp->isp_osinfo.default_port_wwn == 0) { 766 isp->isp_osinfo.default_port_wwn = 0x400000007F000009ull; 767 } | |
768 769 sptr = 0; | 590 591 sptr = 0; |
770 tval = resource_string_value(device_get_name(dev), device_get_unit(dev), 771 "nodewwn", (const char **) &sptr); | 592 tval = resource_string_value(device_get_name(dev), device_get_unit(dev), "nodewwn", (const char **) &sptr); |
772 if (tval == 0 && sptr != 0 && *sptr++ == 'w') { 773 char *eptr = 0; | 593 if (tval == 0 && sptr != 0 && *sptr++ == 'w') { 594 char *eptr = 0; |
774 isp->isp_osinfo.default_node_wwn = strtouq(sptr, &eptr, 16); 775 if (eptr < sptr + 16 || isp->isp_osinfo.default_node_wwn == 0) { | 595 ISP_FC_PC(isp, chan)->def_wwnn = strtouq(sptr, &eptr, 16); 596 if (eptr < sptr + 16 || ISP_FC_PC(isp, chan)->def_wwnn == 0) { |
776 device_printf(dev, "mangled nodewwn hint '%s'\n", sptr); | 597 device_printf(dev, "mangled nodewwn hint '%s'\n", sptr); |
777 isp->isp_osinfo.default_node_wwn = 0; 778 } else { 779 isp->isp_confopts |= ISP_CFG_OWNWWNN; | 598 ISP_FC_PC(isp, chan)->def_wwnn = 0; |
780 } 781 } | 599 } 600 } |
782 if (isp->isp_osinfo.default_node_wwn == 0) { 783 isp->isp_osinfo.default_node_wwn = 0x400000007F000009ull; 784 } | |
785 | 601 |
786 | |
787 tval = 0; | 602 tval = 0; |
788 (void) resource_int_value(device_get_name(dev), device_get_unit(dev), 789 "hysteresis", &tval); | 603 (void) resource_int_value(device_get_name(dev), device_get_unit(dev), "hysteresis", &tval); |
790 if (tval >= 0 && tval < 256) { | 604 if (tval >= 0 && tval < 256) { |
791 isp->isp_osinfo.hysteresis = tval; | 605 ISP_FC_PC(isp, chan)->hysteresis = tval; |
792 } else { | 606 } else { |
793 isp->isp_osinfo.hysteresis = isp_fabric_hysteresis; | 607 ISP_FC_PC(isp, chan)->hysteresis = isp_fabric_hysteresis; |
794 } 795 796 tval = -1; | 608 } 609 610 tval = -1; |
797 (void) resource_int_value(device_get_name(dev), device_get_unit(dev), 798 "loop_down_limit", &tval); | 611 (void) resource_int_value(device_get_name(dev), device_get_unit(dev), "loop_down_limit", &tval); |
799 if (tval >= 0 && tval < 0xffff) { | 612 if (tval >= 0 && tval < 0xffff) { |
800 isp->isp_osinfo.loop_down_limit = tval; | 613 ISP_FC_PC(isp, chan)->loop_down_limit = tval; |
801 } else { | 614 } else { |
802 isp->isp_osinfo.loop_down_limit = isp_loop_down_limit; | 615 ISP_FC_PC(isp, chan)->loop_down_limit = isp_loop_down_limit; |
803 } 804 805 tval = -1; | 616 } 617 618 tval = -1; |
806 (void) resource_int_value(device_get_name(dev), device_get_unit(dev), 807 "gone_device_time", &tval); | 619 (void) resource_int_value(device_get_name(dev), device_get_unit(dev), "gone_device_time", &tval); |
808 if (tval >= 0 && tval < 0xffff) { | 620 if (tval >= 0 && tval < 0xffff) { |
809 isp->isp_osinfo.gone_device_time = tval; | 621 ISP_FC_PC(isp, chan)->gone_device_time = tval; |
810 } else { | 622 } else { |
811 isp->isp_osinfo.gone_device_time = isp_gone_device_time; | 623 ISP_FC_PC(isp, chan)->gone_device_time = isp_gone_device_time; |
812 } 813} | 624 } 625} |
814#endif | |
815 816static int 817isp_pci_attach(device_t dev) 818{ 819 struct resource *regs, *irq; | 626 627static int 628isp_pci_attach(device_t dev) 629{ 630 struct resource *regs, *irq; |
820 int rtp, rgd, iqd, m1, m2; 821 uint32_t data, cmd, linesz, psize, basetype; | 631 int rtp, rgd, iqd, i, m1, m2, locksetup = 0; 632 int isp_nvports = 0; 633 uint32_t data, cmd, linesz, did; |
822 struct isp_pcisoftc *pcs; 823 ispsoftc_t *isp = NULL; | 634 struct isp_pcisoftc *pcs; 635 ispsoftc_t *isp = NULL; |
824 struct ispmdvec *mdvp; 825#if __FreeBSD_version >= 500000 826 int locksetup = 0; 827#endif | 636 size_t psize, xsize; 637 char fwname[32]; |
828 829 pcs = device_get_softc(dev); 830 if (pcs == NULL) { 831 device_printf(dev, "cannot get softc\n"); 832 return (ENOMEM); 833 } 834 memset(pcs, 0, sizeof (*pcs)); | 638 639 pcs = device_get_softc(dev); 640 if (pcs == NULL) { 641 device_printf(dev, "cannot get softc\n"); 642 return (ENOMEM); 643 } 644 memset(pcs, 0, sizeof (*pcs)); |
645 |
|
835 pcs->pci_dev = dev; 836 isp = &pcs->pci_isp; | 646 pcs->pci_dev = dev; 647 isp = &pcs->pci_isp; |
648 isp->isp_dev = dev; 649 isp->isp_nchan = 1; |
|
837 838 /* 839 * Get Generic Options 840 */ | 650 651 /* 652 * Get Generic Options 653 */ |
841 isp_get_generic_options(dev, isp); | 654 isp_get_generic_options(dev, isp, &isp_nvports); |
842 843 /* 844 * Check to see if options have us disabled 845 */ 846 if (isp->isp_osinfo.disabled) { 847 /* 848 * But return zero to preserve unit numbering 849 */ --- 20 unchanged lines hidden (view full) --- 870 rgd = (m2 == PCIM_CMD_MEMEN)? MEM_MAP_REG : IO_MAP_REG; 871 regs = bus_alloc_resource_any(dev, rtp, &rgd, RF_ACTIVE); 872 } 873 if (regs == NULL) { 874 device_printf(dev, "unable to map any ports\n"); 875 goto bad; 876 } 877 if (bootverbose) { | 655 656 /* 657 * Check to see if options have us disabled 658 */ 659 if (isp->isp_osinfo.disabled) { 660 /* 661 * But return zero to preserve unit numbering 662 */ --- 20 unchanged lines hidden (view full) --- 683 rgd = (m2 == PCIM_CMD_MEMEN)? MEM_MAP_REG : IO_MAP_REG; 684 regs = bus_alloc_resource_any(dev, rtp, &rgd, RF_ACTIVE); 685 } 686 if (regs == NULL) { 687 device_printf(dev, "unable to map any ports\n"); 688 goto bad; 689 } 690 if (bootverbose) { |
878 device_printf(dev, "using %s space register mapping\n", 879 (rgd == IO_MAP_REG)? "I/O" : "Memory"); | 691 device_printf(dev, "using %s space register mapping\n", (rgd == IO_MAP_REG)? "I/O" : "Memory"); |
880 } | 692 } |
881 pcs->pci_dev = dev; 882 pcs->pci_reg = regs; | |
883 isp->isp_bus_tag = rman_get_bustag(regs); 884 isp->isp_bus_handle = rman_get_bushandle(regs); 885 | 693 isp->isp_bus_tag = rman_get_bustag(regs); 694 isp->isp_bus_handle = rman_get_bushandle(regs); 695 |
696 pcs->pci_dev = dev; 697 pcs->pci_reg = regs; |
|
886 pcs->pci_poff[BIU_BLOCK >> _BLK_REG_SHFT] = BIU_REGS_OFF; 887 pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS_OFF; 888 pcs->pci_poff[SXP_BLOCK >> _BLK_REG_SHFT] = PCI_SXP_REGS_OFF; 889 pcs->pci_poff[RISC_BLOCK >> _BLK_REG_SHFT] = PCI_RISC_REGS_OFF; 890 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] = DMA_REGS_OFF; | 698 pcs->pci_poff[BIU_BLOCK >> _BLK_REG_SHFT] = BIU_REGS_OFF; 699 pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS_OFF; 700 pcs->pci_poff[SXP_BLOCK >> _BLK_REG_SHFT] = PCI_SXP_REGS_OFF; 701 pcs->pci_poff[RISC_BLOCK >> _BLK_REG_SHFT] = PCI_RISC_REGS_OFF; 702 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] = DMA_REGS_OFF; |
891 mdvp = &mdvec; 892 basetype = ISP_HA_SCSI_UNKNOWN; 893 psize = sizeof (sdparam); 894 if (pci_get_devid(dev) == PCI_QLOGIC_ISP1020) { 895 mdvp = &mdvec; 896 basetype = ISP_HA_SCSI_UNKNOWN; 897 psize = sizeof (sdparam); 898 } 899 if (pci_get_devid(dev) == PCI_QLOGIC_ISP1080) { 900 mdvp = &mdvec_1080; 901 basetype = ISP_HA_SCSI_1080; 902 psize = sizeof (sdparam); 903 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] = 904 ISP1080_DMA_REGS_OFF; 905 } 906 if (pci_get_devid(dev) == PCI_QLOGIC_ISP1240) { 907 mdvp = &mdvec_1080; 908 basetype = ISP_HA_SCSI_1240; 909 psize = 2 * sizeof (sdparam); 910 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] = 911 ISP1080_DMA_REGS_OFF; 912 } 913 if (pci_get_devid(dev) == PCI_QLOGIC_ISP1280) { 914 mdvp = &mdvec_1080; 915 basetype = ISP_HA_SCSI_1280; 916 psize = 2 * sizeof (sdparam); 917 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] = 918 ISP1080_DMA_REGS_OFF; 919 } 920 if (pci_get_devid(dev) == PCI_QLOGIC_ISP10160) { 921 mdvp = &mdvec_12160; 922 basetype = ISP_HA_SCSI_10160; 923 psize = sizeof (sdparam); 924 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] = 925 ISP1080_DMA_REGS_OFF; 926 } 927 if (pci_get_devid(dev) == PCI_QLOGIC_ISP12160) { 928 mdvp = &mdvec_12160; 929 basetype = ISP_HA_SCSI_12160; 930 psize = 2 * sizeof (sdparam); 931 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] = 932 ISP1080_DMA_REGS_OFF; 933 } 934 if (pci_get_devid(dev) == PCI_QLOGIC_ISP2100) { 935 mdvp = &mdvec_2100; 936 basetype = ISP_HA_FC_2100; 937 psize = sizeof (fcparam); 938 pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = 939 PCI_MBOX_REGS2100_OFF; | 703 704 switch (pci_get_devid(dev)) { 705 case PCI_QLOGIC_ISP1020: 706 did = 0x1040; 707 isp->isp_mdvec = &mdvec; 708 isp->isp_type = ISP_HA_SCSI_UNKNOWN; 709 break; 710 case PCI_QLOGIC_ISP1080: 711 did = 0x1080; 712 isp->isp_mdvec = &mdvec_1080; 713 isp->isp_type = ISP_HA_SCSI_1080; 714 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] = ISP1080_DMA_REGS_OFF; 715 break; 716 case PCI_QLOGIC_ISP1240: 717 did = 0x1080; 718 isp->isp_mdvec = &mdvec_1080; 719 isp->isp_type = ISP_HA_SCSI_1240; 720 isp->isp_nchan = 2; 721 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] = ISP1080_DMA_REGS_OFF; 722 break; 723 case PCI_QLOGIC_ISP1280: 724 did = 0x1080; 725 isp->isp_mdvec = &mdvec_1080; 726 isp->isp_type = ISP_HA_SCSI_1280; 727 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] = ISP1080_DMA_REGS_OFF; 728 break; 729 case PCI_QLOGIC_ISP10160: 730 did = 0x12160; 731 isp->isp_mdvec = &mdvec_12160; 732 isp->isp_type = ISP_HA_SCSI_10160; 733 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] = ISP1080_DMA_REGS_OFF; 734 break; 735 case PCI_QLOGIC_ISP12160: 736 did = 0x12160; 737 isp->isp_nchan = 2; 738 isp->isp_mdvec = &mdvec_12160; 739 isp->isp_type = ISP_HA_SCSI_12160; 740 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] = ISP1080_DMA_REGS_OFF; 741 break; 742 case PCI_QLOGIC_ISP2100: 743 did = 0x2100; 744 isp->isp_mdvec = &mdvec_2100; 745 isp->isp_type = ISP_HA_FC_2100; 746 pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS2100_OFF; |
940 if (pci_get_revid(dev) < 3) { 941 /* 942 * XXX: Need to get the actual revision 943 * XXX: number of the 2100 FB. At any rate, 944 * XXX: lower cache line size for early revision 945 * XXX; boards. 946 */ 947 linesz = 1; 948 } | 747 if (pci_get_revid(dev) < 3) { 748 /* 749 * XXX: Need to get the actual revision 750 * XXX: number of the 2100 FB. At any rate, 751 * XXX: lower cache line size for early revision 752 * XXX; boards. 753 */ 754 linesz = 1; 755 } |
756 break; 757 case PCI_QLOGIC_ISP2200: 758 did = 0x2200; 759 isp->isp_mdvec = &mdvec_2200; 760 isp->isp_type = ISP_HA_FC_2200; 761 pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS2100_OFF; 762 break; 763 case PCI_QLOGIC_ISP2300: 764 did = 0x2300; 765 isp->isp_mdvec = &mdvec_2300; 766 isp->isp_type = ISP_HA_FC_2300; 767 pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS2300_OFF; 768 break; 769 case PCI_QLOGIC_ISP2312: 770 case PCI_QLOGIC_ISP6312: 771 did = 0x2300; 772 isp->isp_mdvec = &mdvec_2300; 773 isp->isp_type = ISP_HA_FC_2312; 774 pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS2300_OFF; 775 break; 776 case PCI_QLOGIC_ISP2322: 777 case PCI_QLOGIC_ISP6322: 778 did = 0x2322; 779 isp->isp_mdvec = &mdvec_2300; 780 isp->isp_type = ISP_HA_FC_2322; 781 pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS2300_OFF; 782 break; 783 case PCI_QLOGIC_ISP2422: 784 case PCI_QLOGIC_ISP2432: 785 did = 0x2400; 786 isp->isp_nchan += isp_nvports; 787 isp->isp_mdvec = &mdvec_2400; 788 isp->isp_type = ISP_HA_FC_2400; 789 pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS2400_OFF; 790 break; 791 case PCI_QLOGIC_ISP2532: 792 did = 0x2500; 793 isp->isp_nchan += isp_nvports; 794 isp->isp_mdvec = &mdvec_2500; 795 isp->isp_type = ISP_HA_FC_2500; 796 pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS2400_OFF; 797 break; 798 default: 799 device_printf(dev, "unknown device type\n"); 800 goto bad; 801 break; |
|
949 } | 802 } |
950 if (pci_get_devid(dev) == PCI_QLOGIC_ISP2200) { 951 mdvp = &mdvec_2200; 952 basetype = ISP_HA_FC_2200; | 803 isp->isp_revision = pci_get_revid(dev); 804 805 if (IS_FC(isp)) { |
953 psize = sizeof (fcparam); | 806 psize = sizeof (fcparam); |
954 pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = 955 PCI_MBOX_REGS2100_OFF; | 807 xsize = sizeof (struct isp_fc); 808 } else { 809 psize = sizeof (sdparam); 810 xsize = sizeof (struct isp_spi); |
956 } | 811 } |
957 if (pci_get_devid(dev) == PCI_QLOGIC_ISP2300) { 958 mdvp = &mdvec_2300; 959 basetype = ISP_HA_FC_2300; 960 psize = sizeof (fcparam); 961 pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = 962 PCI_MBOX_REGS2300_OFF; 963 } 964 if (pci_get_devid(dev) == PCI_QLOGIC_ISP2312 || 965 pci_get_devid(dev) == PCI_QLOGIC_ISP6312) { 966 mdvp = &mdvec_2300; 967 basetype = ISP_HA_FC_2312; 968 psize = sizeof (fcparam); 969 pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = 970 PCI_MBOX_REGS2300_OFF; 971 } 972 if (pci_get_devid(dev) == PCI_QLOGIC_ISP2322 || 973 pci_get_devid(dev) == PCI_QLOGIC_ISP6322) { 974 mdvp = &mdvec_2300; 975 basetype = ISP_HA_FC_2322; 976 psize = sizeof (fcparam); 977 pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = 978 PCI_MBOX_REGS2300_OFF; 979 } 980 if (pci_get_devid(dev) == PCI_QLOGIC_ISP2422 || 981 pci_get_devid(dev) == PCI_QLOGIC_ISP2432) { 982 mdvp = &mdvec_2400; 983 basetype = ISP_HA_FC_2400; 984 psize = sizeof (fcparam); 985 pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = 986 PCI_MBOX_REGS2400_OFF; 987 } 988 isp = &pcs->pci_isp; | 812 psize *= isp->isp_nchan; 813 xsize *= isp->isp_nchan; |
989 isp->isp_param = malloc(psize, M_DEVBUF, M_NOWAIT | M_ZERO); 990 if (isp->isp_param == NULL) { 991 device_printf(dev, "cannot allocate parameter data\n"); 992 goto bad; 993 } | 814 isp->isp_param = malloc(psize, M_DEVBUF, M_NOWAIT | M_ZERO); 815 if (isp->isp_param == NULL) { 816 device_printf(dev, "cannot allocate parameter data\n"); 817 goto bad; 818 } |
994 isp->isp_mdvec = mdvp; 995 isp->isp_type = basetype; 996 isp->isp_revision = pci_get_revid(dev); 997 isp->isp_dev = dev; | 819 isp->isp_osinfo.pc.ptr = malloc(xsize, M_DEVBUF, M_NOWAIT | M_ZERO); 820 if (isp->isp_osinfo.pc.ptr == NULL) { 821 device_printf(dev, "cannot allocate parameter data\n"); 822 goto bad; 823 } |
998 999 /* 1000 * Now that we know who we are (roughly) get/set specific options 1001 */ | 824 825 /* 826 * Now that we know who we are (roughly) get/set specific options 827 */ |
1002 isp_get_specific_options(dev, isp); | 828 for (i = 0; i < isp->isp_nchan; i++) { 829 isp_get_specific_options(dev, i, isp); 830 } |
1003 | 831 |
1004#if __FreeBSD_version >= 700000 | |
1005 /* | 832 /* |
1006 * Try and find firmware for this device. | 833 * The 'it' suffix really only matters for SCSI cards in target mode. |
1007 */ | 834 */ |
1008 { 1009 char fwname[32]; 1010 unsigned int did = pci_get_device(dev); 1011 1012 /* 1013 * Map a few pci ids to fw names 1014 */ 1015 switch (did) { 1016 case PCI_PRODUCT_QLOGIC_ISP1020: 1017 did = 0x1040; 1018 break; 1019 case PCI_PRODUCT_QLOGIC_ISP1240: 1020 did = 0x1080; 1021 break; 1022 case PCI_PRODUCT_QLOGIC_ISP10160: 1023 case PCI_PRODUCT_QLOGIC_ISP12160: 1024 did = 0x12160; 1025 break; 1026 case PCI_PRODUCT_QLOGIC_ISP6312: 1027 case PCI_PRODUCT_QLOGIC_ISP2312: 1028 did = 0x2300; 1029 break; 1030 case PCI_PRODUCT_QLOGIC_ISP6322: 1031 did = 0x2322; 1032 break; 1033 case PCI_PRODUCT_QLOGIC_ISP2422: 1034 case PCI_PRODUCT_QLOGIC_ISP2432: 1035 did = 0x2400; 1036 break; 1037 default: 1038 break; 1039 } 1040 1041 isp->isp_osinfo.fw = NULL; 1042 if (isp->isp_role & ISP_ROLE_TARGET) { 1043 snprintf(fwname, sizeof (fwname), "isp_%04x_it", did); 1044 isp->isp_osinfo.fw = firmware_get(fwname); 1045 } 1046 if (isp->isp_osinfo.fw == NULL) { 1047 snprintf(fwname, sizeof (fwname), "isp_%04x", did); 1048 isp->isp_osinfo.fw = firmware_get(fwname); 1049 } 1050 if (isp->isp_osinfo.fw != NULL) { 1051 isp->isp_mdvec->dv_ispfw = isp->isp_osinfo.fw->data; 1052 } | 835 isp->isp_osinfo.fw = NULL; 836 if (IS_SCSI(isp) && (ISP_SPI_PC(isp, 0)->role & ISP_ROLE_TARGET)) { 837 snprintf(fwname, sizeof (fwname), "isp_%04x_it", did); 838 isp->isp_osinfo.fw = firmware_get(fwname); 839 } else if (IS_24XX(isp) && (isp->isp_nchan > 1 || isp->isp_osinfo.forcemulti)) { 840 snprintf(fwname, sizeof (fwname), "isp_%04x_multi", did); 841 isp->isp_osinfo.fw = firmware_get(fwname); |
1053 } | 842 } |
1054#else 1055 if (isp_get_firmware_p) { 1056 int device = (int) pci_get_device(dev); 1057#ifdef ISP_TARGET_MODE 1058 (*isp_get_firmware_p)(0, 1, device, &mdvp->dv_ispfw); 1059#else 1060 (*isp_get_firmware_p)(0, 0, device, &mdvp->dv_ispfw); 1061#endif | 843 if (isp->isp_osinfo.fw == NULL) { 844 snprintf(fwname, sizeof (fwname), "isp_%04x", did); 845 isp->isp_osinfo.fw = firmware_get(fwname); |
1062 } | 846 } |
1063#endif | 847 if (isp->isp_osinfo.fw != NULL) { 848 isp->isp_mdvec->dv_ispfw = isp->isp_osinfo.fw->data; 849 } |
1064 1065 /* 1066 * Make sure that SERR, PERR, WRITE INVALIDATE and BUSMASTER 1067 * are set. 1068 */ 1069 cmd |= PCIM_CMD_SEREN | PCIM_CMD_PERRESPEN | 1070 PCIM_CMD_BUSMASTEREN | PCIM_CMD_INVEN; 1071 1072 if (IS_2300(isp)) { /* per QLogic errata */ 1073 cmd &= ~PCIM_CMD_INVEN; 1074 } 1075 1076 if (IS_2322(isp) || pci_get_devid(dev) == PCI_QLOGIC_ISP6312) { 1077 cmd &= ~PCIM_CMD_INTX_DISABLE; 1078 } 1079 | 850 851 /* 852 * Make sure that SERR, PERR, WRITE INVALIDATE and BUSMASTER 853 * are set. 854 */ 855 cmd |= PCIM_CMD_SEREN | PCIM_CMD_PERRESPEN | 856 PCIM_CMD_BUSMASTEREN | PCIM_CMD_INVEN; 857 858 if (IS_2300(isp)) { /* per QLogic errata */ 859 cmd &= ~PCIM_CMD_INVEN; 860 } 861 862 if (IS_2322(isp) || pci_get_devid(dev) == PCI_QLOGIC_ISP6312) { 863 cmd &= ~PCIM_CMD_INTX_DISABLE; 864 } 865 |
1080#ifdef WE_KNEW_WHAT_WE_WERE_DOING | |
1081 if (IS_24XX(isp)) { | 866 if (IS_24XX(isp)) { |
1082 int reg; 1083 | |
1084 cmd &= ~PCIM_CMD_INTX_DISABLE; | 867 cmd &= ~PCIM_CMD_INTX_DISABLE; |
1085 1086 /* 1087 * Is this a PCI-X card? If so, set max read byte count. 1088 */ 1089 if (pci_find_extcap(dev, PCIY_PCIX, ®) == 0) { 1090 uint16_t pxcmd; 1091 reg += 2; 1092 1093 pxcmd = pci_read_config(dev, reg, 2); 1094 pxcmd &= ~0xc; 1095 pxcmd |= 0x8; 1096 pci_write_config(dev, reg, 2, pxcmd); 1097 } 1098 1099 /* 1100 * Is this a PCI Express card? If so, set max read byte count. 1101 */ 1102 if (pci_find_extcap(dev, PCIY_EXPRESS, ®) == 0) { 1103 uint16_t pectl; 1104 1105 reg += 0x8; 1106 pectl = pci_read_config(dev, reg, 2); 1107 pectl &= ~0x7000; 1108 pectl |= 0x4000; 1109 pci_write_config(dev, reg, 2, pectl); 1110 } | |
1111 } | 868 } |
1112#else 1113 if (IS_24XX(isp)) { 1114 cmd &= ~PCIM_CMD_INTX_DISABLE; 1115 } 1116#endif | |
1117 1118 pci_write_config(dev, PCIR_COMMAND, cmd, 2); 1119 1120 /* 1121 * Make sure the Cache Line Size register is set sensibly. 1122 */ 1123 data = pci_read_config(dev, PCIR_CACHELNSZ, 1); 1124 if (data == 0 || (linesz != PCI_DFLT_LNSZ && data != linesz)) { | 869 870 pci_write_config(dev, PCIR_COMMAND, cmd, 2); 871 872 /* 873 * Make sure the Cache Line Size register is set sensibly. 874 */ 875 data = pci_read_config(dev, PCIR_CACHELNSZ, 1); 876 if (data == 0 || (linesz != PCI_DFLT_LNSZ && data != linesz)) { |
1125 isp_prt(isp, ISP_LOGCONFIG, "set PCI line size to %d from %d", 1126 linesz, data); | 877 isp_prt(isp, ISP_LOGCONFIG, "set PCI line size to %d from %d", linesz, data); |
1127 data = linesz; 1128 pci_write_config(dev, PCIR_CACHELNSZ, data, 1); 1129 } 1130 1131 /* 1132 * Make sure the Latency Timer is sane. 1133 */ 1134 data = pci_read_config(dev, PCIR_LATTIMER, 1); --- 4 unchanged lines hidden (view full) --- 1139 } 1140 1141 /* 1142 * Make sure we've disabled the ROM. 1143 */ 1144 data = pci_read_config(dev, PCIR_ROMADDR, 4); 1145 data &= ~1; 1146 pci_write_config(dev, PCIR_ROMADDR, data, 4); | 878 data = linesz; 879 pci_write_config(dev, PCIR_CACHELNSZ, data, 1); 880 } 881 882 /* 883 * Make sure the Latency Timer is sane. 884 */ 885 data = pci_read_config(dev, PCIR_LATTIMER, 1); --- 4 unchanged lines hidden (view full) --- 890 } 891 892 /* 893 * Make sure we've disabled the ROM. 894 */ 895 data = pci_read_config(dev, PCIR_ROMADDR, 4); 896 data &= ~1; 897 pci_write_config(dev, PCIR_ROMADDR, data, 4); |
1147#if __FreeBSD_version > 700025 | 898 899 /* 900 * Do MSI 901 * 902 * NB: MSI-X needs to be disabled for the 2432 (PCI-Express) 903 */ |
1148 if (IS_24XX(isp) || IS_2322(isp)) { 1149 pcs->msicount = pci_msi_count(dev); 1150 if (pcs->msicount > 1) { 1151 pcs->msicount = 1; 1152 } 1153 if (pci_alloc_msi(dev, &pcs->msicount) == 0) { 1154 iqd = 1; 1155 } else { 1156 iqd = 0; 1157 } 1158 } | 904 if (IS_24XX(isp) || IS_2322(isp)) { 905 pcs->msicount = pci_msi_count(dev); 906 if (pcs->msicount > 1) { 907 pcs->msicount = 1; 908 } 909 if (pci_alloc_msi(dev, &pcs->msicount) == 0) { 910 iqd = 1; 911 } else { 912 iqd = 0; 913 } 914 } |
1159#else 1160 iqd = 0; 1161#endif 1162 irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &iqd, 1163 RF_ACTIVE | RF_SHAREABLE); | 915 irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &iqd, RF_ACTIVE | RF_SHAREABLE); |
1164 if (irq == NULL) { 1165 device_printf(dev, "could not allocate interrupt\n"); 1166 goto bad; 1167 } 1168 | 916 if (irq == NULL) { 917 device_printf(dev, "could not allocate interrupt\n"); 918 goto bad; 919 } 920 |
1169#if __FreeBSD_version >= 500000 | |
1170 /* Make sure the lock is set up. */ 1171 mtx_init(&isp->isp_osinfo.lock, "isp", NULL, MTX_DEF); 1172 locksetup++; | 921 /* Make sure the lock is set up. */ 922 mtx_init(&isp->isp_osinfo.lock, "isp", NULL, MTX_DEF); 923 locksetup++; |
1173#endif | |
1174 | 924 |
1175 if (isp_setup_intr(dev, irq, ISP_IFLAGS, NULL, isp_platform_intr, isp, 1176 &pcs->ih)) { | 925 if (isp_setup_intr(dev, irq, ISP_IFLAGS, NULL, isp_platform_intr, isp, &pcs->ih)) { |
1177 device_printf(dev, "could not setup interrupt\n"); 1178 goto bad; 1179 } 1180 1181 /* 1182 * Last minute checks... 1183 */ 1184 if (IS_23XX(isp) || IS_24XX(isp)) { 1185 isp->isp_port = pci_get_function(dev); 1186 } 1187 | 926 device_printf(dev, "could not setup interrupt\n"); 927 goto bad; 928 } 929 930 /* 931 * Last minute checks... 932 */ 933 if (IS_23XX(isp) || IS_24XX(isp)) { 934 isp->isp_port = pci_get_function(dev); 935 } 936 |
1188 if (IS_23XX(isp)) { 1189 /* 1190 * Can't tell if ROM will hang on 'ABOUT FIRMWARE' command. 1191 */ 1192 isp->isp_touched = 1; 1193 } 1194 | |
1195 /* 1196 * Make sure we're in reset state. 1197 */ 1198 ISP_LOCK(isp); | 937 /* 938 * Make sure we're in reset state. 939 */ 940 ISP_LOCK(isp); |
1199 isp_reset(isp); | 941 isp_reset(isp, 1); |
1200 if (isp->isp_state != ISP_RESETSTATE) { 1201 ISP_UNLOCK(isp); 1202 goto bad; 1203 } 1204 isp_init(isp); | 942 if (isp->isp_state != ISP_RESETSTATE) { 943 ISP_UNLOCK(isp); 944 goto bad; 945 } 946 isp_init(isp); |
1205 if (isp->isp_role != ISP_ROLE_NONE && isp->isp_state != ISP_INITSTATE) { 1206 isp_uninit(isp); 1207 ISP_UNLOCK(isp); 1208 goto bad; | 947 if (isp->isp_state == ISP_INITSTATE) { 948 isp->isp_state = ISP_RUNSTATE; |
1209 } | 949 } |
1210 isp_attach(isp); 1211 if (isp->isp_role != ISP_ROLE_NONE && isp->isp_state != ISP_RUNSTATE) { | 950 ISP_UNLOCK(isp); 951 if (isp_attach(isp)) { 952 ISP_LOCK(isp); |
1212 isp_uninit(isp); 1213 ISP_UNLOCK(isp); 1214 goto bad; 1215 } | 953 isp_uninit(isp); 954 ISP_UNLOCK(isp); 955 goto bad; 956 } |
1216 ISP_UNLOCK(isp); | |
1217 return (0); 1218 1219bad: 1220 if (pcs && pcs->ih) { 1221 (void) bus_teardown_intr(dev, irq, pcs->ih); 1222 } | 957 return (0); 958 959bad: 960 if (pcs && pcs->ih) { 961 (void) bus_teardown_intr(dev, irq, pcs->ih); 962 } |
1223#if __FreeBSD_version >= 500000 | |
1224 if (locksetup && isp) { 1225 mtx_destroy(&isp->isp_osinfo.lock); 1226 } | 963 if (locksetup && isp) { 964 mtx_destroy(&isp->isp_osinfo.lock); 965 } |
1227#endif | |
1228 if (irq) { 1229 (void) bus_release_resource(dev, SYS_RES_IRQ, iqd, irq); 1230 } | 966 if (irq) { 967 (void) bus_release_resource(dev, SYS_RES_IRQ, iqd, irq); 968 } |
1231#if __FreeBSD_version > 700025 | |
1232 if (pcs && pcs->msicount) { 1233 pci_release_msi(dev); 1234 } | 969 if (pcs && pcs->msicount) { 970 pci_release_msi(dev); 971 } |
1235#endif | |
1236 if (regs) { 1237 (void) bus_release_resource(dev, rtp, rgd, regs); 1238 } 1239 if (pcs) { 1240 if (pcs->pci_isp.isp_param) { | 972 if (regs) { 973 (void) bus_release_resource(dev, rtp, rgd, regs); 974 } 975 if (pcs) { 976 if (pcs->pci_isp.isp_param) { |
1241#ifdef ISP_FW_CRASH_DUMP 1242 if (IS_FC(isp) && FCPARAM(isp)->isp_dump_data) { 1243 free(FCPARAM(isp)->isp_dump_data, M_DEVBUF); 1244 } 1245#endif | |
1246 free(pcs->pci_isp.isp_param, M_DEVBUF); | 977 free(pcs->pci_isp.isp_param, M_DEVBUF); |
978 pcs->pci_isp.isp_param = NULL; |
|
1247 } | 979 } |
980 if (pcs->pci_isp.isp_osinfo.pc.ptr) { 981 free(pcs->pci_isp.isp_osinfo.pc.ptr, M_DEVBUF); 982 pcs->pci_isp.isp_osinfo.pc.ptr = NULL; 983 } |
|
1248 } 1249 return (ENXIO); 1250} 1251 1252static int 1253isp_pci_detach(device_t dev) 1254{ 1255 struct isp_pcisoftc *pcs; 1256 ispsoftc_t *isp; 1257 1258 pcs = device_get_softc(dev); 1259 if (pcs == NULL) { 1260 return (ENXIO); 1261 } 1262 isp = (ispsoftc_t *) pcs; 1263 ISP_DISABLE_INTS(isp); | 984 } 985 return (ENXIO); 986} 987 988static int 989isp_pci_detach(device_t dev) 990{ 991 struct isp_pcisoftc *pcs; 992 ispsoftc_t *isp; 993 994 pcs = device_get_softc(dev); 995 if (pcs == NULL) { 996 return (ENXIO); 997 } 998 isp = (ispsoftc_t *) pcs; 999 ISP_DISABLE_INTS(isp); |
1000 mtx_destroy(&isp->isp_osinfo.lock); |
|
1264 return (0); 1265} 1266 1267#define IspVirt2Off(a, x) \ 1268 (((struct isp_pcisoftc *)a)->pci_poff[((x) & _BLK_REG_MASK) >> \ 1269 _BLK_REG_SHFT] + ((x) & 0xfff)) 1270 1271#define BXR2(isp, off) \ 1272 bus_space_read_2(isp->isp_bus_tag, isp->isp_bus_handle, off) 1273#define BXW2(isp, off, v) \ 1274 bus_space_write_2(isp->isp_bus_tag, isp->isp_bus_handle, off, v) 1275#define BXR4(isp, off) \ 1276 bus_space_read_4(isp->isp_bus_tag, isp->isp_bus_handle, off) 1277#define BXW4(isp, off, v) \ 1278 bus_space_write_4(isp->isp_bus_tag, isp->isp_bus_handle, off, v) 1279 1280 | 1001 return (0); 1002} 1003 1004#define IspVirt2Off(a, x) \ 1005 (((struct isp_pcisoftc *)a)->pci_poff[((x) & _BLK_REG_MASK) >> \ 1006 _BLK_REG_SHFT] + ((x) & 0xfff)) 1007 1008#define BXR2(isp, off) \ 1009 bus_space_read_2(isp->isp_bus_tag, isp->isp_bus_handle, off) 1010#define BXW2(isp, off, v) \ 1011 bus_space_write_2(isp->isp_bus_tag, isp->isp_bus_handle, off, v) 1012#define BXR4(isp, off) \ 1013 bus_space_read_4(isp->isp_bus_tag, isp->isp_bus_handle, off) 1014#define BXW4(isp, off, v) \ 1015 bus_space_write_4(isp->isp_bus_tag, isp->isp_bus_handle, off, v) 1016 1017 |
1281static __inline int | 1018static ISP_INLINE int |
1282isp_pci_rd_debounced(ispsoftc_t *isp, int off, uint16_t *rp) 1283{ 1284 uint32_t val0, val1; 1285 int i = 0; 1286 1287 do { 1288 val0 = BXR2(isp, IspVirt2Off(isp, off)); 1289 val1 = BXR2(isp, IspVirt2Off(isp, off)); --- 282 unchanged lines hidden (view full) --- 1572 case BIU2400_FLASH_DATA: 1573 case BIU2400_ICR: 1574 case BIU2400_ISR: 1575 case BIU2400_CSR: 1576 case BIU2400_REQINP: 1577 case BIU2400_REQOUTP: 1578 case BIU2400_RSPINP: 1579 case BIU2400_RSPOUTP: | 1019isp_pci_rd_debounced(ispsoftc_t *isp, int off, uint16_t *rp) 1020{ 1021 uint32_t val0, val1; 1022 int i = 0; 1023 1024 do { 1025 val0 = BXR2(isp, IspVirt2Off(isp, off)); 1026 val1 = BXR2(isp, IspVirt2Off(isp, off)); --- 282 unchanged lines hidden (view full) --- 1309 case BIU2400_FLASH_DATA: 1310 case BIU2400_ICR: 1311 case BIU2400_ISR: 1312 case BIU2400_CSR: 1313 case BIU2400_REQINP: 1314 case BIU2400_REQOUTP: 1315 case BIU2400_RSPINP: 1316 case BIU2400_RSPOUTP: |
1580 case BIU2400_PRI_RQINP: 1581 case BIU2400_PRI_RSPINP: | 1317 case BIU2400_PRI_REQINP: 1318 case BIU2400_PRI_REQOUTP: |
1582 case BIU2400_ATIO_RSPINP: | 1319 case BIU2400_ATIO_RSPINP: |
1583 case BIU2400_ATIO_REQINP: | 1320 case BIU2400_ATIO_RSPOUTP: |
1584 case BIU2400_HCCR: 1585 case BIU2400_GPIOD: 1586 case BIU2400_GPIOE: 1587 case BIU2400_HSEMA: 1588 rv = BXR4(isp, IspVirt2Off(isp, regoff)); 1589 break; 1590 case BIU2400_R2HSTSLO: 1591 rv = BXR4(isp, IspVirt2Off(isp, regoff)); --- 42 unchanged lines hidden (view full) --- 1634 case BIU2400_FLASH_DATA: 1635 case BIU2400_ICR: 1636 case BIU2400_ISR: 1637 case BIU2400_CSR: 1638 case BIU2400_REQINP: 1639 case BIU2400_REQOUTP: 1640 case BIU2400_RSPINP: 1641 case BIU2400_RSPOUTP: | 1321 case BIU2400_HCCR: 1322 case BIU2400_GPIOD: 1323 case BIU2400_GPIOE: 1324 case BIU2400_HSEMA: 1325 rv = BXR4(isp, IspVirt2Off(isp, regoff)); 1326 break; 1327 case BIU2400_R2HSTSLO: 1328 rv = BXR4(isp, IspVirt2Off(isp, regoff)); --- 42 unchanged lines hidden (view full) --- 1371 case BIU2400_FLASH_DATA: 1372 case BIU2400_ICR: 1373 case BIU2400_ISR: 1374 case BIU2400_CSR: 1375 case BIU2400_REQINP: 1376 case BIU2400_REQOUTP: 1377 case BIU2400_RSPINP: 1378 case BIU2400_RSPOUTP: |
1642 case BIU2400_PRI_RQINP: 1643 case BIU2400_PRI_RSPINP: | 1379 case BIU2400_PRI_REQINP: 1380 case BIU2400_PRI_REQOUTP: |
1644 case BIU2400_ATIO_RSPINP: | 1381 case BIU2400_ATIO_RSPINP: |
1645 case BIU2400_ATIO_REQINP: | 1382 case BIU2400_ATIO_RSPOUTP: |
1646 case BIU2400_HCCR: 1647 case BIU2400_GPIOD: 1648 case BIU2400_GPIOE: 1649 case BIU2400_HSEMA: 1650 BXW4(isp, IspVirt2Off(isp, regoff), val); 1651 MEMORYBARRIER(isp, SYNC_REG, IspVirt2Off(isp, regoff), 4); 1652 break; 1653 default: 1654 isp_prt(isp, ISP_LOGERR, 1655 "isp_pci_wr_reg_2400: bad offset 0x%x", regoff); 1656 break; 1657 } 1658} 1659 1660 1661struct imush { 1662 ispsoftc_t *isp; | 1383 case BIU2400_HCCR: 1384 case BIU2400_GPIOD: 1385 case BIU2400_GPIOE: 1386 case BIU2400_HSEMA: 1387 BXW4(isp, IspVirt2Off(isp, regoff), val); 1388 MEMORYBARRIER(isp, SYNC_REG, IspVirt2Off(isp, regoff), 4); 1389 break; 1390 default: 1391 isp_prt(isp, ISP_LOGERR, 1392 "isp_pci_wr_reg_2400: bad offset 0x%x", regoff); 1393 break; 1394 } 1395} 1396 1397 1398struct imush { 1399 ispsoftc_t *isp; |
1400 caddr_t vbase; 1401 int chan; |
|
1663 int error; 1664}; 1665 1666static void imc(void *, bus_dma_segment_t *, int, int); | 1402 int error; 1403}; 1404 1405static void imc(void *, bus_dma_segment_t *, int, int); |
1406static void imc1(void *, bus_dma_segment_t *, int, int); |
|
1667 1668static void 1669imc(void *arg, bus_dma_segment_t *segs, int nseg, int error) 1670{ 1671 struct imush *imushp = (struct imush *) arg; | 1407 1408static void 1409imc(void *arg, bus_dma_segment_t *segs, int nseg, int error) 1410{ 1411 struct imush *imushp = (struct imush *) arg; |
1412 |
|
1672 if (error) { 1673 imushp->error = error; | 1413 if (error) { 1414 imushp->error = error; |
1674 } else { 1675 ispsoftc_t *isp =imushp->isp; 1676 bus_addr_t addr = segs->ds_addr; | 1415 return; 1416 } 1417 if (nseg != 1) { 1418 imushp->error = EINVAL; 1419 return; 1420 } 1421 imushp->isp->isp_rquest = imushp->vbase; 1422 imushp->isp->isp_rquest_dma = segs->ds_addr; 1423 segs->ds_addr += ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(imushp->isp)); 1424 imushp->vbase += ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(imushp->isp)); 1425 imushp->isp->isp_result_dma = segs->ds_addr; 1426 imushp->isp->isp_result = imushp->vbase; |
1677 | 1427 |
1678 isp->isp_rquest_dma = addr; 1679 addr += ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)); 1680 isp->isp_result_dma = addr; 1681 if (IS_FC(isp)) { 1682 addr += ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp)); 1683 FCPARAM(isp)->isp_scdma = addr; 1684 } | 1428#ifdef ISP_TARGET_MODE 1429 if (IS_24XX(imushp->isp)) { 1430 segs->ds_addr += ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(imushp->isp)); 1431 imushp->vbase += ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(imushp->isp)); 1432 imushp->isp->isp_atioq_dma = segs->ds_addr; 1433 imushp->isp->isp_atioq = imushp->vbase; |
1685 } | 1434 } |
1435#endif |
|
1686} 1687 | 1436} 1437 |
1438static void 1439imc1(void *arg, bus_dma_segment_t *segs, int nseg, int error) 1440{ 1441 struct imush *imushp = (struct imush *) arg; 1442 if (error) { 1443 imushp->error = error; 1444 return; 1445 } 1446 if (nseg != 1) { 1447 imushp->error = EINVAL; 1448 return; 1449 } 1450 FCPARAM(imushp->isp, imushp->chan)->isp_scdma = segs->ds_addr; 1451 FCPARAM(imushp->isp, imushp->chan)->isp_scratch = imushp->vbase; 1452} 1453 |
|
1688static int 1689isp_pci_mbxdma(ispsoftc_t *isp) 1690{ 1691 caddr_t base; 1692 uint32_t len; | 1454static int 1455isp_pci_mbxdma(ispsoftc_t *isp) 1456{ 1457 caddr_t base; 1458 uint32_t len; |
1693 int i, error, ns; | 1459 int i, error, ns, cmap = 0; |
1694 bus_size_t slim; /* segment size */ 1695 bus_addr_t llim; /* low limit of unavailable dma */ 1696 bus_addr_t hlim; /* high limit of unavailable dma */ 1697 struct imush im; 1698 1699 /* 1700 * Already been here? If so, leave... 1701 */ --- 17 unchanged lines hidden (view full) --- 1719 } 1720 llim = BUS_SPACE_MAXADDR; 1721 } else { 1722 llim = BUS_SPACE_MAXADDR_32BIT; 1723 slim = (1UL << 24); 1724 } 1725 1726 len = isp->isp_maxcmds * sizeof (struct isp_pcmd); | 1460 bus_size_t slim; /* segment size */ 1461 bus_addr_t llim; /* low limit of unavailable dma */ 1462 bus_addr_t hlim; /* high limit of unavailable dma */ 1463 struct imush im; 1464 1465 /* 1466 * Already been here? If so, leave... 1467 */ --- 17 unchanged lines hidden (view full) --- 1485 } 1486 llim = BUS_SPACE_MAXADDR; 1487 } else { 1488 llim = BUS_SPACE_MAXADDR_32BIT; 1489 slim = (1UL << 24); 1490 } 1491 1492 len = isp->isp_maxcmds * sizeof (struct isp_pcmd); |
1727 isp->isp_osinfo.pcmd_pool = 1728 (struct isp_pcmd *) malloc(len, M_DEVBUF, M_WAITOK | M_ZERO); | 1493 isp->isp_osinfo.pcmd_pool = (struct isp_pcmd *) malloc(len, M_DEVBUF, M_WAITOK | M_ZERO); |
1729 if (isp->isp_osinfo.pcmd_pool == NULL) { 1730 isp_prt(isp, ISP_LOGERR, "cannot allocate pcmds"); 1731 ISP_LOCK(isp); 1732 return (1); 1733 } 1734 1735 /* 1736 * XXX: We don't really support 64 bit target mode for parallel scsi yet 1737 */ 1738#ifdef ISP_TARGET_MODE 1739 if (IS_SCSI(isp) && sizeof (bus_addr_t) > 4) { 1740 free(isp->isp_osinfo.pcmd_pool, M_DEVBUF); | 1494 if (isp->isp_osinfo.pcmd_pool == NULL) { 1495 isp_prt(isp, ISP_LOGERR, "cannot allocate pcmds"); 1496 ISP_LOCK(isp); 1497 return (1); 1498 } 1499 1500 /* 1501 * XXX: We don't really support 64 bit target mode for parallel scsi yet 1502 */ 1503#ifdef ISP_TARGET_MODE 1504 if (IS_SCSI(isp) && sizeof (bus_addr_t) > 4) { 1505 free(isp->isp_osinfo.pcmd_pool, M_DEVBUF); |
1741 ISP_LOCK(isp); | |
1742 isp_prt(isp, ISP_LOGERR, "we cannot do DAC for SPI cards yet"); | 1506 isp_prt(isp, ISP_LOGERR, "we cannot do DAC for SPI cards yet"); |
1507 ISP_LOCK(isp); |
|
1743 return (1); 1744 } 1745#endif 1746 | 1508 return (1); 1509 } 1510#endif 1511 |
1747 if (isp_dma_tag_create(BUS_DMA_ROOTARG(ISP_PCD(isp)), 1, 1748 slim, llim, hlim, NULL, NULL, BUS_SPACE_MAXSIZE, ISP_NSEGS, 1749 slim, 0, &isp->isp_osinfo.dmat)) { | 1512 if (isp_dma_tag_create(BUS_DMA_ROOTARG(ISP_PCD(isp)), 1, slim, llim, hlim, NULL, NULL, BUS_SPACE_MAXSIZE, ISP_NSEGS, slim, 0, &isp->isp_osinfo.dmat)) { |
1750 free(isp->isp_osinfo.pcmd_pool, M_DEVBUF); 1751 ISP_LOCK(isp); 1752 isp_prt(isp, ISP_LOGERR, "could not create master dma tag"); 1753 return (1); 1754 } 1755 | 1513 free(isp->isp_osinfo.pcmd_pool, M_DEVBUF); 1514 ISP_LOCK(isp); 1515 isp_prt(isp, ISP_LOGERR, "could not create master dma tag"); 1516 return (1); 1517 } 1518 |
1756 | |
1757 len = sizeof (XS_T **) * isp->isp_maxcmds; 1758 isp->isp_xflist = (XS_T **) malloc(len, M_DEVBUF, M_WAITOK | M_ZERO); 1759 if (isp->isp_xflist == NULL) { 1760 free(isp->isp_osinfo.pcmd_pool, M_DEVBUF); 1761 ISP_LOCK(isp); 1762 isp_prt(isp, ISP_LOGERR, "cannot alloc xflist array"); 1763 return (1); 1764 } --- 5 unchanged lines hidden (view full) --- 1770 free(isp->isp_xflist, M_DEVBUF); 1771 ISP_LOCK(isp); 1772 isp_prt(isp, ISP_LOGERR, "cannot alloc tgtlist array"); 1773 return (1); 1774 } 1775#endif 1776 1777 /* | 1519 len = sizeof (XS_T **) * isp->isp_maxcmds; 1520 isp->isp_xflist = (XS_T **) malloc(len, M_DEVBUF, M_WAITOK | M_ZERO); 1521 if (isp->isp_xflist == NULL) { 1522 free(isp->isp_osinfo.pcmd_pool, M_DEVBUF); 1523 ISP_LOCK(isp); 1524 isp_prt(isp, ISP_LOGERR, "cannot alloc xflist array"); 1525 return (1); 1526 } --- 5 unchanged lines hidden (view full) --- 1532 free(isp->isp_xflist, M_DEVBUF); 1533 ISP_LOCK(isp); 1534 isp_prt(isp, ISP_LOGERR, "cannot alloc tgtlist array"); 1535 return (1); 1536 } 1537#endif 1538 1539 /* |
1778 * Allocate and map the request, result queues, plus FC scratch area. | 1540 * Allocate and map the request and result queues (and ATIO queue 1541 * if we're a 2400 supporting target mode). |
1779 */ 1780 len = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)); 1781 len += ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp)); | 1542 */ 1543 len = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)); 1544 len += ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp)); |
1782 if (IS_FC(isp)) { 1783 len += ISP2100_SCRLEN; | 1545#ifdef ISP_TARGET_MODE 1546 if (IS_24XX(isp)) { 1547 len += ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp)); |
1784 } | 1548 } |
1549#endif |
|
1785 1786 ns = (len / PAGE_SIZE) + 1; | 1550 1551 ns = (len / PAGE_SIZE) + 1; |
1552 |
|
1787 /* | 1553 /* |
1788 * Create a tag for the control spaces- force it to within 32 bits. | 1554 * Create a tag for the control spaces. We don't always need this 1555 * to be 32 bits, but we do this for simplicity and speed's sake. |
1789 */ | 1556 */ |
1790 if (isp_dma_tag_create(isp->isp_osinfo.dmat, QENTRY_LEN, slim, 1791 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, 1792 NULL, NULL, len, ns, slim, 0, &isp->isp_cdmat)) { 1793 isp_prt(isp, ISP_LOGERR, 1794 "cannot create a dma tag for control spaces"); | 1557 if (isp_dma_tag_create(isp->isp_osinfo.dmat, QENTRY_LEN, slim, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, len, ns, slim, 0, &isp->isp_osinfo.cdmat)) { 1558 isp_prt(isp, ISP_LOGERR, "cannot create a dma tag for control spaces"); |
1795 free(isp->isp_osinfo.pcmd_pool, M_DEVBUF); 1796 free(isp->isp_xflist, M_DEVBUF); 1797#ifdef ISP_TARGET_MODE 1798 free(isp->isp_tgtlist, M_DEVBUF); 1799#endif 1800 ISP_LOCK(isp); 1801 return (1); 1802 } 1803 | 1559 free(isp->isp_osinfo.pcmd_pool, M_DEVBUF); 1560 free(isp->isp_xflist, M_DEVBUF); 1561#ifdef ISP_TARGET_MODE 1562 free(isp->isp_tgtlist, M_DEVBUF); 1563#endif 1564 ISP_LOCK(isp); 1565 return (1); 1566 } 1567 |
1804 if (bus_dmamem_alloc(isp->isp_cdmat, (void **)&base, BUS_DMA_NOWAIT, 1805 &isp->isp_cdmap) != 0) { 1806 isp_prt(isp, ISP_LOGERR, 1807 "cannot allocate %d bytes of CCB memory", len); 1808 bus_dma_tag_destroy(isp->isp_cdmat); | 1568 if (bus_dmamem_alloc(isp->isp_osinfo.cdmat, (void **)&base, BUS_DMA_NOWAIT, &isp->isp_osinfo.cdmap) != 0) { 1569 isp_prt(isp, ISP_LOGERR, "cannot allocate %d bytes of CCB memory", len); 1570 bus_dma_tag_destroy(isp->isp_osinfo.cdmat); |
1809 free(isp->isp_osinfo.pcmd_pool, M_DEVBUF); 1810 free(isp->isp_xflist, M_DEVBUF); 1811#ifdef ISP_TARGET_MODE 1812 free(isp->isp_tgtlist, M_DEVBUF); 1813#endif 1814 ISP_LOCK(isp); 1815 return (1); 1816 } 1817 | 1571 free(isp->isp_osinfo.pcmd_pool, M_DEVBUF); 1572 free(isp->isp_xflist, M_DEVBUF); 1573#ifdef ISP_TARGET_MODE 1574 free(isp->isp_tgtlist, M_DEVBUF); 1575#endif 1576 ISP_LOCK(isp); 1577 return (1); 1578 } 1579 |
1580 im.isp = isp; 1581 im.chan = 0; 1582 im.vbase = base; 1583 im.error = 0; 1584 1585 bus_dmamap_load(isp->isp_osinfo.cdmat, isp->isp_osinfo.cdmap, base, len, imc, &im, 0); 1586 if (im.error) { 1587 isp_prt(isp, ISP_LOGERR, "error %d loading dma map for control areas", im.error); 1588 goto bad; 1589 } 1590 1591 if (IS_FC(isp)) { 1592 for (cmap = 0; cmap < isp->isp_nchan; cmap++) { 1593 struct isp_fc *fc = ISP_FC_PC(isp, cmap); 1594 if (isp_dma_tag_create(isp->isp_osinfo.dmat, 64, slim, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, ISP_FC_SCRLEN, 1, slim, 0, &fc->tdmat)) { 1595 goto bad; 1596 } 1597 if (bus_dmamem_alloc(fc->tdmat, (void **)&base, BUS_DMA_NOWAIT, &fc->tdmap) != 0) { 1598 bus_dma_tag_destroy(fc->tdmat); 1599 goto bad; 1600 } 1601 im.isp = isp; 1602 im.chan = cmap; 1603 im.vbase = base; 1604 im.error = 0; 1605 bus_dmamap_load(fc->tdmat, fc->tdmap, base, ISP_FC_SCRLEN, imc1, &im, 0); 1606 if (im.error) { 1607 bus_dmamem_free(fc->tdmat, base, fc->tdmap); 1608 bus_dma_tag_destroy(fc->tdmat); 1609 goto bad; 1610 } 1611 } 1612 } 1613 |
|
1818 for (i = 0; i < isp->isp_maxcmds; i++) { 1819 struct isp_pcmd *pcmd = &isp->isp_osinfo.pcmd_pool[i]; 1820 error = bus_dmamap_create(isp->isp_osinfo.dmat, 0, &pcmd->dmap); 1821 if (error) { | 1614 for (i = 0; i < isp->isp_maxcmds; i++) { 1615 struct isp_pcmd *pcmd = &isp->isp_osinfo.pcmd_pool[i]; 1616 error = bus_dmamap_create(isp->isp_osinfo.dmat, 0, &pcmd->dmap); 1617 if (error) { |
1822 isp_prt(isp, ISP_LOGERR, 1823 "error %d creating per-cmd DMA maps", error); | 1618 isp_prt(isp, ISP_LOGERR, "error %d creating per-cmd DMA maps", error); |
1824 while (--i >= 0) { | 1619 while (--i >= 0) { |
1825 bus_dmamap_destroy(isp->isp_osinfo.dmat, 1826 isp->isp_osinfo.pcmd_pool[i].dmap); | 1620 bus_dmamap_destroy(isp->isp_osinfo.dmat, isp->isp_osinfo.pcmd_pool[i].dmap); |
1827 } 1828 goto bad; 1829 } | 1621 } 1622 goto bad; 1623 } |
1830 isp_callout_init(&pcmd->wdog); | 1624 callout_init_mtx(&pcmd->wdog, &isp->isp_osinfo.lock, 0); |
1831 if (i == isp->isp_maxcmds-1) { 1832 pcmd->next = NULL; 1833 } else { 1834 pcmd->next = &isp->isp_osinfo.pcmd_pool[i+1]; 1835 } 1836 } 1837 isp->isp_osinfo.pcmd_free = &isp->isp_osinfo.pcmd_pool[0]; | 1625 if (i == isp->isp_maxcmds-1) { 1626 pcmd->next = NULL; 1627 } else { 1628 pcmd->next = &isp->isp_osinfo.pcmd_pool[i+1]; 1629 } 1630 } 1631 isp->isp_osinfo.pcmd_free = &isp->isp_osinfo.pcmd_pool[0]; |
1838 1839 im.isp = isp; 1840 im.error = 0; 1841 bus_dmamap_load(isp->isp_cdmat, isp->isp_cdmap, base, len, imc, &im, 0); 1842 if (im.error) { 1843 isp_prt(isp, ISP_LOGERR, 1844 "error %d loading dma map for control areas", im.error); 1845 goto bad; 1846 } 1847 1848 isp->isp_rquest = base; 1849 base += ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)); 1850 isp->isp_result = base; 1851 if (IS_FC(isp)) { 1852 base += ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp)); 1853 FCPARAM(isp)->isp_scratch = base; 1854 } | |
1855 ISP_LOCK(isp); 1856 return (0); 1857 1858bad: | 1632 ISP_LOCK(isp); 1633 return (0); 1634 1635bad: |
1859 bus_dmamem_free(isp->isp_cdmat, base, isp->isp_cdmap); 1860 bus_dma_tag_destroy(isp->isp_cdmat); | 1636 while (--cmap >= 0) { 1637 struct isp_fc *fc = ISP_FC_PC(isp, cmap); 1638 bus_dmamem_free(fc->tdmat, base, fc->tdmap); 1639 bus_dma_tag_destroy(fc->tdmat); 1640 } 1641 bus_dmamem_free(isp->isp_osinfo.cdmat, base, isp->isp_osinfo.cdmap); 1642 bus_dma_tag_destroy(isp->isp_osinfo.cdmat); |
1861 free(isp->isp_xflist, M_DEVBUF); 1862#ifdef ISP_TARGET_MODE 1863 free(isp->isp_tgtlist, M_DEVBUF); 1864#endif 1865 free(isp->isp_osinfo.pcmd_pool, M_DEVBUF); 1866 isp->isp_rquest = NULL; 1867 ISP_LOCK(isp); 1868 return (1); 1869} 1870 1871typedef struct { 1872 ispsoftc_t *isp; 1873 void *cmd_token; | 1643 free(isp->isp_xflist, M_DEVBUF); 1644#ifdef ISP_TARGET_MODE 1645 free(isp->isp_tgtlist, M_DEVBUF); 1646#endif 1647 free(isp->isp_osinfo.pcmd_pool, M_DEVBUF); 1648 isp->isp_rquest = NULL; 1649 ISP_LOCK(isp); 1650 return (1); 1651} 1652 1653typedef struct { 1654 ispsoftc_t *isp; 1655 void *cmd_token; |
1874 void *rq; 1875 uint32_t *nxtip; 1876 uint32_t optr; | 1656 void *rq; /* original request */ |
1877 int error; | 1657 int error; |
1658 bus_size_t mapsize; |
|
1878} mush_t; 1879 1880#define MUSHERR_NOQENTRIES -2 1881 1882#ifdef ISP_TARGET_MODE | 1659} mush_t; 1660 1661#define MUSHERR_NOQENTRIES -2 1662 1663#ifdef ISP_TARGET_MODE |
1883/* 1884 * We need to handle DMA for target mode differently from initiator mode. 1885 * 1886 * DMA mapping and construction and submission of CTIO Request Entries 1887 * and rendevous for completion are very tightly coupled because we start 1888 * out by knowing (per platform) how much data we have to move, but we 1889 * don't know, up front, how many DMA mapping segments will have to be used 1890 * cover that data, so we don't know how many CTIO Request Entries we 1891 * will end up using. Further, for performance reasons we may want to 1892 * (on the last CTIO for Fibre Channel), send status too (if all went well). 1893 * 1894 * The standard vector still goes through isp_pci_dmasetup, but the callback 1895 * for the DMA mapping routines comes here instead with the whole transfer 1896 * mapped and a pointer to a partially filled in already allocated request 1897 * queue entry. We finish the job. 1898 */ 1899static void tdma_mk(void *, bus_dma_segment_t *, int, int); 1900static void tdma_mkfc(void *, bus_dma_segment_t *, int, int); | 1664static void tdma2_2(void *, bus_dma_segment_t *, int, bus_size_t, int); 1665static void tdma2(void *, bus_dma_segment_t *, int, int); |
1901 | 1666 |
1902#define STATUS_WITH_DATA 1 | 1667static void 1668tdma2_2(void *arg, bus_dma_segment_t *dm_segs, int nseg, bus_size_t mapsize, int error) 1669{ 1670 mush_t *mp; 1671 mp = (mush_t *)arg; 1672 mp->mapsize = mapsize; 1673 tdma2(arg, dm_segs, nseg, error); 1674} |
1903 1904static void | 1675 1676static void |
1905tdma_mk(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) | 1677tdma2(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) |
1906{ 1907 mush_t *mp; | 1678{ 1679 mush_t *mp; |
1908 struct ccb_scsiio *csio; | |
1909 ispsoftc_t *isp; | 1680 ispsoftc_t *isp; |
1910 ct_entry_t *cto, *qe; 1911 uint8_t scsi_status; 1912 uint32_t curi, nxti, handle; 1913 uint32_t sflags; 1914 int32_t resid; 1915 int nth_ctio, nctios, send_status; | 1681 struct ccb_scsiio *csio; 1682 isp_ddir_t ddir; 1683 ispreq_t *rq; |
1916 1917 mp = (mush_t *) arg; 1918 if (error) { 1919 mp->error = error; 1920 return; 1921 } | 1684 1685 mp = (mush_t *) arg; 1686 if (error) { 1687 mp->error = error; 1688 return; 1689 } |
1922 1923 isp = mp->isp; | |
1924 csio = mp->cmd_token; | 1690 csio = mp->cmd_token; |
1925 cto = mp->rq; 1926 curi = isp->isp_reqidx; 1927 qe = (ct_entry_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, curi); 1928 1929 cto->ct_xfrlen = 0; 1930 cto->ct_seg_count = 0; 1931 cto->ct_header.rqs_entry_count = 1; 1932 MEMZERO(cto->ct_dataseg, sizeof(cto->ct_dataseg)); 1933 1934 if (nseg == 0) { 1935 cto->ct_header.rqs_seqno = 1; 1936 isp_prt(isp, ISP_LOGTDEBUG1, 1937 "CTIO[%x] lun%d iid%d tag %x flgs %x sts %x ssts %x res %d", 1938 cto->ct_fwhandle, csio->ccb_h.target_lun, cto->ct_iid, 1939 cto->ct_tag_val, cto->ct_flags, cto->ct_status, 1940 cto->ct_scsi_status, cto->ct_resid); 1941 ISP_TDQE(isp, "tdma_mk[no data]", curi, cto); 1942 isp_put_ctio(isp, cto, qe); 1943 return; 1944 } 1945 1946 nctios = nseg / ISP_RQDSEG; 1947 if (nseg % ISP_RQDSEG) { 1948 nctios++; 1949 } 1950 1951 /* 1952 * Save syshandle, and potentially any SCSI status, which we'll 1953 * reinsert on the last CTIO we're going to send. 1954 */ 1955 1956 handle = cto->ct_syshandle; 1957 cto->ct_syshandle = 0; 1958 cto->ct_header.rqs_seqno = 0; 1959 send_status = (cto->ct_flags & CT_SENDSTATUS) != 0; 1960 1961 if (send_status) { 1962 sflags = cto->ct_flags & (CT_SENDSTATUS | CT_CCINCR); 1963 cto->ct_flags &= ~(CT_SENDSTATUS | CT_CCINCR); 1964 /* 1965 * Preserve residual. 1966 */ 1967 resid = cto->ct_resid; 1968 1969 /* 1970 * Save actual SCSI status. 1971 */ 1972 scsi_status = cto->ct_scsi_status; 1973 1974#ifndef STATUS_WITH_DATA 1975 sflags |= CT_NO_DATA; 1976 /* 1977 * We can't do a status at the same time as a data CTIO, so 1978 * we need to synthesize an extra CTIO at this level. 1979 */ 1980 nctios++; 1981#endif 1982 } else { 1983 sflags = scsi_status = resid = 0; 1984 } 1985 1986 cto->ct_resid = 0; 1987 cto->ct_scsi_status = 0; 1988 1989 if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { 1990 bus_dmamap_sync(isp->isp_osinfo.dmat, 1991 PISP_PCMD(csio)->dmap, BUS_DMASYNC_PREREAD); 1992 } else { 1993 bus_dmamap_sync(isp->isp_osinfo.dmat, 1994 PISP_PCMD(csio)->dmap, BUS_DMASYNC_PREWRITE); 1995 } 1996 1997 nxti = *mp->nxtip; 1998 1999 for (nth_ctio = 0; nth_ctio < nctios; nth_ctio++) { 2000 int seglim; 2001 2002 seglim = nseg; 2003 if (seglim) { 2004 int seg; 2005 2006 if (seglim > ISP_RQDSEG) 2007 seglim = ISP_RQDSEG; 2008 2009 for (seg = 0; seg < seglim; seg++, nseg--) { 2010 /* 2011 * Unlike normal initiator commands, we don't 2012 * do any swizzling here. 2013 */ 2014 cto->ct_dataseg[seg].ds_count = dm_segs->ds_len; 2015 cto->ct_dataseg[seg].ds_base = dm_segs->ds_addr; 2016 cto->ct_xfrlen += dm_segs->ds_len; 2017 dm_segs++; 2018 } 2019 cto->ct_seg_count = seg; 2020 } else { 2021 /* 2022 * This case should only happen when we're sending an 2023 * extra CTIO with final status. 2024 */ 2025 if (send_status == 0) { 2026 isp_prt(isp, ISP_LOGWARN, 2027 "tdma_mk ran out of segments"); 2028 mp->error = EINVAL; | 1691 isp = mp->isp; 1692 rq = mp->rq; 1693 if (nseg) { 1694 if (sizeof (bus_addr_t) > 4) { 1695 if (nseg >= ISP_NSEG64_MAX) { 1696 isp_prt(isp, ISP_LOGERR, "number of segments (%d) exceed maximum we can support (%d)", nseg, ISP_NSEG64_MAX); 1697 mp->error = EFAULT; |
2029 return; 2030 } | 1698 return; 1699 } |
2031 } 2032 2033 /* 2034 * At this point, the fields ct_lun, ct_iid, ct_tagval, 2035 * ct_tagtype, and ct_timeout have been carried over 2036 * unchanged from what our caller had set. 2037 * 2038 * The dataseg fields and the seg_count fields we just got 2039 * through setting. The data direction we've preserved all 2040 * along and only clear it if we're now sending status. 2041 */ 2042 2043 if (nth_ctio == nctios - 1) { 2044 /* 2045 * We're the last in a sequence of CTIOs, so mark 2046 * this CTIO and save the handle to the CCB such that 2047 * when this CTIO completes we can free dma resources 2048 * and do whatever else we need to do to finish the 2049 * rest of the command. We *don't* give this to the 2050 * firmware to work on- the caller will do that. 2051 */ 2052 2053 cto->ct_syshandle = handle; 2054 cto->ct_header.rqs_seqno = 1; 2055 2056 if (send_status) { 2057 cto->ct_scsi_status = scsi_status; 2058 cto->ct_flags |= sflags; 2059 cto->ct_resid = resid; | 1700 if (rq->req_header.rqs_entry_type == RQSTYPE_CTIO2) { 1701 rq->req_header.rqs_entry_type = RQSTYPE_CTIO3; |
2060 } | 1702 } |
2061 if (send_status) { 2062 isp_prt(isp, ISP_LOGTDEBUG1, 2063 "CTIO[%x] lun%d iid %d tag %x ct_flags %x " 2064 "scsi status %x resid %d", 2065 cto->ct_fwhandle, csio->ccb_h.target_lun, 2066 cto->ct_iid, cto->ct_tag_val, cto->ct_flags, 2067 cto->ct_scsi_status, cto->ct_resid); 2068 } else { 2069 isp_prt(isp, ISP_LOGTDEBUG1, 2070 "CTIO[%x] lun%d iid%d tag %x ct_flags 0x%x", 2071 cto->ct_fwhandle, csio->ccb_h.target_lun, 2072 cto->ct_iid, cto->ct_tag_val, 2073 cto->ct_flags); 2074 } 2075 isp_put_ctio(isp, cto, qe); 2076 ISP_TDQE(isp, "last tdma_mk", curi, cto); 2077 if (nctios > 1) { 2078 MEMORYBARRIER(isp, SYNC_REQUEST, 2079 curi, QENTRY_LEN); 2080 } | |
2081 } else { | 1703 } else { |
2082 ct_entry_t *oqe = qe; 2083 2084 /* 2085 * Make sure syshandle fields are clean 2086 */ 2087 cto->ct_syshandle = 0; 2088 cto->ct_header.rqs_seqno = 0; 2089 2090 isp_prt(isp, ISP_LOGTDEBUG1, 2091 "CTIO[%x] lun%d for ID%d ct_flags 0x%x", 2092 cto->ct_fwhandle, csio->ccb_h.target_lun, 2093 cto->ct_iid, cto->ct_flags); 2094 2095 /* 2096 * Get a new CTIO 2097 */ 2098 qe = (ct_entry_t *) 2099 ISP_QUEUE_ENTRY(isp->isp_rquest, nxti); 2100 nxti = ISP_NXT_QENTRY(nxti, RQUEST_QUEUE_LEN(isp)); 2101 if (nxti == mp->optr) { 2102 isp_prt(isp, ISP_LOGTDEBUG0, 2103 "Queue Overflow in tdma_mk"); 2104 mp->error = MUSHERR_NOQENTRIES; | 1704 if (nseg >= ISP_NSEG_MAX) { 1705 isp_prt(isp, ISP_LOGERR, "number of segments (%d) exceed maximum we can support (%d)", nseg, ISP_NSEG_MAX); 1706 mp->error = EFAULT; |
2105 return; 2106 } | 1707 return; 1708 } |
2107 2108 /* 2109 * Now that we're done with the old CTIO, 2110 * flush it out to the request queue. 2111 */ 2112 ISP_TDQE(isp, "dma_tgt_fc", curi, cto); 2113 isp_put_ctio(isp, cto, oqe); 2114 if (nth_ctio != 0) { 2115 MEMORYBARRIER(isp, SYNC_REQUEST, curi, 2116 QENTRY_LEN); 2117 } 2118 curi = ISP_NXT_QENTRY(curi, RQUEST_QUEUE_LEN(isp)); 2119 2120 /* 2121 * Reset some fields in the CTIO so we can reuse 2122 * for the next one we'll flush to the request 2123 * queue. 2124 */ 2125 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO; 2126 cto->ct_header.rqs_entry_count = 1; 2127 cto->ct_header.rqs_flags = 0; 2128 cto->ct_status = 0; 2129 cto->ct_scsi_status = 0; 2130 cto->ct_xfrlen = 0; 2131 cto->ct_resid = 0; 2132 cto->ct_seg_count = 0; 2133 MEMZERO(cto->ct_dataseg, sizeof(cto->ct_dataseg)); | |
2134 } | 1709 } |
2135 } 2136 *mp->nxtip = nxti; 2137} 2138 2139/* 2140 * We don't have to do multiple CTIOs here. Instead, we can just do 2141 * continuation segments as needed. This greatly simplifies the code 2142 * improves performance. 2143 */ 2144 2145static void 2146tdma_mkfc(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) 2147{ 2148 mush_t *mp; 2149 struct ccb_scsiio *csio; 2150 ispsoftc_t *isp; 2151 ct2_entry_t *cto, *qe; 2152 uint32_t curi, nxti; 2153 ispds_t *ds; 2154 ispds64_t *ds64; 2155 int segcnt, seglim; 2156 2157 mp = (mush_t *) arg; 2158 if (error) { 2159 mp->error = error; 2160 return; 2161 } 2162 2163 isp = mp->isp; 2164 csio = mp->cmd_token; 2165 cto = mp->rq; 2166 2167 curi = isp->isp_reqidx; 2168 qe = (ct2_entry_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, curi); 2169 2170 if (nseg == 0) { 2171 if ((cto->ct_flags & CT2_FLAG_MMASK) != CT2_FLAG_MODE1) { 2172 isp_prt(isp, ISP_LOGWARN, 2173 "dma2_tgt_fc, a status CTIO2 without MODE1 " 2174 "set (0x%x)", cto->ct_flags); 2175 mp->error = EINVAL; 2176 return; 2177 } 2178 /* 2179 * We preserve ct_lun, ct_iid, ct_rxid. We set the data 2180 * flags to NO DATA and clear relative offset flags. 2181 * We preserve the ct_resid and the response area. 2182 */ 2183 cto->ct_header.rqs_seqno = 1; 2184 cto->ct_seg_count = 0; 2185 cto->ct_reloff = 0; 2186 isp_prt(isp, ISP_LOGTDEBUG1, 2187 "CTIO2[%x] lun %d->iid%d flgs 0x%x sts 0x%x ssts " 2188 "0x%x res %d", cto->ct_rxid, csio->ccb_h.target_lun, 2189 cto->ct_iid, cto->ct_flags, cto->ct_status, 2190 cto->rsp.m1.ct_scsi_status, cto->ct_resid); 2191 if (FCPARAM(isp)->isp_2klogin) { 2192 isp_put_ctio2e(isp, 2193 (ct2e_entry_t *)cto, (ct2e_entry_t *)qe); | 1710 if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { 1711 bus_dmamap_sync(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap, BUS_DMASYNC_PREWRITE); 1712 ddir = ISP_TO_DEVICE; 1713 } else if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) { 1714 bus_dmamap_sync(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap, BUS_DMASYNC_PREREAD); 1715 ddir = ISP_FROM_DEVICE; |
2194 } else { | 1716 } else { |
2195 isp_put_ctio2(isp, cto, qe); | 1717 ddir = ISP_NOXFR; |
2196 } | 1718 } |
2197 ISP_TDQE(isp, "dma2_tgt_fc[no data]", curi, qe); 2198 return; 2199 } 2200 2201 if ((cto->ct_flags & CT2_FLAG_MMASK) != CT2_FLAG_MODE0) { 2202 isp_prt(isp, ISP_LOGERR, 2203 "dma2_tgt_fc, a data CTIO2 without MODE0 set " 2204 "(0x%x)", cto->ct_flags); 2205 mp->error = EINVAL; 2206 return; 2207 } 2208 2209 2210 nxti = *mp->nxtip; 2211 2212 /* 2213 * Check to see if we need to DAC addressing or not. 2214 * 2215 * Any address that's over the 4GB boundary causes this 2216 * to happen. 2217 */ 2218 segcnt = nseg; 2219 if (sizeof (bus_addr_t) > 4) { 2220 for (segcnt = 0; segcnt < nseg; segcnt++) { 2221 uint64_t addr = dm_segs[segcnt].ds_addr; 2222 if (addr >= 0x100000000LL) { 2223 break; 2224 } 2225 } 2226 } 2227 if (segcnt != nseg) { 2228 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO3; 2229 seglim = ISP_RQDSEG_T3; 2230 ds64 = &cto->rsp.m0.u.ct_dataseg64[0]; 2231 ds = NULL; | |
2232 } else { | 1719 } else { |
2233 seglim = ISP_RQDSEG_T2; 2234 ds64 = NULL; 2235 ds = &cto->rsp.m0.u.ct_dataseg[0]; | 1720 dm_segs = NULL; 1721 nseg = 0; 1722 ddir = ISP_NOXFR; |
2236 } | 1723 } |
2237 cto->ct_seg_count = 0; | |
2238 | 1724 |
2239 /* 2240 * Set up the CTIO2 data segments. 2241 */ 2242 for (segcnt = 0; cto->ct_seg_count < seglim && segcnt < nseg; 2243 cto->ct_seg_count++, segcnt++) { 2244 if (ds64) { 2245 ds64->ds_basehi = 2246 ((uint64_t) (dm_segs[segcnt].ds_addr) >> 32); 2247 ds64->ds_base = dm_segs[segcnt].ds_addr; 2248 ds64->ds_count = dm_segs[segcnt].ds_len; 2249 ds64++; 2250 } else { 2251 ds->ds_base = dm_segs[segcnt].ds_addr; 2252 ds->ds_count = dm_segs[segcnt].ds_len; 2253 ds++; 2254 } 2255 cto->rsp.m0.ct_xfrlen += dm_segs[segcnt].ds_len; 2256#if __FreeBSD_version < 500000 2257 isp_prt(isp, ISP_LOGTDEBUG1, 2258 "isp_send_ctio2: ent0[%d]0x%llx:%llu", 2259 cto->ct_seg_count, (uint64_t)dm_segs[segcnt].ds_addr, 2260 (uint64_t)dm_segs[segcnt].ds_len); 2261#else 2262 isp_prt(isp, ISP_LOGTDEBUG1, 2263 "isp_send_ctio2: ent0[%d]0x%jx:%ju", 2264 cto->ct_seg_count, (uintmax_t)dm_segs[segcnt].ds_addr, 2265 (uintmax_t)dm_segs[segcnt].ds_len); 2266#endif | 1725 if (isp_send_tgt_cmd(isp, rq, dm_segs, nseg, XS_XFRLEN(csio), ddir, &csio->sense_data, csio->sense_len) != CMD_QUEUED) { 1726 mp->error = MUSHERR_NOQENTRIES; |
2267 } | 1727 } |
2268 2269 while (segcnt < nseg) { 2270 uint32_t curip; 2271 int seg; 2272 ispcontreq_t local, *crq = &local, *qep; 2273 2274 qep = (ispcontreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, nxti); 2275 curip = nxti; 2276 nxti = ISP_NXT_QENTRY(curip, RQUEST_QUEUE_LEN(isp)); 2277 if (nxti == mp->optr) { 2278 isp_prt(isp, ISP_LOGTDEBUG0, 2279 "tdma_mkfc: request queue overflow"); 2280 mp->error = MUSHERR_NOQENTRIES; 2281 return; 2282 } 2283 cto->ct_header.rqs_entry_count++; 2284 MEMZERO((void *)crq, sizeof (*crq)); 2285 crq->req_header.rqs_entry_count = 1; 2286 if (cto->ct_header.rqs_entry_type == RQSTYPE_CTIO3) { 2287 seglim = ISP_CDSEG64; 2288 ds = NULL; 2289 ds64 = &((ispcontreq64_t *)crq)->req_dataseg[0]; 2290 crq->req_header.rqs_entry_type = RQSTYPE_A64_CONT; 2291 } else { 2292 seglim = ISP_CDSEG; 2293 ds = &crq->req_dataseg[0]; 2294 ds64 = NULL; 2295 crq->req_header.rqs_entry_type = RQSTYPE_DATASEG; 2296 } 2297 for (seg = 0; segcnt < nseg && seg < seglim; 2298 segcnt++, seg++) { 2299 if (ds64) { 2300 ds64->ds_basehi = 2301 ((uint64_t) (dm_segs[segcnt].ds_addr) >> 32); 2302 ds64->ds_base = dm_segs[segcnt].ds_addr; 2303 ds64->ds_count = dm_segs[segcnt].ds_len; 2304 ds64++; 2305 } else { 2306 ds->ds_base = dm_segs[segcnt].ds_addr; 2307 ds->ds_count = dm_segs[segcnt].ds_len; 2308 ds++; 2309 } 2310#if __FreeBSD_version < 500000 2311 isp_prt(isp, ISP_LOGTDEBUG1, 2312 "isp_send_ctio2: ent%d[%d]%llx:%llu", 2313 cto->ct_header.rqs_entry_count-1, seg, 2314 (uint64_t)dm_segs[segcnt].ds_addr, 2315 (uint64_t)dm_segs[segcnt].ds_len); 2316#else 2317 isp_prt(isp, ISP_LOGTDEBUG1, 2318 "isp_send_ctio2: ent%d[%d]%jx:%ju", 2319 cto->ct_header.rqs_entry_count-1, seg, 2320 (uintmax_t)dm_segs[segcnt].ds_addr, 2321 (uintmax_t)dm_segs[segcnt].ds_len); 2322#endif 2323 cto->rsp.m0.ct_xfrlen += dm_segs[segcnt].ds_len; 2324 cto->ct_seg_count++; 2325 } 2326 MEMORYBARRIER(isp, SYNC_REQUEST, curip, QENTRY_LEN); 2327 isp_put_cont_req(isp, crq, qep); 2328 ISP_TDQE(isp, "cont entry", curi, qep); 2329 } 2330 2331 /* 2332 * No do final twiddling for the CTIO itself. 2333 */ 2334 cto->ct_header.rqs_seqno = 1; 2335 isp_prt(isp, ISP_LOGTDEBUG1, 2336 "CTIO2[%x] lun %d->iid%d flgs 0x%x sts 0x%x ssts 0x%x resid %d", 2337 cto->ct_rxid, csio->ccb_h.target_lun, (int) cto->ct_iid, 2338 cto->ct_flags, cto->ct_status, cto->rsp.m1.ct_scsi_status, 2339 cto->ct_resid); 2340 if (FCPARAM(isp)->isp_2klogin) { 2341 isp_put_ctio2e(isp, (ct2e_entry_t *)cto, (ct2e_entry_t *)qe); 2342 } else { 2343 isp_put_ctio2(isp, cto, qe); 2344 } 2345 ISP_TDQE(isp, "last dma2_tgt_fc", curi, qe); 2346 *mp->nxtip = nxti; | |
2347} 2348#endif 2349 | 1728} 1729#endif 1730 |
2350static void dma_2400(void *, bus_dma_segment_t *, int, int); 2351static void dma2_a64(void *, bus_dma_segment_t *, int, int); | 1731static void dma2_2(void *, bus_dma_segment_t *, int, bus_size_t, int); |
2352static void dma2(void *, bus_dma_segment_t *, int, int); 2353 2354static void | 1732static void dma2(void *, bus_dma_segment_t *, int, int); 1733 1734static void |
2355dma_2400(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) | 1735dma2_2(void *arg, bus_dma_segment_t *dm_segs, int nseg, bus_size_t mapsize, int error) |
2356{ 2357 mush_t *mp; | 1736{ 1737 mush_t *mp; |
2358 ispsoftc_t *isp; 2359 struct ccb_scsiio *csio; 2360 bus_dma_segment_t *eseg; 2361 ispreqt7_t *rq; 2362 int seglim, datalen; 2363 uint32_t nxti; 2364 2365 mp = (mush_t *) arg; 2366 if (error) { 2367 mp->error = error; 2368 return; 2369 } 2370 2371 if (nseg < 1) { 2372 isp_prt(mp->isp, ISP_LOGERR, "bad segment count (%d)", nseg); 2373 mp->error = EFAULT; 2374 return; 2375 } 2376 2377 csio = mp->cmd_token; 2378 isp = mp->isp; 2379 rq = mp->rq; 2380 nxti = *mp->nxtip; 2381 2382 if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { 2383 bus_dmamap_sync(isp->isp_osinfo.dmat, 2384 PISP_PCMD(csio)->dmap, BUS_DMASYNC_PREREAD); 2385 } else { 2386 bus_dmamap_sync(isp->isp_osinfo.dmat, 2387 PISP_PCMD(csio)->dmap, BUS_DMASYNC_PREWRITE); 2388 } 2389 datalen = XS_XFRLEN(csio); 2390 2391 /* 2392 * We're passed an initial partially filled in entry that 2393 * has most fields filled in except for data transfer 2394 * related values. 2395 * 2396 * Our job is to fill in the initial request queue entry and 2397 * then to start allocating and filling in continuation entries 2398 * until we've covered the entire transfer. 2399 */ 2400 2401 rq->req_header.rqs_entry_type = RQSTYPE_T7RQS; 2402 rq->req_dl = datalen; 2403 if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { 2404 rq->req_alen_datadir = 0x2; 2405 } else { 2406 rq->req_alen_datadir = 0x1; 2407 } 2408 2409 eseg = dm_segs + nseg; 2410 2411 rq->req_dataseg.ds_base = DMA_LO32(dm_segs->ds_addr); 2412 rq->req_dataseg.ds_basehi = DMA_HI32(dm_segs->ds_addr); 2413 rq->req_dataseg.ds_count = dm_segs->ds_len; 2414 2415 datalen -= dm_segs->ds_len; 2416 2417 dm_segs++; 2418 rq->req_seg_count++; 2419 2420 while (datalen > 0 && dm_segs != eseg) { 2421 uint32_t onxti; 2422 ispcontreq64_t local, *crq = &local, *cqe; 2423 2424 cqe = (ispcontreq64_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, nxti); 2425 onxti = nxti; 2426 nxti = ISP_NXT_QENTRY(onxti, RQUEST_QUEUE_LEN(isp)); 2427 if (nxti == mp->optr) { 2428 isp_prt(isp, ISP_LOGDEBUG0, "Request Queue Overflow++"); 2429 mp->error = MUSHERR_NOQENTRIES; 2430 return; 2431 } 2432 rq->req_header.rqs_entry_count++; 2433 MEMZERO((void *)crq, sizeof (*crq)); 2434 crq->req_header.rqs_entry_count = 1; 2435 crq->req_header.rqs_entry_type = RQSTYPE_A64_CONT; 2436 2437 seglim = 0; 2438 while (datalen > 0 && seglim < ISP_CDSEG64 && dm_segs != eseg) { 2439 crq->req_dataseg[seglim].ds_base = 2440 DMA_LO32(dm_segs->ds_addr); 2441 crq->req_dataseg[seglim].ds_basehi = 2442 DMA_HI32(dm_segs->ds_addr); 2443 crq->req_dataseg[seglim].ds_count = 2444 dm_segs->ds_len; 2445 rq->req_seg_count++; 2446 dm_segs++; 2447 seglim++; 2448 datalen -= dm_segs->ds_len; 2449 } 2450 if (isp->isp_dblev & ISP_LOGDEBUG1) { 2451 isp_print_bytes(isp, "Continuation", QENTRY_LEN, crq); 2452 } 2453 isp_put_cont64_req(isp, crq, cqe); 2454 MEMORYBARRIER(isp, SYNC_REQUEST, onxti, QENTRY_LEN); 2455 } 2456 *mp->nxtip = nxti; | 1738 mp = (mush_t *)arg; 1739 mp->mapsize = mapsize; 1740 dma2(arg, dm_segs, nseg, error); |
2457} 2458 2459static void | 1741} 1742 1743static void |
2460dma2_a64(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) 2461{ 2462 mush_t *mp; 2463 ispsoftc_t *isp; 2464 struct ccb_scsiio *csio; 2465 bus_dma_segment_t *eseg; 2466 ispreq64_t *rq; 2467 int seglim, datalen; 2468 uint32_t nxti; 2469 2470 mp = (mush_t *) arg; 2471 if (error) { 2472 mp->error = error; 2473 return; 2474 } 2475 2476 if (nseg < 1) { 2477 isp_prt(mp->isp, ISP_LOGERR, "bad segment count (%d)", nseg); 2478 mp->error = EFAULT; 2479 return; 2480 } 2481 csio = mp->cmd_token; 2482 isp = mp->isp; 2483 rq = mp->rq; 2484 nxti = *mp->nxtip; 2485 2486 if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { 2487 bus_dmamap_sync(isp->isp_osinfo.dmat, 2488 PISP_PCMD(csio)->dmap, BUS_DMASYNC_PREREAD); 2489 } else { 2490 bus_dmamap_sync(isp->isp_osinfo.dmat, 2491 PISP_PCMD(csio)->dmap, BUS_DMASYNC_PREWRITE); 2492 } 2493 datalen = XS_XFRLEN(csio); 2494 2495 /* 2496 * We're passed an initial partially filled in entry that 2497 * has most fields filled in except for data transfer 2498 * related values. 2499 * 2500 * Our job is to fill in the initial request queue entry and 2501 * then to start allocating and filling in continuation entries 2502 * until we've covered the entire transfer. 2503 */ 2504 2505 if (IS_FC(isp)) { 2506 rq->req_header.rqs_entry_type = RQSTYPE_T3RQS; 2507 seglim = ISP_RQDSEG_T3; 2508 ((ispreqt3_t *)rq)->req_totalcnt = datalen; 2509 if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { 2510 ((ispreqt3_t *)rq)->req_flags |= REQFLAG_DATA_IN; 2511 } else { 2512 ((ispreqt3_t *)rq)->req_flags |= REQFLAG_DATA_OUT; 2513 } 2514 } else { 2515 rq->req_header.rqs_entry_type = RQSTYPE_A64; 2516 if (csio->cdb_len > 12) { 2517 seglim = 0; 2518 } else { 2519 seglim = ISP_RQDSEG_A64; 2520 } 2521 if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { 2522 rq->req_flags |= REQFLAG_DATA_IN; 2523 } else { 2524 rq->req_flags |= REQFLAG_DATA_OUT; 2525 } 2526 } 2527 2528 eseg = dm_segs + nseg; 2529 2530 while (datalen != 0 && rq->req_seg_count < seglim && dm_segs != eseg) { 2531 if (IS_FC(isp)) { 2532 ispreqt3_t *rq3 = (ispreqt3_t *)rq; 2533 rq3->req_dataseg[rq3->req_seg_count].ds_base = 2534 DMA_LO32(dm_segs->ds_addr); 2535 rq3->req_dataseg[rq3->req_seg_count].ds_basehi = 2536 DMA_HI32(dm_segs->ds_addr); 2537 rq3->req_dataseg[rq3->req_seg_count].ds_count = 2538 dm_segs->ds_len; 2539 } else { 2540 rq->req_dataseg[rq->req_seg_count].ds_base = 2541 DMA_LO32(dm_segs->ds_addr); 2542 rq->req_dataseg[rq->req_seg_count].ds_basehi = 2543 DMA_HI32(dm_segs->ds_addr); 2544 rq->req_dataseg[rq->req_seg_count].ds_count = 2545 dm_segs->ds_len; 2546 } 2547 datalen -= dm_segs->ds_len; 2548 rq->req_seg_count++; 2549 dm_segs++; 2550 } 2551 2552 while (datalen > 0 && dm_segs != eseg) { 2553 uint32_t onxti; 2554 ispcontreq64_t local, *crq = &local, *cqe; 2555 2556 cqe = (ispcontreq64_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, nxti); 2557 onxti = nxti; 2558 nxti = ISP_NXT_QENTRY(onxti, RQUEST_QUEUE_LEN(isp)); 2559 if (nxti == mp->optr) { 2560 isp_prt(isp, ISP_LOGDEBUG0, "Request Queue Overflow++"); 2561 mp->error = MUSHERR_NOQENTRIES; 2562 return; 2563 } 2564 rq->req_header.rqs_entry_count++; 2565 MEMZERO((void *)crq, sizeof (*crq)); 2566 crq->req_header.rqs_entry_count = 1; 2567 crq->req_header.rqs_entry_type = RQSTYPE_A64_CONT; 2568 2569 seglim = 0; 2570 while (datalen > 0 && seglim < ISP_CDSEG64 && dm_segs != eseg) { 2571 crq->req_dataseg[seglim].ds_base = 2572 DMA_LO32(dm_segs->ds_addr); 2573 crq->req_dataseg[seglim].ds_basehi = 2574 DMA_HI32(dm_segs->ds_addr); 2575 crq->req_dataseg[seglim].ds_count = 2576 dm_segs->ds_len; 2577 rq->req_seg_count++; 2578 dm_segs++; 2579 seglim++; 2580 datalen -= dm_segs->ds_len; 2581 } 2582 if (isp->isp_dblev & ISP_LOGDEBUG1) { 2583 isp_print_bytes(isp, "Continuation", QENTRY_LEN, crq); 2584 } 2585 isp_put_cont64_req(isp, crq, cqe); 2586 MEMORYBARRIER(isp, SYNC_REQUEST, onxti, QENTRY_LEN); 2587 } 2588 *mp->nxtip = nxti; 2589} 2590 2591static void | |
2592dma2(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) 2593{ 2594 mush_t *mp; 2595 ispsoftc_t *isp; 2596 struct ccb_scsiio *csio; | 1744dma2(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) 1745{ 1746 mush_t *mp; 1747 ispsoftc_t *isp; 1748 struct ccb_scsiio *csio; |
2597 bus_dma_segment_t *eseg; | 1749 isp_ddir_t ddir; |
2598 ispreq_t *rq; | 1750 ispreq_t *rq; |
2599 int seglim, datalen; 2600 uint32_t nxti; | |
2601 2602 mp = (mush_t *) arg; 2603 if (error) { 2604 mp->error = error; 2605 return; 2606 } | 1751 1752 mp = (mush_t *) arg; 1753 if (error) { 1754 mp->error = error; 1755 return; 1756 } |
2607 2608 if (nseg < 1) { 2609 isp_prt(mp->isp, ISP_LOGERR, "bad segment count (%d)", nseg); 2610 mp->error = EFAULT; 2611 return; 2612 } | |
2613 csio = mp->cmd_token; 2614 isp = mp->isp; 2615 rq = mp->rq; | 1757 csio = mp->cmd_token; 1758 isp = mp->isp; 1759 rq = mp->rq; |
2616 nxti = *mp->nxtip; 2617 2618 if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { 2619 bus_dmamap_sync(isp->isp_osinfo.dmat, 2620 PISP_PCMD(csio)->dmap, BUS_DMASYNC_PREREAD); 2621 } else { 2622 bus_dmamap_sync(isp->isp_osinfo.dmat, 2623 PISP_PCMD(csio)->dmap, BUS_DMASYNC_PREWRITE); 2624 } 2625 2626 datalen = XS_XFRLEN(csio); 2627 2628 /* 2629 * We're passed an initial partially filled in entry that 2630 * has most fields filled in except for data transfer 2631 * related values. 2632 * 2633 * Our job is to fill in the initial request queue entry and 2634 * then to start allocating and filling in continuation entries 2635 * until we've covered the entire transfer. 2636 */ 2637 2638 if (IS_FC(isp)) { 2639 seglim = ISP_RQDSEG_T2; 2640 ((ispreqt2_t *)rq)->req_totalcnt = datalen; 2641 if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { 2642 ((ispreqt2_t *)rq)->req_flags |= REQFLAG_DATA_IN; | 1760 if (nseg) { 1761 if (sizeof (bus_addr_t) > 4) { 1762 if (nseg >= ISP_NSEG64_MAX) { 1763 isp_prt(isp, ISP_LOGERR, "number of segments (%d) exceed maximum we can support (%d)", nseg, ISP_NSEG64_MAX); 1764 mp->error = EFAULT; 1765 return; 1766 } 1767 if (rq->req_header.rqs_entry_type == RQSTYPE_T2RQS) { 1768 rq->req_header.rqs_entry_type = RQSTYPE_T3RQS; 1769 } else if (rq->req_header.rqs_entry_type == RQSTYPE_REQUEST) { 1770 rq->req_header.rqs_entry_type = RQSTYPE_A64; 1771 } |
2643 } else { | 1772 } else { |
2644 ((ispreqt2_t *)rq)->req_flags |= REQFLAG_DATA_OUT; | 1773 if (nseg >= ISP_NSEG_MAX) { 1774 isp_prt(isp, ISP_LOGERR, "number of segments (%d) exceed maximum we can support (%d)", nseg, ISP_NSEG_MAX); 1775 mp->error = EFAULT; 1776 return; 1777 } |
2645 } | 1778 } |
2646 } else { 2647 if (csio->cdb_len > 12) { 2648 seglim = 0; 2649 } else { 2650 seglim = ISP_RQDSEG; 2651 } | |
2652 if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { | 1779 if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { |
2653 rq->req_flags |= REQFLAG_DATA_IN; | 1780 bus_dmamap_sync(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap, BUS_DMASYNC_PREREAD); 1781 ddir = ISP_FROM_DEVICE; 1782 } else if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) { 1783 bus_dmamap_sync(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap, BUS_DMASYNC_PREWRITE); 1784 ddir = ISP_TO_DEVICE; |
2654 } else { | 1785 } else { |
2655 rq->req_flags |= REQFLAG_DATA_OUT; | 1786 ddir = ISP_NOXFR; |
2656 } | 1787 } |
1788 } else { 1789 dm_segs = NULL; 1790 nseg = 0; 1791 ddir = ISP_NOXFR; |
|
2657 } 2658 | 1792 } 1793 |
2659 eseg = dm_segs + nseg; 2660 2661 while (datalen != 0 && rq->req_seg_count < seglim && dm_segs != eseg) { 2662 if (IS_FC(isp)) { 2663 ispreqt2_t *rq2 = (ispreqt2_t *)rq; 2664 rq2->req_dataseg[rq2->req_seg_count].ds_base = 2665 DMA_LO32(dm_segs->ds_addr); 2666 rq2->req_dataseg[rq2->req_seg_count].ds_count = 2667 dm_segs->ds_len; 2668 } else { 2669 rq->req_dataseg[rq->req_seg_count].ds_base = 2670 DMA_LO32(dm_segs->ds_addr); 2671 rq->req_dataseg[rq->req_seg_count].ds_count = 2672 dm_segs->ds_len; 2673 } 2674 datalen -= dm_segs->ds_len; 2675 rq->req_seg_count++; 2676 dm_segs++; | 1794 if (isp_send_cmd(isp, rq, dm_segs, nseg, XS_XFRLEN(csio), ddir) != CMD_QUEUED) { 1795 mp->error = MUSHERR_NOQENTRIES; |
2677 } | 1796 } |
2678 2679 while (datalen > 0 && dm_segs != eseg) { 2680 uint32_t onxti; 2681 ispcontreq_t local, *crq = &local, *cqe; 2682 2683 cqe = (ispcontreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, nxti); 2684 onxti = nxti; 2685 nxti = ISP_NXT_QENTRY(onxti, RQUEST_QUEUE_LEN(isp)); 2686 if (nxti == mp->optr) { 2687 isp_prt(isp, ISP_LOGDEBUG0, "Request Queue Overflow++"); 2688 mp->error = MUSHERR_NOQENTRIES; 2689 return; 2690 } 2691 rq->req_header.rqs_entry_count++; 2692 MEMZERO((void *)crq, sizeof (*crq)); 2693 crq->req_header.rqs_entry_count = 1; 2694 crq->req_header.rqs_entry_type = RQSTYPE_DATASEG; 2695 2696 seglim = 0; 2697 while (datalen > 0 && seglim < ISP_CDSEG && dm_segs != eseg) { 2698 crq->req_dataseg[seglim].ds_base = 2699 DMA_LO32(dm_segs->ds_addr); 2700 crq->req_dataseg[seglim].ds_count = 2701 dm_segs->ds_len; 2702 rq->req_seg_count++; 2703 dm_segs++; 2704 seglim++; 2705 datalen -= dm_segs->ds_len; 2706 } 2707 if (isp->isp_dblev & ISP_LOGDEBUG1) { 2708 isp_print_bytes(isp, "Continuation", QENTRY_LEN, crq); 2709 } 2710 isp_put_cont_req(isp, crq, cqe); 2711 MEMORYBARRIER(isp, SYNC_REQUEST, onxti, QENTRY_LEN); 2712 } 2713 *mp->nxtip = nxti; | |
2714} 2715 | 1797} 1798 |
2716/* 2717 */ | |
2718static int | 1799static int |
2719isp_pci_dmasetup(ispsoftc_t *isp, struct ccb_scsiio *csio, ispreq_t *rq, 2720 uint32_t *nxtip, uint32_t optr) | 1800isp_pci_dmasetup(ispsoftc_t *isp, struct ccb_scsiio *csio, void *ff) |
2721{ | 1801{ |
2722 ispreq_t *qep; | |
2723 mush_t mush, *mp; 2724 void (*eptr)(void *, bus_dma_segment_t *, int, int); | 1802 mush_t mush, *mp; 1803 void (*eptr)(void *, bus_dma_segment_t *, int, int); |
1804 void (*eptr2)(void *, bus_dma_segment_t *, int, bus_size_t, int); |
|
2725 | 1805 |
2726 qep = (ispreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, isp->isp_reqidx); | 1806 mp = &mush; 1807 mp->isp = isp; 1808 mp->cmd_token = csio; 1809 mp->rq = ff; 1810 mp->error = 0; 1811 mp->mapsize = 0; 1812 |
2727#ifdef ISP_TARGET_MODE 2728 if (csio->ccb_h.func_code == XPT_CONT_TARGET_IO) { | 1813#ifdef ISP_TARGET_MODE 1814 if (csio->ccb_h.func_code == XPT_CONT_TARGET_IO) { |
2729 if (IS_FC(isp)) { 2730 eptr = tdma_mkfc; 2731 } else { 2732 eptr = tdma_mk; 2733 } 2734 if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_NONE || 2735 (csio->dxfer_len == 0)) { 2736 mp = &mush; 2737 mp->isp = isp; 2738 mp->cmd_token = csio; 2739 mp->rq = rq; /* really a ct_entry_t or ct2_entry_t */ 2740 mp->nxtip = nxtip; 2741 mp->optr = optr; 2742 mp->error = 0; 2743 (*eptr)(mp, NULL, 0, 0); 2744 goto mbxsync; 2745 } | 1815 eptr = tdma2; 1816 eptr2 = tdma2_2; |
2746 } else 2747#endif | 1817 } else 1818#endif |
2748 if (IS_24XX(isp)) { 2749 eptr = dma_2400; 2750 } else if (sizeof (bus_addr_t) > 4) { 2751 eptr = dma2_a64; 2752 } else { | 1819 { |
2753 eptr = dma2; | 1820 eptr = dma2; |
1821 eptr2 = dma2_2; |
|
2754 } 2755 2756 | 1822 } 1823 1824 |
2757 if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_NONE || 2758 (csio->dxfer_len == 0)) { 2759 rq->req_seg_count = 1; 2760 goto mbxsync; 2761 } 2762 2763 /* 2764 * Do a virtual grapevine step to collect info for 2765 * the callback dma allocation that we have to use... 2766 */ 2767 mp = &mush; 2768 mp->isp = isp; 2769 mp->cmd_token = csio; 2770 mp->rq = rq; 2771 mp->nxtip = nxtip; 2772 mp->optr = optr; 2773 mp->error = 0; 2774 2775 if ((csio->ccb_h.flags & CAM_SCATTER_VALID) == 0) { | 1825 if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_NONE || (csio->dxfer_len == 0)) { 1826 (*eptr)(mp, NULL, 0, 0); 1827 } else if ((csio->ccb_h.flags & CAM_SCATTER_VALID) == 0) { |
2776 if ((csio->ccb_h.flags & CAM_DATA_PHYS) == 0) { 2777 int error; | 1828 if ((csio->ccb_h.flags & CAM_DATA_PHYS) == 0) { 1829 int error; |
2778#if __FreeBSD_version < 500000 2779 int s = splsoftvm(); | 1830 error = bus_dmamap_load(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap, csio->data_ptr, csio->dxfer_len, eptr, mp, 0); 1831#if 0 1832 xpt_print(csio->ccb_h.path, "%s: bus_dmamap_load " "ptr %p len %d returned %d\n", __func__, csio->data_ptr, csio->dxfer_len, error); |
2780#endif | 1833#endif |
2781 error = bus_dmamap_load(isp->isp_osinfo.dmat, 2782 PISP_PCMD(csio)->dmap, csio->data_ptr, 2783 csio->dxfer_len, eptr, mp, 0); 2784#if __FreeBSD_version < 500000 2785 splx(s); 2786#endif | 1834 |
2787 if (error == EINPROGRESS) { | 1835 if (error == EINPROGRESS) { |
2788 bus_dmamap_unload(isp->isp_osinfo.dmat, 2789 PISP_PCMD(csio)->dmap); | 1836 bus_dmamap_unload(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap); |
2790 mp->error = EINVAL; | 1837 mp->error = EINVAL; |
2791 isp_prt(isp, ISP_LOGERR, 2792 "deferred dma allocation not supported"); | 1838 isp_prt(isp, ISP_LOGERR, "deferred dma allocation not supported"); |
2793 } else if (error && mp->error == 0) { 2794#ifdef DIAGNOSTIC | 1839 } else if (error && mp->error == 0) { 1840#ifdef DIAGNOSTIC |
2795 isp_prt(isp, ISP_LOGERR, 2796 "error %d in dma mapping code", error); | 1841 isp_prt(isp, ISP_LOGERR, "error %d in dma mapping code", error); |
2797#endif 2798 mp->error = error; 2799 } 2800 } else { 2801 /* Pointer to physical buffer */ 2802 struct bus_dma_segment seg; 2803 seg.ds_addr = (bus_addr_t)(vm_offset_t)csio->data_ptr; 2804 seg.ds_len = csio->dxfer_len; 2805 (*eptr)(mp, &seg, 1, 0); 2806 } 2807 } else { 2808 struct bus_dma_segment *segs; 2809 2810 if ((csio->ccb_h.flags & CAM_DATA_PHYS) != 0) { | 1842#endif 1843 mp->error = error; 1844 } 1845 } else { 1846 /* Pointer to physical buffer */ 1847 struct bus_dma_segment seg; 1848 seg.ds_addr = (bus_addr_t)(vm_offset_t)csio->data_ptr; 1849 seg.ds_len = csio->dxfer_len; 1850 (*eptr)(mp, &seg, 1, 0); 1851 } 1852 } else { 1853 struct bus_dma_segment *segs; 1854 1855 if ((csio->ccb_h.flags & CAM_DATA_PHYS) != 0) { |
2811 isp_prt(isp, ISP_LOGERR, 2812 "Physical segment pointers unsupported"); | 1856 isp_prt(isp, ISP_LOGERR, "Physical segment pointers unsupported"); |
2813 mp->error = EINVAL; 2814 } else if ((csio->ccb_h.flags & CAM_SG_LIST_PHYS) == 0) { | 1857 mp->error = EINVAL; 1858 } else if ((csio->ccb_h.flags & CAM_SG_LIST_PHYS) == 0) { |
2815 isp_prt(isp, ISP_LOGERR, 2816 "Virtual segment addresses unsupported"); 2817 mp->error = EINVAL; | 1859 struct uio sguio; 1860 int error; 1861 1862 /* 1863 * We're taking advantage of the fact that 1864 * the pointer/length sizes and layout of the iovec 1865 * structure are the same as the bus_dma_segment 1866 * structure. This might be a little dangerous, 1867 * but only if they change the structures, which 1868 * seems unlikely. 1869 */ 1870 KASSERT((sizeof (sguio.uio_iov) == sizeof (csio->data_ptr) && 1871 sizeof (sguio.uio_iovcnt) >= sizeof (csio->sglist_cnt) && 1872 sizeof (sguio.uio_resid) >= sizeof (csio->dxfer_len)), ("Ken's assumption failed")); 1873 sguio.uio_iov = (struct iovec *)csio->data_ptr; 1874 sguio.uio_iovcnt = csio->sglist_cnt; 1875 sguio.uio_resid = csio->dxfer_len; 1876 sguio.uio_segflg = UIO_SYSSPACE; 1877 1878 error = bus_dmamap_load_uio(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap, &sguio, eptr2, mp, 0); 1879 1880 if (error != 0 && mp->error == 0) { 1881 isp_prt(isp, ISP_LOGERR, "error %d in dma mapping code", error); 1882 mp->error = error; 1883 } |
2818 } else { 2819 /* Just use the segments provided */ 2820 segs = (struct bus_dma_segment *) csio->data_ptr; 2821 (*eptr)(mp, segs, csio->sglist_cnt, 0); 2822 } 2823 } 2824 if (mp->error) { 2825 int retval = CMD_COMPLETE; 2826 if (mp->error == MUSHERR_NOQENTRIES) { 2827 retval = CMD_EAGAIN; 2828 } else if (mp->error == EFBIG) { 2829 XS_SETERR(csio, CAM_REQ_TOO_BIG); 2830 } else if (mp->error == EINVAL) { 2831 XS_SETERR(csio, CAM_REQ_INVALID); 2832 } else { 2833 XS_SETERR(csio, CAM_UNREC_HBA_ERROR); 2834 } 2835 return (retval); 2836 } | 1884 } else { 1885 /* Just use the segments provided */ 1886 segs = (struct bus_dma_segment *) csio->data_ptr; 1887 (*eptr)(mp, segs, csio->sglist_cnt, 0); 1888 } 1889 } 1890 if (mp->error) { 1891 int retval = CMD_COMPLETE; 1892 if (mp->error == MUSHERR_NOQENTRIES) { 1893 retval = CMD_EAGAIN; 1894 } else if (mp->error == EFBIG) { 1895 XS_SETERR(csio, CAM_REQ_TOO_BIG); 1896 } else if (mp->error == EINVAL) { 1897 XS_SETERR(csio, CAM_REQ_INVALID); 1898 } else { 1899 XS_SETERR(csio, CAM_UNREC_HBA_ERROR); 1900 } 1901 return (retval); 1902 } |
2837mbxsync: 2838 if (isp->isp_dblev & ISP_LOGDEBUG1) { 2839 isp_print_bytes(isp, "Request Queue Entry", QENTRY_LEN, rq); 2840 } 2841 switch (rq->req_header.rqs_entry_type) { 2842 case RQSTYPE_REQUEST: 2843 isp_put_request(isp, rq, qep); 2844 break; 2845 case RQSTYPE_CMDONLY: 2846 isp_put_extended_request(isp, (ispextreq_t *)rq, 2847 (ispextreq_t *)qep); 2848 break; 2849 case RQSTYPE_T2RQS: 2850 if (FCPARAM(isp)->isp_2klogin) { 2851 isp_put_request_t2e(isp, 2852 (ispreqt2e_t *) rq, (ispreqt2e_t *) qep); 2853 } else { 2854 isp_put_request_t2(isp, 2855 (ispreqt2_t *) rq, (ispreqt2_t *) qep); 2856 } 2857 break; 2858 case RQSTYPE_T3RQS: 2859 if (FCPARAM(isp)->isp_2klogin) { 2860 isp_put_request_t3e(isp, 2861 (ispreqt3e_t *) rq, (ispreqt3e_t *) qep); 2862 break; 2863 } 2864 /* FALLTHROUGH */ 2865 case RQSTYPE_A64: 2866 isp_put_request_t3(isp, (ispreqt3_t *) rq, (ispreqt3_t *) qep); 2867 break; 2868 case RQSTYPE_T7RQS: 2869 isp_put_request_t7(isp, (ispreqt7_t *) rq, (ispreqt7_t *) qep); 2870 break; 2871 } | |
2872 return (CMD_QUEUED); 2873} 2874 2875static void 2876isp_pci_reset0(ispsoftc_t *isp) 2877{ 2878 ISP_DISABLE_INTS(isp); 2879} --- 50 unchanged lines hidden --- | 1903 return (CMD_QUEUED); 1904} 1905 1906static void 1907isp_pci_reset0(ispsoftc_t *isp) 1908{ 1909 ISP_DISABLE_INTS(isp); 1910} --- 50 unchanged lines hidden --- |