forked from mirrors/linux
		
	scsi: aacraid: added support for init_struct_8
This patch lays the groundwork for supporting the new HBA-1000 controller family.A new INIT structure INIT_STRUCT_8 has been added which allows for a variable size for MSI-x vectors among other things, and is used for both Series-8, HBA-1000 and SmartIOC-2000. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renukunta@microsemi.com> Signed-off-by: Dave Carroll <David.Carroll@microsemi.com> Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
		
							parent
							
								
									24b043cb61
								
							
						
					
					
						commit
						d1ef4da848
					
				
					 9 changed files with 259 additions and 136 deletions
				
			
		| 
						 | 
				
			
			@ -1144,7 +1144,9 @@ static int aac_read_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u3
 | 
			
		|||
	long ret;
 | 
			
		||||
 | 
			
		||||
	aac_fib_init(fib);
 | 
			
		||||
	if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2 && !dev->sync_mode) {
 | 
			
		||||
	if ((dev->comm_interface == AAC_COMM_MESSAGE_TYPE2 ||
 | 
			
		||||
		dev->comm_interface == AAC_COMM_MESSAGE_TYPE3) &&
 | 
			
		||||
		!dev->sync_mode) {
 | 
			
		||||
		struct aac_raw_io2 *readcmd2;
 | 
			
		||||
		readcmd2 = (struct aac_raw_io2 *) fib_data(fib);
 | 
			
		||||
		memset(readcmd2, 0, sizeof(struct aac_raw_io2));
 | 
			
		||||
| 
						 | 
				
			
			@ -1270,7 +1272,9 @@ static int aac_write_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u
 | 
			
		|||
	long ret;
 | 
			
		||||
 | 
			
		||||
	aac_fib_init(fib);
 | 
			
		||||
	if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2 && !dev->sync_mode) {
 | 
			
		||||
	if ((dev->comm_interface == AAC_COMM_MESSAGE_TYPE2 ||
 | 
			
		||||
		dev->comm_interface == AAC_COMM_MESSAGE_TYPE3) &&
 | 
			
		||||
		!dev->sync_mode) {
 | 
			
		||||
		struct aac_raw_io2 *writecmd2;
 | 
			
		||||
		writecmd2 = (struct aac_raw_io2 *) fib_data(fib);
 | 
			
		||||
		memset(writecmd2, 0, sizeof(struct aac_raw_io2));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -81,6 +81,11 @@ enum {
 | 
			
		|||
 | 
			
		||||
#define AAC_DEBUG_INSTRUMENT_AIF_DELETE
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Interrupts
 | 
			
		||||
 */
 | 
			
		||||
#define AAC_MAX_HRRQ		64
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * These macros convert from physical channels to virtual channels
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -491,41 +496,64 @@ enum fib_xfer_state {
 | 
			
		|||
#define ADAPTER_INIT_STRUCT_REVISION_4		4 // rocket science
 | 
			
		||||
#define ADAPTER_INIT_STRUCT_REVISION_6		6 /* PMC src */
 | 
			
		||||
#define ADAPTER_INIT_STRUCT_REVISION_7		7 /* Denali */
 | 
			
		||||
#define ADAPTER_INIT_STRUCT_REVISION_8		8 // Thor
 | 
			
		||||
 | 
			
		||||
struct aac_init
 | 
			
		||||
union aac_init
 | 
			
		||||
{
 | 
			
		||||
	__le32	InitStructRevision;
 | 
			
		||||
	__le32	Sa_MSIXVectors;
 | 
			
		||||
	__le32	fsrev;
 | 
			
		||||
	__le32	CommHeaderAddress;
 | 
			
		||||
	__le32	FastIoCommAreaAddress;
 | 
			
		||||
	__le32	AdapterFibsPhysicalAddress;
 | 
			
		||||
	__le32	AdapterFibsVirtualAddress;
 | 
			
		||||
	__le32	AdapterFibsSize;
 | 
			
		||||
	__le32	AdapterFibAlign;
 | 
			
		||||
	__le32	printfbuf;
 | 
			
		||||
	__le32	printfbufsiz;
 | 
			
		||||
	__le32	HostPhysMemPages;   /* number of 4k pages of host
 | 
			
		||||
				       physical memory */
 | 
			
		||||
	__le32	HostElapsedSeconds; /* number of seconds since 1970. */
 | 
			
		||||
	/*
 | 
			
		||||
	 * ADAPTER_INIT_STRUCT_REVISION_4 begins here
 | 
			
		||||
	 */
 | 
			
		||||
	__le32	InitFlags;	/* flags for supported features */
 | 
			
		||||
	struct _r7 {
 | 
			
		||||
		__le32	init_struct_revision;
 | 
			
		||||
		__le32	no_of_msix_vectors;
 | 
			
		||||
		__le32	fsrev;
 | 
			
		||||
		__le32	comm_header_address;
 | 
			
		||||
		__le32	fast_io_comm_area_address;
 | 
			
		||||
		__le32	adapter_fibs_physical_address;
 | 
			
		||||
		__le32	adapter_fibs_virtual_address;
 | 
			
		||||
		__le32	adapter_fibs_size;
 | 
			
		||||
		__le32	adapter_fib_align;
 | 
			
		||||
		__le32	printfbuf;
 | 
			
		||||
		__le32	printfbufsiz;
 | 
			
		||||
		/* number of 4k pages of host phys. mem. */
 | 
			
		||||
		__le32	host_phys_mem_pages;
 | 
			
		||||
		/* number of seconds since 1970. */
 | 
			
		||||
		__le32	host_elapsed_seconds;
 | 
			
		||||
		/* ADAPTER_INIT_STRUCT_REVISION_4 begins here */
 | 
			
		||||
		__le32	init_flags;	/* flags for supported features */
 | 
			
		||||
#define INITFLAGS_NEW_COMM_SUPPORTED	0x00000001
 | 
			
		||||
#define INITFLAGS_DRIVER_USES_UTC_TIME	0x00000010
 | 
			
		||||
#define INITFLAGS_DRIVER_SUPPORTS_PM	0x00000020
 | 
			
		||||
#define INITFLAGS_NEW_COMM_TYPE1_SUPPORTED	0x00000040
 | 
			
		||||
#define INITFLAGS_FAST_JBOD_SUPPORTED	0x00000080
 | 
			
		||||
#define INITFLAGS_NEW_COMM_TYPE2_SUPPORTED	0x00000100
 | 
			
		||||
	__le32	MaxIoCommands;	/* max outstanding commands */
 | 
			
		||||
	__le32	MaxIoSize;	/* largest I/O command */
 | 
			
		||||
	__le32	MaxFibSize;	/* largest FIB to adapter */
 | 
			
		||||
	/* ADAPTER_INIT_STRUCT_REVISION_5 begins here */
 | 
			
		||||
	__le32	MaxNumAif;	/* max number of aif */
 | 
			
		||||
	/* ADAPTER_INIT_STRUCT_REVISION_6 begins here */
 | 
			
		||||
	__le32	HostRRQ_AddrLow;
 | 
			
		||||
	__le32	HostRRQ_AddrHigh;	/* Host RRQ (response queue) for SRC */
 | 
			
		||||
#define INITFLAGS_DRIVER_SUPPORTS_HBA_MODE  0x00000400
 | 
			
		||||
		__le32	max_io_commands;	/* max outstanding commands */
 | 
			
		||||
		__le32	max_io_size;	/* largest I/O command */
 | 
			
		||||
		__le32	max_fib_size;	/* largest FIB to adapter */
 | 
			
		||||
		/* ADAPTER_INIT_STRUCT_REVISION_5 begins here */
 | 
			
		||||
		__le32	max_num_aif;	/* max number of aif */
 | 
			
		||||
		/* ADAPTER_INIT_STRUCT_REVISION_6 begins here */
 | 
			
		||||
		/* Host RRQ (response queue) for SRC */
 | 
			
		||||
		__le32	host_rrq_addr_low;
 | 
			
		||||
		__le32	host_rrq_addr_high;
 | 
			
		||||
	} r7;
 | 
			
		||||
	struct _r8 {
 | 
			
		||||
		/* ADAPTER_INIT_STRUCT_REVISION_8 */
 | 
			
		||||
		__le32	init_struct_revision;
 | 
			
		||||
		__le32	rr_queue_count;
 | 
			
		||||
		__le32	host_elapsed_seconds; /* number of secs since 1970. */
 | 
			
		||||
		__le32	init_flags;
 | 
			
		||||
		__le32	max_io_size;	/* largest I/O command */
 | 
			
		||||
		__le32	max_num_aif;	/* max number of aif */
 | 
			
		||||
		__le32	reserved1;
 | 
			
		||||
		__le32	reserved2;
 | 
			
		||||
		struct _rrq {
 | 
			
		||||
			__le32	host_addr_low;
 | 
			
		||||
			__le32	host_addr_high;
 | 
			
		||||
			__le16	msix_id;
 | 
			
		||||
			__le16	element_count;
 | 
			
		||||
			__le16	comp_thresh;
 | 
			
		||||
			__le16	unused;
 | 
			
		||||
		} rrq[1];		/* up to 64 RRQ addresses */
 | 
			
		||||
	} r8;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum aac_log_level {
 | 
			
		||||
| 
						 | 
				
			
			@ -729,6 +757,7 @@ struct sa_registers {
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
#define SA_INIT_NUM_MSIXVECTORS		1
 | 
			
		||||
#define SA_MINIPORT_REVISION		SA_INIT_NUM_MSIXVECTORS
 | 
			
		||||
 | 
			
		||||
#define sa_readw(AEP, CSR)		readl(&((AEP)->regs.sa->CSR))
 | 
			
		||||
#define sa_readl(AEP, CSR)		readl(&((AEP)->regs.sa->CSR))
 | 
			
		||||
| 
						 | 
				
			
			@ -1106,6 +1135,12 @@ struct aac_bus_info_response {
 | 
			
		|||
#define AAC_OPT_NEW_COMM_TYPE3		cpu_to_le32(1<<30)
 | 
			
		||||
#define AAC_OPT_NEW_COMM_TYPE4		cpu_to_le32(1<<31)
 | 
			
		||||
 | 
			
		||||
#define AAC_COMM_PRODUCER		0
 | 
			
		||||
#define AAC_COMM_MESSAGE		1
 | 
			
		||||
#define AAC_COMM_MESSAGE_TYPE1		3
 | 
			
		||||
#define AAC_COMM_MESSAGE_TYPE2		4
 | 
			
		||||
#define AAC_COMM_MESSAGE_TYPE3		5
 | 
			
		||||
 | 
			
		||||
/* MSIX context */
 | 
			
		||||
struct aac_msix_ctx {
 | 
			
		||||
	int		vector_no;
 | 
			
		||||
| 
						 | 
				
			
			@ -1159,8 +1194,11 @@ struct aac_dev
 | 
			
		|||
 | 
			
		||||
	resource_size_t		base_size, dbg_size;	/* Size of
 | 
			
		||||
							 *  mapped in region */
 | 
			
		||||
 | 
			
		||||
	struct aac_init		*init;		/* Holds initialization info to communicate with adapter */
 | 
			
		||||
	/*
 | 
			
		||||
	 * Holds initialization info
 | 
			
		||||
	 * to communicate with adapter
 | 
			
		||||
	 */
 | 
			
		||||
	union aac_init		*init;
 | 
			
		||||
	dma_addr_t		init_pa;	/* Holds physical address of the init struct */
 | 
			
		||||
 | 
			
		||||
	u32			*host_rrq;	/* response queue
 | 
			
		||||
| 
						 | 
				
			
			@ -1229,10 +1267,6 @@ struct aac_dev
 | 
			
		|||
	u8			needs_dac;
 | 
			
		||||
	u8			raid_scsi_mode;
 | 
			
		||||
	u8			comm_interface;
 | 
			
		||||
#	define AAC_COMM_PRODUCER 0
 | 
			
		||||
#	define AAC_COMM_MESSAGE  1
 | 
			
		||||
#	define AAC_COMM_MESSAGE_TYPE1	3
 | 
			
		||||
#	define AAC_COMM_MESSAGE_TYPE2	4
 | 
			
		||||
	u8			raw_io_interface;
 | 
			
		||||
	u8			raw_io_64;
 | 
			
		||||
	u8			printf_enabled;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -68,104 +68,167 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
 | 
			
		|||
	unsigned long size, align;
 | 
			
		||||
	const unsigned long fibsize = dev->max_fib_size;
 | 
			
		||||
	const unsigned long printfbufsiz = 256;
 | 
			
		||||
	unsigned long host_rrq_size = 0;
 | 
			
		||||
	struct aac_init *init;
 | 
			
		||||
	unsigned long host_rrq_size, aac_init_size;
 | 
			
		||||
	union aac_init *init;
 | 
			
		||||
	dma_addr_t phys;
 | 
			
		||||
	unsigned long aac_max_hostphysmempages;
 | 
			
		||||
 | 
			
		||||
	if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE1 ||
 | 
			
		||||
	    dev->comm_interface == AAC_COMM_MESSAGE_TYPE2)
 | 
			
		||||
		host_rrq_size = (dev->scsi_host_ptr->can_queue
 | 
			
		||||
			+ AAC_NUM_MGT_FIB) * sizeof(u32);
 | 
			
		||||
	size = fibsize + sizeof(struct aac_init) + commsize +
 | 
			
		||||
			commalign + printfbufsiz + host_rrq_size;
 | 
			
		||||
 
 | 
			
		||||
	if ((dev->comm_interface == AAC_COMM_MESSAGE_TYPE1) ||
 | 
			
		||||
		(dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) ||
 | 
			
		||||
		(dev->comm_interface == AAC_COMM_MESSAGE_TYPE3))
 | 
			
		||||
		host_rrq_size =
 | 
			
		||||
			(dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB)
 | 
			
		||||
				* sizeof(u32);
 | 
			
		||||
	else
 | 
			
		||||
		host_rrq_size = 0;
 | 
			
		||||
 | 
			
		||||
	aac_init_size = sizeof(union aac_init);
 | 
			
		||||
	size = fibsize + aac_init_size + commsize + commalign +
 | 
			
		||||
			printfbufsiz + host_rrq_size;
 | 
			
		||||
 | 
			
		||||
	base = pci_alloc_consistent(dev->pdev, size, &phys);
 | 
			
		||||
 | 
			
		||||
	if(base == NULL)
 | 
			
		||||
	{
 | 
			
		||||
	if (base == NULL) {
 | 
			
		||||
		printk(KERN_ERR "aacraid: unable to create mapping.\n");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dev->comm_addr = (void *)base;
 | 
			
		||||
	dev->comm_phys = phys;
 | 
			
		||||
	dev->comm_size = size;
 | 
			
		||||
	
 | 
			
		||||
	if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE1 ||
 | 
			
		||||
	    dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) {
 | 
			
		||||
 | 
			
		||||
	if ((dev->comm_interface == AAC_COMM_MESSAGE_TYPE1) ||
 | 
			
		||||
	    (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) ||
 | 
			
		||||
	    (dev->comm_interface == AAC_COMM_MESSAGE_TYPE3)) {
 | 
			
		||||
		dev->host_rrq = (u32 *)(base + fibsize);
 | 
			
		||||
		dev->host_rrq_pa = phys + fibsize;
 | 
			
		||||
		memset(dev->host_rrq, 0, host_rrq_size);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dev->init = (struct aac_init *)(base + fibsize + host_rrq_size);
 | 
			
		||||
	dev->init = (union aac_init *)(base + fibsize + host_rrq_size);
 | 
			
		||||
	dev->init_pa = phys + fibsize + host_rrq_size;
 | 
			
		||||
 | 
			
		||||
	init = dev->init;
 | 
			
		||||
 | 
			
		||||
	init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION);
 | 
			
		||||
	if (dev->max_fib_size != sizeof(struct hw_fib))
 | 
			
		||||
		init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4);
 | 
			
		||||
	init->Sa_MSIXVectors = cpu_to_le32(SA_INIT_NUM_MSIXVECTORS);
 | 
			
		||||
	init->fsrev = cpu_to_le32(dev->fsrev);
 | 
			
		||||
	if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE3) {
 | 
			
		||||
		int i;
 | 
			
		||||
		u64 addr;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 *	Adapter Fibs are the first thing allocated so that they
 | 
			
		||||
	 *	start page aligned
 | 
			
		||||
	 */
 | 
			
		||||
	dev->aif_base_va = (struct hw_fib *)base;
 | 
			
		||||
	
 | 
			
		||||
	init->AdapterFibsVirtualAddress = 0;
 | 
			
		||||
	init->AdapterFibsPhysicalAddress = cpu_to_le32((u32)phys);
 | 
			
		||||
	init->AdapterFibsSize = cpu_to_le32(fibsize);
 | 
			
		||||
	init->AdapterFibAlign = cpu_to_le32(sizeof(struct hw_fib));
 | 
			
		||||
	/*
 | 
			
		||||
	 * number of 4k pages of host physical memory. The aacraid fw needs
 | 
			
		||||
	 * this number to be less than 4gb worth of pages. New firmware doesn't
 | 
			
		||||
	 * have any issues with the mapping system, but older Firmware did, and
 | 
			
		||||
	 * had *troubles* dealing with the math overloading past 32 bits, thus
 | 
			
		||||
	 * we must limit this field.
 | 
			
		||||
	 */
 | 
			
		||||
	aac_max_hostphysmempages = dma_get_required_mask(&dev->pdev->dev) >> 12;
 | 
			
		||||
	if (aac_max_hostphysmempages < AAC_MAX_HOSTPHYSMEMPAGES)
 | 
			
		||||
		init->HostPhysMemPages = cpu_to_le32(aac_max_hostphysmempages);
 | 
			
		||||
	else
 | 
			
		||||
		init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES);
 | 
			
		||||
		init->r8.init_struct_revision =
 | 
			
		||||
			cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_8);
 | 
			
		||||
		init->r8.init_flags = cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED |
 | 
			
		||||
					INITFLAGS_DRIVER_USES_UTC_TIME |
 | 
			
		||||
					INITFLAGS_DRIVER_SUPPORTS_PM);
 | 
			
		||||
		init->r8.init_flags |=
 | 
			
		||||
				cpu_to_le32(INITFLAGS_DRIVER_SUPPORTS_HBA_MODE);
 | 
			
		||||
		init->r8.rr_queue_count = cpu_to_le32(dev->max_msix);
 | 
			
		||||
		init->r8.max_io_size =
 | 
			
		||||
			cpu_to_le32(dev->scsi_host_ptr->max_sectors << 9);
 | 
			
		||||
		init->r8.max_num_aif = init->r8.reserved1 =
 | 
			
		||||
			init->r8.reserved2 = 0;
 | 
			
		||||
 | 
			
		||||
	init->InitFlags = cpu_to_le32(INITFLAGS_DRIVER_USES_UTC_TIME |
 | 
			
		||||
		INITFLAGS_DRIVER_SUPPORTS_PM);
 | 
			
		||||
	init->MaxIoCommands = cpu_to_le32(dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB);
 | 
			
		||||
	init->MaxIoSize = cpu_to_le32(dev->scsi_host_ptr->max_sectors << 9);
 | 
			
		||||
	init->MaxFibSize = cpu_to_le32(dev->max_fib_size);
 | 
			
		||||
	init->MaxNumAif = cpu_to_le32(dev->max_num_aif);
 | 
			
		||||
		for (i = 0; i < dev->max_msix; i++) {
 | 
			
		||||
			addr = (u64)dev->host_rrq_pa + dev->vector_cap * i *
 | 
			
		||||
					sizeof(u32);
 | 
			
		||||
			init->r8.rrq[i].host_addr_high = cpu_to_le32(
 | 
			
		||||
						upper_32_bits(addr));
 | 
			
		||||
			init->r8.rrq[i].host_addr_low = cpu_to_le32(
 | 
			
		||||
						lower_32_bits(addr));
 | 
			
		||||
			init->r8.rrq[i].msix_id = i;
 | 
			
		||||
			init->r8.rrq[i].element_count = cpu_to_le16(
 | 
			
		||||
					(u16)dev->vector_cap);
 | 
			
		||||
			init->r8.rrq[i].comp_thresh =
 | 
			
		||||
					init->r8.rrq[i].unused = 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	if (dev->comm_interface == AAC_COMM_MESSAGE) {
 | 
			
		||||
		init->InitFlags |= cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED);
 | 
			
		||||
		dprintk((KERN_WARNING"aacraid: New Comm Interface enabled\n"));
 | 
			
		||||
	} else if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE1) {
 | 
			
		||||
		init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_6);
 | 
			
		||||
		init->InitFlags |= cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED |
 | 
			
		||||
			INITFLAGS_NEW_COMM_TYPE1_SUPPORTED | INITFLAGS_FAST_JBOD_SUPPORTED);
 | 
			
		||||
		init->HostRRQ_AddrHigh = cpu_to_le32((u32)((u64)dev->host_rrq_pa >> 32));
 | 
			
		||||
		init->HostRRQ_AddrLow = cpu_to_le32((u32)(dev->host_rrq_pa & 0xffffffff));
 | 
			
		||||
		dprintk((KERN_WARNING"aacraid: New Comm Interface type1 enabled\n"));
 | 
			
		||||
	} else if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) {
 | 
			
		||||
		init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_7);
 | 
			
		||||
		init->InitFlags |= cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED |
 | 
			
		||||
			INITFLAGS_NEW_COMM_TYPE2_SUPPORTED | INITFLAGS_FAST_JBOD_SUPPORTED);
 | 
			
		||||
		init->HostRRQ_AddrHigh = cpu_to_le32((u32)((u64)dev->host_rrq_pa >> 32));
 | 
			
		||||
		init->HostRRQ_AddrLow = cpu_to_le32((u32)(dev->host_rrq_pa & 0xffffffff));
 | 
			
		||||
		/* number of MSI-X */
 | 
			
		||||
		init->Sa_MSIXVectors = cpu_to_le32(dev->max_msix);
 | 
			
		||||
		dprintk((KERN_WARNING"aacraid: New Comm Interface type2 enabled\n"));
 | 
			
		||||
		pr_warn("aacraid: Comm Interface type3 enabled\n");
 | 
			
		||||
	} else {
 | 
			
		||||
		init->r7.init_struct_revision =
 | 
			
		||||
			cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION);
 | 
			
		||||
		if (dev->max_fib_size != sizeof(struct hw_fib))
 | 
			
		||||
			init->r7.init_struct_revision =
 | 
			
		||||
				cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4);
 | 
			
		||||
		init->r7.no_of_msix_vectors = cpu_to_le32(SA_MINIPORT_REVISION);
 | 
			
		||||
		init->r7.fsrev = cpu_to_le32(dev->fsrev);
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 *	Adapter Fibs are the first thing allocated so that they
 | 
			
		||||
		 *	start page aligned
 | 
			
		||||
		 */
 | 
			
		||||
		dev->aif_base_va = (struct hw_fib *)base;
 | 
			
		||||
 | 
			
		||||
		init->r7.adapter_fibs_virtual_address = 0;
 | 
			
		||||
		init->r7.adapter_fibs_physical_address = cpu_to_le32((u32)phys);
 | 
			
		||||
		init->r7.adapter_fibs_size = cpu_to_le32(fibsize);
 | 
			
		||||
		init->r7.adapter_fib_align = cpu_to_le32(sizeof(struct hw_fib));
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * number of 4k pages of host physical memory. The aacraid fw
 | 
			
		||||
		 * needs this number to be less than 4gb worth of pages. New
 | 
			
		||||
		 * firmware doesn't have any issues with the mapping system, but
 | 
			
		||||
		 * older Firmware did, and had *troubles* dealing with the math
 | 
			
		||||
		 * overloading past 32 bits, thus we must limit this field.
 | 
			
		||||
		 */
 | 
			
		||||
		aac_max_hostphysmempages =
 | 
			
		||||
				dma_get_required_mask(&dev->pdev->dev) >> 12;
 | 
			
		||||
		if (aac_max_hostphysmempages < AAC_MAX_HOSTPHYSMEMPAGES)
 | 
			
		||||
			init->r7.host_phys_mem_pages =
 | 
			
		||||
					cpu_to_le32(aac_max_hostphysmempages);
 | 
			
		||||
		else
 | 
			
		||||
			init->r7.host_phys_mem_pages =
 | 
			
		||||
					cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES);
 | 
			
		||||
 | 
			
		||||
		init->r7.init_flags =
 | 
			
		||||
			cpu_to_le32(INITFLAGS_DRIVER_USES_UTC_TIME |
 | 
			
		||||
			INITFLAGS_DRIVER_SUPPORTS_PM);
 | 
			
		||||
		init->r7.max_io_commands =
 | 
			
		||||
			cpu_to_le32(dev->scsi_host_ptr->can_queue +
 | 
			
		||||
					AAC_NUM_MGT_FIB);
 | 
			
		||||
		init->r7.max_io_size =
 | 
			
		||||
			cpu_to_le32(dev->scsi_host_ptr->max_sectors << 9);
 | 
			
		||||
		init->r7.max_fib_size = cpu_to_le32(dev->max_fib_size);
 | 
			
		||||
		init->r7.max_num_aif = cpu_to_le32(dev->max_num_aif);
 | 
			
		||||
 | 
			
		||||
		if (dev->comm_interface == AAC_COMM_MESSAGE) {
 | 
			
		||||
			init->r7.init_flags |=
 | 
			
		||||
				cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED);
 | 
			
		||||
			pr_warn("aacraid: Comm Interface enabled\n");
 | 
			
		||||
		} else if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE1) {
 | 
			
		||||
			init->r7.init_struct_revision =
 | 
			
		||||
				cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_6);
 | 
			
		||||
			init->r7.init_flags |=
 | 
			
		||||
				cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED |
 | 
			
		||||
				INITFLAGS_NEW_COMM_TYPE1_SUPPORTED |
 | 
			
		||||
				INITFLAGS_FAST_JBOD_SUPPORTED);
 | 
			
		||||
			init->r7.host_rrq_addr_high =
 | 
			
		||||
				cpu_to_le32(upper_32_bits(dev->host_rrq_pa));
 | 
			
		||||
			init->r7.host_rrq_addr_low =
 | 
			
		||||
				cpu_to_le32(lower_32_bits(dev->host_rrq_pa));
 | 
			
		||||
			pr_warn("aacraid: Comm Interface type1 enabled\n");
 | 
			
		||||
		} else if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) {
 | 
			
		||||
			init->r7.init_struct_revision =
 | 
			
		||||
				cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_7);
 | 
			
		||||
			init->r7.init_flags |=
 | 
			
		||||
				cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED |
 | 
			
		||||
				INITFLAGS_NEW_COMM_TYPE2_SUPPORTED |
 | 
			
		||||
				INITFLAGS_FAST_JBOD_SUPPORTED);
 | 
			
		||||
			init->r7.host_rrq_addr_high =
 | 
			
		||||
				cpu_to_le32(upper_32_bits(dev->host_rrq_pa));
 | 
			
		||||
			init->r7.host_rrq_addr_low =
 | 
			
		||||
				cpu_to_le32(lower_32_bits(dev->host_rrq_pa));
 | 
			
		||||
			init->r7.no_of_msix_vectors =
 | 
			
		||||
				cpu_to_le32(dev->max_msix);
 | 
			
		||||
			/* must be the COMM_PREFERRED_SETTINGS values */
 | 
			
		||||
			pr_warn("aacraid: Comm Interface type2 enabled\n");
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Increment the base address by the amount already used
 | 
			
		||||
	 */
 | 
			
		||||
	base = base + fibsize + host_rrq_size + sizeof(struct aac_init);
 | 
			
		||||
	base = base + fibsize + host_rrq_size + aac_init_size;
 | 
			
		||||
	phys = (dma_addr_t)((ulong)phys + fibsize + host_rrq_size +
 | 
			
		||||
		sizeof(struct aac_init));
 | 
			
		||||
			aac_init_size);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 *	Align the beginning of Headers to commalign
 | 
			
		||||
| 
						 | 
				
			
			@ -177,7 +240,8 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
 | 
			
		|||
	 *	Fill in addresses of the Comm Area Headers and Queues
 | 
			
		||||
	 */
 | 
			
		||||
	*commaddr = base;
 | 
			
		||||
	init->CommHeaderAddress = cpu_to_le32((u32)phys);
 | 
			
		||||
	if (dev->comm_interface != AAC_COMM_MESSAGE_TYPE3)
 | 
			
		||||
		init->r7.comm_header_address = cpu_to_le32((u32)phys);
 | 
			
		||||
	/*
 | 
			
		||||
	 *	Increment the base address by the size of the CommArea
 | 
			
		||||
	 */
 | 
			
		||||
| 
						 | 
				
			
			@ -187,12 +251,14 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
 | 
			
		|||
	 *	 Place the Printf buffer area after the Fast I/O comm area.
 | 
			
		||||
	 */
 | 
			
		||||
	dev->printfbuf = (void *)base;
 | 
			
		||||
	init->printfbuf = cpu_to_le32(phys);
 | 
			
		||||
	init->printfbufsiz = cpu_to_le32(printfbufsiz);
 | 
			
		||||
	if (dev->comm_interface != AAC_COMM_MESSAGE_TYPE3) {
 | 
			
		||||
		init->r7.printfbuf = cpu_to_le32(phys);
 | 
			
		||||
		init->r7.printfbufsiz = cpu_to_le32(printfbufsiz);
 | 
			
		||||
	}
 | 
			
		||||
	memset(base, 0, printfbufsiz);
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
static void aac_queue_init(struct aac_dev * dev, struct aac_queue * q, u32 *mem, int qsize)
 | 
			
		||||
{
 | 
			
		||||
	atomic_set(&q->numpending, 0);
 | 
			
		||||
| 
						 | 
				
			
			@ -436,26 +502,27 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
 | 
			
		|||
 | 
			
		||||
	if ((!aac_adapter_sync_cmd(dev, GET_ADAPTER_PROPERTIES,
 | 
			
		||||
		0, 0, 0, 0, 0, 0,
 | 
			
		||||
		status+0, status+1, status+2, status+3, NULL)) &&
 | 
			
		||||
	 		(status[0] == 0x00000001)) {
 | 
			
		||||
		status+0, status+1, status+2, status+3, status+4)) &&
 | 
			
		||||
		(status[0] == 0x00000001)) {
 | 
			
		||||
		dev->doorbell_mask = status[3];
 | 
			
		||||
		if (status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_64))
 | 
			
		||||
		if (status[1] & AAC_OPT_NEW_COMM_64)
 | 
			
		||||
			dev->raw_io_64 = 1;
 | 
			
		||||
		dev->sync_mode = aac_sync_mode;
 | 
			
		||||
		if (dev->a_ops.adapter_comm &&
 | 
			
		||||
			(status[1] & le32_to_cpu(AAC_OPT_NEW_COMM))) {
 | 
			
		||||
			(status[1] & AAC_OPT_NEW_COMM)) {
 | 
			
		||||
				dev->comm_interface = AAC_COMM_MESSAGE;
 | 
			
		||||
				dev->raw_io_interface = 1;
 | 
			
		||||
			if ((status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_TYPE1))) {
 | 
			
		||||
			if ((status[1] & AAC_OPT_NEW_COMM_TYPE1)) {
 | 
			
		||||
				/* driver supports TYPE1 (Tupelo) */
 | 
			
		||||
				dev->comm_interface = AAC_COMM_MESSAGE_TYPE1;
 | 
			
		||||
			} else if ((status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_TYPE2))) {
 | 
			
		||||
				/* driver supports TYPE2 (Denali) */
 | 
			
		||||
			} else if (status[1] & AAC_OPT_NEW_COMM_TYPE2) {
 | 
			
		||||
				/* driver supports TYPE2 (Denali, Yosemite) */
 | 
			
		||||
				dev->comm_interface = AAC_COMM_MESSAGE_TYPE2;
 | 
			
		||||
			} else if ((status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_TYPE4)) ||
 | 
			
		||||
				  (status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_TYPE3))) {
 | 
			
		||||
				/* driver doesn't TYPE3 and TYPE4 */
 | 
			
		||||
				/* switch to sync. mode */
 | 
			
		||||
			} else if (status[1] & AAC_OPT_NEW_COMM_TYPE3) {
 | 
			
		||||
				/* driver supports TYPE3 (Yosemite, Thor) */
 | 
			
		||||
				dev->comm_interface = AAC_COMM_MESSAGE_TYPE3;
 | 
			
		||||
			} else if (status[1] & AAC_OPT_NEW_COMM_TYPE4) {
 | 
			
		||||
				/* not supported TYPE - switch to sync. mode */
 | 
			
		||||
				dev->comm_interface = AAC_COMM_MESSAGE_TYPE2;
 | 
			
		||||
				dev->sync_mode = 1;
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -129,11 +129,14 @@ int aac_fib_setup(struct aac_dev * dev)
 | 
			
		|||
	struct hw_fib *hw_fib;
 | 
			
		||||
	dma_addr_t hw_fib_pa;
 | 
			
		||||
	int i;
 | 
			
		||||
	u32 max_cmds;
 | 
			
		||||
 | 
			
		||||
	while (((i = fib_map_alloc(dev)) == -ENOMEM)
 | 
			
		||||
	 && (dev->scsi_host_ptr->can_queue > (64 - AAC_NUM_MGT_FIB))) {
 | 
			
		||||
		dev->init->MaxIoCommands = cpu_to_le32((dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB) >> 1);
 | 
			
		||||
		dev->scsi_host_ptr->can_queue = le32_to_cpu(dev->init->MaxIoCommands) - AAC_NUM_MGT_FIB;
 | 
			
		||||
		max_cmds = (dev->scsi_host_ptr->can_queue+AAC_NUM_MGT_FIB) >> 1;
 | 
			
		||||
		dev->scsi_host_ptr->can_queue = max_cmds - AAC_NUM_MGT_FIB;
 | 
			
		||||
		if (dev->comm_interface != AAC_COMM_MESSAGE_TYPE3)
 | 
			
		||||
			dev->init->r7.max_io_commands = cpu_to_le32(max_cmds);
 | 
			
		||||
	}
 | 
			
		||||
	if (i<0)
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
| 
						 | 
				
			
			@ -761,7 +764,8 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size)
 | 
			
		|||
	unsigned long qflags;
 | 
			
		||||
 | 
			
		||||
	if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE1 ||
 | 
			
		||||
	    dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) {
 | 
			
		||||
		dev->comm_interface == AAC_COMM_MESSAGE_TYPE2 ||
 | 
			
		||||
		dev->comm_interface == AAC_COMM_MESSAGE_TYPE3) {
 | 
			
		||||
		kfree(hw_fib);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -1817,7 +1821,8 @@ int aac_command_thread(void *data)
 | 
			
		|||
				 * and pre-allocate a set of fibs outside the
 | 
			
		||||
				 * lock.
 | 
			
		||||
				 */
 | 
			
		||||
				num = le32_to_cpu(dev->init->AdapterFibsSize)
 | 
			
		||||
				num = le32_to_cpu(dev->init->
 | 
			
		||||
							r7.adapter_fibs_size)
 | 
			
		||||
				    / sizeof(struct hw_fib); /* some extra */
 | 
			
		||||
				spin_lock_irqsave(&dev->fib_lock, flagv);
 | 
			
		||||
				entry = dev->fib_list.next;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1368,7 +1368,7 @@ static int aac_acquire_resources(struct aac_dev *dev)
 | 
			
		|||
		/* After EEH recovery or suspend resume, max_msix count
 | 
			
		||||
		 * may change, therfore updating in init as well.
 | 
			
		||||
		 */
 | 
			
		||||
		dev->init->Sa_MSIXVectors = cpu_to_le32(dev->max_msix);
 | 
			
		||||
		dev->init->r7.no_of_msix_vectors = cpu_to_le32(dev->max_msix);
 | 
			
		||||
		aac_adapter_start(dev);
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,7 +60,7 @@ static int aac_rkt_select_comm(struct aac_dev *dev, int comm)
 | 
			
		|||
		 * case warrants this half baked, but convenient, check here.
 | 
			
		||||
		 */
 | 
			
		||||
		if (dev->scsi_host_ptr->can_queue > AAC_NUM_IO_FIB_RKT) {
 | 
			
		||||
			dev->init->MaxIoCommands =
 | 
			
		||||
			dev->init->r7.max_io_commands =
 | 
			
		||||
				cpu_to_le32(AAC_NUM_IO_FIB_RKT + AAC_NUM_MGT_FIB);
 | 
			
		||||
			dev->scsi_host_ptr->can_queue = AAC_NUM_IO_FIB_RKT;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -315,10 +315,10 @@ static void aac_rx_notify_adapter(struct aac_dev *dev, u32 event)
 | 
			
		|||
 | 
			
		||||
static void aac_rx_start_adapter(struct aac_dev *dev)
 | 
			
		||||
{
 | 
			
		||||
	struct aac_init *init;
 | 
			
		||||
	union aac_init *init;
 | 
			
		||||
 | 
			
		||||
	init = dev->init;
 | 
			
		||||
	init->HostElapsedSeconds = cpu_to_le32(get_seconds());
 | 
			
		||||
	init->r7.host_elapsed_seconds = cpu_to_le32(get_seconds());
 | 
			
		||||
	// We can only use a 32 bit address here
 | 
			
		||||
	rx_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa,
 | 
			
		||||
	  0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -245,12 +245,12 @@ static void aac_sa_interrupt_adapter (struct aac_dev *dev)
 | 
			
		|||
 | 
			
		||||
static void aac_sa_start_adapter(struct aac_dev *dev)
 | 
			
		||||
{
 | 
			
		||||
	struct aac_init *init;
 | 
			
		||||
	union aac_init *init;
 | 
			
		||||
	/*
 | 
			
		||||
	 * Fill in the remaining pieces of the init.
 | 
			
		||||
	 */
 | 
			
		||||
	init = dev->init;
 | 
			
		||||
	init->HostElapsedSeconds = cpu_to_le32(get_seconds());
 | 
			
		||||
	init->r7.host_elapsed_seconds = cpu_to_le32(get_seconds());
 | 
			
		||||
	/* We can only use a 32 bit address here */
 | 
			
		||||
	sa_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, 
 | 
			
		||||
			(u32)(ulong)dev->init_pa, 0, 0, 0, 0, 0,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -384,7 +384,7 @@ static void aac_src_notify_adapter(struct aac_dev *dev, u32 event)
 | 
			
		|||
 | 
			
		||||
static void aac_src_start_adapter(struct aac_dev *dev)
 | 
			
		||||
{
 | 
			
		||||
	struct aac_init *init;
 | 
			
		||||
	union aac_init *init;
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	 /* reset host_rrq_idx first */
 | 
			
		||||
| 
						 | 
				
			
			@ -395,11 +395,22 @@ static void aac_src_start_adapter(struct aac_dev *dev)
 | 
			
		|||
	dev->fibs_pushed_no = 0;
 | 
			
		||||
 | 
			
		||||
	init = dev->init;
 | 
			
		||||
	init->HostElapsedSeconds = cpu_to_le32(get_seconds());
 | 
			
		||||
	if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE3) {
 | 
			
		||||
		init->r8.host_elapsed_seconds = cpu_to_le32(get_seconds());
 | 
			
		||||
		src_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS,
 | 
			
		||||
			(u32)(ulong)dev->init_pa,
 | 
			
		||||
			(u32)((ulong)dev->init_pa>>32),
 | 
			
		||||
			sizeof(struct _r8) +
 | 
			
		||||
			(AAC_MAX_HRRQ - 1) * sizeof(struct _rrq),
 | 
			
		||||
			0, 0, 0, NULL, NULL, NULL, NULL, NULL);
 | 
			
		||||
	} else {
 | 
			
		||||
		init->r7.host_elapsed_seconds = cpu_to_le32(get_seconds());
 | 
			
		||||
		// We can only use a 32 bit address here
 | 
			
		||||
		src_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS,
 | 
			
		||||
			(u32)(ulong)dev->init_pa, 0, 0, 0, 0, 0,
 | 
			
		||||
			NULL, NULL, NULL, NULL, NULL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* We can only use a 32 bit address here */
 | 
			
		||||
	src_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa,
 | 
			
		||||
	  0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -467,7 +478,8 @@ static int aac_src_deliver_message(struct fib *fib)
 | 
			
		|||
 | 
			
		||||
	atomic_inc(&dev->rrq_outstanding[vector_no]);
 | 
			
		||||
 | 
			
		||||
	if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) {
 | 
			
		||||
	if ((dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) ||
 | 
			
		||||
		(dev->comm_interface == AAC_COMM_MESSAGE_TYPE3)) {
 | 
			
		||||
		/* Calculate the amount to the fibsize bits */
 | 
			
		||||
		fibsize = (hdr_size + 127) / 128 - 1;
 | 
			
		||||
		if (fibsize > (ALIGN32 - 1))
 | 
			
		||||
| 
						 | 
				
			
			@ -897,7 +909,8 @@ int aac_srcv_init(struct aac_dev *dev)
 | 
			
		|||
 | 
			
		||||
	if (aac_init_adapter(dev) == NULL)
 | 
			
		||||
		goto error_iounmap;
 | 
			
		||||
	if (dev->comm_interface != AAC_COMM_MESSAGE_TYPE2)
 | 
			
		||||
	if ((dev->comm_interface != AAC_COMM_MESSAGE_TYPE2) &&
 | 
			
		||||
		(dev->comm_interface != AAC_COMM_MESSAGE_TYPE3))
 | 
			
		||||
		goto error_iounmap;
 | 
			
		||||
	if (dev->msi_enabled)
 | 
			
		||||
		aac_src_access_devreg(dev, AAC_ENABLE_MSIX);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue