mega_common.h 9.1 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
/*
 *
 *			Linux MegaRAID device driver
 *
 * Copyright (c) 2003-2004  LSI Logic Corporation.
 *
 *	   This program is free software; you can redistribute it and/or
 *	   modify it under the terms of the GNU General Public License
 *	   as published by the Free Software Foundation; either version
 *	   2 of the License, or (at your option) any later version.
 *
 * FILE		: mega_common.h
 *
 * Libaray of common routine used by all low-level megaraid drivers
 */

#ifndef _MEGA_COMMON_H_
#define _MEGA_COMMON_H_

#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/blkdev.h>
#include <linux/list.h>
#include <linux/moduleparam.h>
29
#include <linux/dma-mapping.h>
L
Linus Torvalds 已提交
30 31 32 33 34 35 36 37 38 39
#include <asm/semaphore.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>


#define LSI_MAX_CHANNELS		16
#define LSI_MAX_LOGICAL_DRIVES_64LD	(64+1)

40 41 42
#define HBA_SIGNATURE_64_BIT		0x299
#define PCI_CONF_AMISIG64		0xa4

43 44 45
#define MEGA_SCSI_INQ_EVPD		1
#define MEGA_INVALID_FIELD_IN_CDB	0x24

L
Linus Torvalds 已提交
46 47 48

/**
 * scb_t - scsi command control block
R
Randy Dunlap 已提交
49 50 51 52 53 54 55 56 57 58 59
 * @ccb			: command control block for individual driver
 * @list		: list of control blocks
 * @gp			: general purpose field for LLDs
 * @sno			: all SCBs have a serial number
 * @scp			: associated scsi command
 * @state		: current state of scb
 * @dma_dir		: direction of data transfer
 * @dma_type		: transfer with sg list, buffer, or no data transfer
 * @dev_channel		: actual channel on the device
 * @dev_target		: actual target on the device
 * @status		: completion status
L
Linus Torvalds 已提交
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
 *
 * This is our central data structure to issue commands the each driver.
 * Driver specific data structures are maintained in the ccb field.
 * scb provides a field 'gp', which can be used by LLD for its own purposes
 *
 * dev_channel and dev_target must be initialized with the actual channel and
 * target on the controller.
 */
typedef struct {
	caddr_t			ccb;
	struct list_head	list;
	unsigned long		gp;
	unsigned int		sno;
	struct scsi_cmnd	*scp;
	uint32_t		state;
	uint32_t		dma_direction;
	uint32_t		dma_type;
	uint16_t		dev_channel;
	uint16_t		dev_target;
	uint32_t		status;
} scb_t;

/*
 * SCB states as it transitions from one state to another
 */
#define SCB_FREE	0x0000	/* on the free list */
#define SCB_ACTIVE	0x0001	/* off the free list */
#define SCB_PENDQ	0x0002	/* on the pending queue */
#define SCB_ISSUED	0x0004	/* issued - owner f/w */
#define SCB_ABORT	0x0008	/* Got an abort for this one */
#define SCB_RESET	0x0010	/* Got a reset for this one */

/*
 * DMA types for scb
 */
#define MRAID_DMA_NONE	0x0000	/* no data transfer for this command */
#define MRAID_DMA_WSG	0x0001	/* data transfer using a sg list */
#define MRAID_DMA_WBUF	0x0002	/* data transfer using a contiguous buffer */


/**
 * struct adapter_t - driver's initialization structure
R
Randy Dunlap 已提交
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
 * @aram dpc_h			: tasklet handle
 * @pdev			: pci configuration pointer for kernel
 * @host			: pointer to host structure of mid-layer
 * @lock			: synchronization lock for mid-layer and driver
 * @quiescent			: driver is quiescent for now.
 * @outstanding_cmds		: number of commands pending in the driver
 * @kscb_list			: pointer to the bulk of SCBs pointers for IO
 * @kscb_pool			: pool of free scbs for IO
 * @kscb_pool_lock		: lock for pool of free scbs
 * @pend_list			: pending commands list
 * @pend_list_lock		: exclusion lock for pending commands list
 * @completed_list		: list of completed commands
 * @completed_list_lock		: exclusion lock for list of completed commands
 * @sglen			: max sg elements supported
 * @device_ids			: to convert kernel device addr to our devices.
 * @raid_device			: raid adapter specific pointer
 * @max_channel			: maximum channel number supported - inclusive
 * @max_target			: max target supported - inclusive
 * @max_lun			: max lun supported - inclusive
 * @unique_id			: unique identifier for each adapter
 * @irq				: IRQ for this adapter
 * @ito				: internal timeout value, (-1) means no timeout
 * @ibuf			: buffer to issue internal commands
 * @ibuf_dma_h			: dma handle for the above buffer
 * @uscb_list			: SCB pointers for user cmds, common mgmt module
 * @uscb_pool			: pool of SCBs for user commands
 * @uscb_pool_lock		: exclusion lock for these SCBs
 * @max_cmds			: max outstanding commands
 * @fw_version			: firmware version
 * @bios_version		: bios version
 * @max_cdb_sz			: biggest CDB size supported.
 * @ha				: is high availability present - clustering
 * @init_id			: initiator ID, the default value should be 7
 * @max_sectors			: max sectors per request
 * @cmd_per_lun			: max outstanding commands per LUN
 * @being_detached		: set when unloading, no more mgmt calls
L
Linus Torvalds 已提交
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
 *
 *
 * mraid_setup_device_map() can be called anytime after the device map is
 * available and MRAID_GET_DEVICE_MAP() can be called whenever the mapping is
 * required, usually from LLD's queue entry point. The formar API sets up the
 * MRAID_IS_LOGICAL(adapter_t *, struct scsi_cmnd *) to find out if the
 * device in question is a logical drive.
 *
 * quiescent flag should be set by the driver if it is not accepting more
 * commands
 *
 * NOTE: The fields of this structures are placed to minimize cache misses
 */

// amount of space required to store the bios and firmware version strings
#define VERSION_SIZE	16

typedef struct {
	struct tasklet_struct	dpc_h;
	struct pci_dev		*pdev;
	struct Scsi_Host	*host;
	spinlock_t		lock;
	uint8_t			quiescent;
	int			outstanding_cmds;
	scb_t			*kscb_list;
	struct list_head	kscb_pool;
	spinlock_t		kscb_pool_lock;
	struct list_head	pend_list;
	spinlock_t		pend_list_lock;
	struct list_head	completed_list;
	spinlock_t		completed_list_lock;
	uint16_t		sglen;
	int			device_ids[LSI_MAX_CHANNELS]
					[LSI_MAX_LOGICAL_DRIVES_64LD];
	caddr_t			raid_device;
	uint8_t			max_channel;
	uint16_t		max_target;
	uint8_t			max_lun;

	uint32_t		unique_id;
178
	int			irq;
L
Linus Torvalds 已提交
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
	uint8_t			ito;
	caddr_t			ibuf;
	dma_addr_t		ibuf_dma_h;
	scb_t			*uscb_list;
	struct list_head	uscb_pool;
	spinlock_t		uscb_pool_lock;
	int			max_cmds;
	uint8_t			fw_version[VERSION_SIZE];
	uint8_t			bios_version[VERSION_SIZE];
	uint8_t			max_cdb_sz;
	uint8_t			ha;
	uint16_t		init_id;
	uint16_t		max_sectors;
	uint16_t		cmd_per_lun;
	atomic_t		being_detached;
} adapter_t;

#define SCSI_FREE_LIST_LOCK(adapter)	(&adapter->kscb_pool_lock)
#define USER_FREE_LIST_LOCK(adapter)	(&adapter->uscb_pool_lock)
#define PENDING_LIST_LOCK(adapter)	(&adapter->pend_list_lock)
#define COMPLETED_LIST_LOCK(adapter)	(&adapter->completed_list_lock)


// conversion from scsi command
#define SCP2HOST(scp)			(scp)->device->host	// to host
#define SCP2HOSTDATA(scp)		SCP2HOST(scp)->hostdata	// to soft state
#define SCP2CHANNEL(scp)		(scp)->device->channel	// to channel
#define SCP2TARGET(scp)			(scp)->device->id	// to target
#define SCP2LUN(scp)			(scp)->device->lun	// to LUN

// generic macro to convert scsi command and host to controller's soft state
#define SCSIHOST2ADAP(host)	(((caddr_t *)(host->hostdata))[0])
#define SCP2ADAPTER(scp)	(adapter_t *)SCSIHOST2ADAP(SCP2HOST(scp))


#define MRAID_IS_LOGICAL(adp, scp)	\
	(SCP2CHANNEL(scp) == (adp)->max_channel) ? 1 : 0

#define MRAID_IS_LOGICAL_SDEV(adp, sdev)	\
	(sdev->channel == (adp)->max_channel) ? 1 : 0

R
Randy Dunlap 已提交
220 221 222 223 224 225 226 227 228 229 230
/**
 * MRAID_GET_DEVICE_MAP - device ids
 * @adp			: adapter's soft state
 * @scp			: mid-layer scsi command pointer
 * @p_chan		: physical channel on the controller
 * @target		: target id of the device or logical drive number
 * @islogical		: set if the command is for the logical drive
 *
 * Macro to retrieve information about device class, logical or physical and
 * the corresponding physical channel and target or logical drive number
 */
L
Linus Torvalds 已提交
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275
#define MRAID_GET_DEVICE_MAP(adp, scp, p_chan, target, islogical)	\
	/*								\
	 * Is the request coming for the virtual channel		\
	 */								\
	islogical = MRAID_IS_LOGICAL(adp, scp);				\
									\
	/*								\
	 * Get an index into our table of drive ids mapping		\
	 */								\
	if (islogical) {						\
		p_chan = 0xFF;						\
		target =						\
		(adp)->device_ids[(adp)->max_channel][SCP2TARGET(scp)];	\
	}								\
	else {								\
		p_chan = ((adp)->device_ids[SCP2CHANNEL(scp)]		\
					[SCP2TARGET(scp)] >> 8) & 0xFF;	\
		target = ((adp)->device_ids[SCP2CHANNEL(scp)]		\
					[SCP2TARGET(scp)] & 0xFF);	\
	}

/*
 * ### Helper routines ###
 */
#define LSI_DBGLVL mraid_debug_level	// each LLD must define a global
 					// mraid_debug_level

#ifdef DEBUG
#if defined (_ASSERT_PANIC)
#define ASSERT_ACTION	panic
#else
#define ASSERT_ACTION	printk
#endif

#define ASSERT(expression)						\
	if (!(expression)) {						\
	ASSERT_ACTION("assertion failed:(%s), file: %s, line: %d:%s\n",	\
			#expression, __FILE__, __LINE__, __FUNCTION__);	\
	}
#else
#define ASSERT(expression)
#endif

/*
 * struct mraid_pci_blk - structure holds DMA memory block info
R
Randy Dunlap 已提交
276 277
 * @vaddr		: virtual address to a memory block
 * @dma_addr		: DMA handle to a memory block
L
Linus Torvalds 已提交
278 279 280 281 282 283 284 285 286 287 288 289 290
 *
 * This structure is filled up for the caller. It is the responsibilty of the
 * caller to allocate this array big enough to store addresses for all
 * requested elements
 */
struct mraid_pci_blk {
	caddr_t		vaddr;
	dma_addr_t	dma_addr;
};

#endif // _MEGA_COMMON_H_

// vim: set ts=8 sw=8 tw=78: