Deleted Added
full compact
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 ---