aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/aacraid/comminit.c
diff options
context:
space:
mode:
authorMahesh Rajashekhara <Mahesh_Rajashekhara@pmc-sierra.com>2011-03-17 05:10:32 -0400
committerJames Bottomley <James.Bottomley@suse.de>2011-03-23 12:36:58 -0400
commite8b12f0fb8352237525961f14ec933e915848840 (patch)
treecdbf1209bdb6dc300434a6608e5ac73d536e47c0 /drivers/scsi/aacraid/comminit.c
parent0a2385cea9a715e11df10fce1f1442d933008a40 (diff)
[SCSI] aacraid: Add new code for PMC-Sierra's SRC based controller family
Added new hardware device 0x28b interface for PMC-Sierra's SRC based controller family. - new src.c file for 0x28b specific functions - new XPORT header required - sync. command interface: doorbell bits shifted (SRC_ODR_SHIFT, SRC_IDR_SHIFT) - async. Interface: different inbound queue handling, no outbound I2O queue available, using doorbell ("PmDoorBellResponseSent") and response buffer on the host ("host_rrq") for status - changed AIF (adapter initiated FIBs) interface: "DoorBellAifPending" bit to inform about pending AIF, "AifRequest" command to read AIF, "NoMoreAifDataAvailable" to mark the end of the AIFs Signed-off-by: Mahesh Rajashekhara <aacraid@pmc-sierra.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/aacraid/comminit.c')
-rw-r--r--drivers/scsi/aacraid/comminit.c58
1 files changed, 45 insertions, 13 deletions
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
index a7261486ccd4..7ac8fdb5577b 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -5,7 +5,8 @@
5 * based on the old aacraid driver that is.. 5 * based on the old aacraid driver that is..
6 * Adaptec aacraid device driver for Linux. 6 * Adaptec aacraid device driver for Linux.
7 * 7 *
8 * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid@adaptec.com) 8 * Copyright (c) 2000-2010 Adaptec, Inc.
9 * 2010 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by 12 * it under the terms of the GNU General Public License as published by
@@ -52,12 +53,16 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
52 unsigned long size, align; 53 unsigned long size, align;
53 const unsigned long fibsize = 4096; 54 const unsigned long fibsize = 4096;
54 const unsigned long printfbufsiz = 256; 55 const unsigned long printfbufsiz = 256;
56 unsigned long host_rrq_size = 0;
55 struct aac_init *init; 57 struct aac_init *init;
56 dma_addr_t phys; 58 dma_addr_t phys;
57 unsigned long aac_max_hostphysmempages; 59 unsigned long aac_max_hostphysmempages;
58 60
59 size = fibsize + sizeof(struct aac_init) + commsize + commalign + printfbufsiz; 61 if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE1)
60 62 host_rrq_size = (dev->scsi_host_ptr->can_queue
63 + AAC_NUM_MGT_FIB) * sizeof(u32);
64 size = fibsize + sizeof(struct aac_init) + commsize +
65 commalign + printfbufsiz + host_rrq_size;
61 66
62 base = pci_alloc_consistent(dev->pdev, size, &phys); 67 base = pci_alloc_consistent(dev->pdev, size, &phys);
63 68
@@ -70,8 +75,14 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
70 dev->comm_phys = phys; 75 dev->comm_phys = phys;
71 dev->comm_size = size; 76 dev->comm_size = size;
72 77
73 dev->init = (struct aac_init *)(base + fibsize); 78 if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE1) {
74 dev->init_pa = phys + fibsize; 79 dev->host_rrq = (u32 *)(base + fibsize);
80 dev->host_rrq_pa = phys + fibsize;
81 memset(dev->host_rrq, 0, host_rrq_size);
82 }
83
84 dev->init = (struct aac_init *)(base + fibsize + host_rrq_size);
85 dev->init_pa = phys + fibsize + host_rrq_size;
75 86
76 init = dev->init; 87 init = dev->init;
77 88
@@ -106,8 +117,13 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
106 117
107 init->InitFlags = 0; 118 init->InitFlags = 0;
108 if (dev->comm_interface == AAC_COMM_MESSAGE) { 119 if (dev->comm_interface == AAC_COMM_MESSAGE) {
109 init->InitFlags = cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED); 120 init->InitFlags |= cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED);
110 dprintk((KERN_WARNING"aacraid: New Comm Interface enabled\n")); 121 dprintk((KERN_WARNING"aacraid: New Comm Interface enabled\n"));
122 } else if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE1) {
123 init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_6);
124 init->InitFlags |= cpu_to_le32(INITFLAGS_NEW_COMM_TYPE1_SUPPORTED);
125 dprintk((KERN_WARNING
126 "aacraid: New Comm Interface type1 enabled\n"));
111 } 127 }
112 init->InitFlags |= cpu_to_le32(INITFLAGS_DRIVER_USES_UTC_TIME | 128 init->InitFlags |= cpu_to_le32(INITFLAGS_DRIVER_USES_UTC_TIME |
113 INITFLAGS_DRIVER_SUPPORTS_PM); 129 INITFLAGS_DRIVER_SUPPORTS_PM);
@@ -115,11 +131,18 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
115 init->MaxIoSize = cpu_to_le32(dev->scsi_host_ptr->max_sectors << 9); 131 init->MaxIoSize = cpu_to_le32(dev->scsi_host_ptr->max_sectors << 9);
116 init->MaxFibSize = cpu_to_le32(dev->max_fib_size); 132 init->MaxFibSize = cpu_to_le32(dev->max_fib_size);
117 133
134 init->MaxNumAif = cpu_to_le32(dev->max_num_aif);
135 init->HostRRQ_AddrHigh = (u32)((u64)dev->host_rrq_pa >> 32);
136 init->HostRRQ_AddrLow = (u32)(dev->host_rrq_pa & 0xffffffff);
137
138
118 /* 139 /*
119 * Increment the base address by the amount already used 140 * Increment the base address by the amount already used
120 */ 141 */
121 base = base + fibsize + sizeof(struct aac_init); 142 base = base + fibsize + host_rrq_size + sizeof(struct aac_init);
122 phys = (dma_addr_t)((ulong)phys + fibsize + sizeof(struct aac_init)); 143 phys = (dma_addr_t)((ulong)phys + fibsize + host_rrq_size +
144 sizeof(struct aac_init));
145
123 /* 146 /*
124 * Align the beginning of Headers to commalign 147 * Align the beginning of Headers to commalign
125 */ 148 */
@@ -314,15 +337,22 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
314 - sizeof(struct aac_write) + sizeof(struct sgentry)) 337 - sizeof(struct aac_write) + sizeof(struct sgentry))
315 / sizeof(struct sgentry); 338 / sizeof(struct sgentry);
316 dev->comm_interface = AAC_COMM_PRODUCER; 339 dev->comm_interface = AAC_COMM_PRODUCER;
317 dev->raw_io_64 = 0; 340 dev->raw_io_interface = dev->raw_io_64 = 0;
341
318 if ((!aac_adapter_sync_cmd(dev, GET_ADAPTER_PROPERTIES, 342 if ((!aac_adapter_sync_cmd(dev, GET_ADAPTER_PROPERTIES,
319 0, 0, 0, 0, 0, 0, status+0, status+1, status+2, NULL, NULL)) && 343 0, 0, 0, 0, 0, 0, status+0, status+1, status+2, NULL, NULL)) &&
320 (status[0] == 0x00000001)) { 344 (status[0] == 0x00000001)) {
321 if (status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_64)) 345 if (status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_64))
322 dev->raw_io_64 = 1; 346 dev->raw_io_64 = 1;
323 if (dev->a_ops.adapter_comm && 347 if (dev->a_ops.adapter_comm) {
324 (status[1] & le32_to_cpu(AAC_OPT_NEW_COMM))) 348 if (status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_TYPE1)) {
325 dev->comm_interface = AAC_COMM_MESSAGE; 349 dev->comm_interface = AAC_COMM_MESSAGE_TYPE1;
350 dev->raw_io_interface = 1;
351 } else if (status[1] & le32_to_cpu(AAC_OPT_NEW_COMM)) {
352 dev->comm_interface = AAC_COMM_MESSAGE;
353 dev->raw_io_interface = 1;
354 }
355 }
326 if ((dev->comm_interface == AAC_COMM_MESSAGE) && 356 if ((dev->comm_interface == AAC_COMM_MESSAGE) &&
327 (status[2] > dev->base_size)) { 357 (status[2] > dev->base_size)) {
328 aac_adapter_ioremap(dev, 0); 358 aac_adapter_ioremap(dev, 0);
@@ -350,10 +380,12 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
350 * status[3] & 0xFFFF maximum number FIBs outstanding 380 * status[3] & 0xFFFF maximum number FIBs outstanding
351 */ 381 */
352 host->max_sectors = (status[1] >> 16) << 1; 382 host->max_sectors = (status[1] >> 16) << 1;
353 dev->max_fib_size = status[1] & 0xFFFF; 383 /* Multiple of 32 for PMC */
384 dev->max_fib_size = status[1] & 0xFFE0;
354 host->sg_tablesize = status[2] >> 16; 385 host->sg_tablesize = status[2] >> 16;
355 dev->sg_tablesize = status[2] & 0xFFFF; 386 dev->sg_tablesize = status[2] & 0xFFFF;
356 host->can_queue = (status[3] & 0xFFFF) - AAC_NUM_MGT_FIB; 387 host->can_queue = (status[3] & 0xFFFF) - AAC_NUM_MGT_FIB;
388 dev->max_num_aif = status[4] & 0xFFFF;
357 /* 389 /*
358 * NOTE: 390 * NOTE:
359 * All these overrides are based on a fixed internal 391 * All these overrides are based on a fixed internal