ciss.c (179705) | ciss.c (180454) |
---|---|
1/*- 2 * Copyright (c) 2001 Michael Smith 3 * Copyright (c) 2004 Paul Saab 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 10 unchanged lines hidden (view full) --- 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * | 1/*- 2 * Copyright (c) 2001 Michael Smith 3 * Copyright (c) 2004 Paul Saab 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 10 unchanged lines hidden (view full) --- 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * |
27 * $FreeBSD: head/sys/dev/ciss/ciss.c 179705 2008-06-10 17:51:51Z ps $ | 27 * $FreeBSD: head/sys/dev/ciss/ciss.c 180454 2008-07-11 21:20:51Z scottl $ |
28 */ 29 30/* 31 * Common Interface for SCSI-3 Support driver. 32 * 33 * CISS claims to provide a common interface between a generic SCSI 34 * transport and an intelligent host adapter. 35 * --- 61 unchanged lines hidden (view full) --- 97#include <machine/endian.h> 98#include <machine/resource.h> 99#include <sys/rman.h> 100 101#include <dev/pci/pcireg.h> 102#include <dev/pci/pcivar.h> 103 104#include <dev/ciss/cissreg.h> | 28 */ 29 30/* 31 * Common Interface for SCSI-3 Support driver. 32 * 33 * CISS claims to provide a common interface between a generic SCSI 34 * transport and an intelligent host adapter. 35 * --- 61 unchanged lines hidden (view full) --- 97#include <machine/endian.h> 98#include <machine/resource.h> 99#include <sys/rman.h> 100 101#include <dev/pci/pcireg.h> 102#include <dev/pci/pcivar.h> 103 104#include <dev/ciss/cissreg.h> |
105#include <dev/ciss/cissvar.h> | |
106#include <dev/ciss/cissio.h> | 105#include <dev/ciss/cissio.h> |
106#include <dev/ciss/cissvar.h> |
|
107 108MALLOC_DEFINE(CISS_MALLOC_CLASS, "ciss_data", "ciss internal data buffers"); 109 110/* pci interface */ 111static int ciss_lookup(device_t dev); 112static int ciss_probe(device_t dev); 113static int ciss_attach(device_t dev); 114static int ciss_detach(device_t dev); 115static int ciss_shutdown(device_t dev); 116 117/* (de)initialisation functions, control wrappers */ 118static int ciss_init_pci(struct ciss_softc *sc); | 107 108MALLOC_DEFINE(CISS_MALLOC_CLASS, "ciss_data", "ciss internal data buffers"); 109 110/* pci interface */ 111static int ciss_lookup(device_t dev); 112static int ciss_probe(device_t dev); 113static int ciss_attach(device_t dev); 114static int ciss_detach(device_t dev); 115static int ciss_shutdown(device_t dev); 116 117/* (de)initialisation functions, control wrappers */ 118static int ciss_init_pci(struct ciss_softc *sc); |
119static int ciss_setup_msix(struct ciss_softc *sc); 120static int ciss_init_perf(struct ciss_softc *sc); |
|
119static int ciss_wait_adapter(struct ciss_softc *sc); 120static int ciss_flush_adapter(struct ciss_softc *sc); 121static int ciss_init_requests(struct ciss_softc *sc); 122static void ciss_command_map_helper(void *arg, bus_dma_segment_t *segs, 123 int nseg, int error); 124static int ciss_identify_adapter(struct ciss_softc *sc); 125static int ciss_init_logical(struct ciss_softc *sc); 126static int ciss_init_physical(struct ciss_softc *sc); --- 5 unchanged lines hidden (view full) --- 132static void ciss_init_sysctl(struct ciss_softc *sc); 133static void ciss_soft_reset(struct ciss_softc *sc); 134static void ciss_free(struct ciss_softc *sc); 135static void ciss_spawn_notify_thread(struct ciss_softc *sc); 136static void ciss_kill_notify_thread(struct ciss_softc *sc); 137 138/* request submission/completion */ 139static int ciss_start(struct ciss_request *cr); | 121static int ciss_wait_adapter(struct ciss_softc *sc); 122static int ciss_flush_adapter(struct ciss_softc *sc); 123static int ciss_init_requests(struct ciss_softc *sc); 124static void ciss_command_map_helper(void *arg, bus_dma_segment_t *segs, 125 int nseg, int error); 126static int ciss_identify_adapter(struct ciss_softc *sc); 127static int ciss_init_logical(struct ciss_softc *sc); 128static int ciss_init_physical(struct ciss_softc *sc); --- 5 unchanged lines hidden (view full) --- 134static void ciss_init_sysctl(struct ciss_softc *sc); 135static void ciss_soft_reset(struct ciss_softc *sc); 136static void ciss_free(struct ciss_softc *sc); 137static void ciss_spawn_notify_thread(struct ciss_softc *sc); 138static void ciss_kill_notify_thread(struct ciss_softc *sc); 139 140/* request submission/completion */ 141static int ciss_start(struct ciss_request *cr); |
140static void ciss_done(struct ciss_softc *sc); | 142static void ciss_done(struct ciss_softc *sc, cr_qhead_t *qh); 143static void ciss_perf_done(struct ciss_softc *sc, cr_qhead_t *qh); |
141static void ciss_intr(void *arg); | 144static void ciss_intr(void *arg); |
142static void ciss_complete(struct ciss_softc *sc); 143static int ciss_report_request(struct ciss_request *cr, int *command_status, 144 int *scsi_status); | 145static void ciss_perf_intr(void *arg); 146static void ciss_perf_msi_intr(void *arg); 147static void ciss_complete(struct ciss_softc *sc, cr_qhead_t *qh); 148static int _ciss_report_request(struct ciss_request *cr, int *command_status, int *scsi_status, const char *func); |
145static int ciss_synch_request(struct ciss_request *cr, int timeout); 146static int ciss_poll_request(struct ciss_request *cr, int timeout); 147static int ciss_wait_request(struct ciss_request *cr, int timeout); 148#if 0 149static int ciss_abort_request(struct ciss_request *cr); 150#endif 151 152/* request queueing */ --- 92 unchanged lines hidden (view full) --- 245 * that are marked hidden by the firmware should be exposed anyways. 246 */ 247static unsigned int ciss_expose_hidden_physical = 0; 248TUNABLE_INT("hw.ciss.expose_hidden_physical", &ciss_expose_hidden_physical); 249 250static unsigned int ciss_nop_message_heartbeat = 0; 251TUNABLE_INT("hw.ciss.nop_message_heartbeat", &ciss_nop_message_heartbeat); 252 | 149static int ciss_synch_request(struct ciss_request *cr, int timeout); 150static int ciss_poll_request(struct ciss_request *cr, int timeout); 151static int ciss_wait_request(struct ciss_request *cr, int timeout); 152#if 0 153static int ciss_abort_request(struct ciss_request *cr); 154#endif 155 156/* request queueing */ --- 92 unchanged lines hidden (view full) --- 249 * that are marked hidden by the firmware should be exposed anyways. 250 */ 251static unsigned int ciss_expose_hidden_physical = 0; 252TUNABLE_INT("hw.ciss.expose_hidden_physical", &ciss_expose_hidden_physical); 253 254static unsigned int ciss_nop_message_heartbeat = 0; 255TUNABLE_INT("hw.ciss.nop_message_heartbeat", &ciss_nop_message_heartbeat); 256 |
257/* 258 * This tunable can force a particular transport to be used: 259 * <= 0 : use default 260 * 1 : force simple 261 * 2 : force performant 262 */ 263static int ciss_force_transport = 0; 264TUNABLE_INT("hw.ciss.force_transport", &ciss_force_transport); 265 266/* 267 * This tunable can force a particular interrupt delivery method to be used: 268 * <= 0 : use default 269 * 1 : force INTx 270 * 2 : force MSIX 271 */ 272static int ciss_force_interrupt = 0; 273TUNABLE_INT("hw.ciss.force_interrupt", &ciss_force_interrupt); 274 |
|
253/************************************************************************ 254 * CISS adapters amazingly don't have a defined programming interface 255 * value. (One could say some very despairing things about PCI and 256 * people just not getting the general idea.) So we are forced to 257 * stick with matching against subvendor/subdevice, and thus have to 258 * be updated for every new CISS adapter that appears. 259 */ 260#define CISS_BOARD_SA5 (1<<0) --- 156 unchanged lines hidden (view full) --- 417 */ 418 if ((error = ciss_init_pci(sc)) != 0) 419 goto out; 420 421 /* 422 * Initialise driver queues. 423 */ 424 ciss_initq_free(sc); | 275/************************************************************************ 276 * CISS adapters amazingly don't have a defined programming interface 277 * value. (One could say some very despairing things about PCI and 278 * people just not getting the general idea.) So we are forced to 279 * stick with matching against subvendor/subdevice, and thus have to 280 * be updated for every new CISS adapter that appears. 281 */ 282#define CISS_BOARD_SA5 (1<<0) --- 156 unchanged lines hidden (view full) --- 439 */ 440 if ((error = ciss_init_pci(sc)) != 0) 441 goto out; 442 443 /* 444 * Initialise driver queues. 445 */ 446 ciss_initq_free(sc); |
425 ciss_initq_busy(sc); 426 ciss_initq_complete(sc); | |
427 ciss_initq_notify(sc); 428 mtx_init(&sc->ciss_mtx, "cissmtx", NULL, MTX_DEF); 429 callout_init_mtx(&sc->ciss_periodic, &sc->ciss_mtx, 0); 430 431 /* 432 * Initalize device sysctls. 433 */ 434 ciss_init_sysctl(sc); --- 118 unchanged lines hidden (view full) --- 553 554/************************************************************************ 555 * Perform PCI-specific attachment actions. 556 */ 557static int 558ciss_init_pci(struct ciss_softc *sc) 559{ 560 uintptr_t cbase, csize, cofs; | 447 ciss_initq_notify(sc); 448 mtx_init(&sc->ciss_mtx, "cissmtx", NULL, MTX_DEF); 449 callout_init_mtx(&sc->ciss_periodic, &sc->ciss_mtx, 0); 450 451 /* 452 * Initalize device sysctls. 453 */ 454 ciss_init_sysctl(sc); --- 118 unchanged lines hidden (view full) --- 573 574/************************************************************************ 575 * Perform PCI-specific attachment actions. 576 */ 577static int 578ciss_init_pci(struct ciss_softc *sc) 579{ 580 uintptr_t cbase, csize, cofs; |
581 uint32_t method, supported_methods; |
|
561 int error; | 582 int error; |
583 void *intr; |
|
562 563 debug_called(1); 564 565 /* 566 * Allocate register window first (we need this to find the config 567 * struct). 568 */ 569 error = ENXIO; --- 36 unchanged lines hidden (view full) --- 606 if ((cofs + sizeof(struct ciss_config_table)) > csize) { 607 ciss_printf(sc, "config table outside window\n"); 608 return(ENXIO); 609 } 610 sc->ciss_cfg = (struct ciss_config_table *)(cbase + cofs); 611 debug(1, "config struct at %p", sc->ciss_cfg); 612 613 /* | 584 585 debug_called(1); 586 587 /* 588 * Allocate register window first (we need this to find the config 589 * struct). 590 */ 591 error = ENXIO; --- 36 unchanged lines hidden (view full) --- 628 if ((cofs + sizeof(struct ciss_config_table)) > csize) { 629 ciss_printf(sc, "config table outside window\n"); 630 return(ENXIO); 631 } 632 sc->ciss_cfg = (struct ciss_config_table *)(cbase + cofs); 633 debug(1, "config struct at %p", sc->ciss_cfg); 634 635 /* |
636 * Calculate the number of request structures/commands we are 637 * going to provide for this adapter. 638 */ 639 sc->ciss_max_requests = min(CISS_MAX_REQUESTS, sc->ciss_cfg->max_outstanding_commands); 640 641 /* |
|
614 * Validate the config structure. If we supported other transport 615 * methods, we could select amongst them at this point in time. 616 */ 617 if (strncmp(sc->ciss_cfg->signature, "CISS", 4)) { 618 ciss_printf(sc, "config signature mismatch (got '%c%c%c%c')\n", 619 sc->ciss_cfg->signature[0], sc->ciss_cfg->signature[1], 620 sc->ciss_cfg->signature[2], sc->ciss_cfg->signature[3]); 621 return(ENXIO); 622 } 623 624 /* | 642 * Validate the config structure. If we supported other transport 643 * methods, we could select amongst them at this point in time. 644 */ 645 if (strncmp(sc->ciss_cfg->signature, "CISS", 4)) { 646 ciss_printf(sc, "config signature mismatch (got '%c%c%c%c')\n", 647 sc->ciss_cfg->signature[0], sc->ciss_cfg->signature[1], 648 sc->ciss_cfg->signature[2], sc->ciss_cfg->signature[3]); 649 return(ENXIO); 650 } 651 652 /* |
625 * Put the board into simple mode, and tell it we're using the low 626 * 4GB of RAM. Set the default interrupt coalescing options. | 653 * Select the mode of operation, prefer Performant. |
627 */ | 654 */ |
628 if (!(sc->ciss_cfg->supported_methods & CISS_TRANSPORT_METHOD_SIMPLE)) { 629 ciss_printf(sc, "adapter does not support 'simple' transport layer\n"); | 655 if (!(sc->ciss_cfg->supported_methods & 656 (CISS_TRANSPORT_METHOD_SIMPLE | CISS_TRANSPORT_METHOD_PERF))) { 657 ciss_printf(sc, "No supported transport layers: 0x%x\n", 658 sc->ciss_cfg->supported_methods); |
630 return(ENXIO); 631 } | 659 return(ENXIO); 660 } |
632 sc->ciss_cfg->requested_method = CISS_TRANSPORT_METHOD_SIMPLE; | 661 662 switch (ciss_force_transport) { 663 case 1: 664 supported_methods = CISS_TRANSPORT_METHOD_SIMPLE; 665 break; 666 case 2: 667 supported_methods = CISS_TRANSPORT_METHOD_PERF; 668 break; 669 default: 670 supported_methods = sc->ciss_cfg->supported_methods; 671 break; 672 } 673 674setup: 675 if (supported_methods & CISS_TRANSPORT_METHOD_PERF) { 676 method = CISS_TRANSPORT_METHOD_PERF; 677 sc->ciss_perf = (struct ciss_perf_config *)(cbase + cofs + 678 sc->ciss_cfg->transport_offset); 679 if (ciss_init_perf(sc)) { 680 supported_methods &= ~method; 681 goto setup; 682 } 683 } else if (supported_methods & CISS_TRANSPORT_METHOD_SIMPLE) { 684 method = CISS_TRANSPORT_METHOD_SIMPLE; 685 } else { 686 ciss_printf(sc, "No supported transport methods: 0x%x\n", 687 sc->ciss_cfg->supported_methods); 688 return(ENXIO); 689 } 690 691 /* 692 * Tell it we're using the low 4GB of RAM. Set the default interrupt 693 * coalescing options. 694 */ 695 sc->ciss_cfg->requested_method = method; |
633 sc->ciss_cfg->command_physlimit = 0; 634 sc->ciss_cfg->interrupt_coalesce_delay = CISS_INTERRUPT_COALESCE_DELAY; 635 sc->ciss_cfg->interrupt_coalesce_count = CISS_INTERRUPT_COALESCE_COUNT; 636 637#ifdef __i386__ 638 sc->ciss_cfg->host_driver |= CISS_DRIVER_SCSI_PREFETCH; 639#endif 640 641 if (ciss_update_config(sc)) { 642 ciss_printf(sc, "adapter refuses to accept config update (IDBR 0x%x)\n", 643 CISS_TL_SIMPLE_READ(sc, CISS_TL_SIMPLE_IDBR)); 644 return(ENXIO); 645 } | 696 sc->ciss_cfg->command_physlimit = 0; 697 sc->ciss_cfg->interrupt_coalesce_delay = CISS_INTERRUPT_COALESCE_DELAY; 698 sc->ciss_cfg->interrupt_coalesce_count = CISS_INTERRUPT_COALESCE_COUNT; 699 700#ifdef __i386__ 701 sc->ciss_cfg->host_driver |= CISS_DRIVER_SCSI_PREFETCH; 702#endif 703 704 if (ciss_update_config(sc)) { 705 ciss_printf(sc, "adapter refuses to accept config update (IDBR 0x%x)\n", 706 CISS_TL_SIMPLE_READ(sc, CISS_TL_SIMPLE_IDBR)); 707 return(ENXIO); 708 } |
646 if (!(sc->ciss_cfg->active_method != CISS_TRANSPORT_METHOD_SIMPLE)) { 647 ciss_printf(sc, 648 "adapter refuses to go into 'simple' transport mode (0x%x, 0x%x)\n", 649 sc->ciss_cfg->supported_methods, sc->ciss_cfg->active_method); 650 return(ENXIO); | 709 if ((sc->ciss_cfg->active_method & method) == 0) { 710 supported_methods &= ~method; 711 if (supported_methods == 0) { 712 ciss_printf(sc, "adapter refuses to go into available transports " 713 "mode (0x%x, 0x%x)\n", supported_methods, 714 sc->ciss_cfg->active_method); 715 return(ENXIO); 716 } else 717 goto setup; |
651 } 652 653 /* 654 * Wait for the adapter to come ready. 655 */ 656 if ((error = ciss_wait_adapter(sc)) != 0) 657 return(error); 658 | 718 } 719 720 /* 721 * Wait for the adapter to come ready. 722 */ 723 if ((error = ciss_wait_adapter(sc)) != 0) 724 return(error); 725 |
726 /* Prepare to possibly use MSIX and/or PERFORMANT interrupts. Normal 727 * interrupts have a rid of 0, this will be overridden if MSIX is used. 728 */ 729 sc->ciss_irq_rid[0] = 0; 730 if (method == CISS_TRANSPORT_METHOD_PERF) { 731 ciss_printf(sc, "PERFORMANT Transport\n"); 732 if ((ciss_force_interrupt != 1) && (ciss_setup_msix(sc) == 0)) 733 intr = ciss_perf_msi_intr; 734 else 735 intr = ciss_perf_intr; 736 } else { 737 ciss_printf(sc, "SIMPLE Transport\n"); 738 /* MSIX doesn't seem to work in SIMPLE mode, only enable if it forced */ 739 if (ciss_force_interrupt == 2) 740 /* If this fails, we automatically revert to INTx */ 741 ciss_setup_msix(sc); 742 sc->ciss_perf = NULL; 743 intr = ciss_intr; 744 } 745 |
|
659 /* 660 * Turn off interrupts before we go routing anything. 661 */ 662 CISS_TL_SIMPLE_DISABLE_INTERRUPTS(sc); 663 664 /* 665 * Allocate and set up our interrupt. 666 */ | 746 /* 747 * Turn off interrupts before we go routing anything. 748 */ 749 CISS_TL_SIMPLE_DISABLE_INTERRUPTS(sc); 750 751 /* 752 * Allocate and set up our interrupt. 753 */ |
667 sc->ciss_irq_rid = 0; | |
668 if ((sc->ciss_irq_resource = | 754 if ((sc->ciss_irq_resource = |
669 bus_alloc_resource_any(sc->ciss_dev, SYS_RES_IRQ, &sc->ciss_irq_rid, | 755 bus_alloc_resource_any(sc->ciss_dev, SYS_RES_IRQ, &sc->ciss_irq_rid[0], |
670 RF_ACTIVE | RF_SHAREABLE)) == NULL) { 671 ciss_printf(sc, "can't allocate interrupt\n"); 672 return(ENXIO); 673 } | 756 RF_ACTIVE | RF_SHAREABLE)) == NULL) { 757 ciss_printf(sc, "can't allocate interrupt\n"); 758 return(ENXIO); 759 } |
760 |
|
674 if (bus_setup_intr(sc->ciss_dev, sc->ciss_irq_resource, | 761 if (bus_setup_intr(sc->ciss_dev, sc->ciss_irq_resource, |
675 INTR_TYPE_CAM|INTR_MPSAFE, NULL, ciss_intr, sc, | 762 INTR_TYPE_CAM|INTR_MPSAFE, NULL, intr, sc, |
676 &sc->ciss_intr)) { 677 ciss_printf(sc, "can't set up interrupt\n"); 678 return(ENXIO); 679 } 680 681 /* 682 * Allocate the parent bus DMA tag appropriate for our PCI 683 * interface. --- 4 unchanged lines hidden (view full) --- 688 if (bus_dma_tag_create(NULL, /* parent */ 689 1, 0, /* alignment, boundary */ 690 BUS_SPACE_MAXADDR, /* lowaddr */ 691 BUS_SPACE_MAXADDR, /* highaddr */ 692 NULL, NULL, /* filter, filterarg */ 693 BUS_SPACE_MAXSIZE_32BIT, /* maxsize */ 694 CISS_COMMAND_SG_LENGTH, /* nsegments */ 695 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ | 763 &sc->ciss_intr)) { 764 ciss_printf(sc, "can't set up interrupt\n"); 765 return(ENXIO); 766 } 767 768 /* 769 * Allocate the parent bus DMA tag appropriate for our PCI 770 * interface. --- 4 unchanged lines hidden (view full) --- 775 if (bus_dma_tag_create(NULL, /* parent */ 776 1, 0, /* alignment, boundary */ 777 BUS_SPACE_MAXADDR, /* lowaddr */ 778 BUS_SPACE_MAXADDR, /* highaddr */ 779 NULL, NULL, /* filter, filterarg */ 780 BUS_SPACE_MAXSIZE_32BIT, /* maxsize */ 781 CISS_COMMAND_SG_LENGTH, /* nsegments */ 782 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ |
696 BUS_DMA_ALLOCNOW, /* flags */ | 783 0, /* flags */ |
697 NULL, NULL, /* lockfunc, lockarg */ 698 &sc->ciss_parent_dmat)) { 699 ciss_printf(sc, "can't allocate parent DMA tag\n"); 700 return(ENOMEM); 701 } 702 703 /* 704 * Create DMA tag for mapping buffers into adapter-addressable 705 * space. 706 */ 707 if (bus_dma_tag_create(sc->ciss_parent_dmat, /* parent */ 708 1, 0, /* alignment, boundary */ 709 BUS_SPACE_MAXADDR, /* lowaddr */ 710 BUS_SPACE_MAXADDR, /* highaddr */ 711 NULL, NULL, /* filter, filterarg */ 712 MAXBSIZE, CISS_COMMAND_SG_LENGTH, /* maxsize, nsegments */ 713 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ | 784 NULL, NULL, /* lockfunc, lockarg */ 785 &sc->ciss_parent_dmat)) { 786 ciss_printf(sc, "can't allocate parent DMA tag\n"); 787 return(ENOMEM); 788 } 789 790 /* 791 * Create DMA tag for mapping buffers into adapter-addressable 792 * space. 793 */ 794 if (bus_dma_tag_create(sc->ciss_parent_dmat, /* parent */ 795 1, 0, /* alignment, boundary */ 796 BUS_SPACE_MAXADDR, /* lowaddr */ 797 BUS_SPACE_MAXADDR, /* highaddr */ 798 NULL, NULL, /* filter, filterarg */ 799 MAXBSIZE, CISS_COMMAND_SG_LENGTH, /* maxsize, nsegments */ 800 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ |
714 0, /* flags */ | 801 BUS_DMA_ALLOCNOW, /* flags */ |
715 busdma_lock_mutex, &sc->ciss_mtx, /* lockfunc, lockarg */ 716 &sc->ciss_buffer_dmat)) { 717 ciss_printf(sc, "can't allocate buffer DMA tag\n"); 718 return(ENOMEM); 719 } 720 return(0); 721} 722 723/************************************************************************ | 802 busdma_lock_mutex, &sc->ciss_mtx, /* lockfunc, lockarg */ 803 &sc->ciss_buffer_dmat)) { 804 ciss_printf(sc, "can't allocate buffer DMA tag\n"); 805 return(ENOMEM); 806 } 807 return(0); 808} 809 810/************************************************************************ |
811 * Setup MSI/MSIX operation (Performant only) 812 * Four interrupts are available, but we only use 1 right now. 813 */ 814static int 815ciss_setup_msix(struct ciss_softc *sc) 816{ 817 uint32_t id; 818 int val, i; 819 820 /* Weed out devices that don't actually support MSI */ 821 id = (pci_get_subvendor(sc->ciss_dev) << 16) | 822 pci_get_subdevice(sc->ciss_dev); 823 if ((id == 0x0e114070) || (id == 0x0e114080) || (id == 0x0e114082) || 824 (id == 0x0e114083)) 825 return (EINVAL); 826 827 val = pci_msix_count(sc->ciss_dev); 828 if ((val != CISS_MSI_COUNT) || (pci_alloc_msix(sc->ciss_dev, &val) != 0)) 829 return (EINVAL); 830 831 sc->ciss_msi = val; 832 ciss_printf(sc, "Using MSIX interrupt\n"); 833 834 for (i = 0; i < CISS_MSI_COUNT; i++) 835 sc->ciss_irq_rid[i] = i + 1; 836 837 return (0); 838 839} 840 841/************************************************************************ 842 * Setup the Performant structures. 843 */ 844static int 845ciss_init_perf(struct ciss_softc *sc) 846{ 847 struct ciss_perf_config *pc = sc->ciss_perf; 848 int reply_size; 849 850 /* 851 * Create the DMA tag for the reply queue. 852 */ 853 reply_size = sizeof(uint64_t) * sc->ciss_max_requests; 854 if (bus_dma_tag_create(sc->ciss_parent_dmat, /* parent */ 855 1, 0, /* alignment, boundary */ 856 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ 857 BUS_SPACE_MAXADDR, /* highaddr */ 858 NULL, NULL, /* filter, filterarg */ 859 reply_size, 1, /* maxsize, nsegments */ 860 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ 861 0, /* flags */ 862 NULL, NULL, /* lockfunc, lockarg */ 863 &sc->ciss_reply_dmat)) { 864 ciss_printf(sc, "can't allocate reply DMA tag\n"); 865 return(ENOMEM); 866 } 867 /* 868 * Allocate memory and make it available for DMA. 869 */ 870 if (bus_dmamem_alloc(sc->ciss_reply_dmat, (void **)&sc->ciss_reply, 871 BUS_DMA_NOWAIT, &sc->ciss_reply_map)) { 872 ciss_printf(sc, "can't allocate reply memory\n"); 873 return(ENOMEM); 874 } 875 bus_dmamap_load(sc->ciss_reply_dmat, sc->ciss_reply_map, sc->ciss_reply, 876 reply_size, ciss_command_map_helper, &sc->ciss_reply_phys, 0); 877 bzero(sc->ciss_reply, reply_size); 878 879 sc->ciss_cycle = 0x1; 880 sc->ciss_rqidx = 0; 881 882 /* 883 * Preload the fetch table with common command sizes. This allows the 884 * hardware to not waste bus cycles for typical i/o commands, but also not 885 * tax the driver to be too exact in choosing sizes. The table is optimized 886 * for page-aligned i/o's, but since most i/o comes from the various pagers, 887 * it's a reasonable assumption to make. 888 */ 889 pc->fetch_count[CISS_SG_FETCH_NONE] = (sizeof(struct ciss_command) + 15) / 16; 890 pc->fetch_count[CISS_SG_FETCH_1] = 891 (sizeof(struct ciss_command) + sizeof(struct ciss_sg_entry) * 1 + 15) / 16; 892 pc->fetch_count[CISS_SG_FETCH_2] = 893 (sizeof(struct ciss_command) + sizeof(struct ciss_sg_entry) * 2 + 15) / 16; 894 pc->fetch_count[CISS_SG_FETCH_4] = 895 (sizeof(struct ciss_command) + sizeof(struct ciss_sg_entry) * 4 + 15) / 16; 896 pc->fetch_count[CISS_SG_FETCH_8] = 897 (sizeof(struct ciss_command) + sizeof(struct ciss_sg_entry) * 8 + 15) / 16; 898 pc->fetch_count[CISS_SG_FETCH_16] = 899 (sizeof(struct ciss_command) + sizeof(struct ciss_sg_entry) * 16 + 15) / 16; 900 pc->fetch_count[CISS_SG_FETCH_32] = 901 (sizeof(struct ciss_command) + sizeof(struct ciss_sg_entry) * 32 + 15) / 16; 902 pc->fetch_count[CISS_SG_FETCH_MAX] = (CISS_COMMAND_ALLOC_SIZE + 15) / 16; 903 904 pc->rq_size = sc->ciss_max_requests; /* XXX less than the card supports? */ 905 pc->rq_count = 1; /* XXX Hardcode for a single queue */ 906 pc->rq_bank_hi = 0; 907 pc->rq_bank_lo = 0; 908 pc->rq[0].rq_addr_hi = 0x0; 909 pc->rq[0].rq_addr_lo = sc->ciss_reply_phys; 910 911 return(0); 912} 913 914/************************************************************************ |
|
724 * Wait for the adapter to come ready. 725 */ 726static int 727ciss_wait_adapter(struct ciss_softc *sc) 728{ 729 int i; 730 731 debug_called(1); --- 117 unchanged lines hidden (view full) --- 849static int 850ciss_init_requests(struct ciss_softc *sc) 851{ 852 struct ciss_request *cr; 853 int i; 854 855 debug_called(1); 856 | 915 * Wait for the adapter to come ready. 916 */ 917static int 918ciss_wait_adapter(struct ciss_softc *sc) 919{ 920 int i; 921 922 debug_called(1); --- 117 unchanged lines hidden (view full) --- 1040static int 1041ciss_init_requests(struct ciss_softc *sc) 1042{ 1043 struct ciss_request *cr; 1044 int i; 1045 1046 debug_called(1); 1047 |
857 /* 858 * Calculate the number of request structures/commands we are 859 * going to provide for this adapter. 860 */ 861 sc->ciss_max_requests = min(CISS_MAX_REQUESTS, sc->ciss_cfg->max_outstanding_commands); 862 | |
863 if (bootverbose) 864 ciss_printf(sc, "using %d of %d available commands\n", 865 sc->ciss_max_requests, sc->ciss_cfg->max_outstanding_commands); 866 867 /* 868 * Create the DMA tag for commands. 869 */ 870 if (bus_dma_tag_create(sc->ciss_parent_dmat, /* parent */ | 1048 if (bootverbose) 1049 ciss_printf(sc, "using %d of %d available commands\n", 1050 sc->ciss_max_requests, sc->ciss_cfg->max_outstanding_commands); 1051 1052 /* 1053 * Create the DMA tag for commands. 1054 */ 1055 if (bus_dma_tag_create(sc->ciss_parent_dmat, /* parent */ |
871 1, 0, /* alignment, boundary */ | 1056 32, 0, /* alignment, boundary */ |
872 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ 873 BUS_SPACE_MAXADDR, /* highaddr */ 874 NULL, NULL, /* filter, filterarg */ 875 CISS_COMMAND_ALLOC_SIZE * 876 sc->ciss_max_requests, 1, /* maxsize, nsegments */ 877 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ | 1057 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ 1058 BUS_SPACE_MAXADDR, /* highaddr */ 1059 NULL, NULL, /* filter, filterarg */ 1060 CISS_COMMAND_ALLOC_SIZE * 1061 sc->ciss_max_requests, 1, /* maxsize, nsegments */ 1062 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ |
878 BUS_DMA_ALLOCNOW, /* flags */ | 1063 0, /* flags */ |
879 NULL, NULL, /* lockfunc, lockarg */ 880 &sc->ciss_command_dmat)) { 881 ciss_printf(sc, "can't allocate command DMA tag\n"); 882 return(ENOMEM); 883 } 884 /* 885 * Allocate memory and make it available for DMA. 886 */ 887 if (bus_dmamem_alloc(sc->ciss_command_dmat, (void **)&sc->ciss_command, 888 BUS_DMA_NOWAIT, &sc->ciss_command_map)) { 889 ciss_printf(sc, "can't allocate command memory\n"); 890 return(ENOMEM); 891 } | 1064 NULL, NULL, /* lockfunc, lockarg */ 1065 &sc->ciss_command_dmat)) { 1066 ciss_printf(sc, "can't allocate command DMA tag\n"); 1067 return(ENOMEM); 1068 } 1069 /* 1070 * Allocate memory and make it available for DMA. 1071 */ 1072 if (bus_dmamem_alloc(sc->ciss_command_dmat, (void **)&sc->ciss_command, 1073 BUS_DMA_NOWAIT, &sc->ciss_command_map)) { 1074 ciss_printf(sc, "can't allocate command memory\n"); 1075 return(ENOMEM); 1076 } |
892 bus_dmamap_load(sc->ciss_command_dmat, sc->ciss_command_map, sc->ciss_command, | 1077 bus_dmamap_load(sc->ciss_command_dmat, sc->ciss_command_map,sc->ciss_command, |
893 CISS_COMMAND_ALLOC_SIZE * sc->ciss_max_requests, | 1078 CISS_COMMAND_ALLOC_SIZE * sc->ciss_max_requests, |
894 ciss_command_map_helper, sc, 0); | 1079 ciss_command_map_helper, &sc->ciss_command_phys, 0); |
895 bzero(sc->ciss_command, CISS_COMMAND_ALLOC_SIZE * sc->ciss_max_requests); 896 897 /* 898 * Set up the request and command structures, push requests onto 899 * the free queue. 900 */ 901 for (i = 1; i < sc->ciss_max_requests; i++) { 902 cr = &sc->ciss_request[i]; 903 cr->cr_sc = sc; 904 cr->cr_tag = i; 905 bus_dmamap_create(sc->ciss_buffer_dmat, 0, &cr->cr_datamap); 906 ciss_enqueue_free(cr); 907 } 908 return(0); 909} 910 911static void 912ciss_command_map_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error) 913{ | 1080 bzero(sc->ciss_command, CISS_COMMAND_ALLOC_SIZE * sc->ciss_max_requests); 1081 1082 /* 1083 * Set up the request and command structures, push requests onto 1084 * the free queue. 1085 */ 1086 for (i = 1; i < sc->ciss_max_requests; i++) { 1087 cr = &sc->ciss_request[i]; 1088 cr->cr_sc = sc; 1089 cr->cr_tag = i; 1090 bus_dmamap_create(sc->ciss_buffer_dmat, 0, &cr->cr_datamap); 1091 ciss_enqueue_free(cr); 1092 } 1093 return(0); 1094} 1095 1096static void 1097ciss_command_map_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error) 1098{ |
914 struct ciss_softc *sc = (struct ciss_softc *)arg; | 1099 uint32_t *addr; |
915 | 1100 |
916 sc->ciss_command_phys = segs->ds_addr; | 1101 addr = arg; 1102 *addr = segs[0].ds_addr; |
917} 918 919/************************************************************************ 920 * Identify the adapter, print some information about it. 921 */ 922static int 923ciss_identify_adapter(struct ciss_softc *sc) 924{ --- 798 unchanged lines hidden (view full) --- 1723 sc->ciss_regs_rid, sc->ciss_regs_resource); 1724 if (sc->ciss_cfg_resource != NULL) 1725 bus_release_resource(sc->ciss_dev, SYS_RES_MEMORY, 1726 sc->ciss_cfg_rid, sc->ciss_cfg_resource); 1727 if (sc->ciss_intr != NULL) 1728 bus_teardown_intr(sc->ciss_dev, sc->ciss_irq_resource, sc->ciss_intr); 1729 if (sc->ciss_irq_resource != NULL) 1730 bus_release_resource(sc->ciss_dev, SYS_RES_IRQ, | 1103} 1104 1105/************************************************************************ 1106 * Identify the adapter, print some information about it. 1107 */ 1108static int 1109ciss_identify_adapter(struct ciss_softc *sc) 1110{ --- 798 unchanged lines hidden (view full) --- 1909 sc->ciss_regs_rid, sc->ciss_regs_resource); 1910 if (sc->ciss_cfg_resource != NULL) 1911 bus_release_resource(sc->ciss_dev, SYS_RES_MEMORY, 1912 sc->ciss_cfg_rid, sc->ciss_cfg_resource); 1913 if (sc->ciss_intr != NULL) 1914 bus_teardown_intr(sc->ciss_dev, sc->ciss_irq_resource, sc->ciss_intr); 1915 if (sc->ciss_irq_resource != NULL) 1916 bus_release_resource(sc->ciss_dev, SYS_RES_IRQ, |
1731 sc->ciss_irq_rid, sc->ciss_irq_resource); | 1917 sc->ciss_irq_rid[0], sc->ciss_irq_resource); 1918 if (sc->ciss_msi) 1919 pci_release_msi(sc->ciss_dev); |
1732 | 1920 |
1733 /* destroy DMA tags */ 1734 if (sc->ciss_parent_dmat) 1735 bus_dma_tag_destroy(sc->ciss_parent_dmat); 1736 | |
1737 while ((cr = ciss_dequeue_free(sc)) != NULL) 1738 bus_dmamap_destroy(sc->ciss_buffer_dmat, cr->cr_datamap); 1739 if (sc->ciss_buffer_dmat) 1740 bus_dma_tag_destroy(sc->ciss_buffer_dmat); 1741 1742 /* destroy command memory and DMA tag */ 1743 if (sc->ciss_command != NULL) { 1744 bus_dmamap_unload(sc->ciss_command_dmat, sc->ciss_command_map); 1745 bus_dmamem_free(sc->ciss_command_dmat, sc->ciss_command, sc->ciss_command_map); 1746 } 1747 if (sc->ciss_command_dmat) 1748 bus_dma_tag_destroy(sc->ciss_command_dmat); 1749 | 1921 while ((cr = ciss_dequeue_free(sc)) != NULL) 1922 bus_dmamap_destroy(sc->ciss_buffer_dmat, cr->cr_datamap); 1923 if (sc->ciss_buffer_dmat) 1924 bus_dma_tag_destroy(sc->ciss_buffer_dmat); 1925 1926 /* destroy command memory and DMA tag */ 1927 if (sc->ciss_command != NULL) { 1928 bus_dmamap_unload(sc->ciss_command_dmat, sc->ciss_command_map); 1929 bus_dmamem_free(sc->ciss_command_dmat, sc->ciss_command, sc->ciss_command_map); 1930 } 1931 if (sc->ciss_command_dmat) 1932 bus_dma_tag_destroy(sc->ciss_command_dmat); 1933 |
1934 if (sc->ciss_reply) { 1935 bus_dmamap_unload(sc->ciss_reply_dmat, sc->ciss_reply_map); 1936 bus_dmamem_free(sc->ciss_reply_dmat, sc->ciss_reply, sc->ciss_reply_map); 1937 } 1938 if (sc->ciss_reply_dmat) 1939 bus_dma_tag_destroy(sc->ciss_reply_dmat); 1940 1941 /* destroy DMA tags */ 1942 if (sc->ciss_parent_dmat) 1943 bus_dma_tag_destroy(sc->ciss_parent_dmat); |
|
1750 if (sc->ciss_logical) { 1751 for (i = 0; i <= sc->ciss_max_logical_bus; i++) { 1752 for (j = 0; j < CISS_MAX_LOGICAL; j++) { 1753 if (sc->ciss_logical[i][j].cl_ldrive) 1754 free(sc->ciss_logical[i][j].cl_ldrive, CISS_MALLOC_CLASS); 1755 if (sc->ciss_logical[i][j].cl_lstatus) 1756 free(sc->ciss_logical[i][j].cl_lstatus, CISS_MALLOC_CLASS); 1757 } --- 57 unchanged lines hidden (view full) --- 1815 * 1816 * Note that the simple transport mechanism does not require any 1817 * reentrancy protection; the OPQ read is atomic. If there is a 1818 * chance of a race with something else that might move the request 1819 * off the busy list, then we will have to lock against that 1820 * (eg. timeouts, etc.) 1821 */ 1822static void | 1944 if (sc->ciss_logical) { 1945 for (i = 0; i <= sc->ciss_max_logical_bus; i++) { 1946 for (j = 0; j < CISS_MAX_LOGICAL; j++) { 1947 if (sc->ciss_logical[i][j].cl_ldrive) 1948 free(sc->ciss_logical[i][j].cl_ldrive, CISS_MALLOC_CLASS); 1949 if (sc->ciss_logical[i][j].cl_lstatus) 1950 free(sc->ciss_logical[i][j].cl_lstatus, CISS_MALLOC_CLASS); 1951 } --- 57 unchanged lines hidden (view full) --- 2009 * 2010 * Note that the simple transport mechanism does not require any 2011 * reentrancy protection; the OPQ read is atomic. If there is a 2012 * chance of a race with something else that might move the request 2013 * off the busy list, then we will have to lock against that 2014 * (eg. timeouts, etc.) 2015 */ 2016static void |
1823ciss_done(struct ciss_softc *sc) | 2017ciss_done(struct ciss_softc *sc, cr_qhead_t *qh) |
1824{ 1825 struct ciss_request *cr; 1826 struct ciss_command *cc; 1827 u_int32_t tag, index; | 2018{ 2019 struct ciss_request *cr; 2020 struct ciss_command *cc; 2021 u_int32_t tag, index; |
1828 int complete; | |
1829 1830 debug_called(3); 1831 1832 /* 1833 * Loop quickly taking requests from the adapter and moving them | 2022 2023 debug_called(3); 2024 2025 /* 2026 * Loop quickly taking requests from the adapter and moving them |
1834 * from the busy queue to the completed queue. | 2027 * to the completed queue. |
1835 */ | 2028 */ |
1836 complete = 0; | |
1837 for (;;) { 1838 1839 /* see if the OPQ contains anything */ 1840 if (!CISS_TL_SIMPLE_OPQ_INTERRUPT(sc)) 1841 break; 1842 1843 tag = CISS_TL_SIMPLE_FETCH_CMD(sc); 1844 if (tag == CISS_TL_SIMPLE_OPQ_EMPTY) 1845 break; 1846 index = tag >> 2; 1847 debug(2, "completed command %d%s", index, 1848 (tag & CISS_HDR_HOST_TAG_ERROR) ? " with error" : ""); 1849 if (index >= sc->ciss_max_requests) { 1850 ciss_printf(sc, "completed invalid request %d (0x%x)\n", index, tag); 1851 continue; 1852 } 1853 cr = &(sc->ciss_request[index]); 1854 cc = CISS_FIND_COMMAND(cr); 1855 cc->header.host_tag = tag; /* not updated by adapter */ | 2029 for (;;) { 2030 2031 /* see if the OPQ contains anything */ 2032 if (!CISS_TL_SIMPLE_OPQ_INTERRUPT(sc)) 2033 break; 2034 2035 tag = CISS_TL_SIMPLE_FETCH_CMD(sc); 2036 if (tag == CISS_TL_SIMPLE_OPQ_EMPTY) 2037 break; 2038 index = tag >> 2; 2039 debug(2, "completed command %d%s", index, 2040 (tag & CISS_HDR_HOST_TAG_ERROR) ? " with error" : ""); 2041 if (index >= sc->ciss_max_requests) { 2042 ciss_printf(sc, "completed invalid request %d (0x%x)\n", index, tag); 2043 continue; 2044 } 2045 cr = &(sc->ciss_request[index]); 2046 cc = CISS_FIND_COMMAND(cr); 2047 cc->header.host_tag = tag; /* not updated by adapter */ |
1856 if (ciss_remove_busy(cr)) { 1857 /* assume this is garbage out of the adapter */ 1858 ciss_printf(sc, "completed nonbusy request %d\n", index); 1859 } else { 1860 ciss_enqueue_complete(cr); 1861 } 1862 complete = 1; | 2048 ciss_enqueue_complete(cr, qh); |
1863 } 1864 | 2049 } 2050 |
2051} 2052 2053static void 2054ciss_perf_done(struct ciss_softc *sc, cr_qhead_t *qh) 2055{ 2056 struct ciss_request *cr; 2057 struct ciss_command *cc; 2058 u_int32_t tag, index; 2059 2060 debug_called(3); 2061 |
|
1865 /* | 2062 /* |
1866 * Invoke completion processing. If we can defer this out of 1867 * interrupt context, that'd be good. | 2063 * Loop quickly taking requests from the adapter and moving them 2064 * to the completed queue. |
1868 */ | 2065 */ |
1869 if (complete) 1870 ciss_complete(sc); | 2066 for (;;) { 2067 tag = sc->ciss_reply[sc->ciss_rqidx]; 2068 if ((tag & CISS_CYCLE_MASK) != sc->ciss_cycle) 2069 break; 2070 index = tag >> 2; 2071 debug(2, "completed command %d%s\n", index, 2072 (tag & CISS_HDR_HOST_TAG_ERROR) ? " with error" : ""); 2073 if (index < sc->ciss_max_requests) { 2074 cr = &(sc->ciss_request[index]); 2075 cc = CISS_FIND_COMMAND(cr); 2076 cc->header.host_tag = tag; /* not updated by adapter */ 2077 ciss_enqueue_complete(cr, qh); 2078 } else { 2079 ciss_printf(sc, "completed invalid request %d (0x%x)\n", index, tag); 2080 } 2081 if (++sc->ciss_rqidx == sc->ciss_max_requests) { 2082 sc->ciss_rqidx = 0; 2083 sc->ciss_cycle ^= 1; 2084 } 2085 } 2086 |
1871} 1872 1873/************************************************************************ 1874 * Take an interrupt from the adapter. 1875 */ 1876static void 1877ciss_intr(void *arg) 1878{ | 2087} 2088 2089/************************************************************************ 2090 * Take an interrupt from the adapter. 2091 */ 2092static void 2093ciss_intr(void *arg) 2094{ |
2095 cr_qhead_t qh; |
|
1879 struct ciss_softc *sc = (struct ciss_softc *)arg; 1880 1881 /* 1882 * The only interrupt we recognise indicates that there are 1883 * entries in the outbound post queue. 1884 */ | 2096 struct ciss_softc *sc = (struct ciss_softc *)arg; 2097 2098 /* 2099 * The only interrupt we recognise indicates that there are 2100 * entries in the outbound post queue. 2101 */ |
2102 STAILQ_INIT(&qh); 2103 ciss_done(sc, &qh); |
|
1885 mtx_lock(&sc->ciss_mtx); | 2104 mtx_lock(&sc->ciss_mtx); |
1886 ciss_done(sc); | 2105 ciss_complete(sc, &qh); |
1887 mtx_unlock(&sc->ciss_mtx); 1888} 1889 | 2106 mtx_unlock(&sc->ciss_mtx); 2107} 2108 |
2109static void 2110ciss_perf_intr(void *arg) 2111{ 2112 struct ciss_softc *sc = (struct ciss_softc *)arg; 2113 2114 /* Clear the interrupt and flush the bridges. Docs say that the flush 2115 * needs to be done twice, which doesn't seem right. 2116 */ 2117 CISS_TL_PERF_CLEAR_INT(sc); 2118 CISS_TL_PERF_FLUSH_INT(sc); 2119 2120 ciss_perf_msi_intr(sc); 2121} 2122 2123static void 2124ciss_perf_msi_intr(void *arg) 2125{ 2126 cr_qhead_t qh; 2127 struct ciss_softc *sc = (struct ciss_softc *)arg; 2128 2129 STAILQ_INIT(&qh); 2130 ciss_perf_done(sc, &qh); 2131 mtx_lock(&sc->ciss_mtx); 2132 ciss_complete(sc, &qh); 2133 mtx_unlock(&sc->ciss_mtx); 2134} 2135 2136 |
|
1890/************************************************************************ 1891 * Process completed requests. 1892 * 1893 * Requests can be completed in three fashions: 1894 * 1895 * - by invoking a callback function (cr_complete is non-null) 1896 * - by waking up a sleeper (cr_flags has CISS_REQ_SLEEP set) 1897 * - by clearing the CISS_REQ_POLL flag in interrupt/timeout context 1898 */ 1899static void | 2137/************************************************************************ 2138 * Process completed requests. 2139 * 2140 * Requests can be completed in three fashions: 2141 * 2142 * - by invoking a callback function (cr_complete is non-null) 2143 * - by waking up a sleeper (cr_flags has CISS_REQ_SLEEP set) 2144 * - by clearing the CISS_REQ_POLL flag in interrupt/timeout context 2145 */ 2146static void |
1900ciss_complete(struct ciss_softc *sc) | 2147ciss_complete(struct ciss_softc *sc, cr_qhead_t *qh) |
1901{ 1902 struct ciss_request *cr; 1903 1904 debug_called(2); 1905 1906 /* 1907 * Loop taking requests off the completed queue and performing 1908 * completion processing on them. 1909 */ 1910 for (;;) { | 2148{ 2149 struct ciss_request *cr; 2150 2151 debug_called(2); 2152 2153 /* 2154 * Loop taking requests off the completed queue and performing 2155 * completion processing on them. 2156 */ 2157 for (;;) { |
1911 if ((cr = ciss_dequeue_complete(sc)) == NULL) | 2158 if ((cr = ciss_dequeue_complete(sc, qh)) == NULL) |
1912 break; 1913 ciss_unmap_request(cr); 1914 | 2159 break; 2160 ciss_unmap_request(cr); 2161 |
2162 if ((cr->cr_flags & CISS_REQ_BUSY) == 0) 2163 ciss_printf(sc, "WARNING: completing non-busy request\n"); 2164 cr->cr_flags &= ~CISS_REQ_BUSY; 2165 |
|
1915 /* 1916 * If the request has a callback, invoke it. 1917 */ 1918 if (cr->cr_complete != NULL) { 1919 cr->cr_complete(cr); 1920 continue; 1921 } 1922 --- 23 unchanged lines hidden (view full) --- 1946 } 1947} 1948 1949/************************************************************************ 1950 * Report on the completion status of a request, and pass back SCSI 1951 * and command status values. 1952 */ 1953static int | 2166 /* 2167 * If the request has a callback, invoke it. 2168 */ 2169 if (cr->cr_complete != NULL) { 2170 cr->cr_complete(cr); 2171 continue; 2172 } 2173 --- 23 unchanged lines hidden (view full) --- 2197 } 2198} 2199 2200/************************************************************************ 2201 * Report on the completion status of a request, and pass back SCSI 2202 * and command status values. 2203 */ 2204static int |
1954ciss_report_request(struct ciss_request *cr, int *command_status, int *scsi_status) | 2205_ciss_report_request(struct ciss_request *cr, int *command_status, int *scsi_status, const char *func) |
1955{ 1956 struct ciss_command *cc; 1957 struct ciss_error_info *ce; 1958 1959 debug_called(2); 1960 1961 cc = CISS_FIND_COMMAND(cr); 1962 ce = (struct ciss_error_info *)&(cc->sg[0]); --- 32 unchanged lines hidden (view full) --- 1995 *scsi_status = -1; 1996 } 1997 } 1998 if (bootverbose) 1999 ciss_printf(cr->cr_sc, "command status 0x%x (%s) scsi status 0x%x\n", 2000 ce->command_status, ciss_name_command_status(ce->command_status), 2001 ce->scsi_status); 2002 if (ce->command_status == CISS_CMD_STATUS_INVALID_COMMAND) { | 2206{ 2207 struct ciss_command *cc; 2208 struct ciss_error_info *ce; 2209 2210 debug_called(2); 2211 2212 cc = CISS_FIND_COMMAND(cr); 2213 ce = (struct ciss_error_info *)&(cc->sg[0]); --- 32 unchanged lines hidden (view full) --- 2246 *scsi_status = -1; 2247 } 2248 } 2249 if (bootverbose) 2250 ciss_printf(cr->cr_sc, "command status 0x%x (%s) scsi status 0x%x\n", 2251 ce->command_status, ciss_name_command_status(ce->command_status), 2252 ce->scsi_status); 2253 if (ce->command_status == CISS_CMD_STATUS_INVALID_COMMAND) { |
2003 ciss_printf(cr->cr_sc, "invalid command, offense size %d at %d, value 0x%x\n", | 2254 ciss_printf(cr->cr_sc, "invalid command, offense size %d at %d, value 0x%x, function %s\n", |
2004 ce->additional_error_info.invalid_command.offense_size, 2005 ce->additional_error_info.invalid_command.offense_offset, | 2255 ce->additional_error_info.invalid_command.offense_size, 2256 ce->additional_error_info.invalid_command.offense_offset, |
2006 ce->additional_error_info.invalid_command.offense_value); | 2257 ce->additional_error_info.invalid_command.offense_value, 2258 func); |
2007 } 2008 } 2009#if 0 2010 ciss_print_request(cr); 2011#endif 2012 return(1); 2013} 2014 --- 16 unchanged lines hidden (view full) --- 2031/************************************************************************ 2032 * Issue a request and poll for completion. 2033 * 2034 * Timeout in milliseconds. 2035 */ 2036static int 2037ciss_poll_request(struct ciss_request *cr, int timeout) 2038{ | 2259 } 2260 } 2261#if 0 2262 ciss_print_request(cr); 2263#endif 2264 return(1); 2265} 2266 --- 16 unchanged lines hidden (view full) --- 2283/************************************************************************ 2284 * Issue a request and poll for completion. 2285 * 2286 * Timeout in milliseconds. 2287 */ 2288static int 2289ciss_poll_request(struct ciss_request *cr, int timeout) 2290{ |
2291 cr_qhead_t qh; 2292 struct ciss_softc *sc; |
|
2039 int error; 2040 2041 debug_called(2); 2042 | 2293 int error; 2294 2295 debug_called(2); 2296 |
2297 STAILQ_INIT(&qh); 2298 sc = cr->cr_sc; |
|
2043 cr->cr_flags |= CISS_REQ_POLL; 2044 if ((error = ciss_start(cr)) != 0) 2045 return(error); 2046 2047 do { | 2299 cr->cr_flags |= CISS_REQ_POLL; 2300 if ((error = ciss_start(cr)) != 0) 2301 return(error); 2302 2303 do { |
2048 ciss_done(cr->cr_sc); | 2304 if (sc->ciss_perf) 2305 ciss_perf_done(sc, &qh); 2306 else 2307 ciss_done(sc, &qh); 2308 ciss_complete(sc, &qh); |
2049 if (!(cr->cr_flags & CISS_REQ_POLL)) 2050 return(0); 2051 DELAY(1000); 2052 } while (timeout-- >= 0); 2053 return(EWOULDBLOCK); 2054} 2055 2056/************************************************************************ 2057 * Issue a request and sleep waiting for completion. 2058 * 2059 * Timeout in milliseconds. Note that a spurious wakeup will reset 2060 * the timeout. 2061 */ 2062static int 2063ciss_wait_request(struct ciss_request *cr, int timeout) 2064{ | 2309 if (!(cr->cr_flags & CISS_REQ_POLL)) 2310 return(0); 2311 DELAY(1000); 2312 } while (timeout-- >= 0); 2313 return(EWOULDBLOCK); 2314} 2315 2316/************************************************************************ 2317 * Issue a request and sleep waiting for completion. 2318 * 2319 * Timeout in milliseconds. Note that a spurious wakeup will reset 2320 * the timeout. 2321 */ 2322static int 2323ciss_wait_request(struct ciss_request *cr, int timeout) 2324{ |
2065 int s, error; | 2325 int error; |
2066 2067 debug_called(2); 2068 2069 cr->cr_flags |= CISS_REQ_SLEEP; 2070 if ((error = ciss_start(cr)) != 0) 2071 return(error); 2072 | 2326 2327 debug_called(2); 2328 2329 cr->cr_flags |= CISS_REQ_SLEEP; 2330 if ((error = ciss_start(cr)) != 0) 2331 return(error); 2332 |
2073 s = splcam(); | |
2074 while ((cr->cr_flags & CISS_REQ_SLEEP) && (error != EWOULDBLOCK)) { 2075 error = msleep(cr, &cr->cr_sc->ciss_mtx, PRIBIO, "cissREQ", (timeout * hz) / 1000); 2076 } | 2333 while ((cr->cr_flags & CISS_REQ_SLEEP) && (error != EWOULDBLOCK)) { 2334 error = msleep(cr, &cr->cr_sc->ciss_mtx, PRIBIO, "cissREQ", (timeout * hz) / 1000); 2335 } |
2077 splx(s); | |
2078 return(error); 2079} 2080 2081#if 0 2082/************************************************************************ 2083 * Abort a request. Note that a potential exists here to race the 2084 * request being completed; the caller must deal with this. 2085 */ --- 57 unchanged lines hidden (view full) --- 2143 */ 2144 if ((cr = ciss_dequeue_free(sc)) == NULL) 2145 return(ENOMEM); 2146 2147 cr->cr_data = NULL; 2148 cr->cr_flags = 0; 2149 cr->cr_complete = NULL; 2150 cr->cr_private = NULL; | 2336 return(error); 2337} 2338 2339#if 0 2340/************************************************************************ 2341 * Abort a request. Note that a potential exists here to race the 2342 * request being completed; the caller must deal with this. 2343 */ --- 57 unchanged lines hidden (view full) --- 2401 */ 2402 if ((cr = ciss_dequeue_free(sc)) == NULL) 2403 return(ENOMEM); 2404 2405 cr->cr_data = NULL; 2406 cr->cr_flags = 0; 2407 cr->cr_complete = NULL; 2408 cr->cr_private = NULL; |
2409 cr->cr_sg_tag = CISS_SG_MAX; /* Backstop to prevent accidents */ |
|
2151 2152 ciss_preen_command(cr); 2153 *crp = cr; 2154 return(0); 2155} 2156 2157static void 2158ciss_preen_command(struct ciss_request *cr) --- 220 unchanged lines hidden (view full) --- 2379 cr->cr_data, cr->cr_length, 2380 ciss_request_map_helper, cr, 0); 2381 if (error != 0) 2382 return (error); 2383 } else { 2384 /* 2385 * Post the command to the adapter. 2386 */ | 2410 2411 ciss_preen_command(cr); 2412 *crp = cr; 2413 return(0); 2414} 2415 2416static void 2417ciss_preen_command(struct ciss_request *cr) --- 220 unchanged lines hidden (view full) --- 2638 cr->cr_data, cr->cr_length, 2639 ciss_request_map_helper, cr, 0); 2640 if (error != 0) 2641 return (error); 2642 } else { 2643 /* 2644 * Post the command to the adapter. 2645 */ |
2387 ciss_enqueue_busy(cr); 2388 CISS_TL_SIMPLE_POST_CMD(cr->cr_sc, CISS_FIND_COMMANDPHYS(cr)); | 2646 cr->cr_sg_tag = CISS_SG_NONE; 2647 cr->cr_flags |= CISS_REQ_BUSY; 2648 if (sc->ciss_perf) 2649 CISS_TL_PERF_POST_CMD(sc, cr); 2650 else 2651 CISS_TL_SIMPLE_POST_CMD(sc, CISS_FIND_COMMANDPHYS(cr)); |
2389 } 2390 2391 return(0); 2392} 2393 2394static void 2395ciss_request_map_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error) 2396{ --- 17 unchanged lines hidden (view full) --- 2414 cc->header.sg_in_list = nseg; 2415 cc->header.sg_total = nseg; 2416 2417 if (cr->cr_flags & CISS_REQ_DATAIN) 2418 bus_dmamap_sync(sc->ciss_buffer_dmat, cr->cr_datamap, BUS_DMASYNC_PREREAD); 2419 if (cr->cr_flags & CISS_REQ_DATAOUT) 2420 bus_dmamap_sync(sc->ciss_buffer_dmat, cr->cr_datamap, BUS_DMASYNC_PREWRITE); 2421 | 2652 } 2653 2654 return(0); 2655} 2656 2657static void 2658ciss_request_map_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error) 2659{ --- 17 unchanged lines hidden (view full) --- 2677 cc->header.sg_in_list = nseg; 2678 cc->header.sg_total = nseg; 2679 2680 if (cr->cr_flags & CISS_REQ_DATAIN) 2681 bus_dmamap_sync(sc->ciss_buffer_dmat, cr->cr_datamap, BUS_DMASYNC_PREREAD); 2682 if (cr->cr_flags & CISS_REQ_DATAOUT) 2683 bus_dmamap_sync(sc->ciss_buffer_dmat, cr->cr_datamap, BUS_DMASYNC_PREWRITE); 2684 |
2685 if (nseg == 1) 2686 cr->cr_sg_tag = CISS_SG_NONE; 2687 else if (nseg == 1) 2688 cr->cr_sg_tag = CISS_SG_1; 2689 else if (nseg == 2) 2690 cr->cr_sg_tag = CISS_SG_2; 2691 else if (nseg <= 4) 2692 cr->cr_sg_tag = CISS_SG_4; 2693 else if (nseg <= 8) 2694 cr->cr_sg_tag = CISS_SG_8; 2695 else if (nseg <= 16) 2696 cr->cr_sg_tag = CISS_SG_16; 2697 else if (nseg <= 32) 2698 cr->cr_sg_tag = CISS_SG_32; 2699 else 2700 cr->cr_sg_tag = CISS_SG_MAX; 2701 |
|
2422 /* 2423 * Post the command to the adapter. 2424 */ | 2702 /* 2703 * Post the command to the adapter. 2704 */ |
2425 ciss_enqueue_busy(cr); 2426 CISS_TL_SIMPLE_POST_CMD(cr->cr_sc, CISS_FIND_COMMANDPHYS(cr)); | 2705 cr->cr_flags |= CISS_REQ_BUSY; 2706 if (sc->ciss_perf) 2707 CISS_TL_PERF_POST_CMD(sc, cr); 2708 else 2709 CISS_TL_SIMPLE_POST_CMD(sc, CISS_FIND_COMMANDPHYS(cr)); |
2427} 2428 2429/************************************************************************ 2430 * Unmap a request from bus-visible space. 2431 */ 2432static void 2433ciss_unmap_request(struct ciss_request *cr) 2434{ --- 62 unchanged lines hidden (view full) --- 2497 return(ENOMEM); 2498 } 2499 2500 for (i = 0; i < sc->ciss_max_logical_bus; i++) { 2501 if ((sc->ciss_cam_sim[i] = cam_sim_alloc(ciss_cam_action, ciss_cam_poll, 2502 "ciss", sc, 2503 device_get_unit(sc->ciss_dev), 2504 &sc->ciss_mtx, | 2710} 2711 2712/************************************************************************ 2713 * Unmap a request from bus-visible space. 2714 */ 2715static void 2716ciss_unmap_request(struct ciss_request *cr) 2717{ --- 62 unchanged lines hidden (view full) --- 2780 return(ENOMEM); 2781 } 2782 2783 for (i = 0; i < sc->ciss_max_logical_bus; i++) { 2784 if ((sc->ciss_cam_sim[i] = cam_sim_alloc(ciss_cam_action, ciss_cam_poll, 2785 "ciss", sc, 2786 device_get_unit(sc->ciss_dev), 2787 &sc->ciss_mtx, |
2788 2, |
|
2505 sc->ciss_max_requests - 2, | 2789 sc->ciss_max_requests - 2, |
2506 sc->ciss_max_requests - 2, | |
2507 sc->ciss_cam_devq)) == NULL) { 2508 ciss_printf(sc, "can't allocate CAM SIM for controller %d\n", i); 2509 return(ENOMEM); 2510 } 2511 2512 /* 2513 * Register bus with this SIM. 2514 */ --- 380 unchanged lines hidden (view full) --- 2895} 2896 2897/************************************************************************ 2898 * Check for possibly-completed commands. 2899 */ 2900static void 2901ciss_cam_poll(struct cam_sim *sim) 2902{ | 2790 sc->ciss_cam_devq)) == NULL) { 2791 ciss_printf(sc, "can't allocate CAM SIM for controller %d\n", i); 2792 return(ENOMEM); 2793 } 2794 2795 /* 2796 * Register bus with this SIM. 2797 */ --- 380 unchanged lines hidden (view full) --- 3178} 3179 3180/************************************************************************ 3181 * Check for possibly-completed commands. 3182 */ 3183static void 3184ciss_cam_poll(struct cam_sim *sim) 3185{ |
3186 cr_qhead_t qh; |
|
2903 struct ciss_softc *sc = cam_sim_softc(sim); 2904 2905 debug_called(2); 2906 | 3187 struct ciss_softc *sc = cam_sim_softc(sim); 3188 3189 debug_called(2); 3190 |
2907 ciss_done(sc); | 3191 STAILQ_INIT(&qh); 3192 if (sc->ciss_perf) 3193 ciss_perf_done(sc, &qh); 3194 else 3195 ciss_done(sc, &qh); 3196 ciss_complete(sc, &qh); |
2908} 2909 2910/************************************************************************ 2911 * Handle completion of a command - pass results back through the CCB 2912 */ 2913static void 2914ciss_cam_complete(struct ciss_request *cr) 2915{ --- 62 unchanged lines hidden (view full) --- 2978 } 2979 2980 /* handle post-command fixup */ 2981 ciss_cam_complete_fixup(sc, csio); 2982 2983 /* tell CAM we're ready for more commands */ 2984 csio->ccb_h.status |= CAM_RELEASE_SIMQ; 2985 | 3197} 3198 3199/************************************************************************ 3200 * Handle completion of a command - pass results back through the CCB 3201 */ 3202static void 3203ciss_cam_complete(struct ciss_request *cr) 3204{ --- 62 unchanged lines hidden (view full) --- 3267 } 3268 3269 /* handle post-command fixup */ 3270 ciss_cam_complete_fixup(sc, csio); 3271 3272 /* tell CAM we're ready for more commands */ 3273 csio->ccb_h.status |= CAM_RELEASE_SIMQ; 3274 |
2986 xpt_done((union ccb *)csio); | |
2987 ciss_release_request(cr); | 3275 ciss_release_request(cr); |
3276 xpt_done((union ccb *)csio); |
|
2988} 2989 2990/******************************************************************************** 2991 * Fix up the result of some commands here. 2992 */ 2993static void 2994ciss_cam_complete_fixup(struct ciss_softc *sc, struct ccb_scsiio *csio) 2995{ --- 156 unchanged lines hidden (view full) --- 3152 * Disable the adapter. 3153 * 3154 * The all requests in completed queue is failed with hardware error. 3155 * This will cause failover in a multipath configuration. 3156 */ 3157static void 3158ciss_disable_adapter(struct ciss_softc *sc) 3159{ | 3277} 3278 3279/******************************************************************************** 3280 * Fix up the result of some commands here. 3281 */ 3282static void 3283ciss_cam_complete_fixup(struct ciss_softc *sc, struct ccb_scsiio *csio) 3284{ --- 156 unchanged lines hidden (view full) --- 3441 * Disable the adapter. 3442 * 3443 * The all requests in completed queue is failed with hardware error. 3444 * This will cause failover in a multipath configuration. 3445 */ 3446static void 3447ciss_disable_adapter(struct ciss_softc *sc) 3448{ |
3449 cr_qhead_t qh; |
|
3160 struct ciss_request *cr; 3161 struct ciss_command *cc; 3162 struct ciss_error_info *ce; | 3450 struct ciss_request *cr; 3451 struct ciss_command *cc; 3452 struct ciss_error_info *ce; |
3163 int s; | 3453 int i; |
3164 | 3454 |
3165 s = splcam(); 3166 | |
3167 CISS_TL_SIMPLE_DISABLE_INTERRUPTS(sc); 3168 pci_disable_busmaster(sc->ciss_dev); 3169 sc->ciss_flags &= ~CISS_FLAG_RUNNING; 3170 | 3455 CISS_TL_SIMPLE_DISABLE_INTERRUPTS(sc); 3456 pci_disable_busmaster(sc->ciss_dev); 3457 sc->ciss_flags &= ~CISS_FLAG_RUNNING; 3458 |
3171 for (;;) { 3172 if ((cr = ciss_dequeue_busy(sc)) == NULL) 3173 break; | 3459 for (i = 1; i < sc->ciss_max_requests; i++) { 3460 cr = &sc->ciss_request[i]; 3461 if ((cr->cr_flags & CISS_REQ_BUSY) == 0) 3462 continue; |
3174 3175 cc = CISS_FIND_COMMAND(cr); 3176 ce = (struct ciss_error_info *)&(cc->sg[0]); 3177 ce->command_status = CISS_CMD_STATUS_HARDWARE_ERROR; | 3463 3464 cc = CISS_FIND_COMMAND(cr); 3465 ce = (struct ciss_error_info *)&(cc->sg[0]); 3466 ce->command_status = CISS_CMD_STATUS_HARDWARE_ERROR; |
3178 ciss_enqueue_complete(cr); | 3467 ciss_enqueue_complete(cr, &qh); |
3179 } 3180 3181 for (;;) { | 3468 } 3469 3470 for (;;) { |
3182 if ((cr = ciss_dequeue_complete(sc)) == NULL) | 3471 if ((cr = ciss_dequeue_complete(sc, &qh)) == NULL) |
3183 break; 3184 3185 /* 3186 * If the request has a callback, invoke it. 3187 */ 3188 if (cr->cr_complete != NULL) { 3189 cr->cr_complete(cr); 3190 continue; 3191 } 3192 3193 /* 3194 * If someone is sleeping on this request, wake them up. 3195 */ 3196 if (cr->cr_flags & CISS_REQ_SLEEP) { 3197 cr->cr_flags &= ~CISS_REQ_SLEEP; 3198 wakeup(cr); 3199 continue; 3200 } 3201 } | 3472 break; 3473 3474 /* 3475 * If the request has a callback, invoke it. 3476 */ 3477 if (cr->cr_complete != NULL) { 3478 cr->cr_complete(cr); 3479 continue; 3480 } 3481 3482 /* 3483 * If someone is sleeping on this request, wake them up. 3484 */ 3485 if (cr->cr_flags & CISS_REQ_SLEEP) { 3486 cr->cr_flags &= ~CISS_REQ_SLEEP; 3487 wakeup(cr); 3488 continue; 3489 } 3490 } |
3202 3203 splx(s); | |
3204} 3205 3206/************************************************************************ 3207 * Request a notification response from the adapter. 3208 * 3209 * If (cr) is NULL, this is the first request of the adapter, so 3210 * reset the adapter's message pointer and start with the oldest 3211 * message available. --- 164 unchanged lines hidden (view full) --- 3376 * the chain will not restart itself. 3377 */ 3378static int 3379ciss_notify_abort(struct ciss_softc *sc) 3380{ 3381 struct ciss_request *cr; 3382 struct ciss_command *cc; 3383 struct ciss_notify_cdb *cnc; | 3491} 3492 3493/************************************************************************ 3494 * Request a notification response from the adapter. 3495 * 3496 * If (cr) is NULL, this is the first request of the adapter, so 3497 * reset the adapter's message pointer and start with the oldest 3498 * message available. --- 164 unchanged lines hidden (view full) --- 3663 * the chain will not restart itself. 3664 */ 3665static int 3666ciss_notify_abort(struct ciss_softc *sc) 3667{ 3668 struct ciss_request *cr; 3669 struct ciss_command *cc; 3670 struct ciss_notify_cdb *cnc; |
3384 int error, s, command_status, scsi_status; | 3671 int error, command_status, scsi_status; |
3385 3386 debug_called(1); 3387 3388 cr = NULL; 3389 error = 0; 3390 3391 /* verify that there's an outstanding command */ 3392 if (!(sc->ciss_flags & CISS_FLAG_NOTIFY_OK)) --- 77 unchanged lines hidden (view full) --- 3470 3471 /* 3472 * Sleep waiting for the notifier command to complete. Note 3473 * that if it doesn't, we may end up in a bad situation, since 3474 * the adapter may deliver it later. Also note that the adapter 3475 * requires the Notify Event command to be cancelled in order to 3476 * maintain internal bookkeeping. 3477 */ | 3672 3673 debug_called(1); 3674 3675 cr = NULL; 3676 error = 0; 3677 3678 /* verify that there's an outstanding command */ 3679 if (!(sc->ciss_flags & CISS_FLAG_NOTIFY_OK)) --- 77 unchanged lines hidden (view full) --- 3757 3758 /* 3759 * Sleep waiting for the notifier command to complete. Note 3760 * that if it doesn't, we may end up in a bad situation, since 3761 * the adapter may deliver it later. Also note that the adapter 3762 * requires the Notify Event command to be cancelled in order to 3763 * maintain internal bookkeeping. 3764 */ |
3478 s = splcam(); | |
3479 while (sc->ciss_periodic_notify != NULL) { 3480 error = msleep(&sc->ciss_periodic_notify, &sc->ciss_mtx, PRIBIO, "cissNEA", hz * 5); 3481 if (error == EWOULDBLOCK) { 3482 ciss_printf(sc, "Notify Event command failed to abort, adapter may wedge.\n"); 3483 break; 3484 } 3485 } | 3765 while (sc->ciss_periodic_notify != NULL) { 3766 error = msleep(&sc->ciss_periodic_notify, &sc->ciss_mtx, PRIBIO, "cissNEA", hz * 5); 3767 if (error == EWOULDBLOCK) { 3768 ciss_printf(sc, "Notify Event command failed to abort, adapter may wedge.\n"); 3769 break; 3770 } 3771 } |
3486 splx(s); | |
3487 3488 out: 3489 /* release the cancel request */ 3490 if (cr != NULL) { 3491 if (cr->cr_data != NULL) 3492 free(cr->cr_data, CISS_MALLOC_CLASS); 3493 ciss_release_request(cr); 3494 } --- 228 unchanged lines hidden (view full) --- 3723/************************************************************************ 3724 * Handle a notify event relating to the status of a physical drive. 3725 */ 3726static void 3727ciss_notify_hotplug(struct ciss_softc *sc, struct ciss_notify *cn) 3728{ 3729 struct ciss_lun_report *cll = NULL; 3730 int bus, target; | 3772 3773 out: 3774 /* release the cancel request */ 3775 if (cr != NULL) { 3776 if (cr->cr_data != NULL) 3777 free(cr->cr_data, CISS_MALLOC_CLASS); 3778 ciss_release_request(cr); 3779 } --- 228 unchanged lines hidden (view full) --- 4008/************************************************************************ 4009 * Handle a notify event relating to the status of a physical drive. 4010 */ 4011static void 4012ciss_notify_hotplug(struct ciss_softc *sc, struct ciss_notify *cn) 4013{ 4014 struct ciss_lun_report *cll = NULL; 4015 int bus, target; |
3731 int s; | |
3732 3733 switch (cn->subclass) { 3734 case CISS_NOTIFY_HOTPLUG_PHYSICAL: 3735 case CISS_NOTIFY_HOTPLUG_NONDISK: 3736 bus = CISS_BIG_MAP_BUS(sc, cn->data.drive.big_physical_drive_number); 3737 target = 3738 CISS_BIG_MAP_TARGET(sc, cn->data.drive.big_physical_drive_number); 3739 | 4016 4017 switch (cn->subclass) { 4018 case CISS_NOTIFY_HOTPLUG_PHYSICAL: 4019 case CISS_NOTIFY_HOTPLUG_NONDISK: 4020 bus = CISS_BIG_MAP_BUS(sc, cn->data.drive.big_physical_drive_number); 4021 target = 4022 CISS_BIG_MAP_TARGET(sc, cn->data.drive.big_physical_drive_number); 4023 |
3740 s = splcam(); | |
3741 if (cn->detail == 0) { 3742 /* 3743 * Mark the device offline so that it'll start producing selection 3744 * timeouts to the upper layer. 3745 */ 3746 if ((bus >= 0) && (target >= 0)) 3747 sc->ciss_physical[bus][target].cp_online = 0; 3748 } else { 3749 /* 3750 * Rescan the physical lun list for new items 3751 */ 3752 cll = ciss_report_luns(sc, CISS_OPCODE_REPORT_PHYSICAL_LUNS, 3753 CISS_MAX_PHYSICAL); 3754 if (cll == NULL) { 3755 ciss_printf(sc, "Warning, cannot get physical lun list\n"); 3756 break; 3757 } 3758 ciss_filter_physical(sc, cll); 3759 } | 4024 if (cn->detail == 0) { 4025 /* 4026 * Mark the device offline so that it'll start producing selection 4027 * timeouts to the upper layer. 4028 */ 4029 if ((bus >= 0) && (target >= 0)) 4030 sc->ciss_physical[bus][target].cp_online = 0; 4031 } else { 4032 /* 4033 * Rescan the physical lun list for new items 4034 */ 4035 cll = ciss_report_luns(sc, CISS_OPCODE_REPORT_PHYSICAL_LUNS, 4036 CISS_MAX_PHYSICAL); 4037 if (cll == NULL) { 4038 ciss_printf(sc, "Warning, cannot get physical lun list\n"); 4039 break; 4040 } 4041 ciss_filter_physical(sc, cll); 4042 } |
3760 splx(s); | |
3761 break; 3762 3763 default: 3764 ciss_printf(sc, "Unknown hotplug event %d\n", cn->subclass); 3765 return; 3766 } 3767 3768 if (cll != NULL) --- 5 unchanged lines hidden (view full) --- 3774 * sleep which is unsafe during an interrupt. 3775 */ 3776static void 3777ciss_notify_thread(void *arg) 3778{ 3779 struct ciss_softc *sc; 3780 struct ciss_request *cr; 3781 struct ciss_notify *cn; | 4043 break; 4044 4045 default: 4046 ciss_printf(sc, "Unknown hotplug event %d\n", cn->subclass); 4047 return; 4048 } 4049 4050 if (cll != NULL) --- 5 unchanged lines hidden (view full) --- 4056 * sleep which is unsafe during an interrupt. 4057 */ 4058static void 4059ciss_notify_thread(void *arg) 4060{ 4061 struct ciss_softc *sc; 4062 struct ciss_request *cr; 4063 struct ciss_notify *cn; |
3782 int s; | |
3783 3784 sc = (struct ciss_softc *)arg; 3785#if __FreeBSD_version >= 500000 3786 mtx_lock(&sc->ciss_mtx); 3787#endif 3788 | 4064 4065 sc = (struct ciss_softc *)arg; 4066#if __FreeBSD_version >= 500000 4067 mtx_lock(&sc->ciss_mtx); 4068#endif 4069 |
3789 s = splcam(); | |
3790 for (;;) { | 4070 for (;;) { |
3791 if (TAILQ_EMPTY(&sc->ciss_notify) != 0 && | 4071 if (STAILQ_EMPTY(&sc->ciss_notify) != 0 && |
3792 (sc->ciss_flags & CISS_FLAG_THREAD_SHUT) == 0) { 3793 msleep(&sc->ciss_notify, &sc->ciss_mtx, PUSER, "idle", 0); 3794 } 3795 3796 if (sc->ciss_flags & CISS_FLAG_THREAD_SHUT) 3797 break; 3798 3799 cr = ciss_dequeue_notify(sc); | 4072 (sc->ciss_flags & CISS_FLAG_THREAD_SHUT) == 0) { 4073 msleep(&sc->ciss_notify, &sc->ciss_mtx, PUSER, "idle", 0); 4074 } 4075 4076 if (sc->ciss_flags & CISS_FLAG_THREAD_SHUT) 4077 break; 4078 4079 cr = ciss_dequeue_notify(sc); |
3800 splx(s); | |
3801 3802 if (cr == NULL) 3803 panic("cr null"); 3804 cn = (struct ciss_notify *)cr->cr_data; 3805 3806 switch (cn->class) { 3807 case CISS_NOTIFY_HOTPLUG: 3808 ciss_notify_hotplug(sc, cn); 3809 break; 3810 case CISS_NOTIFY_LOGICAL: 3811 ciss_notify_logical(sc, cn); 3812 break; 3813 case CISS_NOTIFY_PHYSICAL: 3814 ciss_notify_physical(sc, cn); 3815 break; 3816 } 3817 3818 ciss_release_request(cr); 3819 | 4080 4081 if (cr == NULL) 4082 panic("cr null"); 4083 cn = (struct ciss_notify *)cr->cr_data; 4084 4085 switch (cn->class) { 4086 case CISS_NOTIFY_HOTPLUG: 4087 ciss_notify_hotplug(sc, cn); 4088 break; 4089 case CISS_NOTIFY_LOGICAL: 4090 ciss_notify_logical(sc, cn); 4091 break; 4092 case CISS_NOTIFY_PHYSICAL: 4093 ciss_notify_physical(sc, cn); 4094 break; 4095 } 4096 4097 ciss_release_request(cr); 4098 |
3820 s = splcam(); | |
3821 } 3822 sc->ciss_notify_thread = NULL; 3823 wakeup(&sc->ciss_notify_thread); | 4099 } 4100 sc->ciss_notify_thread = NULL; 4101 wakeup(&sc->ciss_notify_thread); |
3824 splx(s); | |
3825 3826#if __FreeBSD_version >= 500000 3827 mtx_unlock(&sc->ciss_mtx); 3828#endif 3829 kproc_exit(0); 3830} 3831 3832/************************************************************************ --- 377 unchanged lines hidden (view full) --- 4210 4211 debug_called(1); 4212 4213 sc = (struct ciss_softc *)dev->si_drv1; 4214 error = 0; 4215 mtx_lock(&sc->ciss_mtx); 4216 4217 switch(cmd) { | 4102 4103#if __FreeBSD_version >= 500000 4104 mtx_unlock(&sc->ciss_mtx); 4105#endif 4106 kproc_exit(0); 4107} 4108 4109/************************************************************************ --- 377 unchanged lines hidden (view full) --- 4487 4488 debug_called(1); 4489 4490 sc = (struct ciss_softc *)dev->si_drv1; 4491 error = 0; 4492 mtx_lock(&sc->ciss_mtx); 4493 4494 switch(cmd) { |
4495 case CCISS_GETQSTATS: 4496 { 4497 union ciss_statrequest *cr = (union ciss_statrequest *)addr; 4498 4499 switch (cr->cs_item) { 4500 case CISSQ_FREE: 4501 case CISSQ_NOTIFY: 4502 bcopy(&sc->ciss_qstat[cr->cs_item], &cr->cs_qstat, 4503 sizeof(struct ciss_qstat)); 4504 break; 4505 default: 4506 error = ENOIOCTL; 4507 break; 4508 } 4509 4510 break; 4511 } 4512 |
|
4218 case CCISS_GETPCIINFO: 4219 { 4220 cciss_pci_info_struct *pis = (cciss_pci_info_struct *)addr; 4221 4222 pis->bus = pci_get_bus(sc->ciss_dev); 4223 pis->dev_fn = pci_get_slot(sc->ciss_dev); 4224 pis->board_id = pci_get_devid(sc->ciss_dev); 4225 --- 112 unchanged lines hidden --- | 4513 case CCISS_GETPCIINFO: 4514 { 4515 cciss_pci_info_struct *pis = (cciss_pci_info_struct *)addr; 4516 4517 pis->bus = pci_get_bus(sc->ciss_dev); 4518 pis->dev_fn = pci_get_slot(sc->ciss_dev); 4519 pis->board_id = pci_get_devid(sc->ciss_dev); 4520 --- 112 unchanged lines hidden --- |