151973Smsmith/*- 251973Smsmith * Copyright (c) 1999 Michael Smith 351973Smsmith * All rights reserved. 451973Smsmith * 551973Smsmith * Redistribution and use in source and binary forms, with or without 651973Smsmith * modification, are permitted provided that the following conditions 751973Smsmith * are met: 851973Smsmith * 1. Redistributions of source code must retain the above copyright 951973Smsmith * notice, this list of conditions and the following disclaimer. 1051973Smsmith * 2. Redistributions in binary form must reproduce the above copyright 1151973Smsmith * notice, this list of conditions and the following disclaimer in the 1251973Smsmith * documentation and/or other materials provided with the distribution. 1351973Smsmith * 1451973Smsmith * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1551973Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1651973Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1751973Smsmith * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1851973Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1951973Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2051973Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2151973Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2251973Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2351973Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2451973Smsmith * SUCH DAMAGE. 2551973Smsmith * 2651973Smsmith * $FreeBSD$ 2751973Smsmith */ 2851973Smsmith 2951973Smsmith/* 3058188Smsmith * Debugging levels: 3158188Smsmith * 0 - quiet, only emit warnings 3258188Smsmith * 1 - noisy, emit major function points and things done 3358188Smsmith * 2 - extremely noisy, emit trace items in loops, etc. 3458188Smsmith */ 3558188Smsmith#ifdef MLX_DEBUG 3687599Sobrien#define debug(level, fmt, args...) do { if (level <= MLX_DEBUG) printf("%s: " fmt "\n", __func__ , ##args); } while(0) 3787599Sobrien#define debug_called(level) do { if (level <= MLX_DEBUG) printf(__func__ ": called\n"); } while(0) 3858188Smsmith#else 3958188Smsmith#define debug(level, fmt, args...) 4058188Smsmith#define debug_called(level) 4158188Smsmith#endif 4258188Smsmith 4358188Smsmith/* 4460074Smsmith * Regardless of the actual capacity of the controller, we will allocate space 4560074Smsmith * for 64 s/g entries. Typically controllers support 17 or 33 entries (64k or 4660074Smsmith * 128k maximum transfer assuming 4k page size and non-optimal alignment), but 4760074Smsmith * making that fit cleanly without crossing page boundaries requires rounding up 4860074Smsmith * to the next power of two. 4951973Smsmith */ 50238997Sdelphij#define MLX_MAXPHYS (128 * 1024) 5160074Smsmith#define MLX_NSEG 64 5260074Smsmith 5351973Smsmith#define MLX_NSLOTS 256 /* max number of command slots */ 5451973Smsmith 5558188Smsmith#define MLX_MAXDRIVES 32 /* max number of system drives */ 5651973Smsmith 5751973Smsmith/* 5851973Smsmith * Structure describing a System Drive as attached to the controller. 5951973Smsmith */ 6051973Smsmithstruct mlx_sysdrive 6151973Smsmith{ 6251973Smsmith /* from MLX_CMD_ENQSYSDRIVE */ 6351973Smsmith u_int32_t ms_size; 6451973Smsmith int ms_state; 6551973Smsmith int ms_raidlevel; 6651973Smsmith 6751973Smsmith /* synthetic geometry */ 6851973Smsmith int ms_cylinders; 6951973Smsmith int ms_heads; 7051973Smsmith int ms_sectors; 7151973Smsmith 7251973Smsmith /* handle for attached driver */ 7351973Smsmith device_t ms_disk; 7451973Smsmith}; 7551973Smsmith 7651973Smsmith/* 7751973Smsmith * Per-command control structure. 7851973Smsmith */ 7951973Smsmithstruct mlx_command 8051973Smsmith{ 8160938Sjake TAILQ_ENTRY(mlx_command) mc_link; /* list linkage */ 8251973Smsmith 8351973Smsmith struct mlx_softc *mc_sc; /* controller that owns us */ 8451973Smsmith u_int8_t mc_slot; /* command slot we occupy */ 8551973Smsmith u_int16_t mc_status; /* command completion status */ 8654419Smsmith time_t mc_timeout; /* when this command expires */ 8751973Smsmith u_int8_t mc_mailbox[16]; /* command mailbox */ 8851973Smsmith u_int32_t mc_sgphys; /* physical address of s/g array in controller space */ 8951973Smsmith int mc_nsgent; /* number of entries in s/g map */ 9051973Smsmith int mc_flags; 9151973Smsmith#define MLX_CMD_DATAIN (1<<0) 9251973Smsmith#define MLX_CMD_DATAOUT (1<<1) 9351973Smsmith#define MLX_CMD_PRIORITY (1<<2) /* high-priority command */ 9451973Smsmith 9551973Smsmith void *mc_data; /* data buffer */ 9651973Smsmith size_t mc_length; 9751973Smsmith bus_dmamap_t mc_dmamap; /* DMA map for data */ 9851973Smsmith u_int32_t mc_dataphys; /* data buffer base address controller space */ 9951973Smsmith 10051973Smsmith void (* mc_complete)(struct mlx_command *mc); /* completion handler */ 10151973Smsmith void *mc_private; /* submitter-private data or wait channel */ 102119665Sscottl int mc_command; 10351973Smsmith}; 10451973Smsmith 10551973Smsmith/* 10651973Smsmith * Per-controller structure. 10751973Smsmith */ 10851973Smsmithstruct mlx_softc 10951973Smsmith{ 11051973Smsmith /* bus connections */ 11151973Smsmith device_t mlx_dev; 112130585Sphk struct cdev *mlx_dev_t; 11351973Smsmith struct resource *mlx_mem; /* mailbox interface window */ 11469292Smdodd int mlx_mem_rid; 11569292Smdodd int mlx_mem_type; 11651973Smsmith bus_dma_tag_t mlx_parent_dmat;/* parent DMA tag */ 11751973Smsmith bus_dma_tag_t mlx_buffer_dmat;/* data buffer DMA tag */ 11851973Smsmith struct resource *mlx_irq; /* interrupt */ 11951973Smsmith void *mlx_intr; /* interrupt handle */ 12051973Smsmith 12151973Smsmith /* scatter/gather lists and their controller-visible mappings */ 12251973Smsmith struct mlx_sgentry *mlx_sgtable; /* s/g lists */ 12351973Smsmith u_int32_t mlx_sgbusaddr; /* s/g table base address in bus space */ 12451973Smsmith bus_dma_tag_t mlx_sg_dmat; /* s/g buffer DMA tag */ 12551973Smsmith bus_dmamap_t mlx_sg_dmamap; /* map for s/g buffers */ 12651973Smsmith 12751973Smsmith /* controller limits and features */ 12854979Smsmith struct mlx_enquiry2 *mlx_enq2; 12951973Smsmith int mlx_feature; /* controller features/quirks */ 13051973Smsmith#define MLX_FEAT_PAUSEWORKS (1<<0) /* channel pause works as expected */ 13151973Smsmith 13251973Smsmith /* controller queues and arrays */ 13360938Sjake TAILQ_HEAD(, mlx_command) mlx_freecmds; /* command structures available for reuse */ 13460938Sjake TAILQ_HEAD(, mlx_command) mlx_work; /* active commands */ 13551973Smsmith struct mlx_command *mlx_busycmd[MLX_NSLOTS]; /* busy commands */ 13651973Smsmith int mlx_busycmds; /* count of busy commands */ 13751973Smsmith struct mlx_sysdrive mlx_sysdrive[MLX_MAXDRIVES]; /* system drives */ 138240963Sjhb struct bio_queue_head mlx_bioq; /* outstanding I/O operations */ 13951973Smsmith int mlx_waitbufs; /* number of bufs awaiting commands */ 14051973Smsmith 14151973Smsmith /* controller status */ 14251973Smsmith int mlx_geom; 14351973Smsmith#define MLX_GEOM_128_32 0 /* geoemetry translation modes */ 14451973Smsmith#define MLX_GEOM_256_63 1 14551973Smsmith int mlx_state; 14651973Smsmith#define MLX_STATE_INTEN (1<<0) /* interrupts have been enabled */ 14751973Smsmith#define MLX_STATE_SHUTDOWN (1<<1) /* controller is shut down */ 14851973Smsmith#define MLX_STATE_OPEN (1<<2) /* control device is open */ 14951973Smsmith#define MLX_STATE_SUSPEND (1<<3) /* controller is suspended */ 150240608Sjhb#define MLX_STATE_QFROZEN (1<<4) /* bio queue frozen */ 151240608Sjhb struct mtx mlx_io_lock; 152240608Sjhb struct sx mlx_config_lock; 153240608Sjhb struct callout mlx_timeout; /* periodic status monitor */ 15451973Smsmith time_t mlx_lastpoll; /* last time_second we polled for status */ 15559136Smsmith u_int16_t mlx_lastevent; /* sequence number of the last event we recorded */ 15654979Smsmith int mlx_currevent; /* sequence number last time we looked */ 15759136Smsmith int mlx_background; /* if != 0 rebuild or check is in progress */ 15859136Smsmith#define MLX_BACKGROUND_CHECK 1 /* we started a check */ 15959136Smsmith#define MLX_BACKGROUND_REBUILD 2 /* we started a rebuild */ 16059136Smsmith#define MLX_BACKGROUND_SPONTANEOUS 3 /* it just happened somehow */ 16159136Smsmith struct mlx_rebuild_status mlx_rebuildstat; /* last rebuild status */ 16251973Smsmith struct mlx_pause mlx_pause; /* pending pause operation details */ 16351973Smsmith 16458188Smsmith int mlx_flags; 16558188Smsmith#define MLX_SPINUP_REPORTED (1<<0) /* "spinning up drives" message displayed */ 16659447Smsmith#define MLX_EVENTLOG_BUSY (1<<1) /* currently reading event log */ 16754419Smsmith 16851973Smsmith /* interface-specific accessor functions */ 16951973Smsmith int mlx_iftype; /* interface protocol */ 17058188Smsmith#define MLX_IFTYPE_2 2 17151973Smsmith#define MLX_IFTYPE_3 3 17251973Smsmith#define MLX_IFTYPE_4 4 17351973Smsmith#define MLX_IFTYPE_5 5 17451973Smsmith int (* mlx_tryqueue)(struct mlx_softc *sc, struct mlx_command *mc); 17551973Smsmith int (* mlx_findcomplete)(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status); 17651973Smsmith void (* mlx_intaction)(struct mlx_softc *sc, int action); 177240608Sjhb int (* mlx_fw_handshake)(struct mlx_softc *sc, int *error, int *param1, int *param2, int first); 17851973Smsmith#define MLX_INTACTION_DISABLE 0 17951973Smsmith#define MLX_INTACTION_ENABLE 1 18051973Smsmith}; 18151973Smsmith 182240608Sjhb#define MLX_IO_LOCK(sc) mtx_lock(&(sc)->mlx_io_lock) 183240608Sjhb#define MLX_IO_UNLOCK(sc) mtx_unlock(&(sc)->mlx_io_lock) 184240608Sjhb#define MLX_IO_ASSERT_LOCKED(sc) mtx_assert(&(sc)->mlx_io_lock, MA_OWNED) 185240608Sjhb#define MLX_CONFIG_LOCK(sc) sx_xlock(&(sc)->mlx_config_lock) 186240608Sjhb#define MLX_CONFIG_UNLOCK(sc) sx_xunlock(&(sc)->mlx_config_lock) 187240608Sjhb#define MLX_CONFIG_ASSERT_LOCKED(sc) sx_assert(&(sc)->mlx_config_lock, SA_XLOCKED) 18854419Smsmith 18954419Smsmith/* 19051973Smsmith * Interface between bus connections and driver core. 19151973Smsmith */ 19251973Smsmithextern void mlx_free(struct mlx_softc *sc); 19351973Smsmithextern int mlx_attach(struct mlx_softc *sc); 19451973Smsmithextern void mlx_startup(struct mlx_softc *sc); 19551973Smsmithextern void mlx_intr(void *data); 19651973Smsmithextern int mlx_detach(device_t dev); 19751973Smsmithextern int mlx_shutdown(device_t dev); 19851973Smsmithextern int mlx_suspend(device_t dev); 19951973Smsmithextern int mlx_resume(device_t dev); 20051973Smsmithextern d_open_t mlx_open; 20151973Smsmithextern d_close_t mlx_close; 20251973Smsmithextern d_ioctl_t mlx_ioctl; 20351973Smsmith 20451973Smsmithextern devclass_t mlx_devclass; 20559136Smsmithextern devclass_t mlxd_devclass; 20651973Smsmith 20751973Smsmith/* 20851973Smsmith * Mylex System Disk driver 20951973Smsmith */ 21051973Smsmithstruct mlxd_softc 21151973Smsmith{ 21251973Smsmith device_t mlxd_dev; 21351973Smsmith struct mlx_softc *mlxd_controller; 21451973Smsmith struct mlx_sysdrive *mlxd_drive; 215125975Sphk struct disk *mlxd_disk; 21651973Smsmith int mlxd_unit; 21751973Smsmith int mlxd_flags; 21851973Smsmith#define MLXD_OPEN (1<<0) /* drive is open (can't shut down) */ 21951973Smsmith}; 22051973Smsmith 22151973Smsmith/* 22251973Smsmith * Interface between driver core and disk driver (should be using a bus?) 22351973Smsmith */ 224240963Sjhbextern int mlx_submit_buf(struct mlx_softc *sc, struct bio *bp); 22583366Sjulianextern int mlx_submit_ioctl(struct mlx_softc *sc, 22683366Sjulian struct mlx_sysdrive *drive, u_long cmd, 22783366Sjulian caddr_t addr, int32_t flag, struct thread *td); 228240963Sjhbextern void mlxd_intr(struct bio *bp); 22951973Smsmith 23051973Smsmith 231