ciss.c revision 111979
1193323Sed/*-
2193323Sed * Copyright (c) 2001 Michael Smith
3193323Sed * All rights reserved.
4193323Sed *
5193323Sed * Redistribution and use in source and binary forms, with or without
6193323Sed * modification, are permitted provided that the following conditions
7193323Sed * are met:
8193323Sed * 1. Redistributions of source code must retain the above copyright
9193323Sed *    notice, this list of conditions and the following disclaimer.
10193323Sed * 2. Redistributions in binary form must reproduce the above copyright
11193323Sed *    notice, this list of conditions and the following disclaimer in the
12193323Sed *    documentation and/or other materials provided with the distribution.
13193323Sed *
14193323Sed * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15193323Sed * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16193323Sed * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17198090Srdivacky * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18198090Srdivacky * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19193323Sed * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20193323Sed * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21195340Sed * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22193323Sed * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23193323Sed * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24198090Srdivacky * SUCH DAMAGE.
25193323Sed *
26193323Sed *	$FreeBSD: head/sys/dev/ciss/ciss.c 111979 2003-03-08 08:01:31Z phk $
27193323Sed */
28193323Sed
29193323Sed/*
30195340Sed * Common Interface for SCSI-3 Support driver.
31193323Sed *
32193323Sed * CISS claims to provide a common interface between a generic SCSI
33193323Sed * transport and an intelligent host adapter.
34193323Sed *
35193323Sed * This driver supports CISS as defined in the document "CISS Command
36193323Sed * Interface for SCSI-3 Support Open Specification", Version 1.04,
37193323Sed * Valence Number 1, dated 20001127, produced by Compaq Computer
38193323Sed * Corporation.  This document appears to be a hastily and somewhat
39193323Sed * arbitrarlily cut-down version of a larger (and probably even more
40193323Sed * chaotic and inconsistent) Compaq internal document.  Various
41193323Sed * details were also gleaned from Compaq's "cciss" driver for Linux.
42193323Sed *
43193323Sed * We provide a shim layer between the CISS interface and CAM,
44193323Sed * offloading most of the queueing and being-a-disk chores onto CAM.
45193323Sed * Entry to the driver is via the PCI bus attachment (ciss_probe,
46193323Sed * ciss_attach, etc) and via the CAM interface (ciss_cam_action,
47193323Sed * ciss_cam_poll).  The Compaq CISS adapters are, however, poor SCSI
48193323Sed * citizens and we have to fake up some responses to get reasonable
49193323Sed * behaviour out of them.  In addition, the CISS command set is by no
50193323Sed * means adequate to support the functionality of a RAID controller,
51193323Sed * and thus the supported Compaq adapters utilise portions of the
52193323Sed * control protocol from earlier Compaq adapter families.
53193323Sed *
54193323Sed * Note that we only support the "simple" transport layer over PCI.
55193323Sed * This interface (ab)uses the I2O register set (specifically the post
56193323Sed * queues) to exchange commands with the adapter.  Other interfaces
57193323Sed * are available, but we aren't supposed to know about them, and it is
58193323Sed * dubious whether they would provide major performance improvements
59193323Sed * except under extreme load.
60193323Sed *
61193323Sed * Currently the only supported CISS adapters are the Compaq Smart
62193323Sed * Array 5* series (5300, 5i, 532).  Even with only three adapters,
63193323Sed * Compaq still manage to have interface variations.
64193323Sed *
65193323Sed *
66193323Sed * Thanks must go to Fred Harris and Darryl DeVinney at Compaq, as
67193323Sed * well as Paul Saab at Yahoo! for their assistance in making this
68193323Sed * driver happen.
69193323Sed */
70193323Sed
71193323Sed#include <sys/param.h>
72193323Sed#include <sys/systm.h>
73193323Sed#include <sys/malloc.h>
74193323Sed#include <sys/kernel.h>
75193323Sed#include <sys/bus.h>
76193323Sed#include <sys/conf.h>
77193323Sed#include <sys/stat.h>
78193323Sed#include <sys/stdint.h>
79193323Sed
80193323Sed#include <cam/cam.h>
81193323Sed#include <cam/cam_ccb.h>
82193323Sed#include <cam/cam_periph.h>
83193323Sed#include <cam/cam_sim.h>
84193323Sed#include <cam/cam_xpt_sim.h>
85193323Sed#include <cam/scsi/scsi_all.h>
86193323Sed#include <cam/scsi/scsi_message.h>
87193323Sed
88193323Sed#include <machine/clock.h>
89193323Sed#include <machine/bus_memio.h>
90193323Sed#include <machine/bus.h>
91193323Sed#include <machine/endian.h>
92193323Sed#include <machine/resource.h>
93193323Sed#include <sys/rman.h>
94193323Sed
95193323Sed#include <pci/pcireg.h>
96193323Sed#include <pci/pcivar.h>
97193323Sed
98193323Sed#include <dev/ciss/cissreg.h>
99193323Sed#include <dev/ciss/cissvar.h>
100193323Sed#include <dev/ciss/cissio.h>
101193323Sed
102193323SedMALLOC_DEFINE(CISS_MALLOC_CLASS, "ciss_data", "ciss internal data buffers");
103193323Sed
104193323Sed/* pci interface */
105193323Sedstatic int	ciss_lookup(device_t dev);
106193323Sedstatic int	ciss_probe(device_t dev);
107193323Sedstatic int	ciss_attach(device_t dev);
108193323Sedstatic int	ciss_detach(device_t dev);
109193323Sedstatic int	ciss_shutdown(device_t dev);
110193323Sed
111193323Sed/* (de)initialisation functions, control wrappers */
112193323Sedstatic int	ciss_init_pci(struct ciss_softc *sc);
113193323Sedstatic int	ciss_wait_adapter(struct ciss_softc *sc);
114193323Sedstatic int	ciss_flush_adapter(struct ciss_softc *sc);
115193323Sedstatic int	ciss_init_requests(struct ciss_softc *sc);
116193323Sedstatic void	ciss_command_map_helper(void *arg, bus_dma_segment_t *segs,
117193323Sed					int nseg, int error);
118193323Sedstatic int	ciss_identify_adapter(struct ciss_softc *sc);
119193323Sedstatic int	ciss_init_logical(struct ciss_softc *sc);
120193323Sedstatic int	ciss_identify_logical(struct ciss_softc *sc, struct ciss_ldrive *ld);
121193323Sedstatic int	ciss_get_ldrive_status(struct ciss_softc *sc,  struct ciss_ldrive *ld);
122193323Sedstatic int	ciss_update_config(struct ciss_softc *sc);
123193323Sedstatic int	ciss_accept_media(struct ciss_softc *sc, int ldrive, int async);
124193323Sedstatic void	ciss_accept_media_complete(struct ciss_request *cr);
125193323Sedstatic void	ciss_free(struct ciss_softc *sc);
126193323Sed
127193323Sed/* request submission/completion */
128193323Sedstatic int	ciss_start(struct ciss_request *cr);
129193323Sedstatic void	ciss_done(struct ciss_softc *sc);
130193323Sedstatic void	ciss_intr(void *arg);
131193323Sedstatic void	ciss_complete(struct ciss_softc *sc);
132193323Sedstatic int	ciss_report_request(struct ciss_request *cr, int *command_status,
133193323Sed				    int *scsi_status);
134193323Sedstatic int	ciss_synch_request(struct ciss_request *cr, int timeout);
135193323Sedstatic int	ciss_poll_request(struct ciss_request *cr, int timeout);
136193323Sedstatic int	ciss_wait_request(struct ciss_request *cr, int timeout);
137193323Sed#if 0
138193323Sedstatic int	ciss_abort_request(struct ciss_request *cr);
139193323Sed#endif
140193323Sed
141193323Sed/* request queueing */
142193323Sedstatic int	ciss_get_request(struct ciss_softc *sc, struct ciss_request **crp);
143193323Sedstatic void	ciss_preen_command(struct ciss_request *cr);
144193323Sedstatic void 	ciss_release_request(struct ciss_request *cr);
145193323Sed
146193323Sed/* request helpers */
147193323Sedstatic int	ciss_get_bmic_request(struct ciss_softc *sc, struct ciss_request **crp,
148193323Sed				      int opcode, void **bufp, size_t bufsize);
149193323Sedstatic int	ciss_user_command(struct ciss_softc *sc, IOCTL_Command_struct *ioc);
150193323Sed
151193323Sed/* DMA map/unmap */
152193323Sedstatic int	ciss_map_request(struct ciss_request *cr);
153193323Sedstatic void	ciss_request_map_helper(void *arg, bus_dma_segment_t *segs,
154193323Sed					int nseg, int error);
155193323Sedstatic void	ciss_unmap_request(struct ciss_request *cr);
156193323Sed
157193323Sed/* CAM interface */
158193323Sedstatic int	ciss_cam_init(struct ciss_softc *sc);
159193323Sedstatic void	ciss_cam_rescan_target(struct ciss_softc *sc, int target);
160193323Sedstatic void	ciss_cam_rescan_all(struct ciss_softc *sc);
161193323Sedstatic void	ciss_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb);
162193323Sedstatic void	ciss_cam_action(struct cam_sim *sim, union ccb *ccb);
163193323Sedstatic int	ciss_cam_action_io(struct cam_sim *sim, struct ccb_scsiio *csio);
164193323Sedstatic int	ciss_cam_emulate(struct ciss_softc *sc, struct ccb_scsiio *csio);
165193323Sedstatic void	ciss_cam_poll(struct cam_sim *sim);
166193323Sedstatic void	ciss_cam_complete(struct ciss_request *cr);
167193323Sedstatic void	ciss_cam_complete_fixup(struct ciss_softc *sc, struct ccb_scsiio *csio);
168193323Sedstatic struct cam_periph *ciss_find_periph(struct ciss_softc *sc, int target);
169193323Sedstatic int	ciss_name_device(struct ciss_softc *sc, int target);
170193323Sed
171193323Sed/* periodic status monitoring */
172193323Sedstatic void	ciss_periodic(void *arg);
173193323Sedstatic void	ciss_notify_event(struct ciss_softc *sc);
174193323Sedstatic void	ciss_notify_complete(struct ciss_request *cr);
175193323Sedstatic int	ciss_notify_abort(struct ciss_softc *sc);
176193323Sedstatic int	ciss_notify_abort_bmic(struct ciss_softc *sc);
177193323Sedstatic void	ciss_notify_logical(struct ciss_softc *sc, struct ciss_notify *cn);
178193323Sedstatic void	ciss_notify_physical(struct ciss_softc *sc, struct ciss_notify *cn);
179193323Sed
180193323Sed/* debugging output */
181193323Sedstatic void	ciss_print_request(struct ciss_request *cr);
182193323Sedstatic void	ciss_print_ldrive(struct ciss_softc *sc, struct ciss_ldrive *ld);
183193323Sedstatic const char *ciss_name_ldrive_status(int status);
184193323Sedstatic int	ciss_decode_ldrive_status(int status);
185193323Sedstatic const char *ciss_name_ldrive_org(int org);
186198090Srdivackystatic const char *ciss_name_command_status(int status);
187198090Srdivacky
188198090Srdivacky/*
189193323Sed * PCI bus interface.
190193323Sed */
191193323Sedstatic device_method_t ciss_methods[] = {
192193323Sed    /* Device interface */
193193323Sed    DEVMETHOD(device_probe,	ciss_probe),
194193323Sed    DEVMETHOD(device_attach,	ciss_attach),
195193323Sed    DEVMETHOD(device_detach,	ciss_detach),
196193323Sed    DEVMETHOD(device_shutdown,	ciss_shutdown),
197193323Sed    { 0, 0 }
198193323Sed};
199193323Sed
200193323Sedstatic driver_t ciss_pci_driver = {
201193323Sed    "ciss",
202193323Sed    ciss_methods,
203193323Sed    sizeof(struct ciss_softc)
204193323Sed};
205193323Sed
206193323Sedstatic devclass_t	ciss_devclass;
207193323SedDRIVER_MODULE(ciss, pci, ciss_pci_driver, ciss_devclass, 0, 0);
208193323Sed
209193323Sed/*
210193323Sed * Control device interface.
211193323Sed */
212193323Sedstatic d_open_t		ciss_open;
213193323Sedstatic d_close_t	ciss_close;
214193323Sedstatic d_ioctl_t	ciss_ioctl;
215193323Sed
216193323Sed#define CISS_CDEV_MAJOR  166
217193323Sed
218193323Sedstatic struct cdevsw ciss_cdevsw = {
219193323Sed	.d_open =	ciss_open,
220193323Sed	.d_close =	ciss_close,
221193323Sed	.d_ioctl =	ciss_ioctl,
222193323Sed	.d_name =	"ciss",
223193323Sed	.d_maj =	CISS_CDEV_MAJOR,
224193323Sed};
225193323Sed
226193323Sed/************************************************************************
227193323Sed * CISS adapters amazingly don't have a defined programming interface
228193323Sed * value.  (One could say some very despairing things about PCI and
229193323Sed * people just not getting the general idea.)  So we are forced to
230193323Sed * stick with matching against subvendor/subdevice, and thus have to
231193323Sed * be updated for every new CISS adapter that appears.
232193323Sed */
233193323Sed#define CISS_BOARD_SA5	(1<<0)
234193323Sed#define CISS_BOARD_SA5B	(1<<1)
235193323Sed
236193323Sedstatic struct
237193323Sed{
238193323Sed    u_int16_t	subvendor;
239193323Sed    u_int16_t	subdevice;
240193323Sed    int		flags;
241193323Sed    char	*desc;
242193323Sed} ciss_vendor_data[] = {
243193323Sed    { 0x0e11, 0x4070, CISS_BOARD_SA5,	"Compaq Smart Array 5300" },
244193323Sed    { 0x0e11, 0x4080, CISS_BOARD_SA5B,	"Compaq Smart Array 5i" },
245193323Sed    { 0x0e11, 0x4082, CISS_BOARD_SA5B,	"Compaq Smart Array 532" },
246193323Sed    { 0x0e11, 0x4083, CISS_BOARD_SA5B,	"HP Smart Array 5312" },
247193323Sed    { 0x0e11, 0x409A, CISS_BOARD_SA5B,	"HP Smart Array 641" },
248193323Sed    { 0x0e11, 0x409B, CISS_BOARD_SA5B,	"HP Smart Array 642" },
249193323Sed    { 0x0e11, 0x409C, CISS_BOARD_SA5B,	"HP Smart Array 6400" },
250193323Sed    { 0, 0, 0, NULL }
251193323Sed};
252193323Sed
253193323Sed/************************************************************************
254193323Sed * Find a match for the device in our list of known adapters.
255193323Sed */
256193323Sedstatic int
257201360Srdivackyciss_lookup(device_t dev)
258193323Sed{
259193323Sed    int 	i;
260193323Sed
261193323Sed    for (i = 0; ciss_vendor_data[i].desc != NULL; i++)
262193323Sed	if ((pci_get_subvendor(dev) == ciss_vendor_data[i].subvendor) &&
263193323Sed	    (pci_get_subdevice(dev) == ciss_vendor_data[i].subdevice)) {
264193323Sed	    return(i);
265193323Sed	}
266193323Sed    return(-1);
267193323Sed}
268193323Sed
269193323Sed/************************************************************************
270193323Sed * Match a known CISS adapter.
271193323Sed */
272193323Sedstatic int
273193323Sedciss_probe(device_t dev)
274193323Sed{
275193323Sed    int		i;
276193323Sed
277193323Sed    i = ciss_lookup(dev);
278193323Sed    if (i != -1) {
279193323Sed	device_set_desc(dev, ciss_vendor_data[i].desc);
280193323Sed	return(-10);
281193323Sed    }
282193323Sed    return(ENOENT);
283193323Sed}
284193323Sed
285193323Sed/************************************************************************
286193323Sed * Attach the driver to this adapter.
287193323Sed */
288193323Sedstatic int
289193323Sedciss_attach(device_t dev)
290193323Sed{
291193323Sed    struct ciss_softc	*sc;
292193323Sed    int			i, error;
293193323Sed
294193323Sed    debug_called(1);
295193323Sed
296193323Sed#ifdef CISS_DEBUG
297193323Sed    /* print structure/union sizes */
298193323Sed    debug_struct(ciss_command);
299193323Sed    debug_struct(ciss_header);
300193323Sed    debug_union(ciss_device_address);
301193323Sed    debug_struct(ciss_cdb);
302193323Sed    debug_struct(ciss_report_cdb);
303193323Sed    debug_struct(ciss_notify_cdb);
304193323Sed    debug_struct(ciss_notify);
305193323Sed    debug_struct(ciss_message_cdb);
306193323Sed    debug_struct(ciss_error_info_pointer);
307193323Sed    debug_struct(ciss_error_info);
308193323Sed    debug_struct(ciss_sg_entry);
309193323Sed    debug_struct(ciss_config_table);
310193323Sed    debug_struct(ciss_bmic_cdb);
311193323Sed    debug_struct(ciss_bmic_id_ldrive);
312193323Sed    debug_struct(ciss_bmic_id_lstatus);
313193323Sed    debug_struct(ciss_bmic_id_table);
314193323Sed    debug_struct(ciss_bmic_id_pdrive);
315193323Sed    debug_struct(ciss_bmic_blink_pdrive);
316193323Sed    debug_struct(ciss_bmic_flush_cache);
317193323Sed    debug_const(CISS_MAX_REQUESTS);
318193323Sed    debug_const(CISS_MAX_LOGICAL);
319193323Sed    debug_const(CISS_INTERRUPT_COALESCE_DELAY);
320193323Sed    debug_const(CISS_INTERRUPT_COALESCE_COUNT);
321193323Sed    debug_const(CISS_COMMAND_ALLOC_SIZE);
322193323Sed    debug_const(CISS_COMMAND_SG_LENGTH);
323193323Sed
324193323Sed    debug_type(cciss_pci_info_struct);
325193323Sed    debug_type(cciss_coalint_struct);
326193323Sed    debug_type(cciss_coalint_struct);
327193323Sed    debug_type(NodeName_type);
328193323Sed    debug_type(NodeName_type);
329193323Sed    debug_type(Heartbeat_type);
330193323Sed    debug_type(BusTypes_type);
331193323Sed    debug_type(FirmwareVer_type);
332193323Sed    debug_type(DriverVer_type);
333193323Sed    debug_type(IOCTL_Command_struct);
334193323Sed#endif
335193323Sed
336193323Sed    sc = device_get_softc(dev);
337193323Sed    sc->ciss_dev = dev;
338193323Sed
339193323Sed    /*
340193323Sed     * Work out adapter type.
341193323Sed     */
342193323Sed    i = ciss_lookup(dev);
343193323Sed    if (ciss_vendor_data[i].flags & CISS_BOARD_SA5) {
344193323Sed	sc->ciss_interrupt_mask = CISS_TL_SIMPLE_INTR_OPQ_SA5;
345193323Sed    } else if (ciss_vendor_data[i].flags & CISS_BOARD_SA5B) {
346193323Sed	sc->ciss_interrupt_mask = CISS_TL_SIMPLE_INTR_OPQ_SA5B;
347193323Sed    } else {
348193323Sed	/* really an error on our part */
349193323Sed	ciss_printf(sc, "unable to determine hardware type\n");
350193323Sed	error = ENXIO;
351193323Sed	goto out;
352193323Sed    }
353193323Sed
354193323Sed    /*
355193323Sed     * Do PCI-specific init.
356193323Sed     */
357193323Sed    if ((error = ciss_init_pci(sc)) != 0)
358193323Sed	goto out;
359193323Sed
360193323Sed    /*
361193323Sed     * Initialise driver queues.
362193323Sed     */
363193323Sed    ciss_initq_free(sc);
364193323Sed    ciss_initq_busy(sc);
365193323Sed    ciss_initq_complete(sc);
366193323Sed
367193323Sed    /*
368193323Sed     * Initialise command/request pool.
369193323Sed     */
370193323Sed    if ((error = ciss_init_requests(sc)) != 0)
371193323Sed	goto out;
372193323Sed
373193323Sed    /*
374193323Sed     * Get adapter information.
375193323Sed     */
376193323Sed    if ((error = ciss_identify_adapter(sc)) != 0)
377193323Sed	goto out;
378193323Sed
379193323Sed    /*
380193323Sed     * Build our private table of logical devices.
381193323Sed     */
382193323Sed    if ((error = ciss_init_logical(sc)) != 0)
383193323Sed	goto out;
384193323Sed
385193323Sed    /*
386193323Sed     * Enable interrupts so that the CAM scan can complete.
387193323Sed     */
388193323Sed    CISS_TL_SIMPLE_ENABLE_INTERRUPTS(sc);
389193323Sed
390193323Sed    /*
391193323Sed     * Initialise the CAM interface.
392193323Sed     */
393193323Sed    if ((error = ciss_cam_init(sc)) != 0)
394193323Sed	goto out;
395193323Sed
396193323Sed    /*
397193323Sed     * Start the heartbeat routine and event chain.
398193323Sed     */
399193323Sed    ciss_periodic(sc);
400193323Sed
401193323Sed   /*
402193323Sed     * Create the control device.
403193323Sed     */
404193323Sed    sc->ciss_dev_t = make_dev(&ciss_cdevsw, device_get_unit(sc->ciss_dev),
405193323Sed			      UID_ROOT, GID_OPERATOR, S_IRUSR | S_IWUSR,
406193323Sed			      "ciss%d", device_get_unit(sc->ciss_dev));
407193323Sed    sc->ciss_dev_t->si_drv1 = sc;
408193323Sed
409193323Sed    /*
410193323Sed     * The adapter is running; synchronous commands can now sleep
411193323Sed     * waiting for an interrupt to signal completion.
412193323Sed     */
413193323Sed    sc->ciss_flags |= CISS_FLAG_RUNNING;
414193323Sed
415193323Sed    error = 0;
416193323Sed out:
417193323Sed    if (error != 0)
418193323Sed	ciss_free(sc);
419193323Sed    return(error);
420193323Sed}
421193323Sed
422193323Sed/************************************************************************
423193323Sed * Detach the driver from this adapter.
424193323Sed */
425201360Srdivackystatic int
426198090Srdivackyciss_detach(device_t dev)
427201360Srdivacky{
428201360Srdivacky    struct ciss_softc	*sc = device_get_softc(dev);
429201360Srdivacky
430198090Srdivacky    debug_called(1);
431198090Srdivacky
432198090Srdivacky    /* flush adapter cache */
433198090Srdivacky    ciss_flush_adapter(sc);
434198090Srdivacky
435193323Sed    destroy_dev(sc->ciss_dev_t);
436198090Srdivacky
437201360Srdivacky    /* release all resources */
438198090Srdivacky    ciss_free(sc);
439201360Srdivacky
440198090Srdivacky    return(0);
441198090Srdivacky
442193323Sed}
443193323Sed
444193323Sed/************************************************************************
445193323Sed * Prepare adapter for system shutdown.
446193323Sed */
447193323Sedstatic int
448193323Sedciss_shutdown(device_t dev)
449193323Sed{
450193323Sed    struct ciss_softc	*sc = device_get_softc(dev);
451193323Sed
452193323Sed    debug_called(1);
453193323Sed
454193323Sed    /* flush adapter cache */
455193323Sed    ciss_flush_adapter(sc);
456193323Sed
457193323Sed    return(0);
458193323Sed}
459193323Sed
460193323Sed/************************************************************************
461193323Sed * Perform PCI-specific attachment actions.
462193323Sed */
463193323Sedstatic int
464193323Sedciss_init_pci(struct ciss_softc *sc)
465193323Sed{
466193323Sed    uintptr_t		cbase, csize, cofs;
467193323Sed    int			error;
468193323Sed
469193323Sed    debug_called(1);
470193323Sed
471193323Sed    /*
472193323Sed     * Allocate register window first (we need this to find the config
473193323Sed     * struct).
474193323Sed     */
475198090Srdivacky    error = ENXIO;
476193323Sed    sc->ciss_regs_rid = CISS_TL_SIMPLE_BAR_REGS;
477193323Sed    if ((sc->ciss_regs_resource =
478193323Sed	 bus_alloc_resource(sc->ciss_dev, SYS_RES_MEMORY, &sc->ciss_regs_rid,
479193323Sed			    0, ~0, 1, RF_ACTIVE)) == NULL) {
480193323Sed	ciss_printf(sc, "can't allocate register window\n");
481193323Sed	return(ENXIO);
482193323Sed    }
483193323Sed    sc->ciss_regs_bhandle = rman_get_bushandle(sc->ciss_regs_resource);
484193323Sed    sc->ciss_regs_btag = rman_get_bustag(sc->ciss_regs_resource);
485193323Sed
486193323Sed    /*
487193323Sed     * Find the BAR holding the config structure.  If it's not the one
488193323Sed     * we already mapped for registers, map it too.
489193323Sed     */
490193323Sed    sc->ciss_cfg_rid = CISS_TL_SIMPLE_READ(sc, CISS_TL_SIMPLE_CFG_BAR) & 0xffff;
491193323Sed    if (sc->ciss_cfg_rid != sc->ciss_regs_rid) {
492193323Sed	if ((sc->ciss_cfg_resource =
493193323Sed	     bus_alloc_resource(sc->ciss_dev, SYS_RES_MEMORY, &sc->ciss_cfg_rid,
494198090Srdivacky				0, ~0, 1, RF_ACTIVE)) == NULL) {
495193323Sed	    ciss_printf(sc, "can't allocate config window\n");
496193323Sed	    return(ENXIO);
497193323Sed	}
498193323Sed	cbase = (uintptr_t)rman_get_virtual(sc->ciss_cfg_resource);
499193323Sed	csize = rman_get_end(sc->ciss_cfg_resource) -
500193323Sed	    rman_get_start(sc->ciss_cfg_resource) + 1;
501193323Sed    } else {
502193323Sed	cbase = (uintptr_t)rman_get_virtual(sc->ciss_regs_resource);
503193323Sed	csize = rman_get_end(sc->ciss_regs_resource) -
504193323Sed	    rman_get_start(sc->ciss_regs_resource) + 1;
505193323Sed    }
506193323Sed    cofs = CISS_TL_SIMPLE_READ(sc, CISS_TL_SIMPLE_CFG_OFF);
507193323Sed
508193323Sed    /*
509193323Sed     * Use the base/size/offset values we just calculated to
510193323Sed     * sanity-check the config structure.  If it's OK, point to it.
511193323Sed     */
512193323Sed    if ((cofs + sizeof(struct ciss_config_table)) > csize) {
513193323Sed	ciss_printf(sc, "config table outside window\n");
514193323Sed	return(ENXIO);
515193323Sed    }
516193323Sed    sc->ciss_cfg = (struct ciss_config_table *)(cbase + cofs);
517193323Sed    debug(1, "config struct at %p", sc->ciss_cfg);
518193323Sed
519193323Sed    /*
520193323Sed     * Validate the config structure.  If we supported other transport
521198090Srdivacky     * methods, we could select amongst them at this point in time.
522198090Srdivacky     */
523198090Srdivacky    if (strncmp(sc->ciss_cfg->signature, "CISS", 4)) {
524198090Srdivacky	ciss_printf(sc, "config signature mismatch (got '%c%c%c%c')\n",
525193323Sed		    sc->ciss_cfg->signature[0], sc->ciss_cfg->signature[1],
526193323Sed		    sc->ciss_cfg->signature[2], sc->ciss_cfg->signature[3]);
527193323Sed	return(ENXIO);
528193323Sed    }
529193323Sed    if ((sc->ciss_cfg->valence < CISS_MIN_VALENCE) ||
530193323Sed	(sc->ciss_cfg->valence > CISS_MAX_VALENCE)) {
531193323Sed	ciss_printf(sc, "adapter interface specification (%d) unsupported\n",
532198396Srdivacky		    sc->ciss_cfg->valence);
533193323Sed	return(ENXIO);
534193323Sed    }
535193323Sed
536193323Sed    /*
537193323Sed     * Put the board into simple mode, and tell it we're using the low
538193323Sed     * 4GB of RAM.  Set the default interrupt coalescing options.
539193323Sed     */
540194612Sed    if (!(sc->ciss_cfg->supported_methods & CISS_TRANSPORT_METHOD_SIMPLE)) {
541194612Sed	ciss_printf(sc, "adapter does not support 'simple' transport layer\n");
542194612Sed	return(ENXIO);
543200581Srdivacky    }
544194612Sed    sc->ciss_cfg->requested_method = CISS_TRANSPORT_METHOD_SIMPLE;
545193323Sed    sc->ciss_cfg->command_physlimit = 0;
546193323Sed    sc->ciss_cfg->interrupt_coalesce_delay = CISS_INTERRUPT_COALESCE_DELAY;
547193323Sed    sc->ciss_cfg->interrupt_coalesce_count = CISS_INTERRUPT_COALESCE_COUNT;
548193323Sed
549193323Sed    if (ciss_update_config(sc)) {
550193323Sed	ciss_printf(sc, "adapter refuses to accept config update (IDBR 0x%x)\n",
551193323Sed		    CISS_TL_SIMPLE_READ(sc, CISS_TL_SIMPLE_IDBR));
552193323Sed	return(ENXIO);
553193323Sed    }
554193323Sed    if (!(sc->ciss_cfg->active_method != CISS_TRANSPORT_METHOD_SIMPLE)) {
555193323Sed	ciss_printf(sc,
556193323Sed		    "adapter refuses to go into 'simple' transport mode (0x%x, 0x%x)\n",
557193323Sed		    sc->ciss_cfg->supported_methods, sc->ciss_cfg->active_method);
558193323Sed	return(ENXIO);
559193323Sed    }
560193323Sed
561198090Srdivacky    /*
562193323Sed     * Wait for the adapter to come ready.
563193323Sed     */
564193323Sed    if ((error = ciss_wait_adapter(sc)) != 0)
565193323Sed	return(error);
566193323Sed
567193574Sed    /*
568193574Sed     * Turn off interrupts before we go routing anything.
569198090Srdivacky     */
570193323Sed    CISS_TL_SIMPLE_DISABLE_INTERRUPTS(sc);
571193323Sed
572193323Sed    /*
573193323Sed     * Allocate and set up our interrupt.
574193323Sed     */
575193323Sed    sc->ciss_irq_rid = 0;
576193323Sed    if ((sc->ciss_irq_resource =
577193323Sed	 bus_alloc_resource(sc->ciss_dev, SYS_RES_IRQ, &sc->ciss_irq_rid, 0, ~0, 1,
578193323Sed			    RF_ACTIVE | RF_SHAREABLE)) == NULL) {
579193323Sed	ciss_printf(sc, "can't allocate interrupt\n");
580198892Srdivacky	return(ENXIO);
581193323Sed    }
582193323Sed    if (bus_setup_intr(sc->ciss_dev, sc->ciss_irq_resource, INTR_TYPE_CAM, ciss_intr, sc,
583193323Sed		       &sc->ciss_intr)) {
584193323Sed	ciss_printf(sc, "can't set up interrupt\n");
585193323Sed	return(ENXIO);
586193323Sed    }
587198090Srdivacky
588198090Srdivacky    /*
589198090Srdivacky     * Allocate the parent bus DMA tag appropriate for our PCI
590198090Srdivacky     * interface.
591198090Srdivacky     *
592198090Srdivacky     * Note that "simple" adapters can only address within a 32-bit
593198090Srdivacky     * span.
594198090Srdivacky     */
595193323Sed    if (bus_dma_tag_create(NULL, 			/* parent */
596193323Sed			   1, 0, 			/* alignment, boundary */
597193323Sed			   BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
598193323Sed			   BUS_SPACE_MAXADDR, 		/* highaddr */
599193323Sed			   NULL, NULL, 			/* filter, filterarg */
600193323Sed			   MAXBSIZE, CISS_COMMAND_SG_LENGTH,	/* maxsize, nsegments */
601193323Sed			   BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
602193323Sed			   BUS_DMA_ALLOCNOW,		/* flags */
603193323Sed			   &sc->ciss_parent_dmat)) {
604193323Sed	ciss_printf(sc, "can't allocate parent DMA tag\n");
605193323Sed	return(ENOMEM);
606193323Sed    }
607198396Srdivacky
608198396Srdivacky    /*
609198396Srdivacky     * Create DMA tag for mapping buffers into adapter-addressable
610198396Srdivacky     * space.
611198892Srdivacky     */
612198892Srdivacky    if (bus_dma_tag_create(sc->ciss_parent_dmat, 	/* parent */
613198892Srdivacky			   1, 0, 			/* alignment, boundary */
614198892Srdivacky			   BUS_SPACE_MAXADDR,		/* lowaddr */
615193323Sed			   BUS_SPACE_MAXADDR, 		/* highaddr */
616193323Sed			   NULL, NULL, 			/* filter, filterarg */
617193323Sed			   MAXBSIZE, CISS_COMMAND_SG_LENGTH,	/* maxsize, nsegments */
618193323Sed			   BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
619193323Sed			   0,				/* flags */
620193323Sed			   &sc->ciss_buffer_dmat)) {
621193323Sed	ciss_printf(sc, "can't allocate buffer DMA tag\n");
622193574Sed	return(ENOMEM);
623193574Sed    }
624193574Sed    return(0);
625193323Sed}
626193323Sed
627193323Sed/************************************************************************
628193323Sed * Wait for the adapter to come ready.
629193323Sed */
630193323Sedstatic int
631193323Sedciss_wait_adapter(struct ciss_softc *sc)
632193323Sed{
633193323Sed    int		i;
634193323Sed
635193323Sed    debug_called(1);
636193323Sed
637193323Sed    /*
638193323Sed     * Wait for the adapter to come ready.
639193323Sed     */
640193323Sed    if (!(sc->ciss_cfg->active_method & CISS_TRANSPORT_METHOD_READY)) {
641193323Sed	ciss_printf(sc, "waiting for adapter to come ready...\n");
642193323Sed	for (i = 0; !(sc->ciss_cfg->active_method & CISS_TRANSPORT_METHOD_READY); i++) {
643193323Sed	    DELAY(1000000);	/* one second */
644193323Sed	    if (i > 30) {
645193323Sed		ciss_printf(sc, "timed out waiting for adapter to come ready\n");
646193323Sed		return(EIO);
647193323Sed	    }
648193323Sed	}
649193323Sed    }
650198892Srdivacky    return(0);
651193323Sed}
652193323Sed
653193323Sed/************************************************************************
654193323Sed * Flush the adapter cache.
655193323Sed */
656193323Sedstatic int
657193323Sedciss_flush_adapter(struct ciss_softc *sc)
658193323Sed{
659193323Sed    struct ciss_request			*cr;
660193323Sed    struct ciss_bmic_flush_cache	*cbfc;
661193323Sed    int					error, command_status;
662193323Sed
663193323Sed    debug_called(1);
664193323Sed
665193323Sed    cr = NULL;
666193323Sed    cbfc = NULL;
667193323Sed
668193323Sed    /*
669193323Sed     * Build a BMIC request to flush the cache.  We don't disable
670193323Sed     * it, as we may be going to do more I/O (eg. we are emulating
671193323Sed     * the Synchronise Cache command).
672193323Sed     */
673193323Sed    if ((cbfc = malloc(sizeof(*cbfc), CISS_MALLOC_CLASS, M_NOWAIT | M_ZERO)) == NULL) {
674198090Srdivacky	error = ENOMEM;
675193323Sed	goto out;
676193323Sed    }
677193323Sed    if ((error = ciss_get_bmic_request(sc, &cr, CISS_BMIC_FLUSH_CACHE,
678193323Sed				       (void **)&cbfc, sizeof(*cbfc))) != 0)
679193323Sed	goto out;
680193323Sed
681193323Sed    /*
682193323Sed     * Submit the request and wait for it to complete.
683193323Sed     */
684193323Sed    if ((error = ciss_synch_request(cr, 60 * 1000)) != 0) {
685193323Sed	ciss_printf(sc, "error sending BMIC FLUSH_CACHE command (%d)\n", error);
686193323Sed	goto out;
687193323Sed    }
688193323Sed
689193323Sed    /*
690193323Sed     * Check response.
691193323Sed     */
692193323Sed    ciss_report_request(cr, &command_status, NULL);
693193323Sed    switch(command_status) {
694193323Sed    case CISS_CMD_STATUS_SUCCESS:
695193323Sed	break;
696193323Sed    default:
697193323Sed	ciss_printf(sc, "error flushing cache (%s)\n",
698193323Sed		    ciss_name_command_status(command_status));
699193323Sed	error = EIO;
700193323Sed	goto out;
701193323Sed    }
702193323Sed
703193323Sedout:
704193323Sed    if (cbfc != NULL)
705193323Sed	free(cbfc, CISS_MALLOC_CLASS);
706193323Sed    if (cr != NULL)
707193323Sed	ciss_release_request(cr);
708193323Sed    return(error);
709193323Sed}
710193323Sed
711193323Sed/************************************************************************
712193323Sed * Allocate memory for the adapter command structures, initialise
713193323Sed * the request structures.
714193323Sed *
715193323Sed * Note that the entire set of commands are allocated in a single
716193323Sed * contiguous slab.
717193323Sed */
718193323Sedstatic int
719193323Sedciss_init_requests(struct ciss_softc *sc)
720193323Sed{
721193323Sed    struct ciss_request	*cr;
722193323Sed    int			i;
723193323Sed
724193323Sed    debug_called(1);
725193323Sed
726193323Sed    /*
727193323Sed     * Calculate the number of request structures/commands we are
728193323Sed     * going to provide for this adapter.
729193323Sed     */
730193323Sed    sc->ciss_max_requests = min(CISS_MAX_REQUESTS, sc->ciss_cfg->max_outstanding_commands);
731193323Sed
732193323Sed    if (1/*bootverbose*/)
733193323Sed	ciss_printf(sc, "using %d of %d available commands\n",
734193323Sed		    sc->ciss_max_requests, sc->ciss_cfg->max_outstanding_commands);
735193323Sed
736193323Sed    /*
737198090Srdivacky     * Create the DMA tag for commands.
738193323Sed     */
739193323Sed    if (bus_dma_tag_create(sc->ciss_parent_dmat,	/* parent */
740193323Sed			   1, 0, 			/* alignment, boundary */
741193323Sed			   BUS_SPACE_MAXADDR,		/* lowaddr */
742193323Sed			   BUS_SPACE_MAXADDR, 		/* highaddr */
743193323Sed			   NULL, NULL, 			/* filter, filterarg */
744193323Sed			   CISS_COMMAND_ALLOC_SIZE *
745193323Sed			   sc->ciss_max_requests, 1,	/* maxsize, nsegments */
746193323Sed			   BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
747193323Sed			   0,				/* flags */
748193323Sed			   &sc->ciss_command_dmat)) {
749193323Sed	ciss_printf(sc, "can't allocate command DMA tag\n");
750193323Sed	return(ENOMEM);
751193323Sed    }
752193323Sed    /*
753193323Sed     * Allocate memory and make it available for DMA.
754193323Sed     */
755193323Sed    if (bus_dmamem_alloc(sc->ciss_command_dmat, (void **)&sc->ciss_command,
756193323Sed			 BUS_DMA_NOWAIT, &sc->ciss_command_map)) {
757193323Sed	ciss_printf(sc, "can't allocate command memory\n");
758193323Sed	return(ENOMEM);
759193323Sed    }
760193323Sed    bus_dmamap_load(sc->ciss_command_dmat, sc->ciss_command_map, sc->ciss_command,
761193323Sed		    sizeof(struct ciss_command) * sc->ciss_max_requests,
762193323Sed		    ciss_command_map_helper, sc, 0);
763193323Sed    bzero(sc->ciss_command, CISS_COMMAND_ALLOC_SIZE * sc->ciss_max_requests);
764193323Sed
765193323Sed    /*
766193323Sed     * Set up the request and command structures, push requests onto
767193323Sed     * the free queue.
768193323Sed     */
769193323Sed    for (i = 1; i < sc->ciss_max_requests; i++) {
770193323Sed	cr = &sc->ciss_request[i];
771193323Sed	cr->cr_sc = sc;
772193323Sed	cr->cr_tag = i;
773193323Sed	ciss_enqueue_free(cr);
774193323Sed    }
775193323Sed    return(0);
776193323Sed}
777193323Sed
778193323Sedstatic void
779193323Sedciss_command_map_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error)
780193323Sed{
781193323Sed    struct ciss_softc	*sc = (struct ciss_softc *)arg;
782193323Sed
783193323Sed    sc->ciss_command_phys = segs->ds_addr;
784193323Sed}
785193323Sed
786193323Sed/************************************************************************
787193323Sed * Identify the adapter, print some information about it.
788193323Sed */
789193323Sedstatic int
790193323Sedciss_identify_adapter(struct ciss_softc *sc)
791193323Sed{
792193323Sed    struct ciss_request	*cr;
793193323Sed    int			error, command_status;
794193323Sed
795193323Sed    debug_called(1);
796193323Sed
797193323Sed    cr = NULL;
798193323Sed
799193323Sed    /*
800198090Srdivacky     * Get a request, allocate storage for the adapter data.
801193323Sed     */
802193323Sed    if ((error = ciss_get_bmic_request(sc, &cr, CISS_BMIC_ID_CTLR,
803193323Sed				       (void **)&sc->ciss_id,
804193323Sed				       sizeof(*sc->ciss_id))) != 0)
805193323Sed	goto out;
806193323Sed
807193323Sed    /*
808193323Sed     * Submit the request and wait for it to complete.
809193323Sed     */
810193323Sed    if ((error = ciss_synch_request(cr, 60 * 1000)) != 0) {
811193323Sed	ciss_printf(sc, "error sending BMIC ID_CTLR command (%d)\n", error);
812193323Sed	goto out;
813193323Sed    }
814193323Sed
815193323Sed    /*
816193323Sed     * Check response.
817193323Sed     */
818193323Sed    ciss_report_request(cr, &command_status, NULL);
819193323Sed    switch(command_status) {
820193323Sed    case CISS_CMD_STATUS_SUCCESS:		/* buffer right size */
821193323Sed	break;
822193323Sed    case CISS_CMD_STATUS_DATA_UNDERRUN:
823193323Sed    case CISS_CMD_STATUS_DATA_OVERRUN:
824193323Sed	ciss_printf(sc, "data over/underrun reading adapter information\n");
825193323Sed    default:
826193323Sed	ciss_printf(sc, "error reading adapter information (%s)\n",
827193323Sed		    ciss_name_command_status(command_status));
828193323Sed	error = EIO;
829193323Sed	goto out;
830193323Sed    }
831193323Sed
832193323Sed    /* sanity-check reply */
833193323Sed    if (!sc->ciss_id->big_map_supported) {
834193323Sed	ciss_printf(sc, "adapter does not support BIG_MAP\n");
835193323Sed	error = ENXIO;
836193323Sed	goto out;
837193323Sed    }
838193323Sed
839193323Sed#if 0
840193323Sed    /* XXX later revisions may not need this */
841193323Sed    sc->ciss_flags |= CISS_FLAG_FAKE_SYNCH;
842193323Sed#endif
843193323Sed
844193323Sed    /* XXX only really required for old 5300 adapters? */
845193323Sed    sc->ciss_flags |= CISS_FLAG_BMIC_ABORT;
846193323Sed
847193323Sed    /* print information */
848193323Sed    if (1/*bootverbose*/) {
849193323Sed	ciss_printf(sc, "  %d logical drive%s configured\n",
850193323Sed		    sc->ciss_id->configured_logical_drives,
851193323Sed		    (sc->ciss_id->configured_logical_drives == 1) ? "" : "s");
852193323Sed	ciss_printf(sc, "  firmware %4.4s\n", sc->ciss_id->running_firmware_revision);
853193323Sed	ciss_printf(sc, "  %d SCSI channels\n", sc->ciss_id->scsi_bus_count);
854193323Sed
855193323Sed	ciss_printf(sc, "  signature '%.4s'\n", sc->ciss_cfg->signature);
856193323Sed	ciss_printf(sc, "  valence %d\n", sc->ciss_cfg->valence);
857193323Sed	ciss_printf(sc, "  supported I/O methods 0x%b\n",
858193323Sed		    sc->ciss_cfg->supported_methods,
859193323Sed		    "\20\1READY\2simple\3performant\4MEMQ\n");
860193323Sed	ciss_printf(sc, "  active I/O method 0x%b\n",
861193323Sed		    sc->ciss_cfg->active_method, "\20\2simple\3performant\4MEMQ\n");
862193323Sed	ciss_printf(sc, "  4G page base 0x%08x\n",
863193323Sed		    sc->ciss_cfg->command_physlimit);
864193323Sed	ciss_printf(sc, "  interrupt coalesce delay %dus\n",
865		    sc->ciss_cfg->interrupt_coalesce_delay);
866	ciss_printf(sc, "  interrupt coalesce count %d\n",
867		    sc->ciss_cfg->interrupt_coalesce_count);
868	ciss_printf(sc, "  max outstanding commands %d\n",
869		    sc->ciss_cfg->max_outstanding_commands);
870	ciss_printf(sc, "  bus types 0x%b\n", sc->ciss_cfg->bus_types,
871		    "\20\1ultra2\2ultra3\10fibre1\11fibre2\n");
872	ciss_printf(sc, "  server name '%.16s'\n", sc->ciss_cfg->server_name);
873	ciss_printf(sc, "  heartbeat 0x%x\n", sc->ciss_cfg->heartbeat);
874    }
875
876out:
877    if (error) {
878	if (sc->ciss_id != NULL) {
879	    free(sc->ciss_id, CISS_MALLOC_CLASS);
880	    sc->ciss_id = NULL;
881	}
882    }
883    if (cr != NULL)
884	ciss_release_request(cr);
885    return(error);
886}
887
888/************************************************************************
889 * Find logical drives on the adapter.
890 */
891static int
892ciss_init_logical(struct ciss_softc *sc)
893{
894    struct ciss_request		*cr;
895    struct ciss_command		*cc;
896    struct ciss_report_cdb	*crc;
897    struct ciss_lun_report	*cll;
898    int				error, i;
899    size_t			report_size;
900    int				ndrives;
901    int				command_status;
902
903    debug_called(1);
904
905    cr = NULL;
906    cll = NULL;
907
908    /*
909     * Get a request, allocate storage for the address list.
910     */
911    if ((error = ciss_get_request(sc, &cr)) != 0)
912	goto out;
913    report_size = sizeof(*cll) + CISS_MAX_LOGICAL * sizeof(union ciss_device_address);
914    if ((cll = malloc(report_size, CISS_MALLOC_CLASS, M_NOWAIT | M_ZERO)) == NULL) {
915	ciss_printf(sc, "can't allocate memory for logical drive list\n");
916	error = ENOMEM;
917	goto out;
918    }
919
920    /*
921     * Build the Report Logical LUNs command.
922     */
923    cc = CISS_FIND_COMMAND(cr);
924    cr->cr_data = cll;
925    cr->cr_length = report_size;
926    cr->cr_flags = CISS_REQ_DATAIN;
927
928    cc->header.address.physical.mode = CISS_HDR_ADDRESS_MODE_PERIPHERAL;
929    cc->header.address.physical.bus = 0;
930    cc->header.address.physical.target = 0;
931    cc->cdb.cdb_length = sizeof(*crc);
932    cc->cdb.type = CISS_CDB_TYPE_COMMAND;
933    cc->cdb.attribute = CISS_CDB_ATTRIBUTE_SIMPLE;
934    cc->cdb.direction = CISS_CDB_DIRECTION_READ;
935    cc->cdb.timeout = 30;	/* XXX better suggestions? */
936
937    crc = (struct ciss_report_cdb *)&(cc->cdb.cdb[0]);
938    bzero(crc, sizeof(*crc));
939    crc->opcode = CISS_OPCODE_REPORT_LOGICAL_LUNS;
940    crc->length = htonl(report_size);			/* big-endian field */
941    cll->list_size = htonl(report_size - sizeof(*cll));	/* big-endian field */
942
943    /*
944     * Submit the request and wait for it to complete.  (timeout
945     * here should be much greater than above)
946     */
947    if ((error = ciss_synch_request(cr, 60 * 1000)) != 0) {
948	ciss_printf(sc, "error sending Report Logical LUNs command (%d)\n", error);
949	goto out;
950    }
951
952    /*
953     * Check response.  Note that data over/underrun is OK.
954     */
955    ciss_report_request(cr, &command_status, NULL);
956    switch(command_status) {
957    case CISS_CMD_STATUS_SUCCESS:	/* buffer right size */
958    case CISS_CMD_STATUS_DATA_UNDERRUN:	/* buffer too large, not bad */
959	break;
960    case CISS_CMD_STATUS_DATA_OVERRUN:
961	ciss_printf(sc, "WARNING: more logical drives than driver limit (%d), adjust CISS_MAX_LOGICAL\n",
962		    CISS_MAX_LOGICAL);
963	break;
964    default:
965	ciss_printf(sc, "error detecting logical drive configuration (%s)\n",
966		    ciss_name_command_status(command_status));
967	error = EIO;
968	goto out;
969    }
970    ciss_release_request(cr);
971    cr = NULL;
972
973    /* sanity-check reply */
974    ndrives = (ntohl(cll->list_size) / sizeof(union ciss_device_address));
975    if ((ndrives < 0) || (ndrives > CISS_MAX_LOGICAL)) {
976	ciss_printf(sc, "adapter claims to report absurd number of logical drives (%d > %d)\n",
977		    ndrives, CISS_MAX_LOGICAL);
978	return(ENXIO);
979    }
980
981    /*
982     * Save logical drive information.
983     */
984    if (1/*bootverbose*/)
985	ciss_printf(sc, "%d logical drive%s\n", ndrives, (ndrives > 1) ? "s" : "");
986    if (ndrives != sc->ciss_id->configured_logical_drives)
987	ciss_printf(sc, "logical drive map claims %d drives, but adapter claims %d\n",
988		    ndrives, sc->ciss_id->configured_logical_drives);
989    for (i = 0; i < CISS_MAX_LOGICAL; i++) {
990	if (i < ndrives) {
991	    sc->ciss_logical[i].cl_address = cll->lun[i];	/* XXX endianness? */
992	    if (ciss_identify_logical(sc, &sc->ciss_logical[i]) != 0)
993		continue;
994	    /*
995	     * If the drive has had media exchanged, we should bring it online.
996	     */
997	    if (sc->ciss_logical[i].cl_lstatus->media_exchanged)
998		ciss_accept_media(sc, i, 0);
999
1000	} else {
1001	    sc->ciss_logical[i].cl_status = CISS_LD_NONEXISTENT;
1002	}
1003    }
1004    error = 0;
1005
1006 out:
1007    /*
1008     * Note that if the error is a timeout, we are taking a slight
1009     * risk here and assuming that the adapter will not respond at a
1010     * later time, scribbling over host memory.
1011     */
1012    if (cr != NULL)
1013	ciss_release_request(cr);
1014    if (cll != NULL)
1015	free(cll, CISS_MALLOC_CLASS);
1016    return(error);
1017}
1018
1019static int
1020ciss_inquiry_logical(struct ciss_softc *sc, struct ciss_ldrive *ld)
1021{
1022    struct ciss_request			*cr;
1023    struct ciss_command			*cc;
1024    struct scsi_inquiry			*inq;
1025    int					error;
1026    int					command_status;
1027    int					lun;
1028
1029    cr = NULL;
1030    lun = ld->cl_address.logical.lun;
1031
1032    bzero(&ld->cl_geometry, sizeof(ld->cl_geometry));
1033
1034    if ((error = ciss_get_request(sc, &cr)) != 0)
1035	goto out;
1036
1037    cc = CISS_FIND_COMMAND(cr);
1038    cr->cr_data = &ld->cl_geometry;
1039    cr->cr_length = sizeof(ld->cl_geometry);
1040    cr->cr_flags = CISS_REQ_DATAIN;
1041
1042    cc->header.address.logical.mode = CISS_HDR_ADDRESS_MODE_LOGICAL;
1043    cc->header.address.logical.lun  = lun;
1044    cc->cdb.cdb_length = 6;
1045    cc->cdb.type = CISS_CDB_TYPE_COMMAND;
1046    cc->cdb.attribute = CISS_CDB_ATTRIBUTE_SIMPLE;
1047    cc->cdb.direction = CISS_CDB_DIRECTION_READ;
1048    cc->cdb.timeout = 30;
1049
1050    inq = (struct scsi_inquiry *)&(cc->cdb.cdb[0]);
1051    inq->opcode = INQUIRY;
1052    inq->byte2 = SI_EVPD;
1053    inq->page_code = CISS_VPD_LOGICAL_DRIVE_GEOMETRY;
1054    inq->length = sizeof(ld->cl_geometry);
1055
1056    if ((error = ciss_synch_request(cr, 60 * 1000)) != 0) {
1057	ciss_printf(sc, "error getting geometry (%d)\n", error);
1058	goto out;
1059    }
1060
1061    ciss_report_request(cr, &command_status, NULL);
1062    switch(command_status) {
1063    case CISS_CMD_STATUS_SUCCESS:
1064    case CISS_CMD_STATUS_DATA_UNDERRUN:
1065	break;
1066    case CISS_CMD_STATUS_DATA_OVERRUN:
1067	ciss_printf(sc, "WARNING: Data overrun\n");
1068	break;
1069    default:
1070	ciss_printf(sc, "Error detecting logical drive geometry (%s)\n",
1071		    ciss_name_command_status(command_status));
1072	break;
1073    }
1074
1075out:
1076    if (cr != NULL)
1077	ciss_release_request(cr);
1078    return(error);
1079}
1080/************************************************************************
1081 * Identify a logical drive, initialise state related to it.
1082 */
1083static int
1084ciss_identify_logical(struct ciss_softc *sc, struct ciss_ldrive *ld)
1085{
1086    struct ciss_request		*cr;
1087    struct ciss_command		*cc;
1088    struct ciss_bmic_cdb	*cbc;
1089    int				error, command_status;
1090
1091    debug_called(1);
1092
1093    cr = NULL;
1094
1095    /*
1096     * Build a BMIC request to fetch the drive ID.
1097     */
1098    if ((error = ciss_get_bmic_request(sc, &cr, CISS_BMIC_ID_LDRIVE,
1099				       (void **)&ld->cl_ldrive,
1100				       sizeof(*ld->cl_ldrive))) != 0)
1101	goto out;
1102    cc = CISS_FIND_COMMAND(cr);
1103    cbc = (struct ciss_bmic_cdb *)&(cc->cdb.cdb[0]);
1104    cbc->log_drive = ld->cl_address.logical.lun;
1105
1106    /*
1107     * Submit the request and wait for it to complete.
1108     */
1109    if ((error = ciss_synch_request(cr, 60 * 1000)) != 0) {
1110	ciss_printf(sc, "error sending BMIC LDRIVE command (%d)\n", error);
1111	goto out;
1112    }
1113
1114    /*
1115     * Check response.
1116     */
1117    ciss_report_request(cr, &command_status, NULL);
1118    switch(command_status) {
1119    case CISS_CMD_STATUS_SUCCESS:		/* buffer right size */
1120	break;
1121    case CISS_CMD_STATUS_DATA_UNDERRUN:
1122    case CISS_CMD_STATUS_DATA_OVERRUN:
1123	ciss_printf(sc, "data over/underrun reading logical drive ID\n");
1124    default:
1125	ciss_printf(sc, "error reading logical drive ID (%s)\n",
1126		    ciss_name_command_status(command_status));
1127	error = EIO;
1128	goto out;
1129    }
1130    ciss_release_request(cr);
1131    cr = NULL;
1132
1133    /*
1134     * Build a CISS BMIC command to get the logical drive status.
1135     */
1136    if ((error = ciss_get_ldrive_status(sc, ld)) != 0)
1137	goto out;
1138
1139    /*
1140     * Get the logical drive geometry.
1141     */
1142    if ((error = ciss_inquiry_logical(sc, ld)) != 0)
1143	goto out;
1144
1145    /*
1146     * Print the drive's basic characteristics.
1147     */
1148    if (1/*bootverbose*/) {
1149	ciss_printf(sc, "logical drive %d: %s, %dMB ",
1150		    cbc->log_drive, ciss_name_ldrive_org(ld->cl_ldrive->fault_tolerance),
1151		    ((ld->cl_ldrive->blocks_available / (1024 * 1024)) *
1152		     ld->cl_ldrive->block_size));
1153
1154	ciss_print_ldrive(sc, ld);
1155    }
1156out:
1157    if (error != 0) {
1158	/* make the drive not-exist */
1159	ld->cl_status = CISS_LD_NONEXISTENT;
1160	if (ld->cl_ldrive != NULL) {
1161	    free(ld->cl_ldrive, CISS_MALLOC_CLASS);
1162	    ld->cl_ldrive = NULL;
1163	}
1164	if (ld->cl_lstatus != NULL) {
1165	    free(ld->cl_lstatus, CISS_MALLOC_CLASS);
1166	    ld->cl_lstatus = NULL;
1167	}
1168    }
1169    if (cr != NULL)
1170	ciss_release_request(cr);
1171
1172    return(error);
1173}
1174
1175/************************************************************************
1176 * Get status for a logical drive.
1177 *
1178 * XXX should we also do this in response to Test Unit Ready?
1179 */
1180static int
1181ciss_get_ldrive_status(struct ciss_softc *sc,  struct ciss_ldrive *ld)
1182{
1183    struct ciss_request		*cr;
1184    struct ciss_command		*cc;
1185    struct ciss_bmic_cdb	*cbc;
1186    int				error, command_status;
1187
1188    /*
1189     * Build a CISS BMIC command to get the logical drive status.
1190     */
1191    if ((error = ciss_get_bmic_request(sc, &cr, CISS_BMIC_ID_LSTATUS,
1192				       (void **)&ld->cl_lstatus,
1193				       sizeof(*ld->cl_lstatus))) != 0)
1194	goto out;
1195    cc = CISS_FIND_COMMAND(cr);
1196    cbc = (struct ciss_bmic_cdb *)&(cc->cdb.cdb[0]);
1197    cbc->log_drive = ld->cl_address.logical.lun;
1198
1199    /*
1200     * Submit the request and wait for it to complete.
1201     */
1202    if ((error = ciss_synch_request(cr, 60 * 1000)) != 0) {
1203	ciss_printf(sc, "error sending BMIC LSTATUS command (%d)\n", error);
1204	goto out;
1205    }
1206
1207    /*
1208     * Check response.
1209     */
1210    ciss_report_request(cr, &command_status, NULL);
1211    switch(command_status) {
1212    case CISS_CMD_STATUS_SUCCESS:		/* buffer right size */
1213	break;
1214    case CISS_CMD_STATUS_DATA_UNDERRUN:
1215    case CISS_CMD_STATUS_DATA_OVERRUN:
1216	ciss_printf(sc, "data over/underrun reading logical drive status\n");
1217    default:
1218	ciss_printf(sc, "error reading logical drive status (%s)\n",
1219		    ciss_name_command_status(command_status));
1220	error = EIO;
1221	goto out;
1222    }
1223
1224    /*
1225     * Set the drive's summary status based on the returned status.
1226     *
1227     * XXX testing shows that a failed JBOD drive comes back at next
1228     * boot in "queued for expansion" mode.  WTF?
1229     */
1230    ld->cl_status = ciss_decode_ldrive_status(ld->cl_lstatus->status);
1231
1232out:
1233    if (cr != NULL)
1234	ciss_release_request(cr);
1235    return(error);
1236}
1237
1238/************************************************************************
1239 * Notify the adapter of a config update.
1240 */
1241static int
1242ciss_update_config(struct ciss_softc *sc)
1243{
1244    int		i;
1245
1246    debug_called(1);
1247
1248    CISS_TL_SIMPLE_WRITE(sc, CISS_TL_SIMPLE_IDBR, CISS_TL_SIMPLE_IDBR_CFG_TABLE);
1249    for (i = 0; i < 1000; i++) {
1250	if (!(CISS_TL_SIMPLE_READ(sc, CISS_TL_SIMPLE_IDBR) &
1251	      CISS_TL_SIMPLE_IDBR_CFG_TABLE)) {
1252	    return(0);
1253	}
1254	DELAY(1000);
1255    }
1256    return(1);
1257}
1258
1259/************************************************************************
1260 * Accept new media into a logical drive.
1261 *
1262 * XXX The drive has previously been offline; it would be good if we
1263 *     could make sure it's not open right now.
1264 */
1265static int
1266ciss_accept_media(struct ciss_softc *sc, int ldrive, int async)
1267{
1268    struct ciss_request		*cr;
1269    struct ciss_command		*cc;
1270    struct ciss_bmic_cdb	*cbc;
1271    int				error;
1272
1273    debug(0, "bringing logical drive %d back online %ssynchronously",
1274	  ldrive, async ? "a" : "");
1275
1276    /*
1277     * Build a CISS BMIC command to bring the drive back online.
1278     */
1279    if ((error = ciss_get_bmic_request(sc, &cr, CISS_BMIC_ACCEPT_MEDIA,
1280				       NULL, 0)) != 0)
1281	goto out;
1282    cc = CISS_FIND_COMMAND(cr);
1283    cbc = (struct ciss_bmic_cdb *)&(cc->cdb.cdb[0]);
1284    cbc->log_drive = ldrive;
1285
1286    /*
1287     * Dispatch the request asynchronously if we can't sleep waiting
1288     * for it to complete.
1289     */
1290    if (async) {
1291	cr->cr_complete = ciss_accept_media_complete;
1292	if ((error = ciss_start(cr)) != 0)
1293	    goto out;
1294	return(0);
1295    } else {
1296	/*
1297	 * Submit the request and wait for it to complete.
1298	 */
1299	if ((error = ciss_synch_request(cr, 60 * 1000)) != 0) {
1300	    ciss_printf(sc, "error sending BMIC LSTATUS command (%d)\n", error);
1301	    goto out;
1302	}
1303    }
1304
1305    /*
1306     * Call the completion callback manually.
1307     */
1308    ciss_accept_media_complete(cr);
1309    return(0);
1310
1311out:
1312    if (cr != NULL)
1313	ciss_release_request(cr);
1314    return(error);
1315}
1316
1317static void
1318ciss_accept_media_complete(struct ciss_request *cr)
1319{
1320    int				command_status;
1321
1322    /*
1323     * Check response.
1324     */
1325    ciss_report_request(cr, &command_status, NULL);
1326    switch(command_status) {
1327    case CISS_CMD_STATUS_SUCCESS:		/* all OK */
1328	/* we should get a logical drive status changed event here */
1329	break;
1330    default:
1331	ciss_printf(cr->cr_sc, "error accepting media into failed logical drive (%s)\n",
1332		    ciss_name_command_status(command_status));
1333	break;
1334    }
1335    ciss_release_request(cr);
1336}
1337
1338/************************************************************************
1339 * Release adapter resources.
1340 */
1341static void
1342ciss_free(struct ciss_softc *sc)
1343{
1344    debug_called(1);
1345
1346    /* we're going away */
1347    sc->ciss_flags |= CISS_FLAG_ABORTING;
1348
1349    /* terminate the periodic heartbeat routine */
1350    untimeout(ciss_periodic, sc, sc->ciss_periodic);
1351
1352    /* cancel the Event Notify chain */
1353    ciss_notify_abort(sc);
1354
1355    /* free the controller data */
1356    if (sc->ciss_id != NULL)
1357	free(sc->ciss_id, CISS_MALLOC_CLASS);
1358
1359    /* release I/O resources */
1360    if (sc->ciss_regs_resource != NULL)
1361	bus_release_resource(sc->ciss_dev, SYS_RES_MEMORY,
1362			     sc->ciss_regs_rid, sc->ciss_regs_resource);
1363    if (sc->ciss_cfg_resource != NULL)
1364	bus_release_resource(sc->ciss_dev, SYS_RES_MEMORY,
1365			     sc->ciss_cfg_rid, sc->ciss_cfg_resource);
1366    if (sc->ciss_intr != NULL)
1367	bus_teardown_intr(sc->ciss_dev, sc->ciss_irq_resource, sc->ciss_intr);
1368    if (sc->ciss_irq_resource != NULL)
1369	bus_release_resource(sc->ciss_dev, SYS_RES_IRQ,
1370			     sc->ciss_irq_rid, sc->ciss_irq_resource);
1371
1372    /* destroy DMA tags */
1373    if (sc->ciss_parent_dmat)
1374	bus_dma_tag_destroy(sc->ciss_parent_dmat);
1375    if (sc->ciss_buffer_dmat)
1376	bus_dma_tag_destroy(sc->ciss_buffer_dmat);
1377
1378    /* destroy command memory and DMA tag */
1379    if (sc->ciss_command != NULL) {
1380	bus_dmamap_unload(sc->ciss_command_dmat, sc->ciss_command_map);
1381	bus_dmamem_free(sc->ciss_command_dmat, sc->ciss_command, sc->ciss_command_map);
1382    }
1383    if (sc->ciss_buffer_dmat)
1384	bus_dma_tag_destroy(sc->ciss_command_dmat);
1385
1386    /* disconnect from CAM */
1387    if (sc->ciss_cam_sim) {
1388	xpt_bus_deregister(cam_sim_path(sc->ciss_cam_sim));
1389	cam_sim_free(sc->ciss_cam_sim, 0);
1390    }
1391    if (sc->ciss_cam_devq)
1392	cam_simq_free(sc->ciss_cam_devq);
1393    /* XXX what about ciss_cam_path? */
1394}
1395
1396/************************************************************************
1397 * Give a command to the adapter.
1398 *
1399 * Note that this uses the simple transport layer directly.  If we
1400 * want to add support for other layers, we'll need a switch of some
1401 * sort.
1402 *
1403 * Note that the simple transport layer has no way of refusing a
1404 * command; we only have as many request structures as the adapter
1405 * supports commands, so we don't have to check (this presumes that
1406 * the adapter can handle commands as fast as we throw them at it).
1407 */
1408static int
1409ciss_start(struct ciss_request *cr)
1410{
1411    struct ciss_command	*cc;	/* XXX debugging only */
1412    int			error;
1413
1414    cc = CISS_FIND_COMMAND(cr);
1415    debug(2, "post command %d tag %d ", cr->cr_tag, cc->header.host_tag);
1416
1417    /*
1418     * Map the request's data.
1419     */
1420    if ((error = ciss_map_request(cr)))
1421	return(error);
1422
1423#if 0
1424    ciss_print_request(cr);
1425#endif
1426
1427    /*
1428     * Post the command to the adapter.
1429     */
1430    ciss_enqueue_busy(cr);
1431    CISS_TL_SIMPLE_POST_CMD(cr->cr_sc, CISS_FIND_COMMANDPHYS(cr));
1432
1433    return(0);
1434}
1435
1436/************************************************************************
1437 * Fetch completed request(s) from the adapter, queue them for
1438 * completion handling.
1439 *
1440 * Note that this uses the simple transport layer directly.  If we
1441 * want to add support for other layers, we'll need a switch of some
1442 * sort.
1443 *
1444 * Note that the simple transport mechanism does not require any
1445 * reentrancy protection; the OPQ read is atomic.  If there is a
1446 * chance of a race with something else that might move the request
1447 * off the busy list, then we will have to lock against that
1448 * (eg. timeouts, etc.)
1449 */
1450static void
1451ciss_done(struct ciss_softc *sc)
1452{
1453    struct ciss_request	*cr;
1454    struct ciss_command	*cc;
1455    u_int32_t		tag, index;
1456    int			complete;
1457
1458    debug_called(3);
1459
1460    /*
1461     * Loop quickly taking requests from the adapter and moving them
1462     * from the busy queue to the completed queue.
1463     */
1464    complete = 0;
1465    for (;;) {
1466
1467	/* see if the OPQ contains anything */
1468	if (!CISS_TL_SIMPLE_OPQ_INTERRUPT(sc))
1469	    break;
1470
1471	tag = CISS_TL_SIMPLE_FETCH_CMD(sc);
1472	if (tag == CISS_TL_SIMPLE_OPQ_EMPTY)
1473	    break;
1474	index = tag >> 2;
1475	debug(2, "completed command %d%s", index,
1476	      (tag & CISS_HDR_HOST_TAG_ERROR) ? " with error" : "");
1477	if (index >= sc->ciss_max_requests) {
1478	    ciss_printf(sc, "completed invalid request %d (0x%x)\n", index, tag);
1479	    continue;
1480	}
1481	cr = &(sc->ciss_request[index]);
1482	cc = CISS_FIND_COMMAND(cr);
1483	cc->header.host_tag = tag;	/* not updated by adapter */
1484	if (ciss_remove_busy(cr)) {
1485	    /* assume this is garbage out of the adapter */
1486	    ciss_printf(sc, "completed nonbusy request %d\n", index);
1487	} else {
1488	    ciss_enqueue_complete(cr);
1489	}
1490	complete = 1;
1491    }
1492
1493    /*
1494     * Invoke completion processing.  If we can defer this out of
1495     * interrupt context, that'd be good.
1496     */
1497    if (complete)
1498	ciss_complete(sc);
1499}
1500
1501/************************************************************************
1502 * Take an interrupt from the adapter.
1503 */
1504static void
1505ciss_intr(void *arg)
1506{
1507    struct ciss_softc	*sc = (struct ciss_softc *)arg;
1508
1509    /*
1510     * The only interrupt we recognise indicates that there are
1511     * entries in the outbound post queue.
1512     */
1513    ciss_done(sc);
1514}
1515
1516/************************************************************************
1517 * Process completed requests.
1518 *
1519 * Requests can be completed in three fashions:
1520 *
1521 * - by invoking a callback function (cr_complete is non-null)
1522 * - by waking up a sleeper (cr_flags has CISS_REQ_SLEEP set)
1523 * - by clearing the CISS_REQ_POLL flag in interrupt/timeout context
1524 */
1525static void
1526ciss_complete(struct ciss_softc *sc)
1527{
1528    struct ciss_request	*cr;
1529
1530    debug_called(2);
1531
1532    /*
1533     * Loop taking requests off the completed queue and performing
1534     * completion processing on them.
1535     */
1536    for (;;) {
1537	if ((cr = ciss_dequeue_complete(sc)) == NULL)
1538	    break;
1539	ciss_unmap_request(cr);
1540
1541	/*
1542	 * If the request has a callback, invoke it.
1543	 */
1544	if (cr->cr_complete != NULL) {
1545	    cr->cr_complete(cr);
1546	    continue;
1547	}
1548
1549	/*
1550	 * If someone is sleeping on this request, wake them up.
1551	 */
1552	if (cr->cr_flags & CISS_REQ_SLEEP) {
1553	    cr->cr_flags &= ~CISS_REQ_SLEEP;
1554	    wakeup(cr);
1555	    continue;
1556	}
1557
1558	/*
1559	 * If someone is polling this request for completion, signal.
1560	 */
1561	if (cr->cr_flags & CISS_REQ_POLL) {
1562	    cr->cr_flags &= ~CISS_REQ_POLL;
1563	    continue;
1564	}
1565
1566	/*
1567	 * Give up and throw the request back on the free queue.  This
1568	 * should never happen; resources will probably be lost.
1569	 */
1570	ciss_printf(sc, "WARNING: completed command with no submitter\n");
1571	ciss_enqueue_free(cr);
1572    }
1573}
1574
1575/************************************************************************
1576 * Report on the completion status of a request, and pass back SCSI
1577 * and command status values.
1578 */
1579static int
1580ciss_report_request(struct ciss_request *cr, int *command_status, int *scsi_status)
1581{
1582    struct ciss_command		*cc;
1583    struct ciss_error_info	*ce;
1584
1585    debug_called(2);
1586
1587    cc = CISS_FIND_COMMAND(cr);
1588    ce = (struct ciss_error_info *)&(cc->sg[0]);
1589
1590    /*
1591     * We don't consider data under/overrun an error for the Report
1592     * Logical/Physical LUNs commands.
1593     */
1594    if ((cc->header.host_tag & CISS_HDR_HOST_TAG_ERROR) &&
1595	((cc->cdb.cdb[0] == CISS_OPCODE_REPORT_LOGICAL_LUNS) ||
1596	 (cc->cdb.cdb[0] == CISS_OPCODE_REPORT_PHYSICAL_LUNS))) {
1597	cc->header.host_tag &= ~CISS_HDR_HOST_TAG_ERROR;
1598	debug(2, "ignoring irrelevant under/overrun error");
1599    }
1600
1601    /*
1602     * Check the command's error bit, if clear, there's no status and
1603     * everything is OK.
1604     */
1605    if (!(cc->header.host_tag & CISS_HDR_HOST_TAG_ERROR)) {
1606	if (scsi_status != NULL)
1607	    *scsi_status = SCSI_STATUS_OK;
1608	if (command_status != NULL)
1609	    *command_status = CISS_CMD_STATUS_SUCCESS;
1610	return(0);
1611    } else {
1612	if (command_status != NULL)
1613	    *command_status = ce->command_status;
1614	if (scsi_status != NULL) {
1615	    if (ce->command_status == CISS_CMD_STATUS_TARGET_STATUS) {
1616		*scsi_status = ce->scsi_status;
1617	    } else {
1618		*scsi_status = -1;
1619	    }
1620	}
1621	if (bootverbose)
1622	    ciss_printf(cr->cr_sc, "command status 0x%x (%s) scsi status 0x%x\n",
1623			ce->command_status, ciss_name_command_status(ce->command_status),
1624			ce->scsi_status);
1625	if (ce->command_status == CISS_CMD_STATUS_INVALID_COMMAND) {
1626	    ciss_printf(cr->cr_sc, "invalid command, offense size %d at %d, value 0x%x\n",
1627			ce->additional_error_info.invalid_command.offense_size,
1628			ce->additional_error_info.invalid_command.offense_offset,
1629			ce->additional_error_info.invalid_command.offense_value);
1630	}
1631    }
1632    return(1);
1633}
1634
1635/************************************************************************
1636 * Issue a request and don't return until it's completed.
1637 *
1638 * Depending on adapter status, we may poll or sleep waiting for
1639 * completion.
1640 */
1641static int
1642ciss_synch_request(struct ciss_request *cr, int timeout)
1643{
1644    if (cr->cr_sc->ciss_flags & CISS_FLAG_RUNNING) {
1645	return(ciss_wait_request(cr, timeout));
1646    } else {
1647	return(ciss_poll_request(cr, timeout));
1648    }
1649}
1650
1651/************************************************************************
1652 * Issue a request and poll for completion.
1653 *
1654 * Timeout in milliseconds.
1655 */
1656static int
1657ciss_poll_request(struct ciss_request *cr, int timeout)
1658{
1659    int		error;
1660
1661    debug_called(2);
1662
1663    cr->cr_flags |= CISS_REQ_POLL;
1664    if ((error = ciss_start(cr)) != 0)
1665	return(error);
1666
1667    do {
1668	ciss_done(cr->cr_sc);
1669	if (!(cr->cr_flags & CISS_REQ_POLL))
1670	    return(0);
1671	DELAY(1000);
1672    } while (timeout-- >= 0);
1673    return(EWOULDBLOCK);
1674}
1675
1676/************************************************************************
1677 * Issue a request and sleep waiting for completion.
1678 *
1679 * Timeout in milliseconds.  Note that a spurious wakeup will reset
1680 * the timeout.
1681 */
1682static int
1683ciss_wait_request(struct ciss_request *cr, int timeout)
1684{
1685    int		s, error;
1686
1687    debug_called(2);
1688
1689    cr->cr_flags |= CISS_REQ_SLEEP;
1690    if ((error = ciss_start(cr)) != 0)
1691	return(error);
1692
1693    s = splcam();
1694    while (cr->cr_flags & CISS_REQ_SLEEP) {
1695	error = tsleep(cr, PCATCH, "cissREQ", (timeout * hz) / 1000);
1696	/*
1697	 * On wakeup or interruption due to restartable activity, go
1698	 * back and check to see if we're done.
1699	 */
1700	if ((error == 0) || (error == ERESTART)) {
1701	    error = 0;
1702	    continue;
1703	}
1704	/*
1705	 * Timeout, interrupted system call, etc.
1706	 */
1707	break;
1708    }
1709    splx(s);
1710    return(error);
1711}
1712
1713#if 0
1714/************************************************************************
1715 * Abort a request.  Note that a potential exists here to race the
1716 * request being completed; the caller must deal with this.
1717 */
1718static int
1719ciss_abort_request(struct ciss_request *ar)
1720{
1721    struct ciss_request		*cr;
1722    struct ciss_command		*cc;
1723    struct ciss_message_cdb	*cmc;
1724    int				error;
1725
1726    debug_called(1);
1727
1728    /* get a request */
1729    if ((error = ciss_get_request(ar->cr_sc, &cr)) != 0)
1730	return(error);
1731
1732    /* build the abort command */
1733    cc = CISS_FIND_COMMAND(cr);
1734    cc->header.address.mode.mode = CISS_HDR_ADDRESS_MODE_PERIPHERAL;	/* addressing? */
1735    cc->header.address.physical.target = 0;
1736    cc->header.address.physical.bus = 0;
1737    cc->cdb.cdb_length = sizeof(*cmc);
1738    cc->cdb.type = CISS_CDB_TYPE_MESSAGE;
1739    cc->cdb.attribute = CISS_CDB_ATTRIBUTE_SIMPLE;
1740    cc->cdb.direction = CISS_CDB_DIRECTION_NONE;
1741    cc->cdb.timeout = 30;
1742
1743    cmc = (struct ciss_message_cdb *)&(cc->cdb.cdb[0]);
1744    cmc->opcode = CISS_OPCODE_MESSAGE_ABORT;
1745    cmc->type = CISS_MESSAGE_ABORT_TASK;
1746    cmc->abort_tag = ar->cr_tag;	/* endianness?? */
1747
1748    /*
1749     * Send the request and wait for a response.  If we believe we
1750     * aborted the request OK, clear the flag that indicates it's
1751     * running.
1752     */
1753    error = ciss_synch_request(cr, 35 * 1000);
1754    if (!error)
1755	error = ciss_report_request(cr, NULL, NULL);
1756    ciss_release_request(cr);
1757
1758    return(error);
1759}
1760#endif
1761
1762
1763/************************************************************************
1764 * Fetch and initialise a request
1765 */
1766static int
1767ciss_get_request(struct ciss_softc *sc, struct ciss_request **crp)
1768{
1769    struct ciss_request *cr;
1770
1771    debug_called(2);
1772
1773    /*
1774     * Get a request and clean it up.
1775     */
1776    if ((cr = ciss_dequeue_free(sc)) == NULL)
1777	return(ENOMEM);
1778
1779    cr->cr_data = NULL;
1780    cr->cr_flags = 0;
1781    cr->cr_complete = NULL;
1782
1783    ciss_preen_command(cr);
1784    *crp = cr;
1785    return(0);
1786}
1787
1788static void
1789ciss_preen_command(struct ciss_request *cr)
1790{
1791    struct ciss_command	*cc;
1792    u_int32_t		cmdphys;
1793
1794    /*
1795     * Clean up the command structure.
1796     *
1797     * Note that we set up the error_info structure here, since the
1798     * length can be overwritten by any command.
1799     */
1800    cc = CISS_FIND_COMMAND(cr);
1801    cc->header.sg_in_list = 0;		/* kinda inefficient this way */
1802    cc->header.sg_total = 0;
1803    cc->header.host_tag = cr->cr_tag << 2;
1804    cc->header.host_tag_zeroes = 0;
1805    cmdphys = CISS_FIND_COMMANDPHYS(cr);
1806    cc->error_info.error_info_address = cmdphys + sizeof(struct ciss_command);
1807    cc->error_info.error_info_length = CISS_COMMAND_ALLOC_SIZE - sizeof(struct ciss_command);
1808
1809}
1810
1811/************************************************************************
1812 * Release a request to the free list.
1813 */
1814static void
1815ciss_release_request(struct ciss_request *cr)
1816{
1817    struct ciss_softc	*sc;
1818
1819    debug_called(2);
1820
1821    sc = cr->cr_sc;
1822
1823    /* release the request to the free queue */
1824    ciss_requeue_free(cr);
1825}
1826
1827/************************************************************************
1828 * Allocate a request that will be used to send a BMIC command.  Do some
1829 * of the common setup here to avoid duplicating it everywhere else.
1830 */
1831static int
1832ciss_get_bmic_request(struct ciss_softc *sc, struct ciss_request **crp,
1833		      int opcode, void **bufp, size_t bufsize)
1834{
1835    struct ciss_request		*cr;
1836    struct ciss_command		*cc;
1837    struct ciss_bmic_cdb	*cbc;
1838    void			*buf;
1839    int				error;
1840    int				dataout;
1841
1842    debug_called(2);
1843
1844    cr = NULL;
1845    buf = NULL;
1846
1847    /*
1848     * Get a request.
1849     */
1850    if ((error = ciss_get_request(sc, &cr)) != 0)
1851	goto out;
1852
1853    /*
1854     * Allocate data storage if requested, determine the data direction.
1855     */
1856    dataout = 0;
1857    if ((bufsize > 0) && (bufp != NULL)) {
1858	if (*bufp == NULL) {
1859	    if ((buf = malloc(bufsize, CISS_MALLOC_CLASS, M_NOWAIT | M_ZERO)) == NULL) {
1860		error = ENOMEM;
1861		goto out;
1862	    }
1863	} else {
1864	    buf = *bufp;
1865	    dataout = 1;	/* we are given a buffer, so we are writing */
1866	}
1867    }
1868
1869    /*
1870     * Build a CISS BMIC command to get the logical drive ID.
1871     */
1872    cr->cr_data = buf;
1873    cr->cr_length = bufsize;
1874    if (!dataout)
1875	cr->cr_flags = CISS_REQ_DATAIN;
1876
1877    cc = CISS_FIND_COMMAND(cr);
1878    cc->header.address.physical.mode = CISS_HDR_ADDRESS_MODE_PERIPHERAL;
1879    cc->header.address.physical.bus = 0;
1880    cc->header.address.physical.target = 0;
1881    cc->cdb.cdb_length = sizeof(*cbc);
1882    cc->cdb.type = CISS_CDB_TYPE_COMMAND;
1883    cc->cdb.attribute = CISS_CDB_ATTRIBUTE_SIMPLE;
1884    cc->cdb.direction = dataout ? CISS_CDB_DIRECTION_WRITE : CISS_CDB_DIRECTION_READ;
1885    cc->cdb.timeout = 0;
1886
1887    cbc = (struct ciss_bmic_cdb *)&(cc->cdb.cdb[0]);
1888    bzero(cbc, sizeof(*cbc));
1889    cbc->opcode = dataout ? CISS_ARRAY_CONTROLLER_WRITE : CISS_ARRAY_CONTROLLER_READ;
1890    cbc->bmic_opcode = opcode;
1891    cbc->size = htons((u_int16_t)bufsize);
1892
1893out:
1894    if (error) {
1895	if (cr != NULL)
1896	    ciss_release_request(cr);
1897	if ((bufp != NULL) && (*bufp == NULL) && (buf != NULL))
1898	    free(buf, CISS_MALLOC_CLASS);
1899    } else {
1900	*crp = cr;
1901	if ((bufp != NULL) && (*bufp == NULL) && (buf != NULL))
1902	    *bufp = buf;
1903    }
1904    return(error);
1905}
1906
1907/************************************************************************
1908 * Handle a command passed in from userspace.
1909 */
1910static int
1911ciss_user_command(struct ciss_softc *sc, IOCTL_Command_struct *ioc)
1912{
1913    struct ciss_request		*cr;
1914    struct ciss_command		*cc;
1915    struct ciss_error_info	*ce;
1916    int				error;
1917
1918    debug_called(1);
1919
1920    cr = NULL;
1921
1922    /*
1923     * Get a request.
1924     */
1925    if ((error = ciss_get_request(sc, &cr)) != 0)
1926	goto out;
1927    cc = CISS_FIND_COMMAND(cr);
1928
1929    /*
1930     * Allocate an in-kernel databuffer if required, copy in user data.
1931     */
1932    cr->cr_length = ioc->buf_size;
1933    if (ioc->buf_size > 0) {
1934	if ((cr->cr_data = malloc(ioc->buf_size, CISS_MALLOC_CLASS, M_WAITOK)) == NULL) {
1935	    error = ENOMEM;
1936	    goto out;
1937	}
1938	if ((error = copyin(ioc->buf, cr->cr_data, ioc->buf_size))) {
1939	    debug(0, "copyin: bad data buffer %p/%d", ioc->buf, ioc->buf_size);
1940	    goto out;
1941	}
1942    }
1943
1944    /*
1945     * Build the request based on the user command.
1946     */
1947    bcopy(&ioc->LUN_info, &cc->header.address, sizeof(cc->header.address));
1948    bcopy(&ioc->Request, &cc->cdb, sizeof(cc->cdb));
1949
1950    /* XXX anything else to populate here? */
1951
1952    /*
1953     * Run the command.
1954     */
1955    if ((error = ciss_synch_request(cr, 60 * 1000))) {
1956	debug(0, "request failed - %d", error);
1957	goto out;
1958    }
1959
1960    /*
1961     * Copy the results back to the user.
1962     */
1963    ce = (struct ciss_error_info *)&(cc->sg[0]);
1964    bcopy(ce, &ioc->error_info, sizeof(*ce));
1965    if ((ioc->buf_size > 0) &&
1966	(error = copyout(cr->cr_data, ioc->buf, ioc->buf_size))) {
1967	debug(0, "copyout: bad data buffer %p/%d", ioc->buf, ioc->buf_size);
1968	goto out;
1969    }
1970
1971    /* done OK */
1972    error = 0;
1973
1974out:
1975    if ((cr != NULL) && (cr->cr_data != NULL))
1976	free(cr->cr_data, CISS_MALLOC_CLASS);
1977    if (cr != NULL)
1978	ciss_release_request(cr);
1979    return(error);
1980}
1981
1982/************************************************************************
1983 * Map a request into bus-visible space, initialise the scatter/gather
1984 * list.
1985 */
1986static int
1987ciss_map_request(struct ciss_request *cr)
1988{
1989    struct ciss_softc	*sc;
1990
1991    debug_called(2);
1992
1993    sc = cr->cr_sc;
1994
1995    /* check that mapping is necessary */
1996    if ((cr->cr_flags & CISS_REQ_MAPPED) || (cr->cr_data == NULL))
1997	return(0);
1998
1999    bus_dmamap_load(sc->ciss_buffer_dmat, cr->cr_datamap, cr->cr_data, cr->cr_length,
2000		    ciss_request_map_helper, CISS_FIND_COMMAND(cr), 0);
2001
2002    if (cr->cr_flags & CISS_REQ_DATAIN)
2003	bus_dmamap_sync(sc->ciss_buffer_dmat, cr->cr_datamap, BUS_DMASYNC_PREREAD);
2004    if (cr->cr_flags & CISS_REQ_DATAOUT)
2005	bus_dmamap_sync(sc->ciss_buffer_dmat, cr->cr_datamap, BUS_DMASYNC_PREWRITE);
2006
2007    cr->cr_flags |= CISS_REQ_MAPPED;
2008    return(0);
2009}
2010
2011static void
2012ciss_request_map_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error)
2013{
2014    struct ciss_command	*cc;
2015    int			i;
2016
2017    debug_called(2);
2018
2019    cc = (struct ciss_command *)arg;
2020    for (i = 0; i < nseg; i++) {
2021	cc->sg[i].address = segs[i].ds_addr;
2022	cc->sg[i].length = segs[i].ds_len;
2023	cc->sg[i].extension = 0;
2024    }
2025    /* we leave the s/g table entirely within the command */
2026    cc->header.sg_in_list = nseg;
2027    cc->header.sg_total = nseg;
2028}
2029
2030/************************************************************************
2031 * Unmap a request from bus-visible space.
2032 */
2033static void
2034ciss_unmap_request(struct ciss_request *cr)
2035{
2036    struct ciss_softc	*sc;
2037
2038    debug_called(2);
2039
2040    sc = cr->cr_sc;
2041
2042    /* check that unmapping is necessary */
2043    if (!(cr->cr_flags & CISS_REQ_MAPPED) || (cr->cr_data == NULL))
2044	return;
2045
2046    if (cr->cr_flags & CISS_REQ_DATAIN)
2047	bus_dmamap_sync(sc->ciss_buffer_dmat, cr->cr_datamap, BUS_DMASYNC_POSTREAD);
2048    if (cr->cr_flags & CISS_REQ_DATAOUT)
2049	bus_dmamap_sync(sc->ciss_buffer_dmat, cr->cr_datamap, BUS_DMASYNC_POSTWRITE);
2050
2051    bus_dmamap_unload(sc->ciss_buffer_dmat, cr->cr_datamap);
2052    cr->cr_flags &= ~CISS_REQ_MAPPED;
2053}
2054
2055/************************************************************************
2056 * Attach the driver to CAM.
2057 *
2058 * We put all the logical drives on a single SCSI bus.
2059 */
2060static int
2061ciss_cam_init(struct ciss_softc *sc)
2062{
2063
2064    debug_called(1);
2065
2066    /*
2067     * Allocate a devq.  We can reuse this for the masked physical
2068     * devices if we decide to export these as well.
2069     */
2070    if ((sc->ciss_cam_devq = cam_simq_alloc(sc->ciss_max_requests)) == NULL) {
2071	ciss_printf(sc, "can't allocate CAM SIM queue\n");
2072	return(ENOMEM);
2073    }
2074
2075    /*
2076     * Create a SIM.
2077     */
2078    if ((sc->ciss_cam_sim = cam_sim_alloc(ciss_cam_action, ciss_cam_poll, "ciss", sc,
2079					  device_get_unit(sc->ciss_dev),
2080					  sc->ciss_max_requests - 2,
2081					  1,
2082					  sc->ciss_cam_devq)) == NULL) {
2083	ciss_printf(sc, "can't allocate CAM SIM\n");
2084	return(ENOMEM);
2085    }
2086
2087    /*
2088     * Register bus 0 (the 'logical drives' bus) with this SIM.
2089     */
2090    if (xpt_bus_register(sc->ciss_cam_sim, 0) != 0) {
2091	ciss_printf(sc, "can't register SCSI bus 0\n");
2092	return(ENXIO);
2093    }
2094
2095    /*
2096     * Initiate a rescan of the bus.
2097     */
2098    ciss_cam_rescan_all(sc);
2099
2100    return(0);
2101}
2102
2103/************************************************************************
2104 * Initiate a rescan of the 'logical devices' SIM
2105 */
2106static void
2107ciss_cam_rescan_target(struct ciss_softc *sc, int target)
2108{
2109    union ccb	*ccb;
2110
2111    debug_called(1);
2112
2113    if ((ccb = malloc(sizeof(union ccb), M_TEMP, M_WAITOK | M_ZERO)) == NULL) {
2114	ciss_printf(sc, "rescan failed (can't allocate CCB)\n");
2115	return;
2116    }
2117
2118    if (xpt_create_path(&sc->ciss_cam_path, xpt_periph, cam_sim_path(sc->ciss_cam_sim), target, 0)
2119	!= CAM_REQ_CMP) {
2120	ciss_printf(sc, "rescan failed (can't create path)\n");
2121	return;
2122    }
2123
2124    xpt_setup_ccb(&ccb->ccb_h, sc->ciss_cam_path, 5/*priority (low)*/);
2125    ccb->ccb_h.func_code = XPT_SCAN_BUS;
2126    ccb->ccb_h.cbfcnp = ciss_cam_rescan_callback;
2127    ccb->crcn.flags = CAM_FLAG_NONE;
2128    xpt_action(ccb);
2129
2130    /* scan is now in progress */
2131}
2132
2133static void
2134ciss_cam_rescan_all(struct ciss_softc *sc)
2135{
2136    return(ciss_cam_rescan_target(sc, 0));
2137}
2138
2139static void
2140ciss_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb)
2141{
2142    xpt_free_path(ccb->ccb_h.path);
2143    free(ccb, M_TEMP);
2144}
2145
2146/************************************************************************
2147 * Handle requests coming from CAM
2148 */
2149static void
2150ciss_cam_action(struct cam_sim *sim, union ccb *ccb)
2151{
2152    struct ciss_softc	*sc;
2153    struct ccb_scsiio	*csio;
2154    int			target;
2155
2156    sc = cam_sim_softc(sim);
2157    csio = (struct ccb_scsiio *)&ccb->csio;
2158    target = csio->ccb_h.target_id;
2159
2160    switch (ccb->ccb_h.func_code) {
2161
2162	/* perform SCSI I/O */
2163    case XPT_SCSI_IO:
2164	if (!ciss_cam_action_io(sim, csio))
2165	    return;
2166	break;
2167
2168	/* perform geometry calculations */
2169    case XPT_CALC_GEOMETRY:
2170    {
2171	struct ccb_calc_geometry	*ccg = &ccb->ccg;
2172	struct ciss_ldrive		*ld = &sc->ciss_logical[target];
2173
2174	debug(1, "XPT_CALC_GEOMETRY %d:%d:%d", cam_sim_bus(sim), ccb->ccb_h.target_id, ccb->ccb_h.target_lun);
2175
2176	/*
2177	 * Use the cached geometry settings unless the fault tolerance
2178	 * is invalid.
2179	 */
2180	if (ld->cl_geometry.fault_tolerance == 0xFF) {
2181	    u_int32_t			secs_per_cylinder;
2182
2183	    ccg->heads = 255;
2184	    ccg->secs_per_track = 32;
2185	    secs_per_cylinder = ccg->heads * ccg->secs_per_track;
2186	    ccg->cylinders = ccg->volume_size / secs_per_cylinder;
2187	} else {
2188	    ccg->heads = ld->cl_geometry.heads;
2189	    ccg->secs_per_track = ld->cl_geometry.sectors;
2190	    ccg->cylinders = ntohs(ld->cl_geometry.cylinders);
2191	}
2192	ccb->ccb_h.status = CAM_REQ_CMP;
2193        break;
2194    }
2195
2196	/* handle path attribute inquiry */
2197    case XPT_PATH_INQ:
2198    {
2199	struct ccb_pathinq	*cpi = &ccb->cpi;
2200
2201	debug(1, "XPT_PATH_INQ %d:%d:%d", cam_sim_bus(sim), ccb->ccb_h.target_id, ccb->ccb_h.target_lun);
2202
2203	cpi->version_num = 1;
2204	cpi->hba_inquiry = PI_TAG_ABLE;	/* XXX is this correct? */
2205	cpi->target_sprt = 0;
2206	cpi->hba_misc = 0;
2207	cpi->max_target = CISS_MAX_LOGICAL;
2208	cpi->max_lun = 0;		/* 'logical drive' channel only */
2209	cpi->initiator_id = CISS_MAX_LOGICAL;
2210	strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
2211        strncpy(cpi->hba_vid, "msmith@freebsd.org", HBA_IDLEN);
2212        strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
2213        cpi->unit_number = cam_sim_unit(sim);
2214        cpi->bus_id = cam_sim_bus(sim);
2215	cpi->base_transfer_speed = 132 * 1024;	/* XXX what to set this to? */
2216	ccb->ccb_h.status = CAM_REQ_CMP;
2217	break;
2218    }
2219
2220    case XPT_GET_TRAN_SETTINGS:
2221    {
2222	struct ccb_trans_settings	*cts = &ccb->cts;
2223	int				bus, target;
2224
2225	bus = cam_sim_bus(sim);
2226	target = cts->ccb_h.target_id;
2227
2228	debug(1, "XPT_GET_TRAN_SETTINGS %d:%d", bus, target);
2229	cts->valid = 0;
2230
2231	/* disconnect always OK */
2232	cts->flags |= CCB_TRANS_DISC_ENB;
2233	cts->valid |= CCB_TRANS_DISC_VALID;
2234
2235	cts->ccb_h.status = CAM_REQ_CMP;
2236	break;
2237    }
2238
2239    default:		/* we can't do this */
2240	debug(1, "unspported func_code = 0x%x", ccb->ccb_h.func_code);
2241	ccb->ccb_h.status = CAM_REQ_INVALID;
2242	break;
2243    }
2244
2245    xpt_done(ccb);
2246}
2247
2248/************************************************************************
2249 * Handle a CAM SCSI I/O request.
2250 */
2251static int
2252ciss_cam_action_io(struct cam_sim *sim, struct ccb_scsiio *csio)
2253{
2254    struct ciss_softc	*sc;
2255    int			bus, target;
2256    struct ciss_request	*cr;
2257    struct ciss_command	*cc;
2258    int			error;
2259
2260    sc = cam_sim_softc(sim);
2261    bus = cam_sim_bus(sim);
2262    target = csio->ccb_h.target_id;
2263
2264    debug(2, "XPT_SCSI_IO %d:%d:%d", bus, target, csio->ccb_h.target_lun);
2265
2266    /* check for I/O attempt to nonexistent device */
2267    if ((bus != 0) ||
2268	(target > CISS_MAX_LOGICAL) ||
2269	(sc->ciss_logical[target].cl_status == CISS_LD_NONEXISTENT)) {
2270	debug(3, "  device does not exist");
2271	csio->ccb_h.status = CAM_REQ_CMP_ERR;
2272    }
2273
2274    /* firmware does not support commands > 10 bytes */
2275    if (csio->cdb_len > 12/*CISS_CDB_BUFFER_SIZE*/) {
2276	debug(3, "  command too large (%d > %d)", csio->cdb_len, CISS_CDB_BUFFER_SIZE);
2277	csio->ccb_h.status = CAM_REQ_CMP_ERR;
2278    }
2279
2280    /* check that the CDB pointer is not to a physical address */
2281    if ((csio->ccb_h.flags & CAM_CDB_POINTER) && (csio->ccb_h.flags & CAM_CDB_PHYS)) {
2282	debug(3, "  CDB pointer is to physical address");
2283	csio->ccb_h.status = CAM_REQ_CMP_ERR;
2284    }
2285
2286    /* if there is data transfer, it must be to/from a virtual address */
2287    if ((csio->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
2288	if (csio->ccb_h.flags & CAM_DATA_PHYS) {		/* we can't map it */
2289	    debug(3, "  data pointer is to physical address");
2290	    csio->ccb_h.status = CAM_REQ_CMP_ERR;
2291	}
2292	if (csio->ccb_h.flags & CAM_SCATTER_VALID) {	/* we want to do the s/g setup */
2293	    debug(3, "  data has premature s/g setup");
2294	    csio->ccb_h.status = CAM_REQ_CMP_ERR;
2295	}
2296    }
2297
2298    /* abandon aborted ccbs or those that have failed validation */
2299    if ((csio->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_INPROG) {
2300	debug(3, "abandoning CCB due to abort/validation failure");
2301	return(EINVAL);
2302    }
2303
2304    /* handle emulation of some SCSI commands ourself */
2305    if (ciss_cam_emulate(sc, csio))
2306	return(0);
2307
2308    /*
2309     * Get a request to manage this command.  If we can't, return the
2310     * ccb, freeze the queue and flag so that we unfreeze it when a
2311     * request completes.
2312     */
2313    if ((error = ciss_get_request(sc, &cr)) != 0) {
2314	xpt_freeze_simq(sc->ciss_cam_sim, 1);
2315	csio->ccb_h.status |= CAM_REQUEUE_REQ;
2316	return(error);
2317    }
2318
2319    /*
2320     * Build the command.
2321     */
2322    cc = CISS_FIND_COMMAND(cr);
2323    cr->cr_data = csio->data_ptr;
2324    cr->cr_length = csio->dxfer_len;
2325    cr->cr_complete = ciss_cam_complete;
2326    cr->cr_private = csio;
2327
2328    cc->header.address.logical.mode = CISS_HDR_ADDRESS_MODE_LOGICAL;
2329    cc->header.address.logical.lun = target;
2330    cc->cdb.cdb_length = csio->cdb_len;
2331    cc->cdb.type = CISS_CDB_TYPE_COMMAND;
2332    cc->cdb.attribute = CISS_CDB_ATTRIBUTE_SIMPLE;	/* XXX ordered tags? */
2333    if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) {
2334	cr->cr_flags = CISS_REQ_DATAOUT;
2335	cc->cdb.direction = CISS_CDB_DIRECTION_WRITE;
2336    } else if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
2337	cr->cr_flags = CISS_REQ_DATAIN;
2338	cc->cdb.direction = CISS_CDB_DIRECTION_READ;
2339    } else {
2340	cr->cr_flags = 0;
2341	cc->cdb.direction = CISS_CDB_DIRECTION_NONE;
2342    }
2343    cc->cdb.timeout = (csio->ccb_h.timeout / 1000) + 1;
2344    if (csio->ccb_h.flags & CAM_CDB_POINTER) {
2345	bcopy(csio->cdb_io.cdb_ptr, &cc->cdb.cdb[0], csio->cdb_len);
2346    } else {
2347	bcopy(csio->cdb_io.cdb_bytes, &cc->cdb.cdb[0], csio->cdb_len);
2348    }
2349
2350    /*
2351     * Submit the request to the adapter.
2352     *
2353     * Note that this may fail if we're unable to map the request (and
2354     * if we ever learn a transport layer other than simple, may fail
2355     * if the adapter rejects the command).
2356     */
2357    if ((error = ciss_start(cr)) != 0) {
2358	xpt_freeze_simq(sc->ciss_cam_sim, 1);
2359	csio->ccb_h.status |= CAM_REQUEUE_REQ;
2360	ciss_release_request(cr);
2361	return(error);
2362    }
2363
2364    return(0);
2365}
2366
2367/************************************************************************
2368 * Emulate SCSI commands the adapter doesn't handle as we might like.
2369 */
2370static int
2371ciss_cam_emulate(struct ciss_softc *sc, struct ccb_scsiio *csio)
2372{
2373    int		target;
2374    u_int8_t	opcode;
2375
2376
2377    target = csio->ccb_h.target_id;
2378    opcode = (csio->ccb_h.flags & CAM_CDB_POINTER) ?
2379	*(u_int8_t *)csio->cdb_io.cdb_ptr : csio->cdb_io.cdb_bytes[0];
2380
2381    /*
2382     * Handle requests for volumes that don't exist.  A selection timeout
2383     * is slightly better than an illegal request.  Other errors might be
2384     * better.
2385     */
2386    if (sc->ciss_logical[target].cl_status == CISS_LD_NONEXISTENT) {
2387	csio->ccb_h.status = CAM_SEL_TIMEOUT;
2388	xpt_done((union ccb *)csio);
2389	return(1);
2390    }
2391
2392    /*
2393     * Handle requests for volumes that exist but are offline.
2394     *
2395     * I/O operations should fail, everything else should work.
2396     */
2397    if (sc->ciss_logical[target].cl_status == CISS_LD_OFFLINE) {
2398	switch(opcode) {
2399	case READ_6:
2400	case READ_10:
2401	case READ_12:
2402	case WRITE_6:
2403	case WRITE_10:
2404	case WRITE_12:
2405	    csio->ccb_h.status = CAM_SEL_TIMEOUT;
2406	    xpt_done((union ccb *)csio);
2407	    return(1);
2408	}
2409    }
2410
2411
2412    /* if we have to fake Synchronise Cache */
2413    if (sc->ciss_flags & CISS_FLAG_FAKE_SYNCH) {
2414
2415	/*
2416	 * If this is a Synchronise Cache command, typically issued when
2417	 * a device is closed, flush the adapter and complete now.
2418	 */
2419	if (((csio->ccb_h.flags & CAM_CDB_POINTER) ?
2420	     *(u_int8_t *)csio->cdb_io.cdb_ptr : csio->cdb_io.cdb_bytes[0]) == SYNCHRONIZE_CACHE) {
2421	    ciss_flush_adapter(sc);
2422	    csio->ccb_h.status = CAM_REQ_CMP;
2423	    xpt_done((union ccb *)csio);
2424	    return(1);
2425	}
2426    }
2427
2428    return(0);
2429}
2430
2431/************************************************************************
2432 * Check for possibly-completed commands.
2433 */
2434static void
2435ciss_cam_poll(struct cam_sim *sim)
2436{
2437    struct ciss_softc	*sc = cam_sim_softc(sim);
2438
2439    debug_called(2);
2440
2441    ciss_done(sc);
2442}
2443
2444/************************************************************************
2445 * Handle completion of a command - pass results back through the CCB
2446 */
2447static void
2448ciss_cam_complete(struct ciss_request *cr)
2449{
2450    struct ciss_softc		*sc;
2451    struct ciss_command		*cc;
2452    struct ciss_error_info	*ce;
2453    struct ccb_scsiio		*csio;
2454    int				scsi_status;
2455    int				command_status;
2456
2457    debug_called(2);
2458
2459    sc = cr->cr_sc;
2460    cc = CISS_FIND_COMMAND(cr);
2461    ce = (struct ciss_error_info *)&(cc->sg[0]);
2462    csio = (struct ccb_scsiio *)cr->cr_private;
2463
2464    /*
2465     * Extract status values from request.
2466     */
2467    ciss_report_request(cr, &command_status, &scsi_status);
2468    csio->scsi_status = scsi_status;
2469
2470    /*
2471     * Handle specific SCSI status values.
2472     */
2473    switch(scsi_status) {
2474	/* no status due to adapter error */
2475    case -1:
2476	debug(0, "adapter error");
2477	csio->ccb_h.status = CAM_REQ_CMP_ERR;
2478	break;
2479
2480	/* no status due to command completed OK */
2481    case SCSI_STATUS_OK:		/* CISS_SCSI_STATUS_GOOD */
2482	debug(2, "SCSI_STATUS_OK");
2483	csio->ccb_h.status = CAM_REQ_CMP;
2484	break;
2485
2486	/* check condition, sense data included */
2487    case SCSI_STATUS_CHECK_COND:	/* CISS_SCSI_STATUS_CHECK_CONDITION */
2488	debug(0, "SCSI_STATUS_CHECK_COND  sense size %d  resid %d",
2489	      ce->sense_length, ce->residual_count);
2490	bzero(&csio->sense_data, SSD_FULL_SIZE);
2491	bcopy(&ce->sense_info[0], &csio->sense_data, ce->sense_length);
2492	csio->sense_len = ce->sense_length;
2493	csio->resid = ce->residual_count;
2494	csio->ccb_h.status = CAM_SCSI_STATUS_ERROR | CAM_AUTOSNS_VALID;
2495#ifdef CISS_DEBUG
2496	{
2497	    struct scsi_sense_data	*sns = (struct scsi_sense_data *)&ce->sense_info[0];
2498	    debug(0, "sense key %x", sns->flags & SSD_KEY);
2499	}
2500#endif
2501	break;
2502
2503    case SCSI_STATUS_BUSY:		/* CISS_SCSI_STATUS_BUSY */
2504	debug(0, "SCSI_STATUS_BUSY");
2505	csio->ccb_h.status = CAM_SCSI_BUSY;
2506	break;
2507
2508    default:
2509	debug(0, "unknown status 0x%x", csio->scsi_status);
2510	csio->ccb_h.status = CAM_REQ_CMP_ERR;
2511	break;
2512    }
2513
2514    /* handle post-command fixup */
2515    ciss_cam_complete_fixup(sc, csio);
2516
2517    /* tell CAM we're ready for more commands */
2518    csio->ccb_h.status |= CAM_RELEASE_SIMQ;
2519
2520    xpt_done((union ccb *)csio);
2521    ciss_release_request(cr);
2522}
2523
2524/********************************************************************************
2525 * Fix up the result of some commands here.
2526 */
2527static void
2528ciss_cam_complete_fixup(struct ciss_softc *sc, struct ccb_scsiio *csio)
2529{
2530    struct scsi_inquiry_data	*inq;
2531    struct ciss_ldrive		*cl;
2532    int				target;
2533
2534    if (((csio->ccb_h.flags & CAM_CDB_POINTER) ?
2535	 *(u_int8_t *)csio->cdb_io.cdb_ptr : csio->cdb_io.cdb_bytes[0]) == INQUIRY) {
2536
2537	inq = (struct scsi_inquiry_data *)csio->data_ptr;
2538	target = csio->ccb_h.target_id;
2539	cl = &sc->ciss_logical[target];
2540
2541	padstr(inq->vendor, "COMPAQ", 8);
2542	padstr(inq->product, ciss_name_ldrive_org(cl->cl_ldrive->fault_tolerance), 8);
2543	padstr(inq->revision, ciss_name_ldrive_status(cl->cl_lstatus->status), 16);
2544    }
2545}
2546
2547
2548/********************************************************************************
2549 * Find a peripheral attached at (target)
2550 */
2551static struct cam_periph *
2552ciss_find_periph(struct ciss_softc *sc, int target)
2553{
2554    struct cam_periph	*periph;
2555    struct cam_path	*path;
2556    int			status;
2557
2558    status = xpt_create_path(&path, NULL, cam_sim_path(sc->ciss_cam_sim), target, 0);
2559    if (status == CAM_REQ_CMP) {
2560	periph = cam_periph_find(path, NULL);
2561	xpt_free_path(path);
2562    } else {
2563	periph = NULL;
2564    }
2565    return(periph);
2566}
2567
2568/********************************************************************************
2569 * Name the device at (target)
2570 *
2571 * XXX is this strictly correct?
2572 */
2573static int
2574ciss_name_device(struct ciss_softc *sc, int target)
2575{
2576    struct cam_periph	*periph;
2577
2578    if ((periph = ciss_find_periph(sc, target)) != NULL) {
2579	sprintf(sc->ciss_logical[target].cl_name, "%s%d", periph->periph_name, periph->unit_number);
2580	return(0);
2581    }
2582    sc->ciss_logical[target].cl_name[0] = 0;
2583    return(ENOENT);
2584}
2585
2586/************************************************************************
2587 * Periodic status monitoring.
2588 */
2589static void
2590ciss_periodic(void *arg)
2591{
2592    struct ciss_softc	*sc;
2593
2594    debug_called(1);
2595
2596    sc = (struct ciss_softc *)arg;
2597
2598    /*
2599     * Check the adapter heartbeat.
2600     */
2601    if (sc->ciss_cfg->heartbeat == sc->ciss_heartbeat) {
2602	sc->ciss_heart_attack++;
2603	debug(0, "adapter heart attack in progress 0x%x/%d",
2604	      sc->ciss_heartbeat, sc->ciss_heart_attack);
2605	if (sc->ciss_heart_attack == 3) {
2606	    ciss_printf(sc, "ADAPTER HEARTBEAT FAILED\n");
2607	    /* XXX should reset adapter here */
2608	}
2609    } else {
2610	sc->ciss_heartbeat = sc->ciss_cfg->heartbeat;
2611	sc->ciss_heart_attack = 0;
2612	debug(3, "new heartbeat 0x%x", sc->ciss_heartbeat);
2613    }
2614
2615    /*
2616     * If the notify event request has died for some reason, or has
2617     * not started yet, restart it.
2618     */
2619    if (!(sc->ciss_flags & CISS_FLAG_NOTIFY_OK)) {
2620	debug(0, "(re)starting Event Notify chain");
2621	ciss_notify_event(sc);
2622    }
2623
2624    /*
2625     * Reschedule.
2626     */
2627    if (!(sc->ciss_flags & CISS_FLAG_ABORTING))
2628	sc->ciss_periodic = timeout(ciss_periodic, sc, CISS_HEARTBEAT_RATE * hz);
2629}
2630
2631/************************************************************************
2632 * Request a notification response from the adapter.
2633 *
2634 * If (cr) is NULL, this is the first request of the adapter, so
2635 * reset the adapter's message pointer and start with the oldest
2636 * message available.
2637 */
2638static void
2639ciss_notify_event(struct ciss_softc *sc)
2640{
2641    struct ciss_request		*cr;
2642    struct ciss_command		*cc;
2643    struct ciss_notify_cdb	*cnc;
2644    int				error;
2645
2646    debug_called(1);
2647
2648    cr = sc->ciss_periodic_notify;
2649
2650    /* get a request if we don't already have one */
2651    if (cr == NULL) {
2652	if ((error = ciss_get_request(sc, &cr)) != 0) {
2653	    debug(0, "can't get notify event request");
2654	    goto out;
2655	}
2656	sc->ciss_periodic_notify = cr;
2657	cr->cr_complete = ciss_notify_complete;
2658	debug(1, "acquired request %d", cr->cr_tag);
2659    }
2660
2661    /*
2662     * Get a databuffer if we don't already have one, note that the
2663     * adapter command wants a larger buffer than the actual
2664     * structure.
2665     */
2666    if (cr->cr_data == NULL) {
2667	if ((cr->cr_data = malloc(CISS_NOTIFY_DATA_SIZE, CISS_MALLOC_CLASS, M_NOWAIT)) == NULL) {
2668	    debug(0, "can't get notify event request buffer");
2669	    error = ENOMEM;
2670	    goto out;
2671	}
2672	cr->cr_length = CISS_NOTIFY_DATA_SIZE;
2673    }
2674
2675    /* re-setup the request's command (since we never release it) XXX overkill*/
2676    ciss_preen_command(cr);
2677
2678    /* (re)build the notify event command */
2679    cc = CISS_FIND_COMMAND(cr);
2680    cc->header.address.physical.mode = CISS_HDR_ADDRESS_MODE_PERIPHERAL;
2681    cc->header.address.physical.bus = 0;
2682    cc->header.address.physical.target = 0;
2683
2684    cc->cdb.cdb_length = sizeof(*cnc);
2685    cc->cdb.type = CISS_CDB_TYPE_COMMAND;
2686    cc->cdb.attribute = CISS_CDB_ATTRIBUTE_SIMPLE;
2687    cc->cdb.direction = CISS_CDB_DIRECTION_READ;
2688    cc->cdb.timeout = 0;	/* no timeout, we hope */
2689
2690    cnc = (struct ciss_notify_cdb *)&(cc->cdb.cdb[0]);
2691    bzero(cr->cr_data, CISS_NOTIFY_DATA_SIZE);
2692    cnc->opcode = CISS_OPCODE_READ;
2693    cnc->command = CISS_COMMAND_NOTIFY_ON_EVENT;
2694    cnc->timeout = 0;		/* no timeout, we hope */
2695    cnc->synchronous = 0;
2696    cnc->ordered = 0;
2697    cnc->seek_to_oldest = 0;
2698    cnc->new_only = 0;
2699    cnc->length = htonl(CISS_NOTIFY_DATA_SIZE);
2700
2701    /* submit the request */
2702    error = ciss_start(cr);
2703
2704 out:
2705    if (error) {
2706	if (cr != NULL) {
2707	    if (cr->cr_data != NULL)
2708		free(cr->cr_data, CISS_MALLOC_CLASS);
2709	    ciss_release_request(cr);
2710	}
2711	sc->ciss_periodic_notify = NULL;
2712	debug(0, "can't submit notify event request");
2713	sc->ciss_flags &= ~CISS_FLAG_NOTIFY_OK;
2714    } else {
2715	debug(1, "notify event submitted");
2716	sc->ciss_flags |= CISS_FLAG_NOTIFY_OK;
2717    }
2718}
2719
2720static void
2721ciss_notify_complete(struct ciss_request *cr)
2722{
2723    struct ciss_command	*cc;
2724    struct ciss_notify	*cn;
2725    struct ciss_softc	*sc;
2726    int			scsi_status;
2727    int			command_status;
2728
2729    debug_called(1);
2730
2731    cc = CISS_FIND_COMMAND(cr);
2732    cn = (struct ciss_notify *)cr->cr_data;
2733    sc = cr->cr_sc;
2734
2735    /*
2736     * Report request results, decode status.
2737     */
2738    ciss_report_request(cr, &command_status, &scsi_status);
2739
2740    /*
2741     * Abort the chain on a fatal error.
2742     *
2743     * XXX which of these are actually errors?
2744     */
2745    if ((command_status != CISS_CMD_STATUS_SUCCESS) &&
2746	(command_status != CISS_CMD_STATUS_TARGET_STATUS) &&
2747	(command_status != CISS_CMD_STATUS_TIMEOUT)) {	/* XXX timeout? */
2748	ciss_printf(sc, "fatal error in Notify Event request (%s)\n",
2749		    ciss_name_command_status(command_status));
2750	ciss_release_request(cr);
2751	sc->ciss_flags &= ~CISS_FLAG_NOTIFY_OK;
2752	return;
2753    }
2754
2755    /*
2756     * If the adapter gave us a text message, print it.
2757     */
2758    if (cn->message[0] != 0)
2759	ciss_printf(sc, "*** %.80s\n", cn->message);
2760
2761    debug(0, "notify event class %d subclass %d detail %d",
2762		cn->class, cn->subclass, cn->detail);
2763
2764    /*
2765     * If there's room, save the event for a user-level tool.
2766     */
2767    if (((sc->ciss_notify_head + 1) % CISS_MAX_EVENTS) != sc->ciss_notify_tail) {
2768	sc->ciss_notify[sc->ciss_notify_head] = *cn;
2769	sc->ciss_notify_head = (sc->ciss_notify_head + 1) % CISS_MAX_EVENTS;
2770    }
2771
2772    /*
2773     * Some events are directly of interest to us.
2774     */
2775    switch (cn->class) {
2776    case CISS_NOTIFY_LOGICAL:
2777	ciss_notify_logical(sc, cn);
2778	break;
2779    case CISS_NOTIFY_PHYSICAL:
2780	ciss_notify_physical(sc, cn);
2781	break;
2782    }
2783
2784    /*
2785     * If the response indicates that the notifier has been aborted,
2786     * release the notifier command.
2787     */
2788    if ((cn->class == CISS_NOTIFY_NOTIFIER) &&
2789	(cn->subclass == CISS_NOTIFY_NOTIFIER_STATUS) &&
2790	(cn->detail == 1)) {
2791	debug(0, "notifier exiting");
2792	sc->ciss_flags &= ~CISS_FLAG_NOTIFY_OK;
2793	ciss_release_request(cr);
2794	sc->ciss_periodic_notify = NULL;
2795	wakeup(&sc->ciss_periodic_notify);
2796    }
2797
2798    /*
2799     * Send a new notify event command, if we're not aborting.
2800     */
2801    if (!(sc->ciss_flags & CISS_FLAG_ABORTING)) {
2802	ciss_notify_event(sc);
2803    }
2804}
2805
2806/************************************************************************
2807 * Abort the Notify Event chain.
2808 *
2809 * Note that we can't just abort the command in progress; we have to
2810 * explicitly issue an Abort Notify Event command in order for the
2811 * adapter to clean up correctly.
2812 *
2813 * If we are called with CISS_FLAG_ABORTING set in the adapter softc,
2814 * the chain will not restart itself.
2815 */
2816static int
2817ciss_notify_abort(struct ciss_softc *sc)
2818{
2819    struct ciss_request		*cr;
2820    struct ciss_command		*cc;
2821    struct ciss_notify_cdb	*cnc;
2822    int				error, s, command_status, scsi_status;
2823
2824    debug_called(1);
2825
2826    cr = NULL;
2827    error = 0;
2828
2829    /* verify that there's an outstanding command */
2830    if (!(sc->ciss_flags & CISS_FLAG_NOTIFY_OK))
2831	goto out;
2832
2833    /* get a command to issue the abort with */
2834    if ((error = ciss_get_request(sc, &cr)))
2835	goto out;
2836
2837    /* get a buffer for the result */
2838    if ((cr->cr_data = malloc(CISS_NOTIFY_DATA_SIZE, CISS_MALLOC_CLASS, M_NOWAIT)) == NULL) {
2839	debug(0, "can't get notify event request buffer");
2840	error = ENOMEM;
2841	goto out;
2842    }
2843    cr->cr_length = CISS_NOTIFY_DATA_SIZE;
2844
2845    /* build the CDB */
2846    cc = CISS_FIND_COMMAND(cr);
2847    cc->header.address.physical.mode = CISS_HDR_ADDRESS_MODE_PERIPHERAL;
2848    cc->header.address.physical.bus = 0;
2849    cc->header.address.physical.target = 0;
2850    cc->cdb.cdb_length = sizeof(*cnc);
2851    cc->cdb.type = CISS_CDB_TYPE_COMMAND;
2852    cc->cdb.attribute = CISS_CDB_ATTRIBUTE_SIMPLE;
2853    cc->cdb.direction = CISS_CDB_DIRECTION_READ;
2854    cc->cdb.timeout = 0;	/* no timeout, we hope */
2855
2856    cnc = (struct ciss_notify_cdb *)&(cc->cdb.cdb[0]);
2857    bzero(cnc, sizeof(*cnc));
2858    cnc->opcode = CISS_OPCODE_WRITE;
2859    cnc->command = CISS_COMMAND_ABORT_NOTIFY;
2860    cnc->length = htonl(CISS_NOTIFY_DATA_SIZE);
2861
2862    ciss_print_request(cr);
2863
2864    /*
2865     * Submit the request and wait for it to complete.
2866     */
2867    if ((error = ciss_synch_request(cr, 60 * 1000)) != 0) {
2868	ciss_printf(sc, "Abort Notify Event command failed (%d)\n", error);
2869	goto out;
2870    }
2871
2872    /*
2873     * Check response.
2874     */
2875    ciss_report_request(cr, &command_status, &scsi_status);
2876    switch(command_status) {
2877    case CISS_CMD_STATUS_SUCCESS:
2878	break;
2879    case CISS_CMD_STATUS_INVALID_COMMAND:
2880	/*
2881	 * Some older adapters don't support the CISS version of this
2882	 * command.  Fall back to using the BMIC version.
2883	 */
2884	error = ciss_notify_abort_bmic(sc);
2885	if (error != 0)
2886	    goto out;
2887	break;
2888
2889    case CISS_CMD_STATUS_TARGET_STATUS:
2890	/*
2891	 * This can happen if the adapter thinks there wasn't an outstanding
2892	 * Notify Event command but we did.  We clean up here.
2893	 */
2894	if (scsi_status == CISS_SCSI_STATUS_CHECK_CONDITION) {
2895	    if (sc->ciss_periodic_notify != NULL)
2896		ciss_release_request(sc->ciss_periodic_notify);
2897	    error = 0;
2898	    goto out;
2899	}
2900	/* FALLTHROUGH */
2901
2902    default:
2903	ciss_printf(sc, "Abort Notify Event command failed (%s)\n",
2904		    ciss_name_command_status(command_status));
2905	error = EIO;
2906	goto out;
2907    }
2908
2909    /*
2910     * Sleep waiting for the notifier command to complete.  Note
2911     * that if it doesn't, we may end up in a bad situation, since
2912     * the adapter may deliver it later.  Also note that the adapter
2913     * requires the Notify Event command to be cancelled in order to
2914     * maintain internal bookkeeping.
2915     */
2916    s = splcam();
2917    while (sc->ciss_periodic_notify != NULL) {
2918	error = tsleep(&sc->ciss_periodic_notify, 0, "cissNEA", hz * 5);
2919	if (error == EWOULDBLOCK) {
2920	    ciss_printf(sc, "Notify Event command failed to abort, adapter may wedge.\n");
2921	    break;
2922	}
2923    }
2924    splx(s);
2925
2926 out:
2927    /* release the cancel request */
2928    if (cr != NULL) {
2929	if (cr->cr_data != NULL)
2930	    free(cr->cr_data, CISS_MALLOC_CLASS);
2931	ciss_release_request(cr);
2932    }
2933    if (error == 0)
2934	sc->ciss_flags &= ~CISS_FLAG_NOTIFY_OK;
2935    return(error);
2936}
2937
2938/************************************************************************
2939 * Abort the Notify Event chain using a BMIC command.
2940 */
2941static int
2942ciss_notify_abort_bmic(struct ciss_softc *sc)
2943{
2944    struct ciss_request			*cr;
2945    int					error, command_status;
2946
2947    debug_called(1);
2948
2949    cr = NULL;
2950    error = 0;
2951
2952    /* verify that there's an outstanding command */
2953    if (!(sc->ciss_flags & CISS_FLAG_NOTIFY_OK))
2954	goto out;
2955
2956    /*
2957     * Build a BMIC command to cancel the Notify on Event command.
2958     *
2959     * Note that we are sending a CISS opcode here.  Odd.
2960     */
2961    if ((error = ciss_get_bmic_request(sc, &cr, CISS_COMMAND_ABORT_NOTIFY,
2962				       NULL, 0)) != 0)
2963	goto out;
2964
2965    /*
2966     * Submit the request and wait for it to complete.
2967     */
2968    if ((error = ciss_synch_request(cr, 60 * 1000)) != 0) {
2969	ciss_printf(sc, "error sending BMIC Cancel Notify on Event command (%d)\n", error);
2970	goto out;
2971    }
2972
2973    /*
2974     * Check response.
2975     */
2976    ciss_report_request(cr, &command_status, NULL);
2977    switch(command_status) {
2978    case CISS_CMD_STATUS_SUCCESS:
2979	break;
2980    default:
2981	ciss_printf(sc, "error cancelling Notify on Event (%s)\n",
2982		    ciss_name_command_status(command_status));
2983	error = EIO;
2984	goto out;
2985    }
2986
2987out:
2988    if (cr != NULL)
2989	ciss_release_request(cr);
2990    return(error);
2991}
2992
2993/************************************************************************
2994 * Handle a notify event relating to the status of a logical drive.
2995 *
2996 * XXX need to be able to defer some of these to properly handle
2997 *     calling the "ID Physical drive" command, unless the 'extended'
2998 *     drive IDs are always in BIG_MAP format.
2999 */
3000static void
3001ciss_notify_logical(struct ciss_softc *sc, struct ciss_notify *cn)
3002{
3003    struct ciss_ldrive	*ld;
3004    int			ostatus;
3005
3006    debug_called(2);
3007
3008    ld = &sc->ciss_logical[cn->data.logical_status.logical_drive];
3009
3010    switch (cn->subclass) {
3011    case CISS_NOTIFY_LOGICAL_STATUS:
3012	switch (cn->detail) {
3013	case 0:
3014	    ciss_name_device(sc, cn->data.logical_status.logical_drive);
3015	    ciss_printf(sc, "logical drive %d (%s) changed status %s->%s, spare status 0x%b\n",
3016			cn->data.logical_status.logical_drive, ld->cl_name,
3017			ciss_name_ldrive_status(cn->data.logical_status.previous_state),
3018			ciss_name_ldrive_status(cn->data.logical_status.new_state),
3019			cn->data.logical_status.spare_state,
3020			"\20\1configured\2rebuilding\3failed\4in use\5available\n");
3021
3022	    /*
3023	     * Update our idea of the drive's status.
3024	     */
3025	    ostatus = ciss_decode_ldrive_status(cn->data.logical_status.previous_state);
3026	    ld->cl_status = ciss_decode_ldrive_status(cn->data.logical_status.new_state);
3027	    if (ld->cl_lstatus != NULL)
3028		ld->cl_lstatus->status = cn->data.logical_status.new_state;
3029
3030#if 0
3031	    /*
3032	     * Have CAM rescan the drive if its status has changed.
3033	     */
3034	    if (ostatus != ld->cl_status)
3035		ciss_cam_rescan_target(sc, cn->data.logical_status.logical_drive);
3036#endif
3037
3038	    break;
3039
3040	case 1:	/* logical drive has recognised new media, needs Accept Media Exchange */
3041	    ciss_name_device(sc, cn->data.logical_status.logical_drive);
3042	    ciss_printf(sc, "logical drive %d (%s) media exchanged, ready to go online\n",
3043			cn->data.logical_status.logical_drive, ld->cl_name);
3044	    ciss_accept_media(sc, cn->data.logical_status.logical_drive, 1);
3045	    break;
3046
3047	case 2:
3048	case 3:
3049	    ciss_printf(sc, "rebuild of logical drive %d (%s) failed due to %s error\n",
3050			cn->data.rebuild_aborted.logical_drive,
3051			sc->ciss_logical[cn->data.rebuild_aborted.logical_drive].cl_name,
3052			(cn->detail == 2) ? "read" : "write");
3053	    break;
3054	}
3055	break;
3056
3057    case CISS_NOTIFY_LOGICAL_ERROR:
3058	if (cn->detail == 0) {
3059	    ciss_printf(sc, "FATAL I/O ERROR on logical drive %d (%s), SCSI port %d ID %d\n",
3060			cn->data.io_error.logical_drive,
3061			sc->ciss_logical[cn->data.io_error.logical_drive].cl_name,
3062			cn->data.io_error.failure_bus,
3063			cn->data.io_error.failure_drive);
3064	    /* XXX should we take the drive down at this point, or will we be told? */
3065	}
3066	break;
3067
3068    case CISS_NOTIFY_LOGICAL_SURFACE:
3069	if (cn->detail == 0)
3070	    ciss_printf(sc, "logical drive %d (%s) completed consistency initialisation\n",
3071			cn->data.consistency_completed.logical_drive,
3072			sc->ciss_logical[cn->data.consistency_completed.logical_drive].cl_name);
3073	break;
3074    }
3075}
3076
3077/************************************************************************
3078 * Handle a notify event relating to the status of a physical drive.
3079 */
3080static void
3081ciss_notify_physical(struct ciss_softc *sc, struct ciss_notify *cn)
3082{
3083
3084}
3085
3086/************************************************************************
3087 * Print a request.
3088 */
3089static void
3090ciss_print_request(struct ciss_request *cr)
3091{
3092    struct ciss_softc	*sc;
3093    struct ciss_command	*cc;
3094    int			i;
3095
3096    sc = cr->cr_sc;
3097    cc = CISS_FIND_COMMAND(cr);
3098
3099    ciss_printf(sc, "REQUEST @ %p\n", cr);
3100    ciss_printf(sc, "  data %p/%d  tag %d  flags %b\n",
3101	      cr->cr_data, cr->cr_length, cr->cr_tag, cr->cr_flags,
3102	      "\20\1mapped\2sleep\3poll\4dataout\5datain\n");
3103    ciss_printf(sc, "  sg list/total %d/%d  host tag 0x%x\n",
3104		cc->header.sg_in_list, cc->header.sg_total, cc->header.host_tag);
3105    switch(cc->header.address.mode.mode) {
3106    case CISS_HDR_ADDRESS_MODE_PERIPHERAL:
3107    case CISS_HDR_ADDRESS_MODE_MASK_PERIPHERAL:
3108	ciss_printf(sc, "  physical bus %d target %d\n",
3109		    cc->header.address.physical.bus, cc->header.address.physical.target);
3110	break;
3111    case CISS_HDR_ADDRESS_MODE_LOGICAL:
3112	ciss_printf(sc, "  logical unit %d\n", cc->header.address.logical.lun);
3113	break;
3114    }
3115    ciss_printf(sc, "  %s cdb length %d type %s attribute %s\n",
3116		(cc->cdb.direction == CISS_CDB_DIRECTION_NONE) ? "no-I/O" :
3117		(cc->cdb.direction == CISS_CDB_DIRECTION_READ) ? "READ" :
3118		(cc->cdb.direction == CISS_CDB_DIRECTION_WRITE) ? "WRITE" : "??",
3119		cc->cdb.cdb_length,
3120		(cc->cdb.type == CISS_CDB_TYPE_COMMAND) ? "command" :
3121		(cc->cdb.type == CISS_CDB_TYPE_MESSAGE) ? "message" : "??",
3122		(cc->cdb.attribute == CISS_CDB_ATTRIBUTE_UNTAGGED) ? "untagged" :
3123		(cc->cdb.attribute == CISS_CDB_ATTRIBUTE_SIMPLE) ? "simple" :
3124		(cc->cdb.attribute == CISS_CDB_ATTRIBUTE_HEAD_OF_QUEUE) ? "head-of-queue" :
3125		(cc->cdb.attribute == CISS_CDB_ATTRIBUTE_ORDERED) ? "ordered" :
3126		(cc->cdb.attribute == CISS_CDB_ATTRIBUTE_AUTO_CONTINGENT) ? "auto-contingent" : "??");
3127    ciss_printf(sc, "  %*D\n", cc->cdb.cdb_length, &cc->cdb.cdb[0], " ");
3128
3129    if (cc->header.host_tag & CISS_HDR_HOST_TAG_ERROR) {
3130	/* XXX print error info */
3131    } else {
3132	/* since we don't use chained s/g, don't support it here */
3133	for (i = 0; i < cc->header.sg_in_list; i++) {
3134	    if ((i % 4) == 0)
3135		ciss_printf(sc, "   ");
3136	    printf("0x%08x/%d ", (u_int32_t)cc->sg[i].address, cc->sg[i].length);
3137	    if ((((i + 1) % 4) == 0) || (i == (cc->header.sg_in_list - 1)))
3138		printf("\n");
3139	}
3140    }
3141}
3142
3143/************************************************************************
3144 * Print information about the status of a logical drive.
3145 */
3146static void
3147ciss_print_ldrive(struct ciss_softc *sc, struct ciss_ldrive *ld)
3148{
3149    int		bus, target, i;
3150
3151    if (ld->cl_lstatus == NULL) {
3152	printf("does not exist\n");
3153	return;
3154    }
3155
3156    /* print drive status */
3157    switch(ld->cl_lstatus->status) {
3158    case CISS_LSTATUS_OK:
3159	printf("online\n");
3160	break;
3161    case CISS_LSTATUS_INTERIM_RECOVERY:
3162	printf("in interim recovery mode\n");
3163	break;
3164    case CISS_LSTATUS_READY_RECOVERY:
3165	printf("ready to begin recovery\n");
3166	break;
3167    case CISS_LSTATUS_RECOVERING:
3168	bus = CISS_BIG_MAP_BUS(sc, ld->cl_lstatus->drive_rebuilding);
3169	target = CISS_BIG_MAP_BUS(sc, ld->cl_lstatus->drive_rebuilding);
3170	printf("being recovered, working on physical drive %d.%d, %u blocks remaining\n",
3171	       bus, target, ld->cl_lstatus->blocks_to_recover);
3172	break;
3173    case CISS_LSTATUS_EXPANDING:
3174	printf("being expanded, %u blocks remaining\n",
3175	       ld->cl_lstatus->blocks_to_recover);
3176	break;
3177    case CISS_LSTATUS_QUEUED_FOR_EXPANSION:
3178	printf("queued for expansion\n");
3179	break;
3180    case CISS_LSTATUS_FAILED:
3181	printf("queued for expansion\n");
3182	break;
3183    case CISS_LSTATUS_WRONG_PDRIVE:
3184	printf("wrong physical drive inserted\n");
3185	break;
3186    case CISS_LSTATUS_MISSING_PDRIVE:
3187	printf("missing a needed physical drive\n");
3188	break;
3189    case CISS_LSTATUS_BECOMING_READY:
3190	printf("becoming ready\n");
3191	break;
3192    }
3193
3194    /* print failed physical drives */
3195    for (i = 0; i < CISS_BIG_MAP_ENTRIES / 8; i++) {
3196	bus = CISS_BIG_MAP_BUS(sc, ld->cl_lstatus->drive_failure_map[i]);
3197	target = CISS_BIG_MAP_TARGET(sc, ld->cl_lstatus->drive_failure_map[i]);
3198	if (bus == -1)
3199	    continue;
3200	ciss_printf(sc, "physical drive %d:%d (%x) failed\n", bus, target,
3201		    ld->cl_lstatus->drive_failure_map[i]);
3202    }
3203}
3204
3205#ifdef CISS_DEBUG
3206/************************************************************************
3207 * Print information about the controller/driver.
3208 */
3209static void
3210ciss_print_adapter(struct ciss_softc *sc)
3211{
3212    int		i;
3213
3214    ciss_printf(sc, "ADAPTER:\n");
3215    for (i = 0; i < CISSQ_COUNT; i++) {
3216	ciss_printf(sc, "%s     %d/%d\n",
3217	    i == 0 ? "free" :
3218	    i == 1 ? "busy" : "complete",
3219	    sc->ciss_qstat[i].q_length,
3220	    sc->ciss_qstat[i].q_max);
3221    }
3222    ciss_printf(sc, "max_requests %d\n", sc->ciss_max_requests);
3223    ciss_printf(sc, "notify_head/tail %d/%d\n",
3224	sc->ciss_notify_head, sc->ciss_notify_tail);
3225    ciss_printf(sc, "flags %b\n", sc->ciss_flags,
3226	"\20\1notify_ok\2control_open\3aborting\4running\21fake_synch\22bmic_abort\n");
3227
3228    for (i = 0; i < CISS_MAX_LOGICAL; i++) {
3229	ciss_printf(sc, "LOGICAL DRIVE %d:  ", i);
3230	ciss_print_ldrive(sc, sc->ciss_logical + i);
3231    }
3232
3233    for (i = 1; i < sc->ciss_max_requests; i++)
3234	ciss_print_request(sc->ciss_request + i);
3235
3236}
3237
3238/* DDB hook */
3239static void
3240ciss_print0(void)
3241{
3242    struct ciss_softc	*sc;
3243
3244    sc = devclass_get_softc(devclass_find("ciss"), 0);
3245    if (sc == NULL) {
3246	printf("no ciss controllers\n");
3247    } else {
3248	ciss_print_adapter(sc);
3249    }
3250}
3251#endif
3252
3253/************************************************************************
3254 * Return a name for a logical drive status value.
3255 */
3256static const char *
3257ciss_name_ldrive_status(int status)
3258{
3259    switch (status) {
3260    case CISS_LSTATUS_OK:
3261	return("OK");
3262    case CISS_LSTATUS_FAILED:
3263	return("failed");
3264    case CISS_LSTATUS_NOT_CONFIGURED:
3265	return("not configured");
3266    case CISS_LSTATUS_INTERIM_RECOVERY:
3267	return("interim recovery");
3268    case CISS_LSTATUS_READY_RECOVERY:
3269	return("ready for recovery");
3270    case CISS_LSTATUS_RECOVERING:
3271	return("recovering");
3272    case CISS_LSTATUS_WRONG_PDRIVE:
3273	return("wrong physical drive inserted");
3274    case CISS_LSTATUS_MISSING_PDRIVE:
3275	return("missing physical drive");
3276    case CISS_LSTATUS_EXPANDING:
3277	return("expanding");
3278    case CISS_LSTATUS_BECOMING_READY:
3279	return("becoming ready");
3280    case CISS_LSTATUS_QUEUED_FOR_EXPANSION:
3281	return("queued for expansion");
3282    }
3283    return("unknown status");
3284}
3285
3286/************************************************************************
3287 * Return an online/offline/nonexistent value for a logical drive
3288 * status value.
3289 */
3290static int
3291ciss_decode_ldrive_status(int status)
3292{
3293    switch(status) {
3294    case CISS_LSTATUS_NOT_CONFIGURED:
3295	return(CISS_LD_NONEXISTENT);
3296
3297    case CISS_LSTATUS_OK:
3298    case CISS_LSTATUS_INTERIM_RECOVERY:
3299    case CISS_LSTATUS_READY_RECOVERY:
3300    case CISS_LSTATUS_RECOVERING:
3301    case CISS_LSTATUS_EXPANDING:
3302    case CISS_LSTATUS_QUEUED_FOR_EXPANSION:
3303	return(CISS_LD_ONLINE);
3304
3305    case CISS_LSTATUS_FAILED:
3306    case CISS_LSTATUS_WRONG_PDRIVE:
3307    case CISS_LSTATUS_MISSING_PDRIVE:
3308    case CISS_LSTATUS_BECOMING_READY:
3309    default:
3310	return(CISS_LD_OFFLINE);
3311    }
3312}
3313
3314
3315/************************************************************************
3316 * Return a name for a logical drive's organisation.
3317 */
3318static const char *
3319ciss_name_ldrive_org(int org)
3320{
3321    switch(org) {
3322    case CISS_LDRIVE_RAID0:
3323	return("RAID 0");
3324    case CISS_LDRIVE_RAID1:
3325	return("RAID 1");
3326    case CISS_LDRIVE_RAID4:
3327	return("RAID 4");
3328    case CISS_LDRIVE_RAID5:
3329	return("RAID 5");
3330    }
3331    return("unkown");
3332}
3333
3334/************************************************************************
3335 * Return a name for a command status value.
3336 */
3337static const char *
3338ciss_name_command_status(int status)
3339{
3340    switch(status) {
3341    case CISS_CMD_STATUS_SUCCESS:
3342	return("success");
3343    case CISS_CMD_STATUS_TARGET_STATUS:
3344	return("target status");
3345    case CISS_CMD_STATUS_DATA_UNDERRUN:
3346	return("data underrun");
3347    case CISS_CMD_STATUS_DATA_OVERRUN:
3348	return("data overrun");
3349    case CISS_CMD_STATUS_INVALID_COMMAND:
3350	return("invalid command");
3351    case CISS_CMD_STATUS_PROTOCOL_ERROR:
3352	return("protocol error");
3353    case CISS_CMD_STATUS_HARDWARE_ERROR:
3354	return("hardware error");
3355    case CISS_CMD_STATUS_CONNECTION_LOST:
3356	return("connection lost");
3357    case CISS_CMD_STATUS_ABORTED:
3358	return("aborted");
3359    case CISS_CMD_STATUS_ABORT_FAILED:
3360	return("abort failed");
3361    case CISS_CMD_STATUS_UNSOLICITED_ABORT:
3362	return("unsolicited abort");
3363    case CISS_CMD_STATUS_TIMEOUT:
3364	return("timeout");
3365    case CISS_CMD_STATUS_UNABORTABLE:
3366	return("unabortable");
3367    }
3368    return("unknown status");
3369}
3370
3371/************************************************************************
3372 * Handle an open on the control device.
3373 */
3374static int
3375ciss_open(dev_t dev, int flags, int fmt, d_thread_t *p)
3376{
3377    struct ciss_softc	*sc;
3378
3379    debug_called(1);
3380
3381    sc = (struct ciss_softc *)dev->si_drv1;
3382
3383    /* we might want to veto if someone already has us open */
3384
3385    sc->ciss_flags |= CISS_FLAG_CONTROL_OPEN;
3386    return(0);
3387}
3388
3389/************************************************************************
3390 * Handle the last close on the control device.
3391 */
3392static int
3393ciss_close(dev_t dev, int flags, int fmt, d_thread_t *p)
3394{
3395    struct ciss_softc	*sc;
3396
3397    debug_called(1);
3398
3399    sc = (struct ciss_softc *)dev->si_drv1;
3400
3401    sc->ciss_flags &= ~CISS_FLAG_CONTROL_OPEN;
3402    return (0);
3403}
3404
3405/********************************************************************************
3406 * Handle adapter-specific control operations.
3407 *
3408 * Note that the API here is compatible with the Linux driver, in order to
3409 * simplify the porting of Compaq's userland tools.
3410 */
3411static int
3412ciss_ioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, d_thread_t *p)
3413{
3414    struct ciss_softc		*sc;
3415    int				error;
3416
3417    debug_called(1);
3418
3419    sc = (struct ciss_softc *)dev->si_drv1;
3420    error = 0;
3421
3422    switch(cmd) {
3423    case CCISS_GETPCIINFO:
3424    {
3425	cciss_pci_info_struct	*pis = (cciss_pci_info_struct *)addr;
3426
3427	pis->bus = pci_get_bus(sc->ciss_dev);
3428	pis->dev_fn = pci_get_slot(sc->ciss_dev);
3429	pis->board_id = pci_get_devid(sc->ciss_dev);
3430
3431	break;
3432    }
3433
3434    case CCISS_GETINTINFO:
3435    {
3436	cciss_coalint_struct	*cis = (cciss_coalint_struct *)addr;
3437
3438	cis->delay = sc->ciss_cfg->interrupt_coalesce_delay;
3439	cis->count = sc->ciss_cfg->interrupt_coalesce_count;
3440
3441	break;
3442    }
3443
3444    case CCISS_SETINTINFO:
3445    {
3446	cciss_coalint_struct	*cis = (cciss_coalint_struct *)addr;
3447
3448	if ((cis->delay == 0) && (cis->count == 0)) {
3449	    error = EINVAL;
3450	    break;
3451	}
3452
3453	/*
3454	 * XXX apparently this is only safe if the controller is idle,
3455	 *     we should suspend it before doing this.
3456	 */
3457	sc->ciss_cfg->interrupt_coalesce_delay = cis->delay;
3458	sc->ciss_cfg->interrupt_coalesce_count = cis->count;
3459
3460	if (ciss_update_config(sc))
3461	    error = EIO;
3462
3463	/* XXX resume the controller here */
3464	break;
3465    }
3466
3467    case CCISS_GETNODENAME:
3468	bcopy(sc->ciss_cfg->server_name, (NodeName_type *)addr,
3469	      sizeof(NodeName_type));
3470	break;
3471
3472    case CCISS_SETNODENAME:
3473	bcopy((NodeName_type *)addr, sc->ciss_cfg->server_name,
3474	      sizeof(NodeName_type));
3475	if (ciss_update_config(sc))
3476	    error = EIO;
3477	break;
3478
3479    case CCISS_GETHEARTBEAT:
3480	*(Heartbeat_type *)addr = sc->ciss_cfg->heartbeat;
3481	break;
3482
3483    case CCISS_GETBUSTYPES:
3484	*(BusTypes_type *)addr = sc->ciss_cfg->bus_types;
3485	break;
3486
3487    case CCISS_GETFIRMVER:
3488	bcopy(sc->ciss_id->running_firmware_revision, (FirmwareVer_type *)addr,
3489	      sizeof(FirmwareVer_type));
3490	break;
3491
3492    case CCISS_GETDRIVERVER:
3493	*(DriverVer_type *)addr = CISS_DRIVER_VERSION;
3494	break;
3495
3496    case CCISS_REVALIDVOLS:
3497	/*
3498	 * This is a bit ugly; to do it "right" we really need
3499	 * to find any disks that have changed, kick CAM off them,
3500	 * then rescan only these disks.  It'd be nice if they
3501	 * a) told us which disk(s) they were going to play with,
3502	 * and b) which ones had arrived. 8(
3503	 */
3504	break;
3505
3506    case CCISS_PASSTHRU:
3507	error = ciss_user_command(sc, (IOCTL_Command_struct *)addr);
3508	break;
3509
3510    default:
3511	debug(0, "unknown ioctl 0x%lx", cmd);
3512
3513	debug(1, "CCISS_GETPCIINFO:   0x%lx", CCISS_GETPCIINFO);
3514	debug(1, "CCISS_GETINTINFO:   0x%lx", CCISS_GETINTINFO);
3515	debug(1, "CCISS_SETINTINFO:   0x%lx", CCISS_SETINTINFO);
3516	debug(1, "CCISS_GETNODENAME:  0x%lx", CCISS_GETNODENAME);
3517	debug(1, "CCISS_SETNODENAME:  0x%lx", CCISS_SETNODENAME);
3518	debug(1, "CCISS_GETHEARTBEAT: 0x%lx", CCISS_GETHEARTBEAT);
3519	debug(1, "CCISS_GETBUSTYPES:  0x%lx", CCISS_GETBUSTYPES);
3520	debug(1, "CCISS_GETFIRMVER:   0x%lx", CCISS_GETFIRMVER);
3521	debug(1, "CCISS_GETDRIVERVER: 0x%lx", CCISS_GETDRIVERVER);
3522	debug(1, "CCISS_REVALIDVOLS:  0x%lx", CCISS_REVALIDVOLS);
3523	debug(1, "CCISS_PASSTHRU:     0x%lx", CCISS_PASSTHRU);
3524
3525	error = ENOIOCTL;
3526	break;
3527    }
3528
3529    return(error);
3530}
3531