aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/Kconfig5
-rw-r--r--drivers/scsi/Makefile2
-rw-r--r--drivers/scsi/aic94xx/Kconfig41
-rw-r--r--drivers/scsi/aic94xx/Makefile39
-rw-r--r--drivers/scsi/aic94xx/aic94xx.h114
-rw-r--r--drivers/scsi/aic94xx/aic94xx_dev.c353
-rw-r--r--drivers/scsi/aic94xx/aic94xx_dump.c959
-rw-r--r--drivers/scsi/aic94xx/aic94xx_dump.h52
-rw-r--r--drivers/scsi/aic94xx/aic94xx_hwi.c1376
-rw-r--r--drivers/scsi/aic94xx/aic94xx_hwi.h397
-rw-r--r--drivers/scsi/aic94xx/aic94xx_init.c860
-rw-r--r--drivers/scsi/aic94xx/aic94xx_reg.c332
-rw-r--r--drivers/scsi/aic94xx/aic94xx_reg.h302
-rw-r--r--drivers/scsi/aic94xx/aic94xx_reg_def.h2398
-rw-r--r--drivers/scsi/aic94xx/aic94xx_sas.h785
-rw-r--r--drivers/scsi/aic94xx/aic94xx_scb.c732
-rw-r--r--drivers/scsi/aic94xx/aic94xx_sds.c1136
-rw-r--r--drivers/scsi/aic94xx/aic94xx_seq.c1401
-rw-r--r--drivers/scsi/aic94xx/aic94xx_seq.h70
-rw-r--r--drivers/scsi/aic94xx/aic94xx_task.c642
-rw-r--r--drivers/scsi/aic94xx/aic94xx_tmf.c636
-rw-r--r--drivers/scsi/libsas/Kconfig39
-rw-r--r--drivers/scsi/libsas/Makefile36
-rw-r--r--drivers/scsi/libsas/sas_discover.c749
-rw-r--r--drivers/scsi/libsas/sas_dump.c76
-rw-r--r--drivers/scsi/libsas/sas_dump.h42
-rw-r--r--drivers/scsi/libsas/sas_event.c75
-rw-r--r--drivers/scsi/libsas/sas_expander.c1862
-rw-r--r--drivers/scsi/libsas/sas_init.c227
-rw-r--r--drivers/scsi/libsas/sas_internal.h146
-rw-r--r--drivers/scsi/libsas/sas_phy.c157
-rw-r--r--drivers/scsi/libsas/sas_port.c279
-rw-r--r--drivers/scsi/libsas/sas_scsi_host.c786
33 files changed, 17105 insertions, 1 deletions
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index d61662c1a0ee..7de5fdfdab67 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -209,7 +209,7 @@ config SCSI_LOGGING
209 there should be no noticeable performance impact as long as you have 209 there should be no noticeable performance impact as long as you have
210 logging turned off. 210 logging turned off.
211 211
212menu "SCSI Transport Attributes" 212menu "SCSI Transports"
213 depends on SCSI 213 depends on SCSI
214 214
215config SCSI_SPI_ATTRS 215config SCSI_SPI_ATTRS
@@ -242,6 +242,8 @@ config SCSI_SAS_ATTRS
242 If you wish to export transport-specific information about 242 If you wish to export transport-specific information about
243 each attached SAS device to sysfs, say Y. 243 each attached SAS device to sysfs, say Y.
244 244
245source "drivers/scsi/libsas/Kconfig"
246
245endmenu 247endmenu
246 248
247menu "SCSI low-level drivers" 249menu "SCSI low-level drivers"
@@ -431,6 +433,7 @@ config SCSI_AIC7XXX_OLD
431 module will be called aic7xxx_old. 433 module will be called aic7xxx_old.
432 434
433source "drivers/scsi/aic7xxx/Kconfig.aic79xx" 435source "drivers/scsi/aic7xxx/Kconfig.aic79xx"
436source "drivers/scsi/aic94xx/Kconfig"
434 437
435# All the I2O code and drivers do not seem to be 64bit safe. 438# All the I2O code and drivers do not seem to be 64bit safe.
436config SCSI_DPT_I2O 439config SCSI_DPT_I2O
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index b2de9bfdfdcd..83da70decdd1 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_SCSI_SPI_ATTRS) += scsi_transport_spi.o
32obj-$(CONFIG_SCSI_FC_ATTRS) += scsi_transport_fc.o 32obj-$(CONFIG_SCSI_FC_ATTRS) += scsi_transport_fc.o
33obj-$(CONFIG_SCSI_ISCSI_ATTRS) += scsi_transport_iscsi.o 33obj-$(CONFIG_SCSI_ISCSI_ATTRS) += scsi_transport_iscsi.o
34obj-$(CONFIG_SCSI_SAS_ATTRS) += scsi_transport_sas.o 34obj-$(CONFIG_SCSI_SAS_ATTRS) += scsi_transport_sas.o
35obj-$(CONFIG_SCSI_SAS_LIBSAS) += libsas/
35 36
36obj-$(CONFIG_ISCSI_TCP) += libiscsi.o iscsi_tcp.o 37obj-$(CONFIG_ISCSI_TCP) += libiscsi.o iscsi_tcp.o
37obj-$(CONFIG_INFINIBAND_ISER) += libiscsi.o 38obj-$(CONFIG_INFINIBAND_ISER) += libiscsi.o
@@ -68,6 +69,7 @@ obj-$(CONFIG_SCSI_AIC7XXX) += aic7xxx/
68obj-$(CONFIG_SCSI_AIC79XX) += aic7xxx/ 69obj-$(CONFIG_SCSI_AIC79XX) += aic7xxx/
69obj-$(CONFIG_SCSI_AACRAID) += aacraid/ 70obj-$(CONFIG_SCSI_AACRAID) += aacraid/
70obj-$(CONFIG_SCSI_AIC7XXX_OLD) += aic7xxx_old.o 71obj-$(CONFIG_SCSI_AIC7XXX_OLD) += aic7xxx_old.o
72obj-$(CONFIG_SCSI_AIC94XX) += aic94xx/
71obj-$(CONFIG_SCSI_IPS) += ips.o 73obj-$(CONFIG_SCSI_IPS) += ips.o
72obj-$(CONFIG_SCSI_FD_MCS) += fd_mcs.o 74obj-$(CONFIG_SCSI_FD_MCS) += fd_mcs.o
73obj-$(CONFIG_SCSI_FUTURE_DOMAIN)+= fdomain.o 75obj-$(CONFIG_SCSI_FUTURE_DOMAIN)+= fdomain.o
diff --git a/drivers/scsi/aic94xx/Kconfig b/drivers/scsi/aic94xx/Kconfig
new file mode 100644
index 000000000000..0ed391d8ee84
--- /dev/null
+++ b/drivers/scsi/aic94xx/Kconfig
@@ -0,0 +1,41 @@
1#
2# Kernel configuration file for aic94xx SAS/SATA driver.
3#
4# Copyright (c) 2005 Adaptec, Inc. All rights reserved.
5# Copyright (c) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
6#
7# This file is licensed under GPLv2.
8#
9# This file is part of the aic94xx driver.
10#
11# The aic94xx driver is free software; you can redistribute it and/or
12# modify it under the terms of the GNU General Public License as
13# published by the Free Software Foundation; version 2 of the
14# License.
15#
16# The aic94xx driver is distributed in the hope that it will be useful,
17# but WITHOUT ANY WARRANTY; without even the implied warranty of
18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19# General Public License for more details.
20#
21# You should have received a copy of the GNU General Public License
22# along with Aic94xx Driver; if not, write to the Free Software
23# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24#
25#
26
27config SCSI_AIC94XX
28 tristate "Adaptec AIC94xx SAS/SATA support"
29 depends on PCI
30 select SCSI_SAS_LIBSAS
31 help
32 This driver supports Adaptec's SAS/SATA 3Gb/s 64 bit PCI-X
33 AIC94xx chip based host adapters.
34
35config AIC94XX_DEBUG
36 bool "Compile in debug mode"
37 default y
38 depends on SCSI_AIC94XX
39 help
40 Compiles the aic94xx driver in debug mode. In debug mode,
41 the driver prints some messages to the console.
diff --git a/drivers/scsi/aic94xx/Makefile b/drivers/scsi/aic94xx/Makefile
new file mode 100644
index 000000000000..e6b70123940c
--- /dev/null
+++ b/drivers/scsi/aic94xx/Makefile
@@ -0,0 +1,39 @@
1#
2# Makefile for Adaptec aic94xx SAS/SATA driver.
3#
4# Copyright (C) 2005 Adaptec, Inc. All rights reserved.
5# Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
6#
7# This file is licensed under GPLv2.
8#
9# This file is part of the the aic94xx driver.
10#
11# The aic94xx driver is free software; you can redistribute it and/or
12# modify it under the terms of the GNU General Public License as
13# published by the Free Software Foundation; version 2 of the
14# License.
15#
16# The aic94xx driver is distributed in the hope that it will be useful,
17# but WITHOUT ANY WARRANTY; without even the implied warranty of
18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19# General Public License for more details.
20#
21# You should have received a copy of the GNU General Public License
22# along with the aic94xx driver; if not, write to the Free Software
23# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24
25ifeq ($(CONFIG_AIC94XX_DEBUG),y)
26 EXTRA_CFLAGS += -DASD_DEBUG -DASD_ENTER_EXIT
27endif
28
29obj-$(CONFIG_SCSI_AIC94XX) += aic94xx.o
30aic94xx-y += aic94xx_init.o \
31 aic94xx_hwi.o \
32 aic94xx_reg.o \
33 aic94xx_sds.o \
34 aic94xx_seq.o \
35 aic94xx_dump.o \
36 aic94xx_scb.o \
37 aic94xx_dev.o \
38 aic94xx_tmf.o \
39 aic94xx_task.o
diff --git a/drivers/scsi/aic94xx/aic94xx.h b/drivers/scsi/aic94xx/aic94xx.h
new file mode 100644
index 000000000000..cb7caf1c9ce1
--- /dev/null
+++ b/drivers/scsi/aic94xx/aic94xx.h
@@ -0,0 +1,114 @@
1/*
2 * Aic94xx SAS/SATA driver header file.
3 *
4 * Copyright (C) 2005 Adaptec, Inc. All rights reserved.
5 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
6 *
7 * This file is licensed under GPLv2.
8 *
9 * This file is part of the aic94xx driver.
10 *
11 * The aic94xx driver is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; version 2 of the
14 * License.
15 *
16 * The aic94xx driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with the aic94xx driver; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 *
25 * $Id: //depot/aic94xx/aic94xx.h#31 $
26 */
27
28#ifndef _AIC94XX_H_
29#define _AIC94XX_H_
30
31#include <linux/slab.h>
32#include <linux/ctype.h>
33#include <scsi/libsas.h>
34
35#define ASD_DRIVER_NAME "aic94xx"
36#define ASD_DRIVER_DESCRIPTION "Adaptec aic94xx SAS/SATA driver"
37
38#define asd_printk(fmt, ...) printk(KERN_NOTICE ASD_DRIVER_NAME ": " fmt, ## __VA_ARGS__)
39
40#ifdef ASD_ENTER_EXIT
41#define ENTER printk(KERN_NOTICE "%s: ENTER %s\n", ASD_DRIVER_NAME, \
42 __FUNCTION__)
43#define EXIT printk(KERN_NOTICE "%s: --EXIT %s\n", ASD_DRIVER_NAME, \
44 __FUNCTION__)
45#else
46#define ENTER
47#define EXIT
48#endif
49
50#ifdef ASD_DEBUG
51#define ASD_DPRINTK asd_printk
52#else
53#define ASD_DPRINTK(fmt, ...)
54#endif
55
56/* 2*ITNL timeout + 1 second */
57#define AIC94XX_SCB_TIMEOUT (5*HZ)
58
59extern kmem_cache_t *asd_dma_token_cache;
60extern kmem_cache_t *asd_ascb_cache;
61extern char sas_addr_str[2*SAS_ADDR_SIZE + 1];
62
63static inline void asd_stringify_sas_addr(char *p, const u8 *sas_addr)
64{
65 int i;
66 for (i = 0; i < SAS_ADDR_SIZE; i++, p += 2)
67 snprintf(p, 3, "%02X", sas_addr[i]);
68 *p = '\0';
69}
70
71static inline void asd_destringify_sas_addr(u8 *sas_addr, const char *p)
72{
73 int i;
74 for (i = 0; i < SAS_ADDR_SIZE; i++) {
75 u8 h, l;
76 if (!*p)
77 break;
78 h = isdigit(*p) ? *p-'0' : *p-'A'+10;
79 p++;
80 l = isdigit(*p) ? *p-'0' : *p-'A'+10;
81 p++;
82 sas_addr[i] = (h<<4) | l;
83 }
84}
85
86struct asd_ha_struct;
87struct asd_ascb;
88
89int asd_read_ocm(struct asd_ha_struct *asd_ha);
90int asd_read_flash(struct asd_ha_struct *asd_ha);
91
92int asd_dev_found(struct domain_device *dev);
93void asd_dev_gone(struct domain_device *dev);
94
95void asd_invalidate_edb(struct asd_ascb *ascb, int edb_id);
96
97int asd_execute_task(struct sas_task *, int num, unsigned long gfp_flags);
98
99/* ---------- TMFs ---------- */
100int asd_abort_task(struct sas_task *);
101int asd_abort_task_set(struct domain_device *, u8 *lun);
102int asd_clear_aca(struct domain_device *, u8 *lun);
103int asd_clear_task_set(struct domain_device *, u8 *lun);
104int asd_lu_reset(struct domain_device *, u8 *lun);
105int asd_query_task(struct sas_task *);
106
107/* ---------- Adapter and Port management ---------- */
108int asd_clear_nexus_port(struct asd_sas_port *port);
109int asd_clear_nexus_ha(struct sas_ha_struct *sas_ha);
110
111/* ---------- Phy Management ---------- */
112int asd_control_phy(struct asd_sas_phy *phy, enum phy_func func);
113
114#endif
diff --git a/drivers/scsi/aic94xx/aic94xx_dev.c b/drivers/scsi/aic94xx/aic94xx_dev.c
new file mode 100644
index 000000000000..6f8901b748f7
--- /dev/null
+++ b/drivers/scsi/aic94xx/aic94xx_dev.c
@@ -0,0 +1,353 @@
1/*
2 * Aic94xx SAS/SATA DDB management
3 *
4 * Copyright (C) 2005 Adaptec, Inc. All rights reserved.
5 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
6 *
7 * This file is licensed under GPLv2.
8 *
9 * This file is part of the aic94xx driver.
10 *
11 * The aic94xx driver is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; version 2 of the
14 * License.
15 *
16 * The aic94xx driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with the aic94xx driver; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 *
25 * $Id: //depot/aic94xx/aic94xx_dev.c#21 $
26 */
27
28#include "aic94xx.h"
29#include "aic94xx_hwi.h"
30#include "aic94xx_reg.h"
31#include "aic94xx_sas.h"
32
33#define FIND_FREE_DDB(_ha) find_first_zero_bit((_ha)->hw_prof.ddb_bitmap, \
34 (_ha)->hw_prof.max_ddbs)
35#define SET_DDB(_ddb, _ha) set_bit(_ddb, (_ha)->hw_prof.ddb_bitmap)
36#define CLEAR_DDB(_ddb, _ha) clear_bit(_ddb, (_ha)->hw_prof.ddb_bitmap)
37
38static inline int asd_get_ddb(struct asd_ha_struct *asd_ha)
39{
40 unsigned long flags;
41 int ddb, i;
42
43 spin_lock_irqsave(&asd_ha->hw_prof.ddb_lock, flags);
44 ddb = FIND_FREE_DDB(asd_ha);
45 if (ddb >= asd_ha->hw_prof.max_ddbs) {
46 ddb = -ENOMEM;
47 spin_unlock_irqrestore(&asd_ha->hw_prof.ddb_lock, flags);
48 goto out;
49 }
50 SET_DDB(ddb, asd_ha);
51 spin_unlock_irqrestore(&asd_ha->hw_prof.ddb_lock, flags);
52
53 for (i = 0; i < sizeof(struct asd_ddb_ssp_smp_target_port); i+= 4)
54 asd_ddbsite_write_dword(asd_ha, ddb, i, 0);
55out:
56 return ddb;
57}
58
59#define INIT_CONN_TAG offsetof(struct asd_ddb_ssp_smp_target_port, init_conn_tag)
60#define DEST_SAS_ADDR offsetof(struct asd_ddb_ssp_smp_target_port, dest_sas_addr)
61#define SEND_QUEUE_HEAD offsetof(struct asd_ddb_ssp_smp_target_port, send_queue_head)
62#define DDB_TYPE offsetof(struct asd_ddb_ssp_smp_target_port, ddb_type)
63#define CONN_MASK offsetof(struct asd_ddb_ssp_smp_target_port, conn_mask)
64#define DDB_TARG_FLAGS offsetof(struct asd_ddb_ssp_smp_target_port, flags)
65#define DDB_TARG_FLAGS2 offsetof(struct asd_ddb_stp_sata_target_port, flags2)
66#define EXEC_QUEUE_TAIL offsetof(struct asd_ddb_ssp_smp_target_port, exec_queue_tail)
67#define SEND_QUEUE_TAIL offsetof(struct asd_ddb_ssp_smp_target_port, send_queue_tail)
68#define SISTER_DDB offsetof(struct asd_ddb_ssp_smp_target_port, sister_ddb)
69#define MAX_CCONN offsetof(struct asd_ddb_ssp_smp_target_port, max_concurrent_conn)
70#define NUM_CTX offsetof(struct asd_ddb_ssp_smp_target_port, num_contexts)
71#define ATA_CMD_SCBPTR offsetof(struct asd_ddb_stp_sata_target_port, ata_cmd_scbptr)
72#define SATA_TAG_ALLOC_MASK offsetof(struct asd_ddb_stp_sata_target_port, sata_tag_alloc_mask)
73#define NUM_SATA_TAGS offsetof(struct asd_ddb_stp_sata_target_port, num_sata_tags)
74#define SATA_STATUS offsetof(struct asd_ddb_stp_sata_target_port, sata_status)
75#define NCQ_DATA_SCB_PTR offsetof(struct asd_ddb_stp_sata_target_port, ncq_data_scb_ptr)
76#define ITNL_TIMEOUT offsetof(struct asd_ddb_ssp_smp_target_port, itnl_timeout)
77
78static inline void asd_free_ddb(struct asd_ha_struct *asd_ha, int ddb)
79{
80 unsigned long flags;
81
82 if (!ddb || ddb >= 0xFFFF)
83 return;
84 asd_ddbsite_write_byte(asd_ha, ddb, DDB_TYPE, DDB_TYPE_UNUSED);
85 spin_lock_irqsave(&asd_ha->hw_prof.ddb_lock, flags);
86 CLEAR_DDB(ddb, asd_ha);
87 spin_unlock_irqrestore(&asd_ha->hw_prof.ddb_lock, flags);
88}
89
90static inline void asd_set_ddb_type(struct domain_device *dev)
91{
92 struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha;
93 int ddb = (int) (unsigned long) dev->lldd_dev;
94
95 if (dev->dev_type == SATA_PM_PORT)
96 asd_ddbsite_write_byte(asd_ha,ddb, DDB_TYPE, DDB_TYPE_PM_PORT);
97 else if (dev->tproto)
98 asd_ddbsite_write_byte(asd_ha,ddb, DDB_TYPE, DDB_TYPE_TARGET);
99 else
100 asd_ddbsite_write_byte(asd_ha,ddb,DDB_TYPE,DDB_TYPE_INITIATOR);
101}
102
103static int asd_init_sata_tag_ddb(struct domain_device *dev)
104{
105 struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha;
106 int ddb, i;
107
108 ddb = asd_get_ddb(asd_ha);
109 if (ddb < 0)
110 return ddb;
111
112 for (i = 0; i < sizeof(struct asd_ddb_sata_tag); i += 2)
113 asd_ddbsite_write_word(asd_ha, ddb, i, 0xFFFF);
114
115 asd_ddbsite_write_word(asd_ha, (int) (unsigned long) dev->lldd_dev,
116 SISTER_DDB, ddb);
117 return 0;
118}
119
120static inline int asd_init_sata(struct domain_device *dev)
121{
122 struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha;
123 int ddb = (int) (unsigned long) dev->lldd_dev;
124 u32 qdepth = 0;
125 int res = 0;
126
127 asd_ddbsite_write_word(asd_ha, ddb, ATA_CMD_SCBPTR, 0xFFFF);
128 if ((dev->dev_type == SATA_DEV || dev->dev_type == SATA_PM_PORT) &&
129 dev->sata_dev.identify_device &&
130 dev->sata_dev.identify_device[10] != 0) {
131 u16 w75 = le16_to_cpu(dev->sata_dev.identify_device[75]);
132 u16 w76 = le16_to_cpu(dev->sata_dev.identify_device[76]);
133
134 if (w76 & 0x100) /* NCQ? */
135 qdepth = (w75 & 0x1F) + 1;
136 asd_ddbsite_write_dword(asd_ha, ddb, SATA_TAG_ALLOC_MASK,
137 (1<<qdepth)-1);
138 asd_ddbsite_write_byte(asd_ha, ddb, NUM_SATA_TAGS, qdepth);
139 }
140 if (dev->dev_type == SATA_DEV || dev->dev_type == SATA_PM ||
141 dev->dev_type == SATA_PM_PORT) {
142 struct dev_to_host_fis *fis = (struct dev_to_host_fis *)
143 dev->frame_rcvd;
144 asd_ddbsite_write_byte(asd_ha, ddb, SATA_STATUS, fis->status);
145 }
146 asd_ddbsite_write_word(asd_ha, ddb, NCQ_DATA_SCB_PTR, 0xFFFF);
147 if (qdepth > 0)
148 res = asd_init_sata_tag_ddb(dev);
149 return res;
150}
151
152static int asd_init_target_ddb(struct domain_device *dev)
153{
154 int ddb, i;
155 struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha;
156 u8 flags = 0;
157
158 ddb = asd_get_ddb(asd_ha);
159 if (ddb < 0)
160 return ddb;
161
162 dev->lldd_dev = (void *) (unsigned long) ddb;
163
164 asd_ddbsite_write_byte(asd_ha, ddb, 0, DDB_TP_CONN_TYPE);
165 asd_ddbsite_write_byte(asd_ha, ddb, 1, 0);
166 asd_ddbsite_write_word(asd_ha, ddb, INIT_CONN_TAG, 0xFFFF);
167 for (i = 0; i < SAS_ADDR_SIZE; i++)
168 asd_ddbsite_write_byte(asd_ha, ddb, DEST_SAS_ADDR+i,
169 dev->sas_addr[i]);
170 asd_ddbsite_write_word(asd_ha, ddb, SEND_QUEUE_HEAD, 0xFFFF);
171 asd_set_ddb_type(dev);
172 asd_ddbsite_write_byte(asd_ha, ddb, CONN_MASK, dev->port->phy_mask);
173 if (dev->port->oob_mode != SATA_OOB_MODE) {
174 flags |= OPEN_REQUIRED;
175 if ((dev->dev_type == SATA_DEV) ||
176 (dev->tproto & SAS_PROTO_STP)) {
177 struct smp_resp *rps_resp = &dev->sata_dev.rps_resp;
178 if (rps_resp->frame_type == SMP_RESPONSE &&
179 rps_resp->function == SMP_REPORT_PHY_SATA &&
180 rps_resp->result == SMP_RESP_FUNC_ACC) {
181 if (rps_resp->rps.affil_valid)
182 flags |= STP_AFFIL_POL;
183 if (rps_resp->rps.affil_supp)
184 flags |= SUPPORTS_AFFIL;
185 }
186 } else {
187 flags |= CONCURRENT_CONN_SUPP;
188 if (!dev->parent &&
189 (dev->dev_type == EDGE_DEV ||
190 dev->dev_type == FANOUT_DEV))
191 asd_ddbsite_write_byte(asd_ha, ddb, MAX_CCONN,
192 4);
193 else
194 asd_ddbsite_write_byte(asd_ha, ddb, MAX_CCONN,
195 dev->pathways);
196 asd_ddbsite_write_byte(asd_ha, ddb, NUM_CTX, 1);
197 }
198 }
199 if (dev->dev_type == SATA_PM)
200 flags |= SATA_MULTIPORT;
201 asd_ddbsite_write_byte(asd_ha, ddb, DDB_TARG_FLAGS, flags);
202
203 flags = 0;
204 if (dev->tproto & SAS_PROTO_STP)
205 flags |= STP_CL_POL_NO_TX;
206 asd_ddbsite_write_byte(asd_ha, ddb, DDB_TARG_FLAGS2, flags);
207
208 asd_ddbsite_write_word(asd_ha, ddb, EXEC_QUEUE_TAIL, 0xFFFF);
209 asd_ddbsite_write_word(asd_ha, ddb, SEND_QUEUE_TAIL, 0xFFFF);
210 asd_ddbsite_write_word(asd_ha, ddb, SISTER_DDB, 0xFFFF);
211
212 if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTO_STP)) {
213 i = asd_init_sata(dev);
214 if (i < 0) {
215 asd_free_ddb(asd_ha, ddb);
216 return i;
217 }
218 }
219
220 if (dev->dev_type == SAS_END_DEV) {
221 struct sas_end_device *rdev = rphy_to_end_device(dev->rphy);
222 if (rdev->I_T_nexus_loss_timeout > 0)
223 asd_ddbsite_write_word(asd_ha, ddb, ITNL_TIMEOUT,
224 min(rdev->I_T_nexus_loss_timeout,
225 (u16)ITNL_TIMEOUT_CONST));
226 else
227 asd_ddbsite_write_word(asd_ha, ddb, ITNL_TIMEOUT,
228 (u16)ITNL_TIMEOUT_CONST);
229 }
230 return 0;
231}
232
233static int asd_init_sata_pm_table_ddb(struct domain_device *dev)
234{
235 struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha;
236 int ddb, i;
237
238 ddb = asd_get_ddb(asd_ha);
239 if (ddb < 0)
240 return ddb;
241
242 for (i = 0; i < 32; i += 2)
243 asd_ddbsite_write_word(asd_ha, ddb, i, 0xFFFF);
244
245 asd_ddbsite_write_word(asd_ha, (int) (unsigned long) dev->lldd_dev,
246 SISTER_DDB, ddb);
247
248 return 0;
249}
250
251#define PM_PORT_FLAGS offsetof(struct asd_ddb_sata_pm_port, pm_port_flags)
252#define PARENT_DDB offsetof(struct asd_ddb_sata_pm_port, parent_ddb)
253
254/**
255 * asd_init_sata_pm_port_ddb -- SATA Port Multiplier Port
256 * dev: pointer to domain device
257 *
258 * For SATA Port Multiplier Ports we need to allocate one SATA Port
259 * Multiplier Port DDB and depending on whether the target on it
260 * supports SATA II NCQ, one SATA Tag DDB.
261 */
262static int asd_init_sata_pm_port_ddb(struct domain_device *dev)
263{
264 int ddb, i, parent_ddb, pmtable_ddb;
265 struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha;
266 u8 flags;
267
268 ddb = asd_get_ddb(asd_ha);
269 if (ddb < 0)
270 return ddb;
271
272 asd_set_ddb_type(dev);
273 flags = (dev->sata_dev.port_no << 4) | PM_PORT_SET;
274 asd_ddbsite_write_byte(asd_ha, ddb, PM_PORT_FLAGS, flags);
275 asd_ddbsite_write_word(asd_ha, ddb, SISTER_DDB, 0xFFFF);
276 asd_ddbsite_write_word(asd_ha, ddb, ATA_CMD_SCBPTR, 0xFFFF);
277 asd_init_sata(dev);
278
279 parent_ddb = (int) (unsigned long) dev->parent->lldd_dev;
280 asd_ddbsite_write_word(asd_ha, ddb, PARENT_DDB, parent_ddb);
281 pmtable_ddb = asd_ddbsite_read_word(asd_ha, parent_ddb, SISTER_DDB);
282 asd_ddbsite_write_word(asd_ha, pmtable_ddb, dev->sata_dev.port_no,ddb);
283
284 if (asd_ddbsite_read_byte(asd_ha, ddb, NUM_SATA_TAGS) > 0) {
285 i = asd_init_sata_tag_ddb(dev);
286 if (i < 0) {
287 asd_free_ddb(asd_ha, ddb);
288 return i;
289 }
290 }
291 return 0;
292}
293
294static int asd_init_initiator_ddb(struct domain_device *dev)
295{
296 return -ENODEV;
297}
298
299/**
300 * asd_init_sata_pm_ddb -- SATA Port Multiplier
301 * dev: pointer to domain device
302 *
303 * For STP and direct-attached SATA Port Multipliers we need
304 * one target port DDB entry and one SATA PM table DDB entry.
305 */
306static int asd_init_sata_pm_ddb(struct domain_device *dev)
307{
308 int res = 0;
309
310 res = asd_init_target_ddb(dev);
311 if (res)
312 goto out;
313 res = asd_init_sata_pm_table_ddb(dev);
314 if (res)
315 asd_free_ddb(dev->port->ha->lldd_ha,
316 (int) (unsigned long) dev->lldd_dev);
317out:
318 return res;
319}
320
321int asd_dev_found(struct domain_device *dev)
322{
323 int res = 0;
324
325 switch (dev->dev_type) {
326 case SATA_PM:
327 res = asd_init_sata_pm_ddb(dev);
328 break;
329 case SATA_PM_PORT:
330 res = asd_init_sata_pm_port_ddb(dev);
331 break;
332 default:
333 if (dev->tproto)
334 res = asd_init_target_ddb(dev);
335 else
336 res = asd_init_initiator_ddb(dev);
337 }
338 return res;
339}
340
341void asd_dev_gone(struct domain_device *dev)
342{
343 int ddb, sister_ddb;
344 struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha;
345
346 ddb = (int) (unsigned long) dev->lldd_dev;
347 sister_ddb = asd_ddbsite_read_word(asd_ha, ddb, SISTER_DDB);
348
349 if (sister_ddb != 0xFFFF)
350 asd_free_ddb(asd_ha, sister_ddb);
351 asd_free_ddb(asd_ha, ddb);
352 dev->lldd_dev = NULL;
353}
diff --git a/drivers/scsi/aic94xx/aic94xx_dump.c b/drivers/scsi/aic94xx/aic94xx_dump.c
new file mode 100644
index 000000000000..e6ade5996d95
--- /dev/null
+++ b/drivers/scsi/aic94xx/aic94xx_dump.c
@@ -0,0 +1,959 @@
1/*
2 * Aic94xx SAS/SATA driver dump interface.
3 *
4 * Copyright (C) 2004 Adaptec, Inc. All rights reserved.
5 * Copyright (C) 2004 David Chaw <david_chaw@adaptec.com>
6 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
7 *
8 * This file is licensed under GPLv2.
9 *
10 * This file is part of the aic94xx driver.
11 *
12 * The aic94xx driver is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License as
14 * published by the Free Software Foundation; version 2 of the
15 * License.
16 *
17 * The aic94xx driver is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with the aic94xx driver; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 *
26 * 2005/07/14/LT Complete overhaul of this file. Update pages, register
27 * locations, names, etc. Make use of macros. Print more information.
28 * Print all cseq and lseq mip and mdp.
29 *
30 */
31
32#include "linux/pci.h"
33#include "aic94xx.h"
34#include "aic94xx_reg.h"
35#include "aic94xx_reg_def.h"
36#include "aic94xx_sas.h"
37
38#include "aic94xx_dump.h"
39
40#ifdef ASD_DEBUG
41
42#define MD(x) (1 << (x))
43#define MODE_COMMON (1 << 31)
44#define MODE_0_7 (0xFF)
45
46static const struct lseq_cio_regs {
47 char *name;
48 u32 offs;
49 u8 width;
50 u32 mode;
51} LSEQmCIOREGS[] = {
52 {"LmMnSCBPTR", 0x20, 16, MD(0)|MD(1)|MD(2)|MD(3)|MD(4) },
53 {"LmMnDDBPTR", 0x22, 16, MD(0)|MD(1)|MD(2)|MD(3)|MD(4) },
54 {"LmREQMBX", 0x30, 32, MODE_COMMON },
55 {"LmRSPMBX", 0x34, 32, MODE_COMMON },
56 {"LmMnINT", 0x38, 32, MODE_0_7 },
57 {"LmMnINTEN", 0x3C, 32, MODE_0_7 },
58 {"LmXMTPRIMD", 0x40, 32, MODE_COMMON },
59 {"LmXMTPRIMCS", 0x44, 8, MODE_COMMON },
60 {"LmCONSTAT", 0x45, 8, MODE_COMMON },
61 {"LmMnDMAERRS", 0x46, 8, MD(0)|MD(1) },
62 {"LmMnSGDMAERRS", 0x47, 8, MD(0)|MD(1) },
63 {"LmMnEXPHDRP", 0x48, 8, MD(0) },
64 {"LmMnSASAALIGN", 0x48, 8, MD(1) },
65 {"LmMnMSKHDRP", 0x49, 8, MD(0) },
66 {"LmMnSTPALIGN", 0x49, 8, MD(1) },
67 {"LmMnRCVHDRP", 0x4A, 8, MD(0) },
68 {"LmMnXMTHDRP", 0x4A, 8, MD(1) },
69 {"LmALIGNMODE", 0x4B, 8, MD(1) },
70 {"LmMnEXPRCVCNT", 0x4C, 32, MD(0) },
71 {"LmMnXMTCNT", 0x4C, 32, MD(1) },
72 {"LmMnCURRTAG", 0x54, 16, MD(0) },
73 {"LmMnPREVTAG", 0x56, 16, MD(0) },
74 {"LmMnACKOFS", 0x58, 8, MD(1) },
75 {"LmMnXFRLVL", 0x59, 8, MD(0)|MD(1) },
76 {"LmMnSGDMACTL", 0x5A, 8, MD(0)|MD(1) },
77 {"LmMnSGDMASTAT", 0x5B, 8, MD(0)|MD(1) },
78 {"LmMnDDMACTL", 0x5C, 8, MD(0)|MD(1) },
79 {"LmMnDDMASTAT", 0x5D, 8, MD(0)|MD(1) },
80 {"LmMnDDMAMODE", 0x5E, 16, MD(0)|MD(1) },
81 {"LmMnPIPECTL", 0x61, 8, MD(0)|MD(1) },
82 {"LmMnACTSCB", 0x62, 16, MD(0)|MD(1) },
83 {"LmMnSGBHADR", 0x64, 8, MD(0)|MD(1) },
84 {"LmMnSGBADR", 0x65, 8, MD(0)|MD(1) },
85 {"LmMnSGDCNT", 0x66, 8, MD(0)|MD(1) },
86 {"LmMnSGDMADR", 0x68, 32, MD(0)|MD(1) },
87 {"LmMnSGDMADR", 0x6C, 32, MD(0)|MD(1) },
88 {"LmMnXFRCNT", 0x70, 32, MD(0)|MD(1) },
89 {"LmMnXMTCRC", 0x74, 32, MD(1) },
90 {"LmCURRTAG", 0x74, 16, MD(0) },
91 {"LmPREVTAG", 0x76, 16, MD(0) },
92 {"LmMnDPSEL", 0x7B, 8, MD(0)|MD(1) },
93 {"LmDPTHSTAT", 0x7C, 8, MODE_COMMON },
94 {"LmMnHOLDLVL", 0x7D, 8, MD(0) },
95 {"LmMnSATAFS", 0x7E, 8, MD(1) },
96 {"LmMnCMPLTSTAT", 0x7F, 8, MD(0)|MD(1) },
97 {"LmPRMSTAT0", 0x80, 32, MODE_COMMON },
98 {"LmPRMSTAT1", 0x84, 32, MODE_COMMON },
99 {"LmGPRMINT", 0x88, 8, MODE_COMMON },
100 {"LmMnCURRSCB", 0x8A, 16, MD(0) },
101 {"LmPRMICODE", 0x8C, 32, MODE_COMMON },
102 {"LmMnRCVCNT", 0x90, 16, MD(0) },
103 {"LmMnBUFSTAT", 0x92, 16, MD(0) },
104 {"LmMnXMTHDRSIZE",0x92, 8, MD(1) },
105 {"LmMnXMTSIZE", 0x93, 8, MD(1) },
106 {"LmMnTGTXFRCNT", 0x94, 32, MD(0) },
107 {"LmMnEXPROFS", 0x98, 32, MD(0) },
108 {"LmMnXMTROFS", 0x98, 32, MD(1) },
109 {"LmMnRCVROFS", 0x9C, 32, MD(0) },
110 {"LmCONCTL", 0xA0, 16, MODE_COMMON },
111 {"LmBITLTIMER", 0xA2, 16, MODE_COMMON },
112 {"LmWWNLOW", 0xA8, 32, MODE_COMMON },
113 {"LmWWNHIGH", 0xAC, 32, MODE_COMMON },
114 {"LmMnFRMERR", 0xB0, 32, MD(0) },
115 {"LmMnFRMERREN", 0xB4, 32, MD(0) },
116 {"LmAWTIMER", 0xB8, 16, MODE_COMMON },
117 {"LmAWTCTL", 0xBA, 8, MODE_COMMON },
118 {"LmMnHDRCMPS", 0xC0, 32, MD(0) },
119 {"LmMnXMTSTAT", 0xC4, 8, MD(1) },
120 {"LmHWTSTATEN", 0xC5, 8, MODE_COMMON },
121 {"LmMnRRDYRC", 0xC6, 8, MD(0) },
122 {"LmMnRRDYTC", 0xC6, 8, MD(1) },
123 {"LmHWTSTAT", 0xC7, 8, MODE_COMMON },
124 {"LmMnDATABUFADR",0xC8, 16, MD(0)|MD(1) },
125 {"LmDWSSTATUS", 0xCB, 8, MODE_COMMON },
126 {"LmMnACTSTAT", 0xCE, 16, MD(0)|MD(1) },
127 {"LmMnREQSCB", 0xD2, 16, MD(0)|MD(1) },
128 {"LmXXXPRIM", 0xD4, 32, MODE_COMMON },
129 {"LmRCVASTAT", 0xD9, 8, MODE_COMMON },
130 {"LmINTDIS1", 0xDA, 8, MODE_COMMON },
131 {"LmPSTORESEL", 0xDB, 8, MODE_COMMON },
132 {"LmPSTORE", 0xDC, 32, MODE_COMMON },
133 {"LmPRIMSTAT0EN", 0xE0, 32, MODE_COMMON },
134 {"LmPRIMSTAT1EN", 0xE4, 32, MODE_COMMON },
135 {"LmDONETCTL", 0xF2, 16, MODE_COMMON },
136 {NULL, 0, 0, 0 }
137};
138/*
139static struct lseq_cio_regs LSEQmOOBREGS[] = {
140 {"OOB_BFLTR" ,0x100, 8, MD(5)},
141 {"OOB_INIT_MIN" ,0x102,16, MD(5)},
142 {"OOB_INIT_MAX" ,0x104,16, MD(5)},
143 {"OOB_INIT_NEG" ,0x106,16, MD(5)},
144 {"OOB_SAS_MIN" ,0x108,16, MD(5)},
145 {"OOB_SAS_MAX" ,0x10A,16, MD(5)},
146 {"OOB_SAS_NEG" ,0x10C,16, MD(5)},
147 {"OOB_WAKE_MIN" ,0x10E,16, MD(5)},
148 {"OOB_WAKE_MAX" ,0x110,16, MD(5)},
149 {"OOB_WAKE_NEG" ,0x112,16, MD(5)},
150 {"OOB_IDLE_MAX" ,0x114,16, MD(5)},
151 {"OOB_BURST_MAX" ,0x116,16, MD(5)},
152 {"OOB_XMIT_BURST" ,0x118, 8, MD(5)},
153 {"OOB_SEND_PAIRS" ,0x119, 8, MD(5)},
154 {"OOB_INIT_IDLE" ,0x11A, 8, MD(5)},
155 {"OOB_INIT_NEGO" ,0x11C, 8, MD(5)},
156 {"OOB_SAS_IDLE" ,0x11E, 8, MD(5)},
157 {"OOB_SAS_NEGO" ,0x120, 8, MD(5)},
158 {"OOB_WAKE_IDLE" ,0x122, 8, MD(5)},
159 {"OOB_WAKE_NEGO" ,0x124, 8, MD(5)},
160 {"OOB_DATA_KBITS" ,0x126, 8, MD(5)},
161 {"OOB_BURST_DATA" ,0x128,32, MD(5)},
162 {"OOB_ALIGN_0_DATA" ,0x12C,32, MD(5)},
163 {"OOB_ALIGN_1_DATA" ,0x130,32, MD(5)},
164 {"OOB_SYNC_DATA" ,0x134,32, MD(5)},
165 {"OOB_D10_2_DATA" ,0x138,32, MD(5)},
166 {"OOB_PHY_RST_CNT" ,0x13C,32, MD(5)},
167 {"OOB_SIG_GEN" ,0x140, 8, MD(5)},
168 {"OOB_XMIT" ,0x141, 8, MD(5)},
169 {"FUNCTION_MAKS" ,0x142, 8, MD(5)},
170 {"OOB_MODE" ,0x143, 8, MD(5)},
171 {"CURRENT_STATUS" ,0x144, 8, MD(5)},
172 {"SPEED_MASK" ,0x145, 8, MD(5)},
173 {"PRIM_COUNT" ,0x146, 8, MD(5)},
174 {"OOB_SIGNALS" ,0x148, 8, MD(5)},
175 {"OOB_DATA_DET" ,0x149, 8, MD(5)},
176 {"OOB_TIME_OUT" ,0x14C, 8, MD(5)},
177 {"OOB_TIMER_ENABLE" ,0x14D, 8, MD(5)},
178 {"OOB_STATUS" ,0x14E, 8, MD(5)},
179 {"HOT_PLUG_DELAY" ,0x150, 8, MD(5)},
180 {"RCD_DELAY" ,0x151, 8, MD(5)},
181 {"COMSAS_TIMER" ,0x152, 8, MD(5)},
182 {"SNTT_DELAY" ,0x153, 8, MD(5)},
183 {"SPD_CHNG_DELAY" ,0x154, 8, MD(5)},
184 {"SNLT_DELAY" ,0x155, 8, MD(5)},
185 {"SNWT_DELAY" ,0x156, 8, MD(5)},
186 {"ALIGN_DELAY" ,0x157, 8, MD(5)},
187 {"INT_ENABLE_0" ,0x158, 8, MD(5)},
188 {"INT_ENABLE_1" ,0x159, 8, MD(5)},
189 {"INT_ENABLE_2" ,0x15A, 8, MD(5)},
190 {"INT_ENABLE_3" ,0x15B, 8, MD(5)},
191 {"OOB_TEST_REG" ,0x15C, 8, MD(5)},
192 {"PHY_CONTROL_0" ,0x160, 8, MD(5)},
193 {"PHY_CONTROL_1" ,0x161, 8, MD(5)},
194 {"PHY_CONTROL_2" ,0x162, 8, MD(5)},
195 {"PHY_CONTROL_3" ,0x163, 8, MD(5)},
196 {"PHY_OOB_CAL_TX" ,0x164, 8, MD(5)},
197 {"PHY_OOB_CAL_RX" ,0x165, 8, MD(5)},
198 {"OOB_PHY_CAL_TX" ,0x166, 8, MD(5)},
199 {"OOB_PHY_CAL_RX" ,0x167, 8, MD(5)},
200 {"PHY_CONTROL_4" ,0x168, 8, MD(5)},
201 {"PHY_TEST" ,0x169, 8, MD(5)},
202 {"PHY_PWR_CTL" ,0x16A, 8, MD(5)},
203 {"PHY_PWR_DELAY" ,0x16B, 8, MD(5)},
204 {"OOB_SM_CON" ,0x16C, 8, MD(5)},
205 {"ADDR_TRAP_1" ,0x16D, 8, MD(5)},
206 {"ADDR_NEXT_1" ,0x16E, 8, MD(5)},
207 {"NEXT_ST_1" ,0x16F, 8, MD(5)},
208 {"OOB_SM_STATE" ,0x170, 8, MD(5)},
209 {"ADDR_TRAP_2" ,0x171, 8, MD(5)},
210 {"ADDR_NEXT_2" ,0x172, 8, MD(5)},
211 {"NEXT_ST_2" ,0x173, 8, MD(5)},
212 {NULL, 0, 0, 0 }
213};
214*/
215#define STR_8BIT " %30s[0x%04x]:0x%02x\n"
216#define STR_16BIT " %30s[0x%04x]:0x%04x\n"
217#define STR_32BIT " %30s[0x%04x]:0x%08x\n"
218#define STR_64BIT " %30s[0x%04x]:0x%llx\n"
219
220#define PRINT_REG_8bit(_ha, _n, _r) asd_printk(STR_8BIT, #_n, _n, \
221 asd_read_reg_byte(_ha, _r))
222#define PRINT_REG_16bit(_ha, _n, _r) asd_printk(STR_16BIT, #_n, _n, \
223 asd_read_reg_word(_ha, _r))
224#define PRINT_REG_32bit(_ha, _n, _r) asd_printk(STR_32BIT, #_n, _n, \
225 asd_read_reg_dword(_ha, _r))
226
227#define PRINT_CREG_8bit(_ha, _n) asd_printk(STR_8BIT, #_n, _n, \
228 asd_read_reg_byte(_ha, C##_n))
229#define PRINT_CREG_16bit(_ha, _n) asd_printk(STR_16BIT, #_n, _n, \
230 asd_read_reg_word(_ha, C##_n))
231#define PRINT_CREG_32bit(_ha, _n) asd_printk(STR_32BIT, #_n, _n, \
232 asd_read_reg_dword(_ha, C##_n))
233
234#define MSTR_8BIT " Mode:%02d %30s[0x%04x]:0x%02x\n"
235#define MSTR_16BIT " Mode:%02d %30s[0x%04x]:0x%04x\n"
236#define MSTR_32BIT " Mode:%02d %30s[0x%04x]:0x%08x\n"
237
238#define PRINT_MREG_8bit(_ha, _m, _n, _r) asd_printk(MSTR_8BIT, _m, #_n, _n, \
239 asd_read_reg_byte(_ha, _r))
240#define PRINT_MREG_16bit(_ha, _m, _n, _r) asd_printk(MSTR_16BIT, _m, #_n, _n, \
241 asd_read_reg_word(_ha, _r))
242#define PRINT_MREG_32bit(_ha, _m, _n, _r) asd_printk(MSTR_32BIT, _m, #_n, _n, \
243 asd_read_reg_dword(_ha, _r))
244
245/* can also be used for MD when the register is mode aware already */
246#define PRINT_MIS_byte(_ha, _n) asd_printk(STR_8BIT, #_n,CSEQ_##_n-CMAPPEDSCR,\
247 asd_read_reg_byte(_ha, CSEQ_##_n))
248#define PRINT_MIS_word(_ha, _n) asd_printk(STR_16BIT,#_n,CSEQ_##_n-CMAPPEDSCR,\
249 asd_read_reg_word(_ha, CSEQ_##_n))
250#define PRINT_MIS_dword(_ha, _n) \
251 asd_printk(STR_32BIT,#_n,CSEQ_##_n-CMAPPEDSCR,\
252 asd_read_reg_dword(_ha, CSEQ_##_n))
253#define PRINT_MIS_qword(_ha, _n) \
254 asd_printk(STR_64BIT, #_n,CSEQ_##_n-CMAPPEDSCR, \
255 (unsigned long long)(((u64)asd_read_reg_dword(_ha, CSEQ_##_n)) \
256 | (((u64)asd_read_reg_dword(_ha, (CSEQ_##_n)+4))<<32)))
257
258#define CMDP_REG(_n, _m) (_m*(CSEQ_PAGE_SIZE*2)+CSEQ_##_n)
259#define PRINT_CMDP_word(_ha, _n) \
260asd_printk("%20s 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x\n", \
261 #_n, \
262 asd_read_reg_word(_ha, CMDP_REG(_n, 0)), \
263 asd_read_reg_word(_ha, CMDP_REG(_n, 1)), \
264 asd_read_reg_word(_ha, CMDP_REG(_n, 2)), \
265 asd_read_reg_word(_ha, CMDP_REG(_n, 3)), \
266 asd_read_reg_word(_ha, CMDP_REG(_n, 4)), \
267 asd_read_reg_word(_ha, CMDP_REG(_n, 5)), \
268 asd_read_reg_word(_ha, CMDP_REG(_n, 6)), \
269 asd_read_reg_word(_ha, CMDP_REG(_n, 7)))
270
271#define PRINT_CMDP_byte(_ha, _n) \
272asd_printk("%20s 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x\n", \
273 #_n, \
274 asd_read_reg_byte(_ha, CMDP_REG(_n, 0)), \
275 asd_read_reg_byte(_ha, CMDP_REG(_n, 1)), \
276 asd_read_reg_byte(_ha, CMDP_REG(_n, 2)), \
277 asd_read_reg_byte(_ha, CMDP_REG(_n, 3)), \
278 asd_read_reg_byte(_ha, CMDP_REG(_n, 4)), \
279 asd_read_reg_byte(_ha, CMDP_REG(_n, 5)), \
280 asd_read_reg_byte(_ha, CMDP_REG(_n, 6)), \
281 asd_read_reg_byte(_ha, CMDP_REG(_n, 7)))
282
283static void asd_dump_cseq_state(struct asd_ha_struct *asd_ha)
284{
285 int mode;
286
287 asd_printk("CSEQ STATE\n");
288
289 asd_printk("ARP2 REGISTERS\n");
290
291 PRINT_CREG_32bit(asd_ha, ARP2CTL);
292 PRINT_CREG_32bit(asd_ha, ARP2INT);
293 PRINT_CREG_32bit(asd_ha, ARP2INTEN);
294 PRINT_CREG_8bit(asd_ha, MODEPTR);
295 PRINT_CREG_8bit(asd_ha, ALTMODE);
296 PRINT_CREG_8bit(asd_ha, FLAG);
297 PRINT_CREG_8bit(asd_ha, ARP2INTCTL);
298 PRINT_CREG_16bit(asd_ha, STACK);
299 PRINT_CREG_16bit(asd_ha, PRGMCNT);
300 PRINT_CREG_16bit(asd_ha, ACCUM);
301 PRINT_CREG_16bit(asd_ha, SINDEX);
302 PRINT_CREG_16bit(asd_ha, DINDEX);
303 PRINT_CREG_8bit(asd_ha, SINDIR);
304 PRINT_CREG_8bit(asd_ha, DINDIR);
305 PRINT_CREG_8bit(asd_ha, JUMLDIR);
306 PRINT_CREG_8bit(asd_ha, ARP2HALTCODE);
307 PRINT_CREG_16bit(asd_ha, CURRADDR);
308 PRINT_CREG_16bit(asd_ha, LASTADDR);
309 PRINT_CREG_16bit(asd_ha, NXTLADDR);
310
311 asd_printk("IOP REGISTERS\n");
312
313 PRINT_REG_32bit(asd_ha, BISTCTL1, CBISTCTL);
314 PRINT_CREG_32bit(asd_ha, MAPPEDSCR);
315
316 asd_printk("CIO REGISTERS\n");
317
318 for (mode = 0; mode < 9; mode++)
319 PRINT_MREG_16bit(asd_ha, mode, MnSCBPTR, CMnSCBPTR(mode));
320 PRINT_MREG_16bit(asd_ha, 15, MnSCBPTR, CMnSCBPTR(15));
321
322 for (mode = 0; mode < 9; mode++)
323 PRINT_MREG_16bit(asd_ha, mode, MnDDBPTR, CMnDDBPTR(mode));
324 PRINT_MREG_16bit(asd_ha, 15, MnDDBPTR, CMnDDBPTR(15));
325
326 for (mode = 0; mode < 8; mode++)
327 PRINT_MREG_32bit(asd_ha, mode, MnREQMBX, CMnREQMBX(mode));
328 for (mode = 0; mode < 8; mode++)
329 PRINT_MREG_32bit(asd_ha, mode, MnRSPMBX, CMnRSPMBX(mode));
330 for (mode = 0; mode < 8; mode++)
331 PRINT_MREG_32bit(asd_ha, mode, MnINT, CMnINT(mode));
332 for (mode = 0; mode < 8; mode++)
333 PRINT_MREG_32bit(asd_ha, mode, MnINTEN, CMnINTEN(mode));
334
335 PRINT_CREG_8bit(asd_ha, SCRATCHPAGE);
336 for (mode = 0; mode < 8; mode++)
337 PRINT_MREG_8bit(asd_ha, mode, MnSCRATCHPAGE,
338 CMnSCRATCHPAGE(mode));
339
340 PRINT_REG_32bit(asd_ha, CLINKCON, CLINKCON);
341 PRINT_REG_8bit(asd_ha, CCONMSK, CCONMSK);
342 PRINT_REG_8bit(asd_ha, CCONEXIST, CCONEXIST);
343 PRINT_REG_16bit(asd_ha, CCONMODE, CCONMODE);
344 PRINT_REG_32bit(asd_ha, CTIMERCALC, CTIMERCALC);
345 PRINT_REG_8bit(asd_ha, CINTDIS, CINTDIS);
346
347 asd_printk("SCRATCH MEMORY\n");
348
349 asd_printk("MIP 4 >>>>>\n");
350 PRINT_MIS_word(asd_ha, Q_EXE_HEAD);
351 PRINT_MIS_word(asd_ha, Q_EXE_TAIL);
352 PRINT_MIS_word(asd_ha, Q_DONE_HEAD);
353 PRINT_MIS_word(asd_ha, Q_DONE_TAIL);
354 PRINT_MIS_word(asd_ha, Q_SEND_HEAD);
355 PRINT_MIS_word(asd_ha, Q_SEND_TAIL);
356 PRINT_MIS_word(asd_ha, Q_DMA2CHIM_HEAD);
357 PRINT_MIS_word(asd_ha, Q_DMA2CHIM_TAIL);
358 PRINT_MIS_word(asd_ha, Q_COPY_HEAD);
359 PRINT_MIS_word(asd_ha, Q_COPY_TAIL);
360 PRINT_MIS_word(asd_ha, REG0);
361 PRINT_MIS_word(asd_ha, REG1);
362 PRINT_MIS_dword(asd_ha, REG2);
363 PRINT_MIS_byte(asd_ha, LINK_CTL_Q_MAP);
364 PRINT_MIS_byte(asd_ha, MAX_CSEQ_MODE);
365 PRINT_MIS_byte(asd_ha, FREE_LIST_HACK_COUNT);
366
367 asd_printk("MIP 5 >>>>\n");
368 PRINT_MIS_qword(asd_ha, EST_NEXUS_REQ_QUEUE);
369 PRINT_MIS_qword(asd_ha, EST_NEXUS_REQ_COUNT);
370 PRINT_MIS_word(asd_ha, Q_EST_NEXUS_HEAD);
371 PRINT_MIS_word(asd_ha, Q_EST_NEXUS_TAIL);
372 PRINT_MIS_word(asd_ha, NEED_EST_NEXUS_SCB);
373 PRINT_MIS_byte(asd_ha, EST_NEXUS_REQ_HEAD);
374 PRINT_MIS_byte(asd_ha, EST_NEXUS_REQ_TAIL);
375 PRINT_MIS_byte(asd_ha, EST_NEXUS_SCB_OFFSET);
376
377 asd_printk("MIP 6 >>>>\n");
378 PRINT_MIS_word(asd_ha, INT_ROUT_RET_ADDR0);
379 PRINT_MIS_word(asd_ha, INT_ROUT_RET_ADDR1);
380 PRINT_MIS_word(asd_ha, INT_ROUT_SCBPTR);
381 PRINT_MIS_byte(asd_ha, INT_ROUT_MODE);
382 PRINT_MIS_byte(asd_ha, ISR_SCRATCH_FLAGS);
383 PRINT_MIS_word(asd_ha, ISR_SAVE_SINDEX);
384 PRINT_MIS_word(asd_ha, ISR_SAVE_DINDEX);
385 PRINT_MIS_word(asd_ha, Q_MONIRTT_HEAD);
386 PRINT_MIS_word(asd_ha, Q_MONIRTT_TAIL);
387 PRINT_MIS_byte(asd_ha, FREE_SCB_MASK);
388 PRINT_MIS_word(asd_ha, BUILTIN_FREE_SCB_HEAD);
389 PRINT_MIS_word(asd_ha, BUILTIN_FREE_SCB_TAIL);
390 PRINT_MIS_word(asd_ha, EXTENDED_FREE_SCB_HEAD);
391 PRINT_MIS_word(asd_ha, EXTENDED_FREE_SCB_TAIL);
392
393 asd_printk("MIP 7 >>>>\n");
394 PRINT_MIS_qword(asd_ha, EMPTY_REQ_QUEUE);
395 PRINT_MIS_qword(asd_ha, EMPTY_REQ_COUNT);
396 PRINT_MIS_word(asd_ha, Q_EMPTY_HEAD);
397 PRINT_MIS_word(asd_ha, Q_EMPTY_TAIL);
398 PRINT_MIS_word(asd_ha, NEED_EMPTY_SCB);
399 PRINT_MIS_byte(asd_ha, EMPTY_REQ_HEAD);
400 PRINT_MIS_byte(asd_ha, EMPTY_REQ_TAIL);
401 PRINT_MIS_byte(asd_ha, EMPTY_SCB_OFFSET);
402 PRINT_MIS_word(asd_ha, PRIMITIVE_DATA);
403 PRINT_MIS_dword(asd_ha, TIMEOUT_CONST);
404
405 asd_printk("MDP 0 >>>>\n");
406 asd_printk("%-20s %6s %6s %6s %6s %6s %6s %6s %6s\n",
407 "Mode: ", "0", "1", "2", "3", "4", "5", "6", "7");
408 PRINT_CMDP_word(asd_ha, LRM_SAVE_SINDEX);
409 PRINT_CMDP_word(asd_ha, LRM_SAVE_SCBPTR);
410 PRINT_CMDP_word(asd_ha, Q_LINK_HEAD);
411 PRINT_CMDP_word(asd_ha, Q_LINK_TAIL);
412 PRINT_CMDP_byte(asd_ha, LRM_SAVE_SCRPAGE);
413
414 asd_printk("MDP 0 Mode 8 >>>>\n");
415 PRINT_MIS_word(asd_ha, RET_ADDR);
416 PRINT_MIS_word(asd_ha, RET_SCBPTR);
417 PRINT_MIS_word(asd_ha, SAVE_SCBPTR);
418 PRINT_MIS_word(asd_ha, EMPTY_TRANS_CTX);
419 PRINT_MIS_word(asd_ha, RESP_LEN);
420 PRINT_MIS_word(asd_ha, TMF_SCBPTR);
421 PRINT_MIS_word(asd_ha, GLOBAL_PREV_SCB);
422 PRINT_MIS_word(asd_ha, GLOBAL_HEAD);
423 PRINT_MIS_word(asd_ha, CLEAR_LU_HEAD);
424 PRINT_MIS_byte(asd_ha, TMF_OPCODE);
425 PRINT_MIS_byte(asd_ha, SCRATCH_FLAGS);
426 PRINT_MIS_word(asd_ha, HSB_SITE);
427 PRINT_MIS_word(asd_ha, FIRST_INV_SCB_SITE);
428 PRINT_MIS_word(asd_ha, FIRST_INV_DDB_SITE);
429
430 asd_printk("MDP 1 Mode 8 >>>>\n");
431 PRINT_MIS_qword(asd_ha, LUN_TO_CLEAR);
432 PRINT_MIS_qword(asd_ha, LUN_TO_CHECK);
433
434 asd_printk("MDP 2 Mode 8 >>>>\n");
435 PRINT_MIS_qword(asd_ha, HQ_NEW_POINTER);
436 PRINT_MIS_qword(asd_ha, HQ_DONE_BASE);
437 PRINT_MIS_dword(asd_ha, HQ_DONE_POINTER);
438 PRINT_MIS_byte(asd_ha, HQ_DONE_PASS);
439}
440
441#define PRINT_LREG_8bit(_h, _lseq, _n) \
442 asd_printk(STR_8BIT, #_n, _n, asd_read_reg_byte(_h, Lm##_n(_lseq)))
443#define PRINT_LREG_16bit(_h, _lseq, _n) \
444 asd_printk(STR_16BIT, #_n, _n, asd_read_reg_word(_h, Lm##_n(_lseq)))
445#define PRINT_LREG_32bit(_h, _lseq, _n) \
446 asd_printk(STR_32BIT, #_n, _n, asd_read_reg_dword(_h, Lm##_n(_lseq)))
447
448#define PRINT_LMIP_byte(_h, _lseq, _n) \
449 asd_printk(STR_8BIT, #_n, LmSEQ_##_n(_lseq)-LmSCRATCH(_lseq), \
450 asd_read_reg_byte(_h, LmSEQ_##_n(_lseq)))
451#define PRINT_LMIP_word(_h, _lseq, _n) \
452 asd_printk(STR_16BIT, #_n, LmSEQ_##_n(_lseq)-LmSCRATCH(_lseq), \
453 asd_read_reg_word(_h, LmSEQ_##_n(_lseq)))
454#define PRINT_LMIP_dword(_h, _lseq, _n) \
455 asd_printk(STR_32BIT, #_n, LmSEQ_##_n(_lseq)-LmSCRATCH(_lseq), \
456 asd_read_reg_dword(_h, LmSEQ_##_n(_lseq)))
457#define PRINT_LMIP_qword(_h, _lseq, _n) \
458 asd_printk(STR_64BIT, #_n, LmSEQ_##_n(_lseq)-LmSCRATCH(_lseq), \
459 (unsigned long long)(((unsigned long long) \
460 asd_read_reg_dword(_h, LmSEQ_##_n(_lseq))) \
461 | (((unsigned long long) \
462 asd_read_reg_dword(_h, LmSEQ_##_n(_lseq)+4))<<32)))
463
464static void asd_print_lseq_cio_reg(struct asd_ha_struct *asd_ha,
465 u32 lseq_cio_addr, int i)
466{
467 switch (LSEQmCIOREGS[i].width) {
468 case 8:
469 asd_printk("%20s[0x%x]: 0x%02x\n", LSEQmCIOREGS[i].name,
470 LSEQmCIOREGS[i].offs,
471 asd_read_reg_byte(asd_ha, lseq_cio_addr +
472 LSEQmCIOREGS[i].offs));
473
474 break;
475 case 16:
476 asd_printk("%20s[0x%x]: 0x%04x\n", LSEQmCIOREGS[i].name,
477 LSEQmCIOREGS[i].offs,
478 asd_read_reg_word(asd_ha, lseq_cio_addr +
479 LSEQmCIOREGS[i].offs));
480
481 break;
482 case 32:
483 asd_printk("%20s[0x%x]: 0x%08x\n", LSEQmCIOREGS[i].name,
484 LSEQmCIOREGS[i].offs,
485 asd_read_reg_dword(asd_ha, lseq_cio_addr +
486 LSEQmCIOREGS[i].offs));
487 break;
488 }
489}
490
491static void asd_dump_lseq_state(struct asd_ha_struct *asd_ha, int lseq)
492{
493 u32 moffs;
494 int mode;
495
496 asd_printk("LSEQ %d STATE\n", lseq);
497
498 asd_printk("LSEQ%d: ARP2 REGISTERS\n", lseq);
499 PRINT_LREG_32bit(asd_ha, lseq, ARP2CTL);
500 PRINT_LREG_32bit(asd_ha, lseq, ARP2INT);
501 PRINT_LREG_32bit(asd_ha, lseq, ARP2INTEN);
502 PRINT_LREG_8bit(asd_ha, lseq, MODEPTR);
503 PRINT_LREG_8bit(asd_ha, lseq, ALTMODE);
504 PRINT_LREG_8bit(asd_ha, lseq, FLAG);
505 PRINT_LREG_8bit(asd_ha, lseq, ARP2INTCTL);
506 PRINT_LREG_16bit(asd_ha, lseq, STACK);
507 PRINT_LREG_16bit(asd_ha, lseq, PRGMCNT);
508 PRINT_LREG_16bit(asd_ha, lseq, ACCUM);
509 PRINT_LREG_16bit(asd_ha, lseq, SINDEX);
510 PRINT_LREG_16bit(asd_ha, lseq, DINDEX);
511 PRINT_LREG_8bit(asd_ha, lseq, SINDIR);
512 PRINT_LREG_8bit(asd_ha, lseq, DINDIR);
513 PRINT_LREG_8bit(asd_ha, lseq, JUMLDIR);
514 PRINT_LREG_8bit(asd_ha, lseq, ARP2HALTCODE);
515 PRINT_LREG_16bit(asd_ha, lseq, CURRADDR);
516 PRINT_LREG_16bit(asd_ha, lseq, LASTADDR);
517 PRINT_LREG_16bit(asd_ha, lseq, NXTLADDR);
518
519 asd_printk("LSEQ%d: IOP REGISTERS\n", lseq);
520
521 PRINT_LREG_32bit(asd_ha, lseq, MODECTL);
522 PRINT_LREG_32bit(asd_ha, lseq, DBGMODE);
523 PRINT_LREG_32bit(asd_ha, lseq, CONTROL);
524 PRINT_REG_32bit(asd_ha, BISTCTL0, LmBISTCTL0(lseq));
525 PRINT_REG_32bit(asd_ha, BISTCTL1, LmBISTCTL1(lseq));
526
527 asd_printk("LSEQ%d: CIO REGISTERS\n", lseq);
528 asd_printk("Mode common:\n");
529
530 for (mode = 0; mode < 8; mode++) {
531 u32 lseq_cio_addr = LmSEQ_PHY_BASE(mode, lseq);
532 int i;
533
534 for (i = 0; LSEQmCIOREGS[i].name; i++)
535 if (LSEQmCIOREGS[i].mode == MODE_COMMON)
536 asd_print_lseq_cio_reg(asd_ha,lseq_cio_addr,i);
537 }
538
539 asd_printk("Mode unique:\n");
540 for (mode = 0; mode < 8; mode++) {
541 u32 lseq_cio_addr = LmSEQ_PHY_BASE(mode, lseq);
542 int i;
543
544 asd_printk("Mode %d\n", mode);
545 for (i = 0; LSEQmCIOREGS[i].name; i++) {
546 if (!(LSEQmCIOREGS[i].mode & (1 << mode)))
547 continue;
548 asd_print_lseq_cio_reg(asd_ha, lseq_cio_addr, i);
549 }
550 }
551
552 asd_printk("SCRATCH MEMORY\n");
553
554 asd_printk("LSEQ%d MIP 0 >>>>\n", lseq);
555 PRINT_LMIP_word(asd_ha, lseq, Q_TGTXFR_HEAD);
556 PRINT_LMIP_word(asd_ha, lseq, Q_TGTXFR_TAIL);
557 PRINT_LMIP_byte(asd_ha, lseq, LINK_NUMBER);
558 PRINT_LMIP_byte(asd_ha, lseq, SCRATCH_FLAGS);
559 PRINT_LMIP_qword(asd_ha, lseq, CONNECTION_STATE);
560 PRINT_LMIP_word(asd_ha, lseq, CONCTL);
561 PRINT_LMIP_byte(asd_ha, lseq, CONSTAT);
562 PRINT_LMIP_byte(asd_ha, lseq, CONNECTION_MODES);
563 PRINT_LMIP_word(asd_ha, lseq, REG1_ISR);
564 PRINT_LMIP_word(asd_ha, lseq, REG2_ISR);
565 PRINT_LMIP_word(asd_ha, lseq, REG3_ISR);
566 PRINT_LMIP_qword(asd_ha, lseq,REG0_ISR);
567
568 asd_printk("LSEQ%d MIP 1 >>>>\n", lseq);
569 PRINT_LMIP_word(asd_ha, lseq, EST_NEXUS_SCBPTR0);
570 PRINT_LMIP_word(asd_ha, lseq, EST_NEXUS_SCBPTR1);
571 PRINT_LMIP_word(asd_ha, lseq, EST_NEXUS_SCBPTR2);
572 PRINT_LMIP_word(asd_ha, lseq, EST_NEXUS_SCBPTR3);
573 PRINT_LMIP_byte(asd_ha, lseq, EST_NEXUS_SCB_OPCODE0);
574 PRINT_LMIP_byte(asd_ha, lseq, EST_NEXUS_SCB_OPCODE1);
575 PRINT_LMIP_byte(asd_ha, lseq, EST_NEXUS_SCB_OPCODE2);
576 PRINT_LMIP_byte(asd_ha, lseq, EST_NEXUS_SCB_OPCODE3);
577 PRINT_LMIP_byte(asd_ha, lseq, EST_NEXUS_SCB_HEAD);
578 PRINT_LMIP_byte(asd_ha, lseq, EST_NEXUS_SCB_TAIL);
579 PRINT_LMIP_byte(asd_ha, lseq, EST_NEXUS_BUF_AVAIL);
580 PRINT_LMIP_dword(asd_ha, lseq, TIMEOUT_CONST);
581 PRINT_LMIP_word(asd_ha, lseq, ISR_SAVE_SINDEX);
582 PRINT_LMIP_word(asd_ha, lseq, ISR_SAVE_DINDEX);
583
584 asd_printk("LSEQ%d MIP 2 >>>>\n", lseq);
585 PRINT_LMIP_word(asd_ha, lseq, EMPTY_SCB_PTR0);
586 PRINT_LMIP_word(asd_ha, lseq, EMPTY_SCB_PTR1);
587 PRINT_LMIP_word(asd_ha, lseq, EMPTY_SCB_PTR2);
588 PRINT_LMIP_word(asd_ha, lseq, EMPTY_SCB_PTR3);
589 PRINT_LMIP_byte(asd_ha, lseq, EMPTY_SCB_OPCD0);
590 PRINT_LMIP_byte(asd_ha, lseq, EMPTY_SCB_OPCD1);
591 PRINT_LMIP_byte(asd_ha, lseq, EMPTY_SCB_OPCD2);
592 PRINT_LMIP_byte(asd_ha, lseq, EMPTY_SCB_OPCD3);
593 PRINT_LMIP_byte(asd_ha, lseq, EMPTY_SCB_HEAD);
594 PRINT_LMIP_byte(asd_ha, lseq, EMPTY_SCB_TAIL);
595 PRINT_LMIP_byte(asd_ha, lseq, EMPTY_BUFS_AVAIL);
596
597 asd_printk("LSEQ%d MIP 3 >>>>\n", lseq);
598 PRINT_LMIP_dword(asd_ha, lseq, DEV_PRES_TMR_TOUT_CONST);
599 PRINT_LMIP_dword(asd_ha, lseq, SATA_INTERLOCK_TIMEOUT);
600 PRINT_LMIP_dword(asd_ha, lseq, SRST_ASSERT_TIMEOUT);
601 PRINT_LMIP_dword(asd_ha, lseq, RCV_FIS_TIMEOUT);
602 PRINT_LMIP_dword(asd_ha, lseq, ONE_MILLISEC_TIMEOUT);
603 PRINT_LMIP_dword(asd_ha, lseq, TEN_MS_COMINIT_TIMEOUT);
604 PRINT_LMIP_dword(asd_ha, lseq, SMP_RCV_TIMEOUT);
605
606 for (mode = 0; mode < 3; mode++) {
607 asd_printk("LSEQ%d MDP 0 MODE %d >>>>\n", lseq, mode);
608 moffs = mode * LSEQ_MODE_SCRATCH_SIZE;
609
610 asd_printk(STR_16BIT, "RET_ADDR", 0,
611 asd_read_reg_word(asd_ha, LmSEQ_RET_ADDR(lseq)
612 + moffs));
613 asd_printk(STR_16BIT, "REG0_MODE", 2,
614 asd_read_reg_word(asd_ha, LmSEQ_REG0_MODE(lseq)
615 + moffs));
616 asd_printk(STR_16BIT, "MODE_FLAGS", 4,
617 asd_read_reg_word(asd_ha, LmSEQ_MODE_FLAGS(lseq)
618 + moffs));
619 asd_printk(STR_16BIT, "RET_ADDR2", 0x6,
620 asd_read_reg_word(asd_ha, LmSEQ_RET_ADDR2(lseq)
621 + moffs));
622 asd_printk(STR_16BIT, "RET_ADDR1", 0x8,
623 asd_read_reg_word(asd_ha, LmSEQ_RET_ADDR1(lseq)
624 + moffs));
625 asd_printk(STR_8BIT, "OPCODE_TO_CSEQ", 0xB,
626 asd_read_reg_byte(asd_ha, LmSEQ_OPCODE_TO_CSEQ(lseq)
627 + moffs));
628 asd_printk(STR_16BIT, "DATA_TO_CSEQ", 0xC,
629 asd_read_reg_word(asd_ha, LmSEQ_DATA_TO_CSEQ(lseq)
630 + moffs));
631 }
632
633 asd_printk("LSEQ%d MDP 0 MODE 5 >>>>\n", lseq);
634 moffs = LSEQ_MODE5_PAGE0_OFFSET;
635 asd_printk(STR_16BIT, "RET_ADDR", 0,
636 asd_read_reg_word(asd_ha, LmSEQ_RET_ADDR(lseq) + moffs));
637 asd_printk(STR_16BIT, "REG0_MODE", 2,
638 asd_read_reg_word(asd_ha, LmSEQ_REG0_MODE(lseq) + moffs));
639 asd_printk(STR_16BIT, "MODE_FLAGS", 4,
640 asd_read_reg_word(asd_ha, LmSEQ_MODE_FLAGS(lseq) + moffs));
641 asd_printk(STR_16BIT, "RET_ADDR2", 0x6,
642 asd_read_reg_word(asd_ha, LmSEQ_RET_ADDR2(lseq) + moffs));
643 asd_printk(STR_16BIT, "RET_ADDR1", 0x8,
644 asd_read_reg_word(asd_ha, LmSEQ_RET_ADDR1(lseq) + moffs));
645 asd_printk(STR_8BIT, "OPCODE_TO_CSEQ", 0xB,
646 asd_read_reg_byte(asd_ha, LmSEQ_OPCODE_TO_CSEQ(lseq) + moffs));
647 asd_printk(STR_16BIT, "DATA_TO_CSEQ", 0xC,
648 asd_read_reg_word(asd_ha, LmSEQ_DATA_TO_CSEQ(lseq) + moffs));
649
650 asd_printk("LSEQ%d MDP 0 MODE 0 >>>>\n", lseq);
651 PRINT_LMIP_word(asd_ha, lseq, FIRST_INV_DDB_SITE);
652 PRINT_LMIP_word(asd_ha, lseq, EMPTY_TRANS_CTX);
653 PRINT_LMIP_word(asd_ha, lseq, RESP_LEN);
654 PRINT_LMIP_word(asd_ha, lseq, FIRST_INV_SCB_SITE);
655 PRINT_LMIP_dword(asd_ha, lseq, INTEN_SAVE);
656 PRINT_LMIP_byte(asd_ha, lseq, LINK_RST_FRM_LEN);
657 PRINT_LMIP_byte(asd_ha, lseq, LINK_RST_PROTOCOL);
658 PRINT_LMIP_byte(asd_ha, lseq, RESP_STATUS);
659 PRINT_LMIP_byte(asd_ha, lseq, LAST_LOADED_SGE);
660 PRINT_LMIP_byte(asd_ha, lseq, SAVE_SCBPTR);
661
662 asd_printk("LSEQ%d MDP 0 MODE 1 >>>>\n", lseq);
663 PRINT_LMIP_word(asd_ha, lseq, Q_XMIT_HEAD);
664 PRINT_LMIP_word(asd_ha, lseq, M1_EMPTY_TRANS_CTX);
665 PRINT_LMIP_word(asd_ha, lseq, INI_CONN_TAG);
666 PRINT_LMIP_byte(asd_ha, lseq, FAILED_OPEN_STATUS);
667 PRINT_LMIP_byte(asd_ha, lseq, XMIT_REQUEST_TYPE);
668 PRINT_LMIP_byte(asd_ha, lseq, M1_RESP_STATUS);
669 PRINT_LMIP_byte(asd_ha, lseq, M1_LAST_LOADED_SGE);
670 PRINT_LMIP_word(asd_ha, lseq, M1_SAVE_SCBPTR);
671
672 asd_printk("LSEQ%d MDP 0 MODE 2 >>>>\n", lseq);
673 PRINT_LMIP_word(asd_ha, lseq, PORT_COUNTER);
674 PRINT_LMIP_word(asd_ha, lseq, PM_TABLE_PTR);
675 PRINT_LMIP_word(asd_ha, lseq, SATA_INTERLOCK_TMR_SAVE);
676 PRINT_LMIP_word(asd_ha, lseq, IP_BITL);
677 PRINT_LMIP_word(asd_ha, lseq, COPY_SMP_CONN_TAG);
678 PRINT_LMIP_byte(asd_ha, lseq, P0M2_OFFS1AH);
679
680 asd_printk("LSEQ%d MDP 0 MODE 4/5 >>>>\n", lseq);
681 PRINT_LMIP_byte(asd_ha, lseq, SAVED_OOB_STATUS);
682 PRINT_LMIP_byte(asd_ha, lseq, SAVED_OOB_MODE);
683 PRINT_LMIP_word(asd_ha, lseq, Q_LINK_HEAD);
684 PRINT_LMIP_byte(asd_ha, lseq, LINK_RST_ERR);
685 PRINT_LMIP_byte(asd_ha, lseq, SAVED_OOB_SIGNALS);
686 PRINT_LMIP_byte(asd_ha, lseq, SAS_RESET_MODE);
687 PRINT_LMIP_byte(asd_ha, lseq, LINK_RESET_RETRY_COUNT);
688 PRINT_LMIP_byte(asd_ha, lseq, NUM_LINK_RESET_RETRIES);
689 PRINT_LMIP_word(asd_ha, lseq, OOB_INT_ENABLES);
690 PRINT_LMIP_word(asd_ha, lseq, NOTIFY_TIMER_TIMEOUT);
691 PRINT_LMIP_word(asd_ha, lseq, NOTIFY_TIMER_DOWN_COUNT);
692
693 asd_printk("LSEQ%d MDP 1 MODE 0 >>>>\n", lseq);
694 PRINT_LMIP_qword(asd_ha, lseq, SG_LIST_PTR_ADDR0);
695 PRINT_LMIP_qword(asd_ha, lseq, SG_LIST_PTR_ADDR1);
696
697 asd_printk("LSEQ%d MDP 1 MODE 1 >>>>\n", lseq);
698 PRINT_LMIP_qword(asd_ha, lseq, M1_SG_LIST_PTR_ADDR0);
699 PRINT_LMIP_qword(asd_ha, lseq, M1_SG_LIST_PTR_ADDR1);
700
701 asd_printk("LSEQ%d MDP 1 MODE 2 >>>>\n", lseq);
702 PRINT_LMIP_dword(asd_ha, lseq, INVALID_DWORD_COUNT);
703 PRINT_LMIP_dword(asd_ha, lseq, DISPARITY_ERROR_COUNT);
704 PRINT_LMIP_dword(asd_ha, lseq, LOSS_OF_SYNC_COUNT);
705
706 asd_printk("LSEQ%d MDP 1 MODE 4/5 >>>>\n", lseq);
707 PRINT_LMIP_dword(asd_ha, lseq, FRAME_TYPE_MASK);
708 PRINT_LMIP_dword(asd_ha, lseq, HASHED_SRC_ADDR_MASK_PRINT);
709 PRINT_LMIP_byte(asd_ha, lseq, NUM_FILL_BYTES_MASK);
710 PRINT_LMIP_word(asd_ha, lseq, TAG_MASK);
711 PRINT_LMIP_word(asd_ha, lseq, TARGET_PORT_XFER_TAG);
712 PRINT_LMIP_dword(asd_ha, lseq, DATA_OFFSET);
713
714 asd_printk("LSEQ%d MDP 2 MODE 0 >>>>\n", lseq);
715 PRINT_LMIP_dword(asd_ha, lseq, SMP_RCV_TIMER_TERM_TS);
716 PRINT_LMIP_byte(asd_ha, lseq, DEVICE_BITS);
717 PRINT_LMIP_word(asd_ha, lseq, SDB_DDB);
718 PRINT_LMIP_word(asd_ha, lseq, SDB_NUM_TAGS);
719 PRINT_LMIP_word(asd_ha, lseq, SDB_CURR_TAG);
720
721 asd_printk("LSEQ%d MDP 2 MODE 1 >>>>\n", lseq);
722 PRINT_LMIP_qword(asd_ha, lseq, TX_ID_ADDR_FRAME);
723 PRINT_LMIP_dword(asd_ha, lseq, OPEN_TIMER_TERM_TS);
724 PRINT_LMIP_dword(asd_ha, lseq, SRST_AS_TIMER_TERM_TS);
725 PRINT_LMIP_dword(asd_ha, lseq, LAST_LOADED_SG_EL);
726
727 asd_printk("LSEQ%d MDP 2 MODE 2 >>>>\n", lseq);
728 PRINT_LMIP_dword(asd_ha, lseq, CLOSE_TIMER_TERM_TS);
729 PRINT_LMIP_dword(asd_ha, lseq, BREAK_TIMER_TERM_TS);
730 PRINT_LMIP_dword(asd_ha, lseq, DWS_RESET_TIMER_TERM_TS);
731 PRINT_LMIP_dword(asd_ha, lseq, SATA_INTERLOCK_TIMER_TERM_TS);
732 PRINT_LMIP_dword(asd_ha, lseq, MCTL_TIMER_TERM_TS);
733
734 asd_printk("LSEQ%d MDP 2 MODE 4/5 >>>>\n", lseq);
735 PRINT_LMIP_dword(asd_ha, lseq, COMINIT_TIMER_TERM_TS);
736 PRINT_LMIP_dword(asd_ha, lseq, RCV_ID_TIMER_TERM_TS);
737 PRINT_LMIP_dword(asd_ha, lseq, RCV_FIS_TIMER_TERM_TS);
738 PRINT_LMIP_dword(asd_ha, lseq, DEV_PRES_TIMER_TERM_TS);
739}
740
741/**
742 * asd_dump_ddb_site -- dump a CSEQ DDB site
743 * @asd_ha: pointer to host adapter structure
744 * @site_no: site number of interest
745 */
746void asd_dump_target_ddb(struct asd_ha_struct *asd_ha, u16 site_no)
747{
748 if (site_no >= asd_ha->hw_prof.max_ddbs)
749 return;
750
751#define DDB_FIELDB(__name) \
752 asd_ddbsite_read_byte(asd_ha, site_no, \
753 offsetof(struct asd_ddb_ssp_smp_target_port, __name))
754#define DDB2_FIELDB(__name) \
755 asd_ddbsite_read_byte(asd_ha, site_no, \
756 offsetof(struct asd_ddb_stp_sata_target_port, __name))
757#define DDB_FIELDW(__name) \
758 asd_ddbsite_read_word(asd_ha, site_no, \
759 offsetof(struct asd_ddb_ssp_smp_target_port, __name))
760
761#define DDB_FIELDD(__name) \
762 asd_ddbsite_read_dword(asd_ha, site_no, \
763 offsetof(struct asd_ddb_ssp_smp_target_port, __name))
764
765 asd_printk("DDB: 0x%02x\n", site_no);
766 asd_printk("conn_type: 0x%02x\n", DDB_FIELDB(conn_type));
767 asd_printk("conn_rate: 0x%02x\n", DDB_FIELDB(conn_rate));
768 asd_printk("init_conn_tag: 0x%04x\n", be16_to_cpu(DDB_FIELDW(init_conn_tag)));
769 asd_printk("send_queue_head: 0x%04x\n", be16_to_cpu(DDB_FIELDW(send_queue_head)));
770 asd_printk("sq_suspended: 0x%02x\n", DDB_FIELDB(sq_suspended));
771 asd_printk("DDB Type: 0x%02x\n", DDB_FIELDB(ddb_type));
772 asd_printk("AWT Default: 0x%04x\n", DDB_FIELDW(awt_def));
773 asd_printk("compat_features: 0x%02x\n", DDB_FIELDB(compat_features));
774 asd_printk("Pathway Blocked Count: 0x%02x\n",
775 DDB_FIELDB(pathway_blocked_count));
776 asd_printk("arb_wait_time: 0x%04x\n", DDB_FIELDW(arb_wait_time));
777 asd_printk("more_compat_features: 0x%08x\n",
778 DDB_FIELDD(more_compat_features));
779 asd_printk("Conn Mask: 0x%02x\n", DDB_FIELDB(conn_mask));
780 asd_printk("flags: 0x%02x\n", DDB_FIELDB(flags));
781 asd_printk("flags2: 0x%02x\n", DDB2_FIELDB(flags2));
782 asd_printk("ExecQ Tail: 0x%04x\n",DDB_FIELDW(exec_queue_tail));
783 asd_printk("SendQ Tail: 0x%04x\n",DDB_FIELDW(send_queue_tail));
784 asd_printk("Active Task Count: 0x%04x\n",
785 DDB_FIELDW(active_task_count));
786 asd_printk("ITNL Reason: 0x%02x\n", DDB_FIELDB(itnl_reason));
787 asd_printk("ITNL Timeout Const: 0x%04x\n", DDB_FIELDW(itnl_timeout));
788 asd_printk("ITNL timestamp: 0x%08x\n", DDB_FIELDD(itnl_timestamp));
789}
790
791void asd_dump_ddb_0(struct asd_ha_struct *asd_ha)
792{
793#define DDB0_FIELDB(__name) \
794 asd_ddbsite_read_byte(asd_ha, 0, \
795 offsetof(struct asd_ddb_seq_shared, __name))
796#define DDB0_FIELDW(__name) \
797 asd_ddbsite_read_word(asd_ha, 0, \
798 offsetof(struct asd_ddb_seq_shared, __name))
799
800#define DDB0_FIELDD(__name) \
801 asd_ddbsite_read_dword(asd_ha,0 , \
802 offsetof(struct asd_ddb_seq_shared, __name))
803
804#define DDB0_FIELDA(__name, _o) \
805 asd_ddbsite_read_byte(asd_ha, 0, \
806 offsetof(struct asd_ddb_seq_shared, __name)+_o)
807
808
809 asd_printk("DDB: 0\n");
810 asd_printk("q_free_ddb_head:%04x\n", DDB0_FIELDW(q_free_ddb_head));
811 asd_printk("q_free_ddb_tail:%04x\n", DDB0_FIELDW(q_free_ddb_tail));
812 asd_printk("q_free_ddb_cnt:%04x\n", DDB0_FIELDW(q_free_ddb_cnt));
813 asd_printk("q_used_ddb_head:%04x\n", DDB0_FIELDW(q_used_ddb_head));
814 asd_printk("q_used_ddb_tail:%04x\n", DDB0_FIELDW(q_used_ddb_tail));
815 asd_printk("shared_mem_lock:%04x\n", DDB0_FIELDW(shared_mem_lock));
816 asd_printk("smp_conn_tag:%04x\n", DDB0_FIELDW(smp_conn_tag));
817 asd_printk("est_nexus_buf_cnt:%04x\n", DDB0_FIELDW(est_nexus_buf_cnt));
818 asd_printk("est_nexus_buf_thresh:%04x\n",
819 DDB0_FIELDW(est_nexus_buf_thresh));
820 asd_printk("conn_not_active:%02x\n", DDB0_FIELDB(conn_not_active));
821 asd_printk("phy_is_up:%02x\n", DDB0_FIELDB(phy_is_up));
822 asd_printk("port_map_by_links:%02x %02x %02x %02x "
823 "%02x %02x %02x %02x\n",
824 DDB0_FIELDA(port_map_by_links, 0),
825 DDB0_FIELDA(port_map_by_links, 1),
826 DDB0_FIELDA(port_map_by_links, 2),
827 DDB0_FIELDA(port_map_by_links, 3),
828 DDB0_FIELDA(port_map_by_links, 4),
829 DDB0_FIELDA(port_map_by_links, 5),
830 DDB0_FIELDA(port_map_by_links, 6),
831 DDB0_FIELDA(port_map_by_links, 7));
832}
833
834static void asd_dump_scb_site(struct asd_ha_struct *asd_ha, u16 site_no)
835{
836
837#define SCB_FIELDB(__name) \
838 asd_scbsite_read_byte(asd_ha, site_no, sizeof(struct scb_header) \
839 + offsetof(struct initiate_ssp_task, __name))
840#define SCB_FIELDW(__name) \
841 asd_scbsite_read_word(asd_ha, site_no, sizeof(struct scb_header) \
842 + offsetof(struct initiate_ssp_task, __name))
843#define SCB_FIELDD(__name) \
844 asd_scbsite_read_dword(asd_ha, site_no, sizeof(struct scb_header) \
845 + offsetof(struct initiate_ssp_task, __name))
846
847 asd_printk("Total Xfer Len: 0x%08x.\n", SCB_FIELDD(total_xfer_len));
848 asd_printk("Frame Type: 0x%02x.\n", SCB_FIELDB(ssp_frame.frame_type));
849 asd_printk("Tag: 0x%04x.\n", SCB_FIELDW(ssp_frame.tag));
850 asd_printk("Target Port Xfer Tag: 0x%04x.\n",
851 SCB_FIELDW(ssp_frame.tptt));
852 asd_printk("Data Offset: 0x%08x.\n", SCB_FIELDW(ssp_frame.data_offs));
853 asd_printk("Retry Count: 0x%02x.\n", SCB_FIELDB(retry_count));
854}
855
856/**
857 * asd_dump_scb_sites -- dump currently used CSEQ SCB sites
858 * @asd_ha: pointer to host adapter struct
859 */
860void asd_dump_scb_sites(struct asd_ha_struct *asd_ha)
861{
862 u16 site_no;
863
864 for (site_no = 0; site_no < asd_ha->hw_prof.max_scbs; site_no++) {
865 u8 opcode;
866
867 if (!SCB_SITE_VALID(site_no))
868 continue;
869
870 /* We are only interested in SCB sites currently used.
871 */
872 opcode = asd_scbsite_read_byte(asd_ha, site_no,
873 offsetof(struct scb_header,
874 opcode));
875 if (opcode == 0xFF)
876 continue;
877
878 asd_printk("\nSCB: 0x%x\n", site_no);
879 asd_dump_scb_site(asd_ha, site_no);
880 }
881}
882
883/**
884 * ads_dump_seq_state -- dump CSEQ and LSEQ states
885 * @asd_ha: pointer to host adapter structure
886 * @lseq_mask: mask of LSEQs of interest
887 */
888void asd_dump_seq_state(struct asd_ha_struct *asd_ha, u8 lseq_mask)
889{
890 int lseq;
891
892 asd_dump_cseq_state(asd_ha);
893
894 if (lseq_mask != 0)
895 for_each_sequencer(lseq_mask, lseq_mask, lseq)
896 asd_dump_lseq_state(asd_ha, lseq);
897}
898
899void asd_dump_frame_rcvd(struct asd_phy *phy,
900 struct done_list_struct *dl)
901{
902 unsigned long flags;
903 int i;
904
905 switch ((dl->status_block[1] & 0x70) >> 3) {
906 case SAS_PROTO_STP:
907 ASD_DPRINTK("STP proto device-to-host FIS:\n");
908 break;
909 default:
910 case SAS_PROTO_SSP:
911 ASD_DPRINTK("SAS proto IDENTIFY:\n");
912 break;
913 }
914 spin_lock_irqsave(&phy->sas_phy.frame_rcvd_lock, flags);
915 for (i = 0; i < phy->sas_phy.frame_rcvd_size; i+=4)
916 ASD_DPRINTK("%02x: %02x %02x %02x %02x\n",
917 i,
918 phy->frame_rcvd[i],
919 phy->frame_rcvd[i+1],
920 phy->frame_rcvd[i+2],
921 phy->frame_rcvd[i+3]);
922 spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags);
923}
924
925static inline void asd_dump_scb(struct asd_ascb *ascb, int ind)
926{
927 asd_printk("scb%d: vaddr: 0x%p, dma_handle: 0x%llx, next: 0x%llx, "
928 "index:%d, opcode:0x%02x\n",
929 ind, ascb->dma_scb.vaddr,
930 (unsigned long long)ascb->dma_scb.dma_handle,
931 (unsigned long long)
932 le64_to_cpu(ascb->scb->header.next_scb),
933 le16_to_cpu(ascb->scb->header.index),
934 ascb->scb->header.opcode);
935}
936
937void asd_dump_scb_list(struct asd_ascb *ascb, int num)
938{
939 int i = 0;
940
941 asd_printk("dumping %d scbs:\n", num);
942
943 asd_dump_scb(ascb, i++);
944 --num;
945
946 if (num > 0 && !list_empty(&ascb->list)) {
947 struct list_head *el;
948
949 list_for_each(el, &ascb->list) {
950 struct asd_ascb *s = list_entry(el, struct asd_ascb,
951 list);
952 asd_dump_scb(s, i++);
953 if (--num <= 0)
954 break;
955 }
956 }
957}
958
959#endif /* ASD_DEBUG */
diff --git a/drivers/scsi/aic94xx/aic94xx_dump.h b/drivers/scsi/aic94xx/aic94xx_dump.h
new file mode 100644
index 000000000000..0c388e7da6bb
--- /dev/null
+++ b/drivers/scsi/aic94xx/aic94xx_dump.h
@@ -0,0 +1,52 @@
1/*
2 * Aic94xx SAS/SATA driver dump header file.
3 *
4 * Copyright (C) 2005 Adaptec, Inc. All rights reserved.
5 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
6 *
7 * This file is licensed under GPLv2.
8 *
9 * This file is part of the aic94xx driver.
10 *
11 * The aic94xx driver is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; version 2 of the
14 * License.
15 *
16 * The aic94xx driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with the aic94xx driver; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 *
25 */
26
27#ifndef _AIC94XX_DUMP_H_
28#define _AIC94XX_DUMP_H_
29
30#ifdef ASD_DEBUG
31
32void asd_dump_ddb_0(struct asd_ha_struct *asd_ha);
33void asd_dump_target_ddb(struct asd_ha_struct *asd_ha, u16 site_no);
34void asd_dump_scb_sites(struct asd_ha_struct *asd_ha);
35void asd_dump_seq_state(struct asd_ha_struct *asd_ha, u8 lseq_mask);
36void asd_dump_frame_rcvd(struct asd_phy *phy,
37 struct done_list_struct *dl);
38void asd_dump_scb_list(struct asd_ascb *ascb, int num);
39#else /* ASD_DEBUG */
40
41static inline void asd_dump_ddb_0(struct asd_ha_struct *asd_ha) { }
42static inline void asd_dump_target_ddb(struct asd_ha_struct *asd_ha,
43 u16 site_no) { }
44static inline void asd_dump_scb_sites(struct asd_ha_struct *asd_ha) { }
45static inline void asd_dump_seq_state(struct asd_ha_struct *asd_ha,
46 u8 lseq_mask) { }
47static inline void asd_dump_frame_rcvd(struct asd_phy *phy,
48 struct done_list_struct *dl) { }
49static inline void asd_dump_scb_list(struct asd_ascb *ascb, int num) { }
50#endif /* ASD_DEBUG */
51
52#endif /* _AIC94XX_DUMP_H_ */
diff --git a/drivers/scsi/aic94xx/aic94xx_hwi.c b/drivers/scsi/aic94xx/aic94xx_hwi.c
new file mode 100644
index 000000000000..075cea85b56b
--- /dev/null
+++ b/drivers/scsi/aic94xx/aic94xx_hwi.c
@@ -0,0 +1,1376 @@
1/*
2 * Aic94xx SAS/SATA driver hardware interface.
3 *
4 * Copyright (C) 2005 Adaptec, Inc. All rights reserved.
5 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
6 *
7 * This file is licensed under GPLv2.
8 *
9 * This file is part of the aic94xx driver.
10 *
11 * The aic94xx driver is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; version 2 of the
14 * License.
15 *
16 * The aic94xx driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with the aic94xx driver; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 *
25 */
26
27#include <linux/pci.h>
28#include <linux/delay.h>
29#include <linux/module.h>
30
31#include "aic94xx.h"
32#include "aic94xx_reg.h"
33#include "aic94xx_hwi.h"
34#include "aic94xx_seq.h"
35#include "aic94xx_dump.h"
36
37u32 MBAR0_SWB_SIZE;
38
39/* ---------- Initialization ---------- */
40
41static void asd_get_user_sas_addr(struct asd_ha_struct *asd_ha)
42{
43 extern char sas_addr_str[];
44 /* If the user has specified a WWN it overrides other settings
45 */
46 if (sas_addr_str[0] != '\0')
47 asd_destringify_sas_addr(asd_ha->hw_prof.sas_addr,
48 sas_addr_str);
49 else if (asd_ha->hw_prof.sas_addr[0] != 0)
50 asd_stringify_sas_addr(sas_addr_str, asd_ha->hw_prof.sas_addr);
51}
52
53static void asd_propagate_sas_addr(struct asd_ha_struct *asd_ha)
54{
55 int i;
56
57 for (i = 0; i < ASD_MAX_PHYS; i++) {
58 if (asd_ha->hw_prof.phy_desc[i].sas_addr[0] == 0)
59 continue;
60 /* Set a phy's address only if it has none.
61 */
62 ASD_DPRINTK("setting phy%d addr to %llx\n", i,
63 SAS_ADDR(asd_ha->hw_prof.sas_addr));
64 memcpy(asd_ha->hw_prof.phy_desc[i].sas_addr,
65 asd_ha->hw_prof.sas_addr, SAS_ADDR_SIZE);
66 }
67}
68
69/* ---------- PHY initialization ---------- */
70
71static void asd_init_phy_identify(struct asd_phy *phy)
72{
73 phy->identify_frame = phy->id_frm_tok->vaddr;
74
75 memset(phy->identify_frame, 0, sizeof(*phy->identify_frame));
76
77 phy->identify_frame->dev_type = SAS_END_DEV;
78 if (phy->sas_phy.role & PHY_ROLE_INITIATOR)
79 phy->identify_frame->initiator_bits = phy->sas_phy.iproto;
80 if (phy->sas_phy.role & PHY_ROLE_TARGET)
81 phy->identify_frame->target_bits = phy->sas_phy.tproto;
82 memcpy(phy->identify_frame->sas_addr, phy->phy_desc->sas_addr,
83 SAS_ADDR_SIZE);
84 phy->identify_frame->phy_id = phy->sas_phy.id;
85}
86
87static int asd_init_phy(struct asd_phy *phy)
88{
89 struct asd_ha_struct *asd_ha = phy->sas_phy.ha->lldd_ha;
90 struct asd_sas_phy *sas_phy = &phy->sas_phy;
91
92 sas_phy->enabled = 1;
93 sas_phy->class = SAS;
94 sas_phy->iproto = SAS_PROTO_ALL;
95 sas_phy->tproto = 0;
96 sas_phy->type = PHY_TYPE_PHYSICAL;
97 sas_phy->role = PHY_ROLE_INITIATOR;
98 sas_phy->oob_mode = OOB_NOT_CONNECTED;
99 sas_phy->linkrate = PHY_LINKRATE_NONE;
100
101 phy->id_frm_tok = asd_alloc_coherent(asd_ha,
102 sizeof(*phy->identify_frame),
103 GFP_KERNEL);
104 if (!phy->id_frm_tok) {
105 asd_printk("no mem for IDENTIFY for phy%d\n", sas_phy->id);
106 return -ENOMEM;
107 } else
108 asd_init_phy_identify(phy);
109
110 memset(phy->frame_rcvd, 0, sizeof(phy->frame_rcvd));
111
112 return 0;
113}
114
115static int asd_init_phys(struct asd_ha_struct *asd_ha)
116{
117 u8 i;
118 u8 phy_mask = asd_ha->hw_prof.enabled_phys;
119
120 for (i = 0; i < ASD_MAX_PHYS; i++) {
121 struct asd_phy *phy = &asd_ha->phys[i];
122
123 phy->phy_desc = &asd_ha->hw_prof.phy_desc[i];
124
125 phy->sas_phy.enabled = 0;
126 phy->sas_phy.id = i;
127 phy->sas_phy.sas_addr = &phy->phy_desc->sas_addr[0];
128 phy->sas_phy.frame_rcvd = &phy->frame_rcvd[0];
129 phy->sas_phy.ha = &asd_ha->sas_ha;
130 phy->sas_phy.lldd_phy = phy;
131 }
132
133 /* Now enable and initialize only the enabled phys. */
134 for_each_phy(phy_mask, phy_mask, i) {
135 int err = asd_init_phy(&asd_ha->phys[i]);
136 if (err)
137 return err;
138 }
139
140 return 0;
141}
142
143/* ---------- Sliding windows ---------- */
144
145static int asd_init_sw(struct asd_ha_struct *asd_ha)
146{
147 struct pci_dev *pcidev = asd_ha->pcidev;
148 int err;
149 u32 v;
150
151 /* Unlock MBARs */
152 err = pci_read_config_dword(pcidev, PCI_CONF_MBAR_KEY, &v);
153 if (err) {
154 asd_printk("couldn't access conf. space of %s\n",
155 pci_name(pcidev));
156 goto Err;
157 }
158 if (v)
159 err = pci_write_config_dword(pcidev, PCI_CONF_MBAR_KEY, v);
160 if (err) {
161 asd_printk("couldn't write to MBAR_KEY of %s\n",
162 pci_name(pcidev));
163 goto Err;
164 }
165
166 /* Set sliding windows A, B and C to point to proper internal
167 * memory regions.
168 */
169 pci_write_config_dword(pcidev, PCI_CONF_MBAR0_SWA, REG_BASE_ADDR);
170 pci_write_config_dword(pcidev, PCI_CONF_MBAR0_SWB,
171 REG_BASE_ADDR_CSEQCIO);
172 pci_write_config_dword(pcidev, PCI_CONF_MBAR0_SWC, REG_BASE_ADDR_EXSI);
173 asd_ha->io_handle[0].swa_base = REG_BASE_ADDR;
174 asd_ha->io_handle[0].swb_base = REG_BASE_ADDR_CSEQCIO;
175 asd_ha->io_handle[0].swc_base = REG_BASE_ADDR_EXSI;
176 MBAR0_SWB_SIZE = asd_ha->io_handle[0].len - 0x80;
177 if (!asd_ha->iospace) {
178 /* MBAR1 will point to OCM (On Chip Memory) */
179 pci_write_config_dword(pcidev, PCI_CONF_MBAR1, OCM_BASE_ADDR);
180 asd_ha->io_handle[1].swa_base = OCM_BASE_ADDR;
181 }
182 spin_lock_init(&asd_ha->iolock);
183Err:
184 return err;
185}
186
187/* ---------- SCB initialization ---------- */
188
189/**
190 * asd_init_scbs - manually allocate the first SCB.
191 * @asd_ha: pointer to host adapter structure
192 *
193 * This allocates the very first SCB which would be sent to the
194 * sequencer for execution. Its bus address is written to
195 * CSEQ_Q_NEW_POINTER, mode page 2, mode 8. Since the bus address of
196 * the _next_ scb to be DMA-ed to the host adapter is read from the last
197 * SCB DMA-ed to the host adapter, we have to always stay one step
198 * ahead of the sequencer and keep one SCB already allocated.
199 */
200static int asd_init_scbs(struct asd_ha_struct *asd_ha)
201{
202 struct asd_seq_data *seq = &asd_ha->seq;
203 int bitmap_bytes;
204
205 /* allocate the index array and bitmap */
206 asd_ha->seq.tc_index_bitmap_bits = asd_ha->hw_prof.max_scbs;
207 asd_ha->seq.tc_index_array = kzalloc(asd_ha->seq.tc_index_bitmap_bits*
208 sizeof(void *), GFP_KERNEL);
209 if (!asd_ha->seq.tc_index_array)
210 return -ENOMEM;
211
212 bitmap_bytes = (asd_ha->seq.tc_index_bitmap_bits+7)/8;
213 bitmap_bytes = BITS_TO_LONGS(bitmap_bytes*8)*sizeof(unsigned long);
214 asd_ha->seq.tc_index_bitmap = kzalloc(bitmap_bytes, GFP_KERNEL);
215 if (!asd_ha->seq.tc_index_bitmap)
216 return -ENOMEM;
217
218 spin_lock_init(&seq->tc_index_lock);
219
220 seq->next_scb.size = sizeof(struct scb);
221 seq->next_scb.vaddr = dma_pool_alloc(asd_ha->scb_pool, GFP_KERNEL,
222 &seq->next_scb.dma_handle);
223 if (!seq->next_scb.vaddr) {
224 kfree(asd_ha->seq.tc_index_bitmap);
225 kfree(asd_ha->seq.tc_index_array);
226 asd_ha->seq.tc_index_bitmap = NULL;
227 asd_ha->seq.tc_index_array = NULL;
228 return -ENOMEM;
229 }
230
231 seq->pending = 0;
232 spin_lock_init(&seq->pend_q_lock);
233 INIT_LIST_HEAD(&seq->pend_q);
234
235 return 0;
236}
237
238static inline void asd_get_max_scb_ddb(struct asd_ha_struct *asd_ha)
239{
240 asd_ha->hw_prof.max_scbs = asd_get_cmdctx_size(asd_ha)/ASD_SCB_SIZE;
241 asd_ha->hw_prof.max_ddbs = asd_get_devctx_size(asd_ha)/ASD_DDB_SIZE;
242 ASD_DPRINTK("max_scbs:%d, max_ddbs:%d\n",
243 asd_ha->hw_prof.max_scbs,
244 asd_ha->hw_prof.max_ddbs);
245}
246
247/* ---------- Done List initialization ---------- */
248
249static void asd_dl_tasklet_handler(unsigned long);
250
251static int asd_init_dl(struct asd_ha_struct *asd_ha)
252{
253 asd_ha->seq.actual_dl
254 = asd_alloc_coherent(asd_ha,
255 ASD_DL_SIZE * sizeof(struct done_list_struct),
256 GFP_KERNEL);
257 if (!asd_ha->seq.actual_dl)
258 return -ENOMEM;
259 asd_ha->seq.dl = asd_ha->seq.actual_dl->vaddr;
260 asd_ha->seq.dl_toggle = ASD_DEF_DL_TOGGLE;
261 asd_ha->seq.dl_next = 0;
262 tasklet_init(&asd_ha->seq.dl_tasklet, asd_dl_tasklet_handler,
263 (unsigned long) asd_ha);
264
265 return 0;
266}
267
268/* ---------- EDB and ESCB init ---------- */
269
270static int asd_alloc_edbs(struct asd_ha_struct *asd_ha, unsigned int gfp_flags)
271{
272 struct asd_seq_data *seq = &asd_ha->seq;
273 int i;
274
275 seq->edb_arr = kmalloc(seq->num_edbs*sizeof(*seq->edb_arr), gfp_flags);
276 if (!seq->edb_arr)
277 return -ENOMEM;
278
279 for (i = 0; i < seq->num_edbs; i++) {
280 seq->edb_arr[i] = asd_alloc_coherent(asd_ha, ASD_EDB_SIZE,
281 gfp_flags);
282 if (!seq->edb_arr[i])
283 goto Err_unroll;
284 memset(seq->edb_arr[i]->vaddr, 0, ASD_EDB_SIZE);
285 }
286
287 ASD_DPRINTK("num_edbs:%d\n", seq->num_edbs);
288
289 return 0;
290
291Err_unroll:
292 for (i-- ; i >= 0; i--)
293 asd_free_coherent(asd_ha, seq->edb_arr[i]);
294 kfree(seq->edb_arr);
295 seq->edb_arr = NULL;
296
297 return -ENOMEM;
298}
299
300static int asd_alloc_escbs(struct asd_ha_struct *asd_ha,
301 unsigned int gfp_flags)
302{
303 struct asd_seq_data *seq = &asd_ha->seq;
304 struct asd_ascb *escb;
305 int i, escbs;
306
307 seq->escb_arr = kmalloc(seq->num_escbs*sizeof(*seq->escb_arr),
308 gfp_flags);
309 if (!seq->escb_arr)
310 return -ENOMEM;
311
312 escbs = seq->num_escbs;
313 escb = asd_ascb_alloc_list(asd_ha, &escbs, gfp_flags);
314 if (!escb) {
315 asd_printk("couldn't allocate list of escbs\n");
316 goto Err;
317 }
318 seq->num_escbs -= escbs; /* subtract what was not allocated */
319 ASD_DPRINTK("num_escbs:%d\n", seq->num_escbs);
320
321 for (i = 0; i < seq->num_escbs; i++, escb = list_entry(escb->list.next,
322 struct asd_ascb,
323 list)) {
324 seq->escb_arr[i] = escb;
325 escb->scb->header.opcode = EMPTY_SCB;
326 }
327
328 return 0;
329Err:
330 kfree(seq->escb_arr);
331 seq->escb_arr = NULL;
332 return -ENOMEM;
333
334}
335
336static void asd_assign_edbs2escbs(struct asd_ha_struct *asd_ha)
337{
338 struct asd_seq_data *seq = &asd_ha->seq;
339 int i, k, z = 0;
340
341 for (i = 0; i < seq->num_escbs; i++) {
342 struct asd_ascb *ascb = seq->escb_arr[i];
343 struct empty_scb *escb = &ascb->scb->escb;
344
345 ascb->edb_index = z;
346
347 escb->num_valid = ASD_EDBS_PER_SCB;
348
349 for (k = 0; k < ASD_EDBS_PER_SCB; k++) {
350 struct sg_el *eb = &escb->eb[k];
351 struct asd_dma_tok *edb = seq->edb_arr[z++];
352
353 memset(eb, 0, sizeof(*eb));
354 eb->bus_addr = cpu_to_le64(((u64) edb->dma_handle));
355 eb->size = cpu_to_le32(((u32) edb->size));
356 }
357 }
358}
359
360/**
361 * asd_init_escbs -- allocate and initialize empty scbs
362 * @asd_ha: pointer to host adapter structure
363 *
364 * An empty SCB has sg_elements of ASD_EDBS_PER_SCB (7) buffers.
365 * They transport sense data, etc.
366 */
367static int asd_init_escbs(struct asd_ha_struct *asd_ha)
368{
369 struct asd_seq_data *seq = &asd_ha->seq;
370 int err = 0;
371
372 /* Allocate two empty data buffers (edb) per sequencer. */
373 int edbs = 2*(1+asd_ha->hw_prof.num_phys);
374
375 seq->num_escbs = (edbs+ASD_EDBS_PER_SCB-1)/ASD_EDBS_PER_SCB;
376 seq->num_edbs = seq->num_escbs * ASD_EDBS_PER_SCB;
377
378 err = asd_alloc_edbs(asd_ha, GFP_KERNEL);
379 if (err) {
380 asd_printk("couldn't allocate edbs\n");
381 return err;
382 }
383
384 err = asd_alloc_escbs(asd_ha, GFP_KERNEL);
385 if (err) {
386 asd_printk("couldn't allocate escbs\n");
387 return err;
388 }
389
390 asd_assign_edbs2escbs(asd_ha);
391 /* In order to insure that normal SCBs do not overfill sequencer
392 * memory and leave no space for escbs (halting condition),
393 * we increment pending here by the number of escbs. However,
394 * escbs are never pending.
395 */
396 seq->pending = seq->num_escbs;
397 seq->can_queue = 1 + (asd_ha->hw_prof.max_scbs - seq->pending)/2;
398
399 return 0;
400}
401
402/* ---------- HW initialization ---------- */
403
404/**
405 * asd_chip_hardrst -- hard reset the chip
406 * @asd_ha: pointer to host adapter structure
407 *
408 * This takes 16 cycles and is synchronous to CFCLK, which runs
409 * at 200 MHz, so this should take at most 80 nanoseconds.
410 */
411int asd_chip_hardrst(struct asd_ha_struct *asd_ha)
412{
413 int i;
414 int count = 100;
415 u32 reg;
416
417 for (i = 0 ; i < 4 ; i++) {
418 asd_write_reg_dword(asd_ha, COMBIST, HARDRST);
419 }
420
421 do {
422 udelay(1);
423 reg = asd_read_reg_dword(asd_ha, CHIMINT);
424 if (reg & HARDRSTDET) {
425 asd_write_reg_dword(asd_ha, CHIMINT,
426 HARDRSTDET|PORRSTDET);
427 return 0;
428 }
429 } while (--count > 0);
430
431 return -ENODEV;
432}
433
434/**
435 * asd_init_chip -- initialize the chip
436 * @asd_ha: pointer to host adapter structure
437 *
438 * Hard resets the chip, disables HA interrupts, downloads the sequnecer
439 * microcode and starts the sequencers. The caller has to explicitly
440 * enable HA interrupts with asd_enable_ints(asd_ha).
441 */
442static int asd_init_chip(struct asd_ha_struct *asd_ha)
443{
444 int err;
445
446 err = asd_chip_hardrst(asd_ha);
447 if (err) {
448 asd_printk("couldn't hard reset %s\n",
449 pci_name(asd_ha->pcidev));
450 goto out;
451 }
452
453 asd_disable_ints(asd_ha);
454
455 err = asd_init_seqs(asd_ha);
456 if (err) {
457 asd_printk("couldn't init seqs for %s\n",
458 pci_name(asd_ha->pcidev));
459 goto out;
460 }
461
462 err = asd_start_seqs(asd_ha);
463 if (err) {
464 asd_printk("coudln't start seqs for %s\n",
465 pci_name(asd_ha->pcidev));
466 goto out;
467 }
468out:
469 return err;
470}
471
472#define MAX_DEVS ((OCM_MAX_SIZE) / (ASD_DDB_SIZE))
473
474static int max_devs = 0;
475module_param_named(max_devs, max_devs, int, S_IRUGO);
476MODULE_PARM_DESC(max_devs, "\n"
477 "\tMaximum number of SAS devices to support (not LUs).\n"
478 "\tDefault: 2176, Maximum: 65663.\n");
479
480static int max_cmnds = 0;
481module_param_named(max_cmnds, max_cmnds, int, S_IRUGO);
482MODULE_PARM_DESC(max_cmnds, "\n"
483 "\tMaximum number of commands queuable.\n"
484 "\tDefault: 512, Maximum: 66047.\n");
485
486static void asd_extend_devctx_ocm(struct asd_ha_struct *asd_ha)
487{
488 unsigned long dma_addr = OCM_BASE_ADDR;
489 u32 d;
490
491 dma_addr -= asd_ha->hw_prof.max_ddbs * ASD_DDB_SIZE;
492 asd_write_reg_addr(asd_ha, DEVCTXBASE, (dma_addr_t) dma_addr);
493 d = asd_read_reg_dword(asd_ha, CTXDOMAIN);
494 d |= 4;
495 asd_write_reg_dword(asd_ha, CTXDOMAIN, d);
496 asd_ha->hw_prof.max_ddbs += MAX_DEVS;
497}
498
499static int asd_extend_devctx(struct asd_ha_struct *asd_ha)
500{
501 dma_addr_t dma_handle;
502 unsigned long dma_addr;
503 u32 d;
504 int size;
505
506 asd_extend_devctx_ocm(asd_ha);
507
508 asd_ha->hw_prof.ddb_ext = NULL;
509 if (max_devs <= asd_ha->hw_prof.max_ddbs || max_devs > 0xFFFF) {
510 max_devs = asd_ha->hw_prof.max_ddbs;
511 return 0;
512 }
513
514 size = (max_devs - asd_ha->hw_prof.max_ddbs + 1) * ASD_DDB_SIZE;
515
516 asd_ha->hw_prof.ddb_ext = asd_alloc_coherent(asd_ha, size, GFP_KERNEL);
517 if (!asd_ha->hw_prof.ddb_ext) {
518 asd_printk("couldn't allocate memory for %d devices\n",
519 max_devs);
520 max_devs = asd_ha->hw_prof.max_ddbs;
521 return -ENOMEM;
522 }
523 dma_handle = asd_ha->hw_prof.ddb_ext->dma_handle;
524 dma_addr = ALIGN((unsigned long) dma_handle, ASD_DDB_SIZE);
525 dma_addr -= asd_ha->hw_prof.max_ddbs * ASD_DDB_SIZE;
526 dma_handle = (dma_addr_t) dma_addr;
527 asd_write_reg_addr(asd_ha, DEVCTXBASE, dma_handle);
528 d = asd_read_reg_dword(asd_ha, CTXDOMAIN);
529 d &= ~4;
530 asd_write_reg_dword(asd_ha, CTXDOMAIN, d);
531
532 asd_ha->hw_prof.max_ddbs = max_devs;
533
534 return 0;
535}
536
537static int asd_extend_cmdctx(struct asd_ha_struct *asd_ha)
538{
539 dma_addr_t dma_handle;
540 unsigned long dma_addr;
541 u32 d;
542 int size;
543
544 asd_ha->hw_prof.scb_ext = NULL;
545 if (max_cmnds <= asd_ha->hw_prof.max_scbs || max_cmnds > 0xFFFF) {
546 max_cmnds = asd_ha->hw_prof.max_scbs;
547 return 0;
548 }
549
550 size = (max_cmnds - asd_ha->hw_prof.max_scbs + 1) * ASD_SCB_SIZE;
551
552 asd_ha->hw_prof.scb_ext = asd_alloc_coherent(asd_ha, size, GFP_KERNEL);
553 if (!asd_ha->hw_prof.scb_ext) {
554 asd_printk("couldn't allocate memory for %d commands\n",
555 max_cmnds);
556 max_cmnds = asd_ha->hw_prof.max_scbs;
557 return -ENOMEM;
558 }
559 dma_handle = asd_ha->hw_prof.scb_ext->dma_handle;
560 dma_addr = ALIGN((unsigned long) dma_handle, ASD_SCB_SIZE);
561 dma_addr -= asd_ha->hw_prof.max_scbs * ASD_SCB_SIZE;
562 dma_handle = (dma_addr_t) dma_addr;
563 asd_write_reg_addr(asd_ha, CMDCTXBASE, dma_handle);
564 d = asd_read_reg_dword(asd_ha, CTXDOMAIN);
565 d &= ~1;
566 asd_write_reg_dword(asd_ha, CTXDOMAIN, d);
567
568 asd_ha->hw_prof.max_scbs = max_cmnds;
569
570 return 0;
571}
572
573/**
574 * asd_init_ctxmem -- initialize context memory
575 * asd_ha: pointer to host adapter structure
576 *
577 * This function sets the maximum number of SCBs and
578 * DDBs which can be used by the sequencer. This is normally
579 * 512 and 128 respectively. If support for more SCBs or more DDBs
580 * is required then CMDCTXBASE, DEVCTXBASE and CTXDOMAIN are
581 * initialized here to extend context memory to point to host memory,
582 * thus allowing unlimited support for SCBs and DDBs -- only limited
583 * by host memory.
584 */
585static int asd_init_ctxmem(struct asd_ha_struct *asd_ha)
586{
587 int bitmap_bytes;
588
589 asd_get_max_scb_ddb(asd_ha);
590 asd_extend_devctx(asd_ha);
591 asd_extend_cmdctx(asd_ha);
592
593 /* The kernel wants bitmaps to be unsigned long sized. */
594 bitmap_bytes = (asd_ha->hw_prof.max_ddbs+7)/8;
595 bitmap_bytes = BITS_TO_LONGS(bitmap_bytes*8)*sizeof(unsigned long);
596 asd_ha->hw_prof.ddb_bitmap = kzalloc(bitmap_bytes, GFP_KERNEL);
597 if (!asd_ha->hw_prof.ddb_bitmap)
598 return -ENOMEM;
599 spin_lock_init(&asd_ha->hw_prof.ddb_lock);
600
601 return 0;
602}
603
604int asd_init_hw(struct asd_ha_struct *asd_ha)
605{
606 int err;
607 u32 v;
608
609 err = asd_init_sw(asd_ha);
610 if (err)
611 return err;
612
613 err = pci_read_config_dword(asd_ha->pcidev, PCIC_HSTPCIX_CNTRL, &v);
614 if (err) {
615 asd_printk("couldn't read PCIC_HSTPCIX_CNTRL of %s\n",
616 pci_name(asd_ha->pcidev));
617 return err;
618 }
619 pci_write_config_dword(asd_ha->pcidev, PCIC_HSTPCIX_CNTRL,
620 v | SC_TMR_DIS);
621 if (err) {
622 asd_printk("couldn't disable split completion timer of %s\n",
623 pci_name(asd_ha->pcidev));
624 return err;
625 }
626
627 err = asd_read_ocm(asd_ha);
628 if (err) {
629 asd_printk("couldn't read ocm(%d)\n", err);
630 /* While suspicios, it is not an error that we
631 * couldn't read the OCM. */
632 }
633
634 err = asd_read_flash(asd_ha);
635 if (err) {
636 asd_printk("couldn't read flash(%d)\n", err);
637 /* While suspicios, it is not an error that we
638 * couldn't read FLASH memory.
639 */
640 }
641
642 asd_init_ctxmem(asd_ha);
643
644 asd_get_user_sas_addr(asd_ha);
645 if (!asd_ha->hw_prof.sas_addr[0]) {
646 asd_printk("No SAS Address provided for %s\n",
647 pci_name(asd_ha->pcidev));
648 err = -ENODEV;
649 goto Out;
650 }
651
652 asd_propagate_sas_addr(asd_ha);
653
654 err = asd_init_phys(asd_ha);
655 if (err) {
656 asd_printk("couldn't initialize phys for %s\n",
657 pci_name(asd_ha->pcidev));
658 goto Out;
659 }
660
661 err = asd_init_scbs(asd_ha);
662 if (err) {
663 asd_printk("couldn't initialize scbs for %s\n",
664 pci_name(asd_ha->pcidev));
665 goto Out;
666 }
667
668 err = asd_init_dl(asd_ha);
669 if (err) {
670 asd_printk("couldn't initialize the done list:%d\n",
671 err);
672 goto Out;
673 }
674
675 err = asd_init_escbs(asd_ha);
676 if (err) {
677 asd_printk("couldn't initialize escbs\n");
678 goto Out;
679 }
680
681 err = asd_init_chip(asd_ha);
682 if (err) {
683 asd_printk("couldn't init the chip\n");
684 goto Out;
685 }
686Out:
687 return err;
688}
689
690/* ---------- Chip reset ---------- */
691
692/**
693 * asd_chip_reset -- reset the host adapter, etc
694 * @asd_ha: pointer to host adapter structure of interest
695 *
696 * Called from the ISR. Hard reset the chip. Let everything
697 * timeout. This should be no different than hot-unplugging the
698 * host adapter. Once everything times out we'll init the chip with
699 * a call to asd_init_chip() and enable interrupts with asd_enable_ints().
700 * XXX finish.
701 */
702static void asd_chip_reset(struct asd_ha_struct *asd_ha)
703{
704 struct sas_ha_struct *sas_ha = &asd_ha->sas_ha;
705
706 ASD_DPRINTK("chip reset for %s\n", pci_name(asd_ha->pcidev));
707 asd_chip_hardrst(asd_ha);
708 sas_ha->notify_ha_event(sas_ha, HAE_RESET);
709}
710
711/* ---------- Done List Routines ---------- */
712
713static void asd_dl_tasklet_handler(unsigned long data)
714{
715 struct asd_ha_struct *asd_ha = (struct asd_ha_struct *) data;
716 struct asd_seq_data *seq = &asd_ha->seq;
717 unsigned long flags;
718
719 while (1) {
720 struct done_list_struct *dl = &seq->dl[seq->dl_next];
721 struct asd_ascb *ascb;
722
723 if ((dl->toggle & DL_TOGGLE_MASK) != seq->dl_toggle)
724 break;
725
726 /* find the aSCB */
727 spin_lock_irqsave(&seq->tc_index_lock, flags);
728 ascb = asd_tc_index_find(seq, (int)le16_to_cpu(dl->index));
729 spin_unlock_irqrestore(&seq->tc_index_lock, flags);
730 if (unlikely(!ascb)) {
731 ASD_DPRINTK("BUG:sequencer:dl:no ascb?!\n");
732 goto next_1;
733 } else if (ascb->scb->header.opcode == EMPTY_SCB) {
734 goto out;
735 } else if (!ascb->uldd_timer && !del_timer(&ascb->timer)) {
736 goto next_1;
737 }
738 spin_lock_irqsave(&seq->pend_q_lock, flags);
739 list_del_init(&ascb->list);
740 seq->pending--;
741 spin_unlock_irqrestore(&seq->pend_q_lock, flags);
742 out:
743 ascb->tasklet_complete(ascb, dl);
744
745 next_1:
746 seq->dl_next = (seq->dl_next + 1) & (ASD_DL_SIZE-1);
747 if (!seq->dl_next)
748 seq->dl_toggle ^= DL_TOGGLE_MASK;
749 }
750}
751
752/* ---------- Interrupt Service Routines ---------- */
753
754/**
755 * asd_process_donelist_isr -- schedule processing of done list entries
756 * @asd_ha: pointer to host adapter structure
757 */
758static inline void asd_process_donelist_isr(struct asd_ha_struct *asd_ha)
759{
760 tasklet_schedule(&asd_ha->seq.dl_tasklet);
761}
762
763/**
764 * asd_com_sas_isr -- process device communication interrupt (COMINT)
765 * @asd_ha: pointer to host adapter structure
766 */
767static inline void asd_com_sas_isr(struct asd_ha_struct *asd_ha)
768{
769 u32 comstat = asd_read_reg_dword(asd_ha, COMSTAT);
770
771 /* clear COMSTAT int */
772 asd_write_reg_dword(asd_ha, COMSTAT, 0xFFFFFFFF);
773
774 if (comstat & CSBUFPERR) {
775 asd_printk("%s: command/status buffer dma parity error\n",
776 pci_name(asd_ha->pcidev));
777 } else if (comstat & CSERR) {
778 int i;
779 u32 dmaerr = asd_read_reg_dword(asd_ha, DMAERR);
780 dmaerr &= 0xFF;
781 asd_printk("%s: command/status dma error, DMAERR: 0x%02x, "
782 "CSDMAADR: 0x%04x, CSDMAADR+4: 0x%04x\n",
783 pci_name(asd_ha->pcidev),
784 dmaerr,
785 asd_read_reg_dword(asd_ha, CSDMAADR),
786 asd_read_reg_dword(asd_ha, CSDMAADR+4));
787 asd_printk("CSBUFFER:\n");
788 for (i = 0; i < 8; i++) {
789 asd_printk("%08x %08x %08x %08x\n",
790 asd_read_reg_dword(asd_ha, CSBUFFER),
791 asd_read_reg_dword(asd_ha, CSBUFFER+4),
792 asd_read_reg_dword(asd_ha, CSBUFFER+8),
793 asd_read_reg_dword(asd_ha, CSBUFFER+12));
794 }
795 asd_dump_seq_state(asd_ha, 0);
796 } else if (comstat & OVLYERR) {
797 u32 dmaerr = asd_read_reg_dword(asd_ha, DMAERR);
798 dmaerr = (dmaerr >> 8) & 0xFF;
799 asd_printk("%s: overlay dma error:0x%x\n",
800 pci_name(asd_ha->pcidev),
801 dmaerr);
802 }
803 asd_chip_reset(asd_ha);
804}
805
806static inline void asd_arp2_err(struct asd_ha_struct *asd_ha, u32 dchstatus)
807{
808 static const char *halt_code[256] = {
809 "UNEXPECTED_INTERRUPT0",
810 "UNEXPECTED_INTERRUPT1",
811 "UNEXPECTED_INTERRUPT2",
812 "UNEXPECTED_INTERRUPT3",
813 "UNEXPECTED_INTERRUPT4",
814 "UNEXPECTED_INTERRUPT5",
815 "UNEXPECTED_INTERRUPT6",
816 "UNEXPECTED_INTERRUPT7",
817 "UNEXPECTED_INTERRUPT8",
818 "UNEXPECTED_INTERRUPT9",
819 "UNEXPECTED_INTERRUPT10",
820 [11 ... 19] = "unknown[11,19]",
821 "NO_FREE_SCB_AVAILABLE",
822 "INVALID_SCB_OPCODE",
823 "INVALID_MBX_OPCODE",
824 "INVALID_ATA_STATE",
825 "ATA_QUEUE_FULL",
826 "ATA_TAG_TABLE_FAULT",
827 "ATA_TAG_MASK_FAULT",
828 "BAD_LINK_QUEUE_STATE",
829 "DMA2CHIM_QUEUE_ERROR",
830 "EMPTY_SCB_LIST_FULL",
831 "unknown[30]",
832 "IN_USE_SCB_ON_FREE_LIST",
833 "BAD_OPEN_WAIT_STATE",
834 "INVALID_STP_AFFILIATION",
835 "unknown[34]",
836 "EXEC_QUEUE_ERROR",
837 "TOO_MANY_EMPTIES_NEEDED",
838 "EMPTY_REQ_QUEUE_ERROR",
839 "Q_MONIRTT_MGMT_ERROR",
840 "TARGET_MODE_FLOW_ERROR",
841 "DEVICE_QUEUE_NOT_FOUND",
842 "START_IRTT_TIMER_ERROR",
843 "ABORT_TASK_ILLEGAL_REQ",
844 [43 ... 255] = "unknown[43,255]"
845 };
846
847 if (dchstatus & CSEQINT) {
848 u32 arp2int = asd_read_reg_dword(asd_ha, CARP2INT);
849
850 if (arp2int & (ARP2WAITTO|ARP2ILLOPC|ARP2PERR|ARP2CIOPERR)) {
851 asd_printk("%s: CSEQ arp2int:0x%x\n",
852 pci_name(asd_ha->pcidev),
853 arp2int);
854 } else if (arp2int & ARP2HALTC)
855 asd_printk("%s: CSEQ halted: %s\n",
856 pci_name(asd_ha->pcidev),
857 halt_code[(arp2int>>16)&0xFF]);
858 else
859 asd_printk("%s: CARP2INT:0x%x\n",
860 pci_name(asd_ha->pcidev),
861 arp2int);
862 }
863 if (dchstatus & LSEQINT_MASK) {
864 int lseq;
865 u8 lseq_mask = dchstatus & LSEQINT_MASK;
866
867 for_each_sequencer(lseq_mask, lseq_mask, lseq) {
868 u32 arp2int = asd_read_reg_dword(asd_ha,
869 LmARP2INT(lseq));
870 if (arp2int & (ARP2WAITTO | ARP2ILLOPC | ARP2PERR
871 | ARP2CIOPERR)) {
872 asd_printk("%s: LSEQ%d arp2int:0x%x\n",
873 pci_name(asd_ha->pcidev),
874 lseq, arp2int);
875 /* XXX we should only do lseq reset */
876 } else if (arp2int & ARP2HALTC)
877 asd_printk("%s: LSEQ%d halted: %s\n",
878 pci_name(asd_ha->pcidev),
879 lseq,halt_code[(arp2int>>16)&0xFF]);
880 else
881 asd_printk("%s: LSEQ%d ARP2INT:0x%x\n",
882 pci_name(asd_ha->pcidev), lseq,
883 arp2int);
884 }
885 }
886 asd_chip_reset(asd_ha);
887}
888
889/**
890 * asd_dch_sas_isr -- process device channel interrupt (DEVINT)
891 * @asd_ha: pointer to host adapter structure
892 */
893static inline void asd_dch_sas_isr(struct asd_ha_struct *asd_ha)
894{
895 u32 dchstatus = asd_read_reg_dword(asd_ha, DCHSTATUS);
896
897 if (dchstatus & CFIFTOERR) {
898 asd_printk("%s: CFIFTOERR\n", pci_name(asd_ha->pcidev));
899 asd_chip_reset(asd_ha);
900 } else
901 asd_arp2_err(asd_ha, dchstatus);
902}
903
904/**
905 * ads_rbi_exsi_isr -- process external system interface interrupt (INITERR)
906 * @asd_ha: pointer to host adapter structure
907 */
908static inline void asd_rbi_exsi_isr(struct asd_ha_struct *asd_ha)
909{
910 u32 stat0r = asd_read_reg_dword(asd_ha, ASISTAT0R);
911
912 if (!(stat0r & ASIERR)) {
913 asd_printk("hmm, EXSI interrupted but no error?\n");
914 return;
915 }
916
917 if (stat0r & ASIFMTERR) {
918 asd_printk("ASI SEEPROM format error for %s\n",
919 pci_name(asd_ha->pcidev));
920 } else if (stat0r & ASISEECHKERR) {
921 u32 stat1r = asd_read_reg_dword(asd_ha, ASISTAT1R);
922 asd_printk("ASI SEEPROM checksum 0x%x error for %s\n",
923 stat1r & CHECKSUM_MASK,
924 pci_name(asd_ha->pcidev));
925 } else {
926 u32 statr = asd_read_reg_dword(asd_ha, ASIERRSTATR);
927
928 if (!(statr & CPI2ASIMSTERR_MASK)) {
929 ASD_DPRINTK("hmm, ASIERR?\n");
930 return;
931 } else {
932 u32 addr = asd_read_reg_dword(asd_ha, ASIERRADDR);
933 u32 data = asd_read_reg_dword(asd_ha, ASIERRDATAR);
934
935 asd_printk("%s: CPI2 xfer err: addr: 0x%x, wdata: 0x%x, "
936 "count: 0x%x, byteen: 0x%x, targerr: 0x%x "
937 "master id: 0x%x, master err: 0x%x\n",
938 pci_name(asd_ha->pcidev),
939 addr, data,
940 (statr & CPI2ASIBYTECNT_MASK) >> 16,
941 (statr & CPI2ASIBYTEEN_MASK) >> 12,
942 (statr & CPI2ASITARGERR_MASK) >> 8,
943 (statr & CPI2ASITARGMID_MASK) >> 4,
944 (statr & CPI2ASIMSTERR_MASK));
945 }
946 }
947 asd_chip_reset(asd_ha);
948}
949
950/**
951 * asd_hst_pcix_isr -- process host interface interrupts
952 * @asd_ha: pointer to host adapter structure
953 *
954 * Asserted on PCIX errors: target abort, etc.
955 */
956static inline void asd_hst_pcix_isr(struct asd_ha_struct *asd_ha)
957{
958 u16 status;
959 u32 pcix_status;
960 u32 ecc_status;
961
962 pci_read_config_word(asd_ha->pcidev, PCI_STATUS, &status);
963 pci_read_config_dword(asd_ha->pcidev, PCIX_STATUS, &pcix_status);
964 pci_read_config_dword(asd_ha->pcidev, ECC_CTRL_STAT, &ecc_status);
965
966 if (status & PCI_STATUS_DETECTED_PARITY)
967 asd_printk("parity error for %s\n", pci_name(asd_ha->pcidev));
968 else if (status & PCI_STATUS_REC_MASTER_ABORT)
969 asd_printk("master abort for %s\n", pci_name(asd_ha->pcidev));
970 else if (status & PCI_STATUS_REC_TARGET_ABORT)
971 asd_printk("target abort for %s\n", pci_name(asd_ha->pcidev));
972 else if (status & PCI_STATUS_PARITY)
973 asd_printk("data parity for %s\n", pci_name(asd_ha->pcidev));
974 else if (pcix_status & RCV_SCE) {
975 asd_printk("received split completion error for %s\n",
976 pci_name(asd_ha->pcidev));
977 pci_write_config_dword(asd_ha->pcidev,PCIX_STATUS,pcix_status);
978 /* XXX: Abort task? */
979 return;
980 } else if (pcix_status & UNEXP_SC) {
981 asd_printk("unexpected split completion for %s\n",
982 pci_name(asd_ha->pcidev));
983 pci_write_config_dword(asd_ha->pcidev,PCIX_STATUS,pcix_status);
984 /* ignore */
985 return;
986 } else if (pcix_status & SC_DISCARD)
987 asd_printk("split completion discarded for %s\n",
988 pci_name(asd_ha->pcidev));
989 else if (ecc_status & UNCOR_ECCERR)
990 asd_printk("uncorrectable ECC error for %s\n",
991 pci_name(asd_ha->pcidev));
992 asd_chip_reset(asd_ha);
993}
994
995/**
996 * asd_hw_isr -- host adapter interrupt service routine
997 * @irq: ignored
998 * @dev_id: pointer to host adapter structure
999 * @regs: ignored
1000 *
1001 * The ISR processes done list entries and level 3 error handling.
1002 */
1003irqreturn_t asd_hw_isr(int irq, void *dev_id, struct pt_regs *regs)
1004{
1005 struct asd_ha_struct *asd_ha = dev_id;
1006 u32 chimint = asd_read_reg_dword(asd_ha, CHIMINT);
1007
1008 if (!chimint)
1009 return IRQ_NONE;
1010
1011 asd_write_reg_dword(asd_ha, CHIMINT, chimint);
1012 (void) asd_read_reg_dword(asd_ha, CHIMINT);
1013
1014 if (chimint & DLAVAIL)
1015 asd_process_donelist_isr(asd_ha);
1016 if (chimint & COMINT)
1017 asd_com_sas_isr(asd_ha);
1018 if (chimint & DEVINT)
1019 asd_dch_sas_isr(asd_ha);
1020 if (chimint & INITERR)
1021 asd_rbi_exsi_isr(asd_ha);
1022 if (chimint & HOSTERR)
1023 asd_hst_pcix_isr(asd_ha);
1024
1025 return IRQ_HANDLED;
1026}
1027
1028/* ---------- SCB handling ---------- */
1029
1030static inline struct asd_ascb *asd_ascb_alloc(struct asd_ha_struct *asd_ha,
1031 unsigned int gfp_flags)
1032{
1033 extern kmem_cache_t *asd_ascb_cache;
1034 struct asd_seq_data *seq = &asd_ha->seq;
1035 struct asd_ascb *ascb;
1036 unsigned long flags;
1037
1038 ascb = kmem_cache_alloc(asd_ascb_cache, gfp_flags);
1039
1040 if (ascb) {
1041 memset(ascb, 0, sizeof(*ascb));
1042 ascb->dma_scb.size = sizeof(struct scb);
1043 ascb->dma_scb.vaddr = dma_pool_alloc(asd_ha->scb_pool,
1044 gfp_flags,
1045 &ascb->dma_scb.dma_handle);
1046 if (!ascb->dma_scb.vaddr) {
1047 kmem_cache_free(asd_ascb_cache, ascb);
1048 return NULL;
1049 }
1050 memset(ascb->dma_scb.vaddr, 0, sizeof(struct scb));
1051 asd_init_ascb(asd_ha, ascb);
1052
1053 spin_lock_irqsave(&seq->tc_index_lock, flags);
1054 ascb->tc_index = asd_tc_index_get(seq, ascb);
1055 spin_unlock_irqrestore(&seq->tc_index_lock, flags);
1056 if (ascb->tc_index == -1)
1057 goto undo;
1058
1059 ascb->scb->header.index = cpu_to_le16((u16)ascb->tc_index);
1060 }
1061
1062 return ascb;
1063undo:
1064 dma_pool_free(asd_ha->scb_pool, ascb->dma_scb.vaddr,
1065 ascb->dma_scb.dma_handle);
1066 kmem_cache_free(asd_ascb_cache, ascb);
1067 ASD_DPRINTK("no index for ascb\n");
1068 return NULL;
1069}
1070
1071/**
1072 * asd_ascb_alloc_list -- allocate a list of aSCBs
1073 * @asd_ha: pointer to host adapter structure
1074 * @num: pointer to integer number of aSCBs
1075 * @gfp_flags: GFP_ flags.
1076 *
1077 * This is the only function which is used to allocate aSCBs.
1078 * It can allocate one or many. If more than one, then they form
1079 * a linked list in two ways: by their list field of the ascb struct
1080 * and by the next_scb field of the scb_header.
1081 *
1082 * Returns NULL if no memory was available, else pointer to a list
1083 * of ascbs. When this function returns, @num would be the number
1084 * of SCBs which were not able to be allocated, 0 if all requested
1085 * were able to be allocated.
1086 */
1087struct asd_ascb *asd_ascb_alloc_list(struct asd_ha_struct
1088 *asd_ha, int *num,
1089 unsigned int gfp_flags)
1090{
1091 struct asd_ascb *first = NULL;
1092
1093 for ( ; *num > 0; --*num) {
1094 struct asd_ascb *ascb = asd_ascb_alloc(asd_ha, gfp_flags);
1095
1096 if (!ascb)
1097 break;
1098 else if (!first)
1099 first = ascb;
1100 else {
1101 struct asd_ascb *last = list_entry(first->list.prev,
1102 struct asd_ascb,
1103 list);
1104 list_add_tail(&ascb->list, &first->list);
1105 last->scb->header.next_scb =
1106 cpu_to_le64(((u64)ascb->dma_scb.dma_handle));
1107 }
1108 }
1109
1110 return first;
1111}
1112
1113/**
1114 * asd_swap_head_scb -- swap the head scb
1115 * @asd_ha: pointer to host adapter structure
1116 * @ascb: pointer to the head of an ascb list
1117 *
1118 * The sequencer knows the DMA address of the next SCB to be DMAed to
1119 * the host adapter, from initialization or from the last list DMAed.
1120 * seq->next_scb keeps the address of this SCB. The sequencer will
1121 * DMA to the host adapter this list of SCBs. But the head (first
1122 * element) of this list is not known to the sequencer. Here we swap
1123 * the head of the list with the known SCB (memcpy()).
1124 * Only one memcpy() is required per list so it is in our interest
1125 * to keep the list of SCB as long as possible so that the ratio
1126 * of number of memcpy calls to the number of SCB DMA-ed is as small
1127 * as possible.
1128 *
1129 * LOCKING: called with the pending list lock held.
1130 */
1131static inline void asd_swap_head_scb(struct asd_ha_struct *asd_ha,
1132 struct asd_ascb *ascb)
1133{
1134 struct asd_seq_data *seq = &asd_ha->seq;
1135 struct asd_ascb *last = list_entry(ascb->list.prev,
1136 struct asd_ascb,
1137 list);
1138 struct asd_dma_tok t = ascb->dma_scb;
1139
1140 memcpy(seq->next_scb.vaddr, ascb->scb, sizeof(*ascb->scb));
1141 ascb->dma_scb = seq->next_scb;
1142 ascb->scb = ascb->dma_scb.vaddr;
1143 seq->next_scb = t;
1144 last->scb->header.next_scb =
1145 cpu_to_le64(((u64)seq->next_scb.dma_handle));
1146}
1147
1148/**
1149 * asd_start_timers -- (add and) start timers of SCBs
1150 * @list: pointer to struct list_head of the scbs
1151 * @to: timeout in jiffies
1152 *
1153 * If an SCB in the @list has no timer function, assign the default
1154 * one, then start the timer of the SCB. This function is
1155 * intended to be called from asd_post_ascb_list(), just prior to
1156 * posting the SCBs to the sequencer.
1157 */
1158static inline void asd_start_scb_timers(struct list_head *list)
1159{
1160 struct asd_ascb *ascb;
1161 list_for_each_entry(ascb, list, list) {
1162 if (!ascb->uldd_timer) {
1163 ascb->timer.data = (unsigned long) ascb;
1164 ascb->timer.function = asd_ascb_timedout;
1165 ascb->timer.expires = jiffies + AIC94XX_SCB_TIMEOUT;
1166 add_timer(&ascb->timer);
1167 }
1168 }
1169}
1170
1171/**
1172 * asd_post_ascb_list -- post a list of 1 or more aSCBs to the host adapter
1173 * @asd_ha: pointer to a host adapter structure
1174 * @ascb: pointer to the first aSCB in the list
1175 * @num: number of aSCBs in the list (to be posted)
1176 *
1177 * See queueing comment in asd_post_escb_list().
1178 *
1179 * Additional note on queuing: In order to minimize the ratio of memcpy()
1180 * to the number of ascbs sent, we try to batch-send as many ascbs as possible
1181 * in one go.
1182 * Two cases are possible:
1183 * A) can_queue >= num,
1184 * B) can_queue < num.
1185 * Case A: we can send the whole batch at once. Increment "pending"
1186 * in the beginning of this function, when it is checked, in order to
1187 * eliminate races when this function is called by multiple processes.
1188 * Case B: should never happen if the managing layer considers
1189 * lldd_queue_size.
1190 */
1191int asd_post_ascb_list(struct asd_ha_struct *asd_ha, struct asd_ascb *ascb,
1192 int num)
1193{
1194 unsigned long flags;
1195 LIST_HEAD(list);
1196 int can_queue;
1197
1198 spin_lock_irqsave(&asd_ha->seq.pend_q_lock, flags);
1199 can_queue = asd_ha->hw_prof.max_scbs - asd_ha->seq.pending;
1200 if (can_queue >= num)
1201 asd_ha->seq.pending += num;
1202 else
1203 can_queue = 0;
1204
1205 if (!can_queue) {
1206 spin_unlock_irqrestore(&asd_ha->seq.pend_q_lock, flags);
1207 asd_printk("%s: scb queue full\n", pci_name(asd_ha->pcidev));
1208 return -SAS_QUEUE_FULL;
1209 }
1210
1211 asd_swap_head_scb(asd_ha, ascb);
1212
1213 __list_add(&list, ascb->list.prev, &ascb->list);
1214
1215 asd_start_scb_timers(&list);
1216
1217 asd_ha->seq.scbpro += num;
1218 list_splice_init(&list, asd_ha->seq.pend_q.prev);
1219 asd_write_reg_dword(asd_ha, SCBPRO, (u32)asd_ha->seq.scbpro);
1220 spin_unlock_irqrestore(&asd_ha->seq.pend_q_lock, flags);
1221
1222 return 0;
1223}
1224
1225/**
1226 * asd_post_escb_list -- post a list of 1 or more empty scb
1227 * @asd_ha: pointer to a host adapter structure
1228 * @ascb: pointer to the first empty SCB in the list
1229 * @num: number of aSCBs in the list (to be posted)
1230 *
1231 * This is essentially the same as asd_post_ascb_list, but we do not
1232 * increment pending, add those to the pending list or get indexes.
1233 * See asd_init_escbs() and asd_init_post_escbs().
1234 *
1235 * Since sending a list of ascbs is a superset of sending a single
1236 * ascb, this function exists to generalize this. More specifically,
1237 * when sending a list of those, we want to do only a _single_
1238 * memcpy() at swap head, as opposed to for each ascb sent (in the
1239 * case of sending them one by one). That is, we want to minimize the
1240 * ratio of memcpy() operations to the number of ascbs sent. The same
1241 * logic applies to asd_post_ascb_list().
1242 */
1243int asd_post_escb_list(struct asd_ha_struct *asd_ha, struct asd_ascb *ascb,
1244 int num)
1245{
1246 unsigned long flags;
1247
1248 spin_lock_irqsave(&asd_ha->seq.pend_q_lock, flags);
1249 asd_swap_head_scb(asd_ha, ascb);
1250 asd_ha->seq.scbpro += num;
1251 asd_write_reg_dword(asd_ha, SCBPRO, (u32)asd_ha->seq.scbpro);
1252 spin_unlock_irqrestore(&asd_ha->seq.pend_q_lock, flags);
1253
1254 return 0;
1255}
1256
1257/* ---------- LED ---------- */
1258
1259/**
1260 * asd_turn_led -- turn on/off an LED
1261 * @asd_ha: pointer to host adapter structure
1262 * @phy_id: the PHY id whose LED we want to manupulate
1263 * @op: 1 to turn on, 0 to turn off
1264 */
1265void asd_turn_led(struct asd_ha_struct *asd_ha, int phy_id, int op)
1266{
1267 if (phy_id < ASD_MAX_PHYS) {
1268 u32 v = asd_read_reg_dword(asd_ha, LmCONTROL(phy_id));
1269 if (op)
1270 v |= LEDPOL;
1271 else
1272 v &= ~LEDPOL;
1273 asd_write_reg_dword(asd_ha, LmCONTROL(phy_id), v);
1274 }
1275}
1276
1277/**
1278 * asd_control_led -- enable/disable an LED on the board
1279 * @asd_ha: pointer to host adapter structure
1280 * @phy_id: integer, the phy id
1281 * @op: integer, 1 to enable, 0 to disable the LED
1282 *
1283 * First we output enable the LED, then we set the source
1284 * to be an external module.
1285 */
1286void asd_control_led(struct asd_ha_struct *asd_ha, int phy_id, int op)
1287{
1288 if (phy_id < ASD_MAX_PHYS) {
1289 u32 v;
1290
1291 v = asd_read_reg_dword(asd_ha, GPIOOER);
1292 if (op)
1293 v |= (1 << phy_id);
1294 else
1295 v &= ~(1 << phy_id);
1296 asd_write_reg_dword(asd_ha, GPIOOER, v);
1297
1298 v = asd_read_reg_dword(asd_ha, GPIOCNFGR);
1299 if (op)
1300 v |= (1 << phy_id);
1301 else
1302 v &= ~(1 << phy_id);
1303 asd_write_reg_dword(asd_ha, GPIOCNFGR, v);
1304 }
1305}
1306
1307/* ---------- PHY enable ---------- */
1308
1309static int asd_enable_phy(struct asd_ha_struct *asd_ha, int phy_id)
1310{
1311 struct asd_phy *phy = &asd_ha->phys[phy_id];
1312
1313 asd_write_reg_byte(asd_ha, LmSEQ_OOB_REG(phy_id, INT_ENABLE_2), 0);
1314 asd_write_reg_byte(asd_ha, LmSEQ_OOB_REG(phy_id, HOT_PLUG_DELAY),
1315 HOTPLUG_DELAY_TIMEOUT);
1316
1317 /* Get defaults from manuf. sector */
1318 /* XXX we need defaults for those in case MS is broken. */
1319 asd_write_reg_byte(asd_ha, LmSEQ_OOB_REG(phy_id, PHY_CONTROL_0),
1320 phy->phy_desc->phy_control_0);
1321 asd_write_reg_byte(asd_ha, LmSEQ_OOB_REG(phy_id, PHY_CONTROL_1),
1322 phy->phy_desc->phy_control_1);
1323 asd_write_reg_byte(asd_ha, LmSEQ_OOB_REG(phy_id, PHY_CONTROL_2),
1324 phy->phy_desc->phy_control_2);
1325 asd_write_reg_byte(asd_ha, LmSEQ_OOB_REG(phy_id, PHY_CONTROL_3),
1326 phy->phy_desc->phy_control_3);
1327
1328 asd_write_reg_dword(asd_ha, LmSEQ_TEN_MS_COMINIT_TIMEOUT(phy_id),
1329 ASD_COMINIT_TIMEOUT);
1330
1331 asd_write_reg_addr(asd_ha, LmSEQ_TX_ID_ADDR_FRAME(phy_id),
1332 phy->id_frm_tok->dma_handle);
1333
1334 asd_control_led(asd_ha, phy_id, 1);
1335
1336 return 0;
1337}
1338
1339int asd_enable_phys(struct asd_ha_struct *asd_ha, const u8 phy_mask)
1340{
1341 u8 phy_m;
1342 u8 i;
1343 int num = 0, k;
1344 struct asd_ascb *ascb;
1345 struct asd_ascb *ascb_list;
1346
1347 if (!phy_mask) {
1348 asd_printk("%s called with phy_mask of 0!?\n", __FUNCTION__);
1349 return 0;
1350 }
1351
1352 for_each_phy(phy_mask, phy_m, i) {
1353 num++;
1354 asd_enable_phy(asd_ha, i);
1355 }
1356
1357 k = num;
1358 ascb_list = asd_ascb_alloc_list(asd_ha, &k, GFP_KERNEL);
1359 if (!ascb_list) {
1360 asd_printk("no memory for control phy ascb list\n");
1361 return -ENOMEM;
1362 }
1363 num -= k;
1364
1365 ascb = ascb_list;
1366 for_each_phy(phy_mask, phy_m, i) {
1367 asd_build_control_phy(ascb, i, ENABLE_PHY);
1368 ascb = list_entry(ascb->list.next, struct asd_ascb, list);
1369 }
1370 ASD_DPRINTK("posting %d control phy scbs\n", num);
1371 k = asd_post_ascb_list(asd_ha, ascb_list, num);
1372 if (k)
1373 asd_ascb_free_list(ascb_list);
1374
1375 return k;
1376}
diff --git a/drivers/scsi/aic94xx/aic94xx_hwi.h b/drivers/scsi/aic94xx/aic94xx_hwi.h
new file mode 100644
index 000000000000..c7d505388fed
--- /dev/null
+++ b/drivers/scsi/aic94xx/aic94xx_hwi.h
@@ -0,0 +1,397 @@
1/*
2 * Aic94xx SAS/SATA driver hardware interface header file.
3 *
4 * Copyright (C) 2005 Adaptec, Inc. All rights reserved.
5 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
6 *
7 * This file is licensed under GPLv2.
8 *
9 * This file is part of the aic94xx driver.
10 *
11 * The aic94xx driver is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; version 2 of the
14 * License.
15 *
16 * The aic94xx driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with the aic94xx driver; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 *
25 */
26
27#ifndef _AIC94XX_HWI_H_
28#define _AIC94XX_HWI_H_
29
30#include <linux/interrupt.h>
31#include <linux/pci.h>
32#include <linux/dma-mapping.h>
33
34#include <scsi/libsas.h>
35
36#include "aic94xx.h"
37#include "aic94xx_sas.h"
38
39/* Define ASD_MAX_PHYS to the maximum phys ever. Currently 8. */
40#define ASD_MAX_PHYS 8
41#define ASD_PCBA_SN_SIZE 12
42
43/* Those are to be further named properly, the "RAZORx" part, and
44 * subsequently included in include/linux/pci_ids.h.
45 */
46#define PCI_DEVICE_ID_ADAPTEC2_RAZOR10 0x410
47#define PCI_DEVICE_ID_ADAPTEC2_RAZOR12 0x412
48#define PCI_DEVICE_ID_ADAPTEC2_RAZOR1E 0x41E
49#define PCI_DEVICE_ID_ADAPTEC2_RAZOR30 0x430
50#define PCI_DEVICE_ID_ADAPTEC2_RAZOR32 0x432
51#define PCI_DEVICE_ID_ADAPTEC2_RAZOR3E 0x43E
52#define PCI_DEVICE_ID_ADAPTEC2_RAZOR3F 0x43F
53
54struct asd_ha_addrspace {
55 void __iomem *addr;
56 unsigned long start; /* pci resource start */
57 unsigned long len; /* pci resource len */
58 unsigned long flags; /* pci resource flags */
59
60 /* addresses internal to the host adapter */
61 u32 swa_base; /* mmspace 1 (MBAR1) uses this only */
62 u32 swb_base;
63 u32 swc_base;
64};
65
66struct bios_struct {
67 int present;
68 u8 maj;
69 u8 min;
70 u32 bld;
71};
72
73struct unit_element_struct {
74 u16 num;
75 u16 size;
76 void *area;
77};
78
79struct flash_struct {
80 u32 bar;
81 int present;
82 int wide;
83 u8 manuf;
84 u8 dev_id;
85 u8 sec_prot;
86
87 u32 dir_offs;
88};
89
90struct asd_phy_desc {
91 /* From CTRL-A settings, then set to what is appropriate */
92 u8 sas_addr[SAS_ADDR_SIZE];
93 u8 max_sas_lrate;
94 u8 min_sas_lrate;
95 u8 max_sata_lrate;
96 u8 min_sata_lrate;
97 u8 flags;
98#define ASD_CRC_DIS 1
99#define ASD_SATA_SPINUP_HOLD 2
100
101 u8 phy_control_0; /* mode 5 reg 0x160 */
102 u8 phy_control_1; /* mode 5 reg 0x161 */
103 u8 phy_control_2; /* mode 5 reg 0x162 */
104 u8 phy_control_3; /* mode 5 reg 0x163 */
105};
106
107struct asd_dma_tok {
108 void *vaddr;
109 dma_addr_t dma_handle;
110 size_t size;
111};
112
113struct hw_profile {
114 struct bios_struct bios;
115 struct unit_element_struct ue;
116 struct flash_struct flash;
117
118 u8 sas_addr[SAS_ADDR_SIZE];
119 char pcba_sn[ASD_PCBA_SN_SIZE+1];
120
121 u8 enabled_phys; /* mask of enabled phys */
122 struct asd_phy_desc phy_desc[ASD_MAX_PHYS];
123 u32 max_scbs; /* absolute sequencer scb queue size */
124 struct asd_dma_tok *scb_ext;
125 u32 max_ddbs;
126 struct asd_dma_tok *ddb_ext;
127
128 spinlock_t ddb_lock;
129 void *ddb_bitmap;
130
131 int num_phys; /* ENABLEABLE */
132 int max_phys; /* REPORTED + ENABLEABLE */
133
134 unsigned addr_range; /* max # of addrs; max # of possible ports */
135 unsigned port_name_base;
136 unsigned dev_name_base;
137 unsigned sata_name_base;
138};
139
140struct asd_ascb {
141 struct list_head list;
142 struct asd_ha_struct *ha;
143
144 struct scb *scb; /* equals dma_scb->vaddr */
145 struct asd_dma_tok dma_scb;
146 struct asd_dma_tok *sg_arr;
147
148 void (*tasklet_complete)(struct asd_ascb *, struct done_list_struct *);
149 u8 uldd_timer:1;
150
151 /* internally generated command */
152 struct timer_list timer;
153 struct completion completion;
154 u8 tag_valid:1;
155 __be16 tag; /* error recovery only */
156
157 /* If this is an Empty SCB, index of first edb in seq->edb_arr. */
158 int edb_index;
159
160 /* Used by the timer timeout function. */
161 int tc_index;
162
163 void *uldd_task;
164};
165
166#define ASD_DL_SIZE_BITS 0x8
167#define ASD_DL_SIZE (1<<(2+ASD_DL_SIZE_BITS))
168#define ASD_DEF_DL_TOGGLE 0x01
169
170struct asd_seq_data {
171 spinlock_t pend_q_lock;
172 u16 scbpro;
173 int pending;
174 struct list_head pend_q;
175 int can_queue; /* per adapter */
176 struct asd_dma_tok next_scb; /* next scb to be delivered to CSEQ */
177
178 spinlock_t tc_index_lock;
179 void **tc_index_array;
180 void *tc_index_bitmap;
181 int tc_index_bitmap_bits;
182
183 struct tasklet_struct dl_tasklet;
184 struct done_list_struct *dl; /* array of done list entries, equals */
185 struct asd_dma_tok *actual_dl; /* actual_dl->vaddr */
186 int dl_toggle;
187 int dl_next;
188
189 int num_edbs;
190 struct asd_dma_tok **edb_arr;
191 int num_escbs;
192 struct asd_ascb **escb_arr; /* array of pointers to escbs */
193};
194
195/* This is the Host Adapter structure. It describes the hardware
196 * SAS adapter.
197 */
198struct asd_ha_struct {
199 struct pci_dev *pcidev;
200 const char *name;
201
202 struct sas_ha_struct sas_ha;
203
204 u8 revision_id;
205
206 int iospace;
207 spinlock_t iolock;
208 struct asd_ha_addrspace io_handle[2];
209
210 struct hw_profile hw_prof;
211
212 struct asd_phy phys[ASD_MAX_PHYS];
213 struct asd_sas_port ports[ASD_MAX_PHYS];
214
215 struct dma_pool *scb_pool;
216
217 struct asd_seq_data seq; /* sequencer related */
218};
219
220/* ---------- Common macros ---------- */
221
222#define ASD_BUSADDR_LO(__dma_handle) ((u32)(__dma_handle))
223#define ASD_BUSADDR_HI(__dma_handle) (((sizeof(dma_addr_t))==8) \
224 ? ((u32)((__dma_handle) >> 32)) \
225 : ((u32)0))
226
227#define dev_to_asd_ha(__dev) pci_get_drvdata(to_pci_dev(__dev))
228#define SCB_SITE_VALID(__site_no) (((__site_no) & 0xF0FF) != 0x00FF \
229 && ((__site_no) & 0xF0FF) > 0x001F)
230/* For each bit set in __lseq_mask, set __lseq to equal the bit
231 * position of the set bit and execute the statement following.
232 * __mc is the temporary mask, used as a mask "counter".
233 */
234#define for_each_sequencer(__lseq_mask, __mc, __lseq) \
235 for ((__mc)=(__lseq_mask),(__lseq)=0;(__mc)!=0;(__lseq++),(__mc)>>=1)\
236 if (((__mc) & 1))
237#define for_each_phy(__lseq_mask, __mc, __lseq) \
238 for ((__mc)=(__lseq_mask),(__lseq)=0;(__mc)!=0;(__lseq++),(__mc)>>=1)\
239 if (((__mc) & 1))
240
241#define PHY_ENABLED(_HA, _I) ((_HA)->hw_prof.enabled_phys & (1<<(_I)))
242
243/* ---------- DMA allocs ---------- */
244
245static inline struct asd_dma_tok *asd_dmatok_alloc(unsigned int flags)
246{
247 return kmem_cache_alloc(asd_dma_token_cache, flags);
248}
249
250static inline void asd_dmatok_free(struct asd_dma_tok *token)
251{
252 kmem_cache_free(asd_dma_token_cache, token);
253}
254
255static inline struct asd_dma_tok *asd_alloc_coherent(struct asd_ha_struct *
256 asd_ha, size_t size,
257 unsigned int flags)
258{
259 struct asd_dma_tok *token = asd_dmatok_alloc(flags);
260 if (token) {
261 token->size = size;
262 token->vaddr = dma_alloc_coherent(&asd_ha->pcidev->dev,
263 token->size,
264 &token->dma_handle,
265 flags);
266 if (!token->vaddr) {
267 asd_dmatok_free(token);
268 token = NULL;
269 }
270 }
271 return token;
272}
273
274static inline void asd_free_coherent(struct asd_ha_struct *asd_ha,
275 struct asd_dma_tok *token)
276{
277 if (token) {
278 dma_free_coherent(&asd_ha->pcidev->dev, token->size,
279 token->vaddr, token->dma_handle);
280 asd_dmatok_free(token);
281 }
282}
283
284static inline void asd_init_ascb(struct asd_ha_struct *asd_ha,
285 struct asd_ascb *ascb)
286{
287 INIT_LIST_HEAD(&ascb->list);
288 ascb->scb = ascb->dma_scb.vaddr;
289 ascb->ha = asd_ha;
290 ascb->timer.function = NULL;
291 init_timer(&ascb->timer);
292 ascb->tc_index = -1;
293 init_completion(&ascb->completion);
294}
295
296/* Must be called with the tc_index_lock held!
297 */
298static inline void asd_tc_index_release(struct asd_seq_data *seq, int index)
299{
300 seq->tc_index_array[index] = NULL;
301 clear_bit(index, seq->tc_index_bitmap);
302}
303
304/* Must be called with the tc_index_lock held!
305 */
306static inline int asd_tc_index_get(struct asd_seq_data *seq, void *ptr)
307{
308 int index;
309
310 index = find_first_zero_bit(seq->tc_index_bitmap,
311 seq->tc_index_bitmap_bits);
312 if (index == seq->tc_index_bitmap_bits)
313 return -1;
314
315 seq->tc_index_array[index] = ptr;
316 set_bit(index, seq->tc_index_bitmap);
317
318 return index;
319}
320
321/* Must be called with the tc_index_lock held!
322 */
323static inline void *asd_tc_index_find(struct asd_seq_data *seq, int index)
324{
325 return seq->tc_index_array[index];
326}
327
328/**
329 * asd_ascb_free -- free a single aSCB after is has completed
330 * @ascb: pointer to the aSCB of interest
331 *
332 * This frees an aSCB after it has been executed/completed by
333 * the sequencer.
334 */
335static inline void asd_ascb_free(struct asd_ascb *ascb)
336{
337 if (ascb) {
338 struct asd_ha_struct *asd_ha = ascb->ha;
339 unsigned long flags;
340
341 BUG_ON(!list_empty(&ascb->list));
342 spin_lock_irqsave(&ascb->ha->seq.tc_index_lock, flags);
343 asd_tc_index_release(&ascb->ha->seq, ascb->tc_index);
344 spin_unlock_irqrestore(&ascb->ha->seq.tc_index_lock, flags);
345 dma_pool_free(asd_ha->scb_pool, ascb->dma_scb.vaddr,
346 ascb->dma_scb.dma_handle);
347 kmem_cache_free(asd_ascb_cache, ascb);
348 }
349}
350
351/**
352 * asd_ascb_list_free -- free a list of ascbs
353 * @ascb_list: a list of ascbs
354 *
355 * This function will free a list of ascbs allocated by asd_ascb_alloc_list.
356 * It is used when say the scb queueing function returned QUEUE_FULL,
357 * and we do not need the ascbs any more.
358 */
359static inline void asd_ascb_free_list(struct asd_ascb *ascb_list)
360{
361 LIST_HEAD(list);
362 struct list_head *n, *pos;
363
364 __list_add(&list, ascb_list->list.prev, &ascb_list->list);
365 list_for_each_safe(pos, n, &list) {
366 list_del_init(pos);
367 asd_ascb_free(list_entry(pos, struct asd_ascb, list));
368 }
369}
370
371/* ---------- Function declarations ---------- */
372
373int asd_init_hw(struct asd_ha_struct *asd_ha);
374irqreturn_t asd_hw_isr(int irq, void *dev_id, struct pt_regs *regs);
375
376
377struct asd_ascb *asd_ascb_alloc_list(struct asd_ha_struct
378 *asd_ha, int *num,
379 unsigned int gfp_mask);
380
381int asd_post_ascb_list(struct asd_ha_struct *asd_ha, struct asd_ascb *ascb,
382 int num);
383int asd_post_escb_list(struct asd_ha_struct *asd_ha, struct asd_ascb *ascb,
384 int num);
385
386int asd_init_post_escbs(struct asd_ha_struct *asd_ha);
387void asd_build_control_phy(struct asd_ascb *ascb, int phy_id, u8 subfunc);
388void asd_control_led(struct asd_ha_struct *asd_ha, int phy_id, int op);
389void asd_turn_led(struct asd_ha_struct *asd_ha, int phy_id, int op);
390int asd_enable_phys(struct asd_ha_struct *asd_ha, const u8 phy_mask);
391void asd_build_initiate_link_adm_task(struct asd_ascb *ascb, int phy_id,
392 u8 subfunc);
393
394void asd_ascb_timedout(unsigned long data);
395int asd_chip_hardrst(struct asd_ha_struct *asd_ha);
396
397#endif
diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c
new file mode 100644
index 000000000000..3ec2e46f80c6
--- /dev/null
+++ b/drivers/scsi/aic94xx/aic94xx_init.c
@@ -0,0 +1,860 @@
1/*
2 * Aic94xx SAS/SATA driver initialization.
3 *
4 * Copyright (C) 2005 Adaptec, Inc. All rights reserved.
5 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
6 *
7 * This file is licensed under GPLv2.
8 *
9 * This file is part of the aic94xx driver.
10 *
11 * The aic94xx driver is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; version 2 of the
14 * License.
15 *
16 * The aic94xx driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with the aic94xx driver; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 *
25 */
26
27#include <linux/config.h>
28#include <linux/module.h>
29#include <linux/init.h>
30#include <linux/kernel.h>
31#include <linux/pci.h>
32#include <linux/delay.h>
33
34#include <scsi/scsi_host.h>
35
36#include "aic94xx.h"
37#include "aic94xx_reg.h"
38#include "aic94xx_hwi.h"
39#include "aic94xx_seq.h"
40
41/* The format is "version.release.patchlevel" */
42#define ASD_DRIVER_VERSION "1.0.2"
43
44static int use_msi = 0;
45module_param_named(use_msi, use_msi, int, S_IRUGO);
46MODULE_PARM_DESC(use_msi, "\n"
47 "\tEnable(1) or disable(0) using PCI MSI.\n"
48 "\tDefault: 0");
49
50static int lldd_max_execute_num = 0;
51module_param_named(collector, lldd_max_execute_num, int, S_IRUGO);
52MODULE_PARM_DESC(collector, "\n"
53 "\tIf greater than one, tells the SAS Layer to run in Task Collector\n"
54 "\tMode. If 1 or 0, tells the SAS Layer to run in Direct Mode.\n"
55 "\tThe aic94xx SAS LLDD supports both modes.\n"
56 "\tDefault: 0 (Direct Mode).\n");
57
58char sas_addr_str[2*SAS_ADDR_SIZE + 1] = "";
59
60static struct scsi_transport_template *aic94xx_transport_template;
61
62static struct scsi_host_template aic94xx_sht = {
63 .module = THIS_MODULE,
64 /* .name is initialized */
65 .name = "aic94xx",
66 .queuecommand = sas_queuecommand,
67 .target_alloc = sas_target_alloc,
68 .slave_configure = sas_slave_configure,
69 .slave_destroy = sas_slave_destroy,
70 .change_queue_depth = sas_change_queue_depth,
71 .change_queue_type = sas_change_queue_type,
72 .bios_param = sas_bios_param,
73 .can_queue = 1,
74 .cmd_per_lun = 1,
75 .this_id = -1,
76 .sg_tablesize = SG_ALL,
77 .max_sectors = SCSI_DEFAULT_MAX_SECTORS,
78 .use_clustering = ENABLE_CLUSTERING,
79};
80
81static int __devinit asd_map_memio(struct asd_ha_struct *asd_ha)
82{
83 int err, i;
84 struct asd_ha_addrspace *io_handle;
85
86 asd_ha->iospace = 0;
87 for (i = 0; i < 3; i += 2) {
88 io_handle = &asd_ha->io_handle[i==0?0:1];
89 io_handle->start = pci_resource_start(asd_ha->pcidev, i);
90 io_handle->len = pci_resource_len(asd_ha->pcidev, i);
91 io_handle->flags = pci_resource_flags(asd_ha->pcidev, i);
92 err = -ENODEV;
93 if (!io_handle->start || !io_handle->len) {
94 asd_printk("MBAR%d start or length for %s is 0.\n",
95 i==0?0:1, pci_name(asd_ha->pcidev));
96 goto Err;
97 }
98 err = pci_request_region(asd_ha->pcidev, i, ASD_DRIVER_NAME);
99 if (err) {
100 asd_printk("couldn't reserve memory region for %s\n",
101 pci_name(asd_ha->pcidev));
102 goto Err;
103 }
104 if (io_handle->flags & IORESOURCE_CACHEABLE)
105 io_handle->addr = ioremap(io_handle->start,
106 io_handle->len);
107 else
108 io_handle->addr = ioremap_nocache(io_handle->start,
109 io_handle->len);
110 if (!io_handle->addr) {
111 asd_printk("couldn't map MBAR%d of %s\n", i==0?0:1,
112 pci_name(asd_ha->pcidev));
113 goto Err_unreq;
114 }
115 }
116
117 return 0;
118Err_unreq:
119 pci_release_region(asd_ha->pcidev, i);
120Err:
121 if (i > 0) {
122 io_handle = &asd_ha->io_handle[0];
123 iounmap(io_handle->addr);
124 pci_release_region(asd_ha->pcidev, 0);
125 }
126 return err;
127}
128
129static void __devexit asd_unmap_memio(struct asd_ha_struct *asd_ha)
130{
131 struct asd_ha_addrspace *io_handle;
132
133 io_handle = &asd_ha->io_handle[1];
134 iounmap(io_handle->addr);
135 pci_release_region(asd_ha->pcidev, 2);
136
137 io_handle = &asd_ha->io_handle[0];
138 iounmap(io_handle->addr);
139 pci_release_region(asd_ha->pcidev, 0);
140}
141
142static int __devinit asd_map_ioport(struct asd_ha_struct *asd_ha)
143{
144 int i = PCI_IOBAR_OFFSET, err;
145 struct asd_ha_addrspace *io_handle = &asd_ha->io_handle[0];
146
147 asd_ha->iospace = 1;
148 io_handle->start = pci_resource_start(asd_ha->pcidev, i);
149 io_handle->len = pci_resource_len(asd_ha->pcidev, i);
150 io_handle->flags = pci_resource_flags(asd_ha->pcidev, i);
151 io_handle->addr = (void __iomem *) io_handle->start;
152 if (!io_handle->start || !io_handle->len) {
153 asd_printk("couldn't get IO ports for %s\n",
154 pci_name(asd_ha->pcidev));
155 return -ENODEV;
156 }
157 err = pci_request_region(asd_ha->pcidev, i, ASD_DRIVER_NAME);
158 if (err) {
159 asd_printk("couldn't reserve io space for %s\n",
160 pci_name(asd_ha->pcidev));
161 }
162
163 return err;
164}
165
166static void __devexit asd_unmap_ioport(struct asd_ha_struct *asd_ha)
167{
168 pci_release_region(asd_ha->pcidev, PCI_IOBAR_OFFSET);
169}
170
171static int __devinit asd_map_ha(struct asd_ha_struct *asd_ha)
172{
173 int err;
174 u16 cmd_reg;
175
176 err = pci_read_config_word(asd_ha->pcidev, PCI_COMMAND, &cmd_reg);
177 if (err) {
178 asd_printk("couldn't read command register of %s\n",
179 pci_name(asd_ha->pcidev));
180 goto Err;
181 }
182
183 err = -ENODEV;
184 if (cmd_reg & PCI_COMMAND_MEMORY) {
185 if ((err = asd_map_memio(asd_ha)))
186 goto Err;
187 } else if (cmd_reg & PCI_COMMAND_IO) {
188 if ((err = asd_map_ioport(asd_ha)))
189 goto Err;
190 asd_printk("%s ioport mapped -- upgrade your hardware\n",
191 pci_name(asd_ha->pcidev));
192 } else {
193 asd_printk("no proper device access to %s\n",
194 pci_name(asd_ha->pcidev));
195 goto Err;
196 }
197
198 return 0;
199Err:
200 return err;
201}
202
203static void __devexit asd_unmap_ha(struct asd_ha_struct *asd_ha)
204{
205 if (asd_ha->iospace)
206 asd_unmap_ioport(asd_ha);
207 else
208 asd_unmap_memio(asd_ha);
209}
210
211static const char *asd_dev_rev[30] = {
212 [0] = "A0",
213 [1] = "A1",
214 [8] = "B0",
215};
216
217static int __devinit asd_common_setup(struct asd_ha_struct *asd_ha)
218{
219 int err, i;
220
221 err = pci_read_config_byte(asd_ha->pcidev, PCI_REVISION_ID,
222 &asd_ha->revision_id);
223 if (err) {
224 asd_printk("couldn't read REVISION ID register of %s\n",
225 pci_name(asd_ha->pcidev));
226 goto Err;
227 }
228 err = -ENODEV;
229 if (asd_ha->revision_id < AIC9410_DEV_REV_B0) {
230 asd_printk("%s is revision %s (%X), which is not supported\n",
231 pci_name(asd_ha->pcidev),
232 asd_dev_rev[asd_ha->revision_id],
233 asd_ha->revision_id);
234 goto Err;
235 }
236 /* Provide some sane default values. */
237 asd_ha->hw_prof.max_scbs = 512;
238 asd_ha->hw_prof.max_ddbs = 128;
239 asd_ha->hw_prof.num_phys = ASD_MAX_PHYS;
240 /* All phys are enabled, by default. */
241 asd_ha->hw_prof.enabled_phys = 0xFF;
242 for (i = 0; i < ASD_MAX_PHYS; i++) {
243 asd_ha->hw_prof.phy_desc[i].max_sas_lrate = PHY_LINKRATE_3;
244 asd_ha->hw_prof.phy_desc[i].min_sas_lrate = PHY_LINKRATE_1_5;
245 asd_ha->hw_prof.phy_desc[i].max_sata_lrate= PHY_LINKRATE_1_5;
246 asd_ha->hw_prof.phy_desc[i].min_sata_lrate= PHY_LINKRATE_1_5;
247 }
248
249 return 0;
250Err:
251 return err;
252}
253
254static int __devinit asd_aic9410_setup(struct asd_ha_struct *asd_ha)
255{
256 int err = asd_common_setup(asd_ha);
257
258 if (err)
259 return err;
260
261 asd_ha->hw_prof.addr_range = 8;
262 asd_ha->hw_prof.port_name_base = 0;
263 asd_ha->hw_prof.dev_name_base = 8;
264 asd_ha->hw_prof.sata_name_base = 16;
265
266 return 0;
267}
268
269static int __devinit asd_aic9405_setup(struct asd_ha_struct *asd_ha)
270{
271 int err = asd_common_setup(asd_ha);
272
273 if (err)
274 return err;
275
276 asd_ha->hw_prof.addr_range = 4;
277 asd_ha->hw_prof.port_name_base = 0;
278 asd_ha->hw_prof.dev_name_base = 4;
279 asd_ha->hw_prof.sata_name_base = 8;
280
281 return 0;
282}
283
284static ssize_t asd_show_dev_rev(struct device *dev,
285 struct device_attribute *attr, char *buf)
286{
287 struct asd_ha_struct *asd_ha = dev_to_asd_ha(dev);
288 return snprintf(buf, PAGE_SIZE, "%s\n",
289 asd_dev_rev[asd_ha->revision_id]);
290}
291static DEVICE_ATTR(revision, S_IRUGO, asd_show_dev_rev, NULL);
292
293static ssize_t asd_show_dev_bios_build(struct device *dev,
294 struct device_attribute *attr,char *buf)
295{
296 struct asd_ha_struct *asd_ha = dev_to_asd_ha(dev);
297 return snprintf(buf, PAGE_SIZE, "%d\n", asd_ha->hw_prof.bios.bld);
298}
299static DEVICE_ATTR(bios_build, S_IRUGO, asd_show_dev_bios_build, NULL);
300
301static ssize_t asd_show_dev_pcba_sn(struct device *dev,
302 struct device_attribute *attr, char *buf)
303{
304 struct asd_ha_struct *asd_ha = dev_to_asd_ha(dev);
305 return snprintf(buf, PAGE_SIZE, "%s\n", asd_ha->hw_prof.pcba_sn);
306}
307static DEVICE_ATTR(pcba_sn, S_IRUGO, asd_show_dev_pcba_sn, NULL);
308
309static void asd_create_dev_attrs(struct asd_ha_struct *asd_ha)
310{
311 device_create_file(&asd_ha->pcidev->dev, &dev_attr_revision);
312 device_create_file(&asd_ha->pcidev->dev, &dev_attr_bios_build);
313 device_create_file(&asd_ha->pcidev->dev, &dev_attr_pcba_sn);
314}
315
316static void asd_remove_dev_attrs(struct asd_ha_struct *asd_ha)
317{
318 device_remove_file(&asd_ha->pcidev->dev, &dev_attr_revision);
319 device_remove_file(&asd_ha->pcidev->dev, &dev_attr_bios_build);
320 device_remove_file(&asd_ha->pcidev->dev, &dev_attr_pcba_sn);
321}
322
323/* The first entry, 0, is used for dynamic ids, the rest for devices
324 * we know about.
325 */
326static struct asd_pcidev_struct {
327 const char * name;
328 int (*setup)(struct asd_ha_struct *asd_ha);
329} asd_pcidev_data[] = {
330 /* Id 0 is used for dynamic ids. */
331 { .name = "Adaptec AIC-94xx SAS/SATA Host Adapter",
332 .setup = asd_aic9410_setup
333 },
334 { .name = "Adaptec AIC-9410W SAS/SATA Host Adapter",
335 .setup = asd_aic9410_setup
336 },
337 { .name = "Adaptec AIC-9405W SAS/SATA Host Adapter",
338 .setup = asd_aic9405_setup
339 },
340};
341
342static inline int asd_create_ha_caches(struct asd_ha_struct *asd_ha)
343{
344 asd_ha->scb_pool = dma_pool_create(ASD_DRIVER_NAME "_scb_pool",
345 &asd_ha->pcidev->dev,
346 sizeof(struct scb),
347 8, 0);
348 if (!asd_ha->scb_pool) {
349 asd_printk("couldn't create scb pool\n");
350 return -ENOMEM;
351 }
352
353 return 0;
354}
355
356/**
357 * asd_free_edbs -- free empty data buffers
358 * asd_ha: pointer to host adapter structure
359 */
360static inline void asd_free_edbs(struct asd_ha_struct *asd_ha)
361{
362 struct asd_seq_data *seq = &asd_ha->seq;
363 int i;
364
365 for (i = 0; i < seq->num_edbs; i++)
366 asd_free_coherent(asd_ha, seq->edb_arr[i]);
367 kfree(seq->edb_arr);
368 seq->edb_arr = NULL;
369}
370
371static inline void asd_free_escbs(struct asd_ha_struct *asd_ha)
372{
373 struct asd_seq_data *seq = &asd_ha->seq;
374 int i;
375
376 for (i = 0; i < seq->num_escbs; i++) {
377 if (!list_empty(&seq->escb_arr[i]->list))
378 list_del_init(&seq->escb_arr[i]->list);
379
380 asd_ascb_free(seq->escb_arr[i]);
381 }
382 kfree(seq->escb_arr);
383 seq->escb_arr = NULL;
384}
385
386static inline void asd_destroy_ha_caches(struct asd_ha_struct *asd_ha)
387{
388 int i;
389
390 if (asd_ha->hw_prof.ddb_ext)
391 asd_free_coherent(asd_ha, asd_ha->hw_prof.ddb_ext);
392 if (asd_ha->hw_prof.scb_ext)
393 asd_free_coherent(asd_ha, asd_ha->hw_prof.scb_ext);
394
395 if (asd_ha->hw_prof.ddb_bitmap)
396 kfree(asd_ha->hw_prof.ddb_bitmap);
397 asd_ha->hw_prof.ddb_bitmap = NULL;
398
399 for (i = 0; i < ASD_MAX_PHYS; i++) {
400 struct asd_phy *phy = &asd_ha->phys[i];
401
402 asd_free_coherent(asd_ha, phy->id_frm_tok);
403 }
404 if (asd_ha->seq.escb_arr)
405 asd_free_escbs(asd_ha);
406 if (asd_ha->seq.edb_arr)
407 asd_free_edbs(asd_ha);
408 if (asd_ha->hw_prof.ue.area) {
409 kfree(asd_ha->hw_prof.ue.area);
410 asd_ha->hw_prof.ue.area = NULL;
411 }
412 if (asd_ha->seq.tc_index_array) {
413 kfree(asd_ha->seq.tc_index_array);
414 kfree(asd_ha->seq.tc_index_bitmap);
415 asd_ha->seq.tc_index_array = NULL;
416 asd_ha->seq.tc_index_bitmap = NULL;
417 }
418 if (asd_ha->seq.actual_dl) {
419 asd_free_coherent(asd_ha, asd_ha->seq.actual_dl);
420 asd_ha->seq.actual_dl = NULL;
421 asd_ha->seq.dl = NULL;
422 }
423 if (asd_ha->seq.next_scb.vaddr) {
424 dma_pool_free(asd_ha->scb_pool, asd_ha->seq.next_scb.vaddr,
425 asd_ha->seq.next_scb.dma_handle);
426 asd_ha->seq.next_scb.vaddr = NULL;
427 }
428 dma_pool_destroy(asd_ha->scb_pool);
429 asd_ha->scb_pool = NULL;
430}
431
432kmem_cache_t *asd_dma_token_cache;
433kmem_cache_t *asd_ascb_cache;
434
435static int asd_create_global_caches(void)
436{
437 if (!asd_dma_token_cache) {
438 asd_dma_token_cache
439 = kmem_cache_create(ASD_DRIVER_NAME "_dma_token",
440 sizeof(struct asd_dma_tok),
441 0,
442 SLAB_HWCACHE_ALIGN,
443 NULL, NULL);
444 if (!asd_dma_token_cache) {
445 asd_printk("couldn't create dma token cache\n");
446 return -ENOMEM;
447 }
448 }
449
450 if (!asd_ascb_cache) {
451 asd_ascb_cache = kmem_cache_create(ASD_DRIVER_NAME "_ascb",
452 sizeof(struct asd_ascb),
453 0,
454 SLAB_HWCACHE_ALIGN,
455 NULL, NULL);
456 if (!asd_ascb_cache) {
457 asd_printk("couldn't create ascb cache\n");
458 goto Err;
459 }
460 }
461
462 return 0;
463Err:
464 kmem_cache_destroy(asd_dma_token_cache);
465 asd_dma_token_cache = NULL;
466 return -ENOMEM;
467}
468
469static void asd_destroy_global_caches(void)
470{
471 if (asd_dma_token_cache)
472 kmem_cache_destroy(asd_dma_token_cache);
473 asd_dma_token_cache = NULL;
474
475 if (asd_ascb_cache)
476 kmem_cache_destroy(asd_ascb_cache);
477 asd_ascb_cache = NULL;
478}
479
480static int asd_register_sas_ha(struct asd_ha_struct *asd_ha)
481{
482 int i;
483 struct asd_sas_phy **sas_phys =
484 kmalloc(ASD_MAX_PHYS * sizeof(struct asd_sas_phy), GFP_KERNEL);
485 struct asd_sas_port **sas_ports =
486 kmalloc(ASD_MAX_PHYS * sizeof(struct asd_sas_port), GFP_KERNEL);
487
488 if (!sas_phys || !sas_ports) {
489 kfree(sas_phys);
490 kfree(sas_ports);
491 return -ENOMEM;
492 }
493
494 asd_ha->sas_ha.sas_ha_name = (char *) asd_ha->name;
495 asd_ha->sas_ha.lldd_module = THIS_MODULE;
496 asd_ha->sas_ha.sas_addr = &asd_ha->hw_prof.sas_addr[0];
497
498 for (i = 0; i < ASD_MAX_PHYS; i++) {
499 sas_phys[i] = &asd_ha->phys[i].sas_phy;
500 sas_ports[i] = &asd_ha->ports[i];
501 }
502
503 asd_ha->sas_ha.sas_phy = sas_phys;
504 asd_ha->sas_ha.sas_port= sas_ports;
505 asd_ha->sas_ha.num_phys= ASD_MAX_PHYS;
506
507 asd_ha->sas_ha.lldd_queue_size = asd_ha->seq.can_queue;
508
509 return sas_register_ha(&asd_ha->sas_ha);
510}
511
512static int asd_unregister_sas_ha(struct asd_ha_struct *asd_ha)
513{
514 int err;
515
516 err = sas_unregister_ha(&asd_ha->sas_ha);
517
518 sas_remove_host(asd_ha->sas_ha.core.shost);
519 scsi_remove_host(asd_ha->sas_ha.core.shost);
520 scsi_host_put(asd_ha->sas_ha.core.shost);
521
522 kfree(asd_ha->sas_ha.sas_phy);
523 kfree(asd_ha->sas_ha.sas_port);
524
525 return err;
526}
527
528static int __devinit asd_pci_probe(struct pci_dev *dev,
529 const struct pci_device_id *id)
530{
531 struct asd_pcidev_struct *asd_dev;
532 unsigned asd_id = (unsigned) id->driver_data;
533 struct asd_ha_struct *asd_ha;
534 struct Scsi_Host *shost;
535 int err;
536
537 if (asd_id >= ARRAY_SIZE(asd_pcidev_data)) {
538 asd_printk("wrong driver_data in PCI table\n");
539 return -ENODEV;
540 }
541
542 if ((err = pci_enable_device(dev))) {
543 asd_printk("couldn't enable device %s\n", pci_name(dev));
544 return err;
545 }
546
547 pci_set_master(dev);
548
549 err = -ENOMEM;
550
551 shost = scsi_host_alloc(&aic94xx_sht, sizeof(void *));
552 if (!shost)
553 goto Err;
554
555 asd_dev = &asd_pcidev_data[asd_id];
556
557 asd_ha = kzalloc(sizeof(*asd_ha), GFP_KERNEL);
558 if (!asd_ha) {
559 asd_printk("out of memory\n");
560 goto Err;
561 }
562 asd_ha->pcidev = dev;
563 asd_ha->sas_ha.pcidev = asd_ha->pcidev;
564 asd_ha->sas_ha.lldd_ha = asd_ha;
565
566 asd_ha->name = asd_dev->name;
567 asd_printk("found %s, device %s\n", asd_ha->name, pci_name(dev));
568
569 SHOST_TO_SAS_HA(shost) = &asd_ha->sas_ha;
570 asd_ha->sas_ha.core.shost = shost;
571 shost->transportt = aic94xx_transport_template;
572 shost->max_id = ~0;
573 shost->max_lun = ~0;
574 shost->max_cmd_len = 16;
575
576 err = scsi_add_host(shost, &dev->dev);
577 if (err) {
578 scsi_host_put(shost);
579 goto Err_free;
580 }
581
582
583
584 err = asd_dev->setup(asd_ha);
585 if (err)
586 goto Err_free;
587
588 err = -ENODEV;
589 if (!pci_set_dma_mask(dev, DMA_64BIT_MASK)
590 && !pci_set_consistent_dma_mask(dev, DMA_64BIT_MASK))
591 ;
592 else if (!pci_set_dma_mask(dev, DMA_32BIT_MASK)
593 && !pci_set_consistent_dma_mask(dev, DMA_32BIT_MASK))
594 ;
595 else {
596 asd_printk("no suitable DMA mask for %s\n", pci_name(dev));
597 goto Err_free;
598 }
599
600 pci_set_drvdata(dev, asd_ha);
601
602 err = asd_map_ha(asd_ha);
603 if (err)
604 goto Err_free;
605
606 err = asd_create_ha_caches(asd_ha);
607 if (err)
608 goto Err_unmap;
609
610 err = asd_init_hw(asd_ha);
611 if (err)
612 goto Err_free_cache;
613
614 asd_printk("device %s: SAS addr %llx, PCBA SN %s, %d phys, %d enabled "
615 "phys, flash %s, BIOS %s%d\n",
616 pci_name(dev), SAS_ADDR(asd_ha->hw_prof.sas_addr),
617 asd_ha->hw_prof.pcba_sn, asd_ha->hw_prof.max_phys,
618 asd_ha->hw_prof.num_phys,
619 asd_ha->hw_prof.flash.present ? "present" : "not present",
620 asd_ha->hw_prof.bios.present ? "build " : "not present",
621 asd_ha->hw_prof.bios.bld);
622
623 if (use_msi)
624 pci_enable_msi(asd_ha->pcidev);
625
626 err = request_irq(asd_ha->pcidev->irq, asd_hw_isr, SA_SHIRQ,
627 ASD_DRIVER_NAME, asd_ha);
628 if (err) {
629 asd_printk("couldn't get irq %d for %s\n",
630 asd_ha->pcidev->irq, pci_name(asd_ha->pcidev));
631 goto Err_irq;
632 }
633 asd_enable_ints(asd_ha);
634
635 err = asd_init_post_escbs(asd_ha);
636 if (err) {
637 asd_printk("couldn't post escbs for %s\n",
638 pci_name(asd_ha->pcidev));
639 goto Err_escbs;
640 }
641 ASD_DPRINTK("escbs posted\n");
642
643 asd_create_dev_attrs(asd_ha);
644
645 err = asd_register_sas_ha(asd_ha);
646 if (err)
647 goto Err_reg_sas;
648
649 err = asd_enable_phys(asd_ha, asd_ha->hw_prof.enabled_phys);
650 if (err) {
651 asd_printk("coudln't enable phys, err:%d\n", err);
652 goto Err_en_phys;
653 }
654 ASD_DPRINTK("enabled phys\n");
655 /* give the phy enabling interrupt event time to come in (1s
656 * is empirically about all it takes) */
657 ssleep(1);
658 /* Wait for discovery to finish */
659 scsi_flush_work(asd_ha->sas_ha.core.shost);
660
661 return 0;
662Err_en_phys:
663 asd_unregister_sas_ha(asd_ha);
664Err_reg_sas:
665 asd_remove_dev_attrs(asd_ha);
666Err_escbs:
667 asd_disable_ints(asd_ha);
668 free_irq(dev->irq, asd_ha);
669Err_irq:
670 if (use_msi)
671 pci_disable_msi(dev);
672 asd_chip_hardrst(asd_ha);
673Err_free_cache:
674 asd_destroy_ha_caches(asd_ha);
675Err_unmap:
676 asd_unmap_ha(asd_ha);
677Err_free:
678 kfree(asd_ha);
679 scsi_remove_host(shost);
680Err:
681 pci_disable_device(dev);
682 return err;
683}
684
685static void asd_free_queues(struct asd_ha_struct *asd_ha)
686{
687 unsigned long flags;
688 LIST_HEAD(pending);
689 struct list_head *n, *pos;
690
691 spin_lock_irqsave(&asd_ha->seq.pend_q_lock, flags);
692 asd_ha->seq.pending = 0;
693 list_splice_init(&asd_ha->seq.pend_q, &pending);
694 spin_unlock_irqrestore(&asd_ha->seq.pend_q_lock, flags);
695
696 if (!list_empty(&pending))
697 ASD_DPRINTK("Uh-oh! Pending is not empty!\n");
698
699 list_for_each_safe(pos, n, &pending) {
700 struct asd_ascb *ascb = list_entry(pos, struct asd_ascb, list);
701 list_del_init(pos);
702 ASD_DPRINTK("freeing from pending\n");
703 asd_ascb_free(ascb);
704 }
705}
706
707static void asd_turn_off_leds(struct asd_ha_struct *asd_ha)
708{
709 u8 phy_mask = asd_ha->hw_prof.enabled_phys;
710 u8 i;
711
712 for_each_phy(phy_mask, phy_mask, i) {
713 asd_turn_led(asd_ha, i, 0);
714 asd_control_led(asd_ha, i, 0);
715 }
716}
717
718static void __devexit asd_pci_remove(struct pci_dev *dev)
719{
720 struct asd_ha_struct *asd_ha = pci_get_drvdata(dev);
721
722 if (!asd_ha)
723 return;
724
725 asd_unregister_sas_ha(asd_ha);
726
727 asd_disable_ints(asd_ha);
728
729 asd_remove_dev_attrs(asd_ha);
730
731 /* XXX more here as needed */
732
733 free_irq(dev->irq, asd_ha);
734 if (use_msi)
735 pci_disable_msi(asd_ha->pcidev);
736 asd_turn_off_leds(asd_ha);
737 asd_chip_hardrst(asd_ha);
738 asd_free_queues(asd_ha);
739 asd_destroy_ha_caches(asd_ha);
740 asd_unmap_ha(asd_ha);
741 kfree(asd_ha);
742 pci_disable_device(dev);
743 return;
744}
745
746static ssize_t asd_version_show(struct device_driver *driver, char *buf)
747{
748 return snprintf(buf, PAGE_SIZE, "%s\n", ASD_DRIVER_VERSION);
749}
750static DRIVER_ATTR(version, S_IRUGO, asd_version_show, NULL);
751
752static void asd_create_driver_attrs(struct device_driver *driver)
753{
754 driver_create_file(driver, &driver_attr_version);
755}
756
757static void asd_remove_driver_attrs(struct device_driver *driver)
758{
759 driver_remove_file(driver, &driver_attr_version);
760}
761
762static struct sas_domain_function_template aic94xx_transport_functions = {
763 .lldd_port_formed = asd_update_port_links,
764
765 .lldd_dev_found = asd_dev_found,
766 .lldd_dev_gone = asd_dev_gone,
767
768 .lldd_execute_task = asd_execute_task,
769
770 .lldd_abort_task = asd_abort_task,
771 .lldd_abort_task_set = asd_abort_task_set,
772 .lldd_clear_aca = asd_clear_aca,
773 .lldd_clear_task_set = asd_clear_task_set,
774 .lldd_I_T_nexus_reset = NULL,
775 .lldd_lu_reset = asd_lu_reset,
776 .lldd_query_task = asd_query_task,
777
778 .lldd_clear_nexus_port = asd_clear_nexus_port,
779 .lldd_clear_nexus_ha = asd_clear_nexus_ha,
780
781 .lldd_control_phy = asd_control_phy,
782};
783
784static const struct pci_device_id aic94xx_pci_table[] __devinitdata = {
785 {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR10),
786 0, 0, 1},
787 {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR12),
788 0, 0, 1},
789 {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR1E),
790 0, 0, 1},
791 {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR30),
792 0, 0, 2},
793 {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR32),
794 0, 0, 2},
795 {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR3E),
796 0, 0, 2},
797 {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR3F),
798 0, 0, 2},
799 {}
800};
801
802MODULE_DEVICE_TABLE(pci, aic94xx_pci_table);
803
804static struct pci_driver aic94xx_pci_driver = {
805 .name = ASD_DRIVER_NAME,
806 .id_table = aic94xx_pci_table,
807 .probe = asd_pci_probe,
808 .remove = __devexit_p(asd_pci_remove),
809};
810
811static int __init aic94xx_init(void)
812{
813 int err;
814
815
816 asd_printk("%s version %s loaded\n", ASD_DRIVER_DESCRIPTION,
817 ASD_DRIVER_VERSION);
818
819 err = asd_create_global_caches();
820 if (err)
821 return err;
822
823 aic94xx_transport_template =
824 sas_domain_attach_transport(&aic94xx_transport_functions);
825 if (err)
826 goto out_destroy_caches;
827
828 err = pci_register_driver(&aic94xx_pci_driver);
829 if (err)
830 goto out_release_transport;
831
832 asd_create_driver_attrs(&aic94xx_pci_driver.driver);
833
834 return err;
835
836 out_release_transport:
837 sas_release_transport(aic94xx_transport_template);
838 out_destroy_caches:
839 asd_destroy_global_caches();
840
841 return err;
842}
843
844static void __exit aic94xx_exit(void)
845{
846 asd_remove_driver_attrs(&aic94xx_pci_driver.driver);
847 pci_unregister_driver(&aic94xx_pci_driver);
848 sas_release_transport(aic94xx_transport_template);
849 asd_destroy_global_caches();
850 asd_printk("%s version %s unloaded\n", ASD_DRIVER_DESCRIPTION,
851 ASD_DRIVER_VERSION);
852}
853
854module_init(aic94xx_init);
855module_exit(aic94xx_exit);
856
857MODULE_AUTHOR("Luben Tuikov <luben_tuikov@adaptec.com>");
858MODULE_DESCRIPTION(ASD_DRIVER_DESCRIPTION);
859MODULE_LICENSE("GPL v2");
860MODULE_VERSION(ASD_DRIVER_VERSION);
diff --git a/drivers/scsi/aic94xx/aic94xx_reg.c b/drivers/scsi/aic94xx/aic94xx_reg.c
new file mode 100644
index 000000000000..f210dac3203d
--- /dev/null
+++ b/drivers/scsi/aic94xx/aic94xx_reg.c
@@ -0,0 +1,332 @@
1/*
2 * Aic94xx SAS/SATA driver register access.
3 *
4 * Copyright (C) 2005 Adaptec, Inc. All rights reserved.
5 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
6 *
7 * This file is licensed under GPLv2.
8 *
9 * This file is part of the aic94xx driver.
10 *
11 * The aic94xx driver is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; version 2 of the
14 * License.
15 *
16 * The aic94xx driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with the aic94xx driver; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 *
25 */
26
27#include <linux/pci.h>
28#include "aic94xx_reg.h"
29#include "aic94xx.h"
30
31/* Writing to device address space.
32 * Offset comes before value to remind that the operation of
33 * this function is *offs = val.
34 */
35static inline void asd_write_byte(struct asd_ha_struct *asd_ha,
36 unsigned long offs, u8 val)
37{
38 if (unlikely(asd_ha->iospace))
39 outb(val,
40 (unsigned long)asd_ha->io_handle[0].addr + (offs & 0xFF));
41 else
42 writeb(val, asd_ha->io_handle[0].addr + offs);
43 wmb();
44}
45
46static inline void asd_write_word(struct asd_ha_struct *asd_ha,
47 unsigned long offs, u16 val)
48{
49 if (unlikely(asd_ha->iospace))
50 outw(val,
51 (unsigned long)asd_ha->io_handle[0].addr + (offs & 0xFF));
52 else
53 writew(val, asd_ha->io_handle[0].addr + offs);
54 wmb();
55}
56
57static inline void asd_write_dword(struct asd_ha_struct *asd_ha,
58 unsigned long offs, u32 val)
59{
60 if (unlikely(asd_ha->iospace))
61 outl(val,
62 (unsigned long)asd_ha->io_handle[0].addr + (offs & 0xFF));
63 else
64 writel(val, asd_ha->io_handle[0].addr + offs);
65 wmb();
66}
67
68/* Reading from device address space.
69 */
70static inline u8 asd_read_byte(struct asd_ha_struct *asd_ha,
71 unsigned long offs)
72{
73 u8 val;
74 if (unlikely(asd_ha->iospace))
75 val = inb((unsigned long) asd_ha->io_handle[0].addr
76 + (offs & 0xFF));
77 else
78 val = readb(asd_ha->io_handle[0].addr + offs);
79 rmb();
80 return val;
81}
82
83static inline u16 asd_read_word(struct asd_ha_struct *asd_ha,
84 unsigned long offs)
85{
86 u16 val;
87 if (unlikely(asd_ha->iospace))
88 val = inw((unsigned long)asd_ha->io_handle[0].addr
89 + (offs & 0xFF));
90 else
91 val = readw(asd_ha->io_handle[0].addr + offs);
92 rmb();
93 return val;
94}
95
96static inline u32 asd_read_dword(struct asd_ha_struct *asd_ha,
97 unsigned long offs)
98{
99 u32 val;
100 if (unlikely(asd_ha->iospace))
101 val = inl((unsigned long) asd_ha->io_handle[0].addr
102 + (offs & 0xFF));
103 else
104 val = readl(asd_ha->io_handle[0].addr + offs);
105 rmb();
106 return val;
107}
108
109static inline u32 asd_mem_offs_swa(void)
110{
111 return 0;
112}
113
114static inline u32 asd_mem_offs_swc(void)
115{
116 return asd_mem_offs_swa() + MBAR0_SWA_SIZE;
117}
118
119static inline u32 asd_mem_offs_swb(void)
120{
121 return asd_mem_offs_swc() + MBAR0_SWC_SIZE + 0x20;
122}
123
124/* We know that the register wanted is in the range
125 * of the sliding window.
126 */
127#define ASD_READ_SW(ww, type, ord) \
128static inline type asd_read_##ww##_##ord (struct asd_ha_struct *asd_ha,\
129 u32 reg) \
130{ \
131 struct asd_ha_addrspace *io_handle = &asd_ha->io_handle[0]; \
132 u32 map_offs=(reg - io_handle-> ww##_base )+asd_mem_offs_##ww ();\
133 return asd_read_##ord (asd_ha, (unsigned long) map_offs); \
134}
135
136#define ASD_WRITE_SW(ww, type, ord) \
137static inline void asd_write_##ww##_##ord (struct asd_ha_struct *asd_ha,\
138 u32 reg, type val) \
139{ \
140 struct asd_ha_addrspace *io_handle = &asd_ha->io_handle[0]; \
141 u32 map_offs=(reg - io_handle-> ww##_base )+asd_mem_offs_##ww ();\
142 asd_write_##ord (asd_ha, (unsigned long) map_offs, val); \
143}
144
145ASD_READ_SW(swa, u8, byte);
146ASD_READ_SW(swa, u16, word);
147ASD_READ_SW(swa, u32, dword);
148
149ASD_READ_SW(swb, u8, byte);
150ASD_READ_SW(swb, u16, word);
151ASD_READ_SW(swb, u32, dword);
152
153ASD_READ_SW(swc, u8, byte);
154ASD_READ_SW(swc, u16, word);
155ASD_READ_SW(swc, u32, dword);
156
157ASD_WRITE_SW(swa, u8, byte);
158ASD_WRITE_SW(swa, u16, word);
159ASD_WRITE_SW(swa, u32, dword);
160
161ASD_WRITE_SW(swb, u8, byte);
162ASD_WRITE_SW(swb, u16, word);
163ASD_WRITE_SW(swb, u32, dword);
164
165ASD_WRITE_SW(swc, u8, byte);
166ASD_WRITE_SW(swc, u16, word);
167ASD_WRITE_SW(swc, u32, dword);
168
169/*
170 * A word about sliding windows:
171 * MBAR0 is divided into sliding windows A, C and B, in that order.
172 * SWA starts at offset 0 of MBAR0, up to 0x57, with size 0x58 bytes.
173 * SWC starts at offset 0x58 of MBAR0, up to 0x60, with size 0x8 bytes.
174 * From 0x60 to 0x7F, we have a copy of PCI config space 0x60-0x7F.
175 * SWB starts at offset 0x80 of MBAR0 and extends to the end of MBAR0.
176 * See asd_init_sw() in aic94xx_hwi.c
177 *
178 * We map the most common registers we'd access of the internal 4GB
179 * host adapter memory space. If a register/internal memory location
180 * is wanted which is not mapped, we slide SWB, by paging it,
181 * see asd_move_swb() in aic94xx_reg.c.
182 */
183
184/**
185 * asd_move_swb -- move sliding window B
186 * @asd_ha: pointer to host adapter structure
187 * @reg: register desired to be within range of the new window
188 */
189static inline void asd_move_swb(struct asd_ha_struct *asd_ha, u32 reg)
190{
191 u32 base = reg & ~(MBAR0_SWB_SIZE-1);
192 pci_write_config_dword(asd_ha->pcidev, PCI_CONF_MBAR0_SWB, base);
193 asd_ha->io_handle[0].swb_base = base;
194}
195
196static void __asd_write_reg_byte(struct asd_ha_struct *asd_ha, u32 reg, u8 val)
197{
198 struct asd_ha_addrspace *io_handle=&asd_ha->io_handle[0];
199 BUG_ON(reg >= 0xC0000000 || reg < ALL_BASE_ADDR);
200 if (io_handle->swa_base <= reg
201 && reg < io_handle->swa_base + MBAR0_SWA_SIZE)
202 asd_write_swa_byte (asd_ha, reg,val);
203 else if (io_handle->swb_base <= reg
204 && reg < io_handle->swb_base + MBAR0_SWB_SIZE)
205 asd_write_swb_byte (asd_ha, reg, val);
206 else if (io_handle->swc_base <= reg
207 && reg < io_handle->swc_base + MBAR0_SWC_SIZE)
208 asd_write_swc_byte (asd_ha, reg, val);
209 else {
210 /* Ok, we have to move SWB */
211 asd_move_swb(asd_ha, reg);
212 asd_write_swb_byte (asd_ha, reg, val);
213 }
214}
215
216#define ASD_WRITE_REG(type, ord) \
217void asd_write_reg_##ord (struct asd_ha_struct *asd_ha, u32 reg, type val)\
218{ \
219 struct asd_ha_addrspace *io_handle=&asd_ha->io_handle[0]; \
220 unsigned long flags; \
221 BUG_ON(reg >= 0xC0000000 || reg < ALL_BASE_ADDR); \
222 spin_lock_irqsave(&asd_ha->iolock, flags); \
223 if (io_handle->swa_base <= reg \
224 && reg < io_handle->swa_base + MBAR0_SWA_SIZE) \
225 asd_write_swa_##ord (asd_ha, reg,val); \
226 else if (io_handle->swb_base <= reg \
227 && reg < io_handle->swb_base + MBAR0_SWB_SIZE) \
228 asd_write_swb_##ord (asd_ha, reg, val); \
229 else if (io_handle->swc_base <= reg \
230 && reg < io_handle->swc_base + MBAR0_SWC_SIZE) \
231 asd_write_swc_##ord (asd_ha, reg, val); \
232 else { \
233 /* Ok, we have to move SWB */ \
234 asd_move_swb(asd_ha, reg); \
235 asd_write_swb_##ord (asd_ha, reg, val); \
236 } \
237 spin_unlock_irqrestore(&asd_ha->iolock, flags); \
238}
239
240ASD_WRITE_REG(u8, byte);
241ASD_WRITE_REG(u16,word);
242ASD_WRITE_REG(u32,dword);
243
244static u8 __asd_read_reg_byte(struct asd_ha_struct *asd_ha, u32 reg)
245{
246 struct asd_ha_addrspace *io_handle=&asd_ha->io_handle[0];
247 u8 val;
248 BUG_ON(reg >= 0xC0000000 || reg < ALL_BASE_ADDR);
249 if (io_handle->swa_base <= reg
250 && reg < io_handle->swa_base + MBAR0_SWA_SIZE)
251 val = asd_read_swa_byte (asd_ha, reg);
252 else if (io_handle->swb_base <= reg
253 && reg < io_handle->swb_base + MBAR0_SWB_SIZE)
254 val = asd_read_swb_byte (asd_ha, reg);
255 else if (io_handle->swc_base <= reg
256 && reg < io_handle->swc_base + MBAR0_SWC_SIZE)
257 val = asd_read_swc_byte (asd_ha, reg);
258 else {
259 /* Ok, we have to move SWB */
260 asd_move_swb(asd_ha, reg);
261 val = asd_read_swb_byte (asd_ha, reg);
262 }
263 return val;
264}
265
266#define ASD_READ_REG(type, ord) \
267type asd_read_reg_##ord (struct asd_ha_struct *asd_ha, u32 reg) \
268{ \
269 struct asd_ha_addrspace *io_handle=&asd_ha->io_handle[0]; \
270 type val; \
271 unsigned long flags; \
272 BUG_ON(reg >= 0xC0000000 || reg < ALL_BASE_ADDR); \
273 spin_lock_irqsave(&asd_ha->iolock, flags); \
274 if (io_handle->swa_base <= reg \
275 && reg < io_handle->swa_base + MBAR0_SWA_SIZE) \
276 val = asd_read_swa_##ord (asd_ha, reg); \
277 else if (io_handle->swb_base <= reg \
278 && reg < io_handle->swb_base + MBAR0_SWB_SIZE) \
279 val = asd_read_swb_##ord (asd_ha, reg); \
280 else if (io_handle->swc_base <= reg \
281 && reg < io_handle->swc_base + MBAR0_SWC_SIZE) \
282 val = asd_read_swc_##ord (asd_ha, reg); \
283 else { \
284 /* Ok, we have to move SWB */ \
285 asd_move_swb(asd_ha, reg); \
286 val = asd_read_swb_##ord (asd_ha, reg); \
287 } \
288 spin_unlock_irqrestore(&asd_ha->iolock, flags); \
289 return val; \
290}
291
292ASD_READ_REG(u8, byte);
293ASD_READ_REG(u16,word);
294ASD_READ_REG(u32,dword);
295
296/**
297 * asd_read_reg_string -- read a string of bytes from io space memory
298 * @asd_ha: pointer to host adapter structure
299 * @dst: pointer to a destination buffer where data will be written to
300 * @offs: start offset (register) to read from
301 * @count: number of bytes to read
302 */
303void asd_read_reg_string(struct asd_ha_struct *asd_ha, void *dst,
304 u32 offs, int count)
305{
306 u8 *p = dst;
307 unsigned long flags;
308
309 spin_lock_irqsave(&asd_ha->iolock, flags);
310 for ( ; count > 0; count--, offs++, p++)
311 *p = __asd_read_reg_byte(asd_ha, offs);
312 spin_unlock_irqrestore(&asd_ha->iolock, flags);
313}
314
315/**
316 * asd_write_reg_string -- write a string of bytes to io space memory
317 * @asd_ha: pointer to host adapter structure
318 * @src: pointer to source buffer where data will be read from
319 * @offs: start offset (register) to write to
320 * @count: number of bytes to write
321 */
322void asd_write_reg_string(struct asd_ha_struct *asd_ha, void *src,
323 u32 offs, int count)
324{
325 u8 *p = src;
326 unsigned long flags;
327
328 spin_lock_irqsave(&asd_ha->iolock, flags);
329 for ( ; count > 0; count--, offs++, p++)
330 __asd_write_reg_byte(asd_ha, offs, *p);
331 spin_unlock_irqrestore(&asd_ha->iolock, flags);
332}
diff --git a/drivers/scsi/aic94xx/aic94xx_reg.h b/drivers/scsi/aic94xx/aic94xx_reg.h
new file mode 100644
index 000000000000..2279307fd27e
--- /dev/null
+++ b/drivers/scsi/aic94xx/aic94xx_reg.h
@@ -0,0 +1,302 @@
1/*
2 * Aic94xx SAS/SATA driver hardware registers definitions.
3 *
4 * Copyright (C) 2005 Adaptec, Inc. All rights reserved.
5 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
6 *
7 * This file is licensed under GPLv2.
8 *
9 * This file is part of the aic94xx driver.
10 *
11 * The aic94xx driver is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; version 2 of the
14 * License.
15 *
16 * The aic94xx driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with the aic94xx driver; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 *
25 */
26
27#ifndef _AIC94XX_REG_H_
28#define _AIC94XX_REG_H_
29
30#include <asm/io.h>
31#include "aic94xx_hwi.h"
32
33/* Values */
34#define AIC9410_DEV_REV_B0 0x8
35
36/* MBAR0, SWA, SWB, SWC, internal memory space addresses */
37#define REG_BASE_ADDR 0xB8000000
38#define REG_BASE_ADDR_CSEQCIO 0xB8002000
39#define REG_BASE_ADDR_EXSI 0xB8042800
40
41#define MBAR0_SWA_SIZE 0x58
42extern u32 MBAR0_SWB_SIZE;
43#define MBAR0_SWC_SIZE 0x8
44
45/* MBAR1, points to On Chip Memory */
46#define OCM_BASE_ADDR 0xA0000000
47#define OCM_MAX_SIZE 0x20000
48
49/* Smallest address possible to reference */
50#define ALL_BASE_ADDR OCM_BASE_ADDR
51
52/* PCI configuration space registers */
53#define PCI_IOBAR_OFFSET 4
54
55#define PCI_CONF_MBAR1 0x6C
56#define PCI_CONF_MBAR0_SWA 0x70
57#define PCI_CONF_MBAR0_SWB 0x74
58#define PCI_CONF_MBAR0_SWC 0x78
59#define PCI_CONF_MBAR_KEY 0x7C
60#define PCI_CONF_FLSH_BAR 0xB8
61
62#include "aic94xx_reg_def.h"
63
64u8 asd_read_reg_byte(struct asd_ha_struct *asd_ha, u32 reg);
65u16 asd_read_reg_word(struct asd_ha_struct *asd_ha, u32 reg);
66u32 asd_read_reg_dword(struct asd_ha_struct *asd_ha, u32 reg);
67
68void asd_write_reg_byte(struct asd_ha_struct *asd_ha, u32 reg, u8 val);
69void asd_write_reg_word(struct asd_ha_struct *asd_ha, u32 reg, u16 val);
70void asd_write_reg_dword(struct asd_ha_struct *asd_ha, u32 reg, u32 val);
71
72void asd_read_reg_string(struct asd_ha_struct *asd_ha, void *dst,
73 u32 offs, int count);
74void asd_write_reg_string(struct asd_ha_struct *asd_ha, void *src,
75 u32 offs, int count);
76
77#define ASD_READ_OCM(type, ord, S) \
78static inline type asd_read_ocm_##ord (struct asd_ha_struct *asd_ha, \
79 u32 offs) \
80{ \
81 struct asd_ha_addrspace *io_handle = &asd_ha->io_handle[1]; \
82 type val = read##S (io_handle->addr + (unsigned long) offs); \
83 rmb(); \
84 return val; \
85}
86
87ASD_READ_OCM(u8, byte, b);
88ASD_READ_OCM(u16,word, w);
89ASD_READ_OCM(u32,dword,l);
90
91#define ASD_WRITE_OCM(type, ord, S) \
92static inline void asd_write_ocm_##ord (struct asd_ha_struct *asd_ha, \
93 u32 offs, type val) \
94{ \
95 struct asd_ha_addrspace *io_handle = &asd_ha->io_handle[1]; \
96 write##S (val, io_handle->addr + (unsigned long) offs); \
97 return; \
98}
99
100ASD_WRITE_OCM(u8, byte, b);
101ASD_WRITE_OCM(u16,word, w);
102ASD_WRITE_OCM(u32,dword,l);
103
104#define ASD_DDBSITE_READ(type, ord) \
105static inline type asd_ddbsite_read_##ord (struct asd_ha_struct *asd_ha, \
106 u16 ddb_site_no, \
107 u16 offs) \
108{ \
109 asd_write_reg_word(asd_ha, ALTCIOADR, MnDDB_SITE + offs); \
110 asd_write_reg_word(asd_ha, ADDBPTR, ddb_site_no); \
111 return asd_read_reg_##ord (asd_ha, CTXACCESS); \
112}
113
114ASD_DDBSITE_READ(u32, dword);
115ASD_DDBSITE_READ(u16, word);
116
117static inline u8 asd_ddbsite_read_byte(struct asd_ha_struct *asd_ha,
118 u16 ddb_site_no,
119 u16 offs)
120{
121 if (offs & 1)
122 return asd_ddbsite_read_word(asd_ha, ddb_site_no,
123 offs & ~1) >> 8;
124 else
125 return asd_ddbsite_read_word(asd_ha, ddb_site_no,
126 offs) & 0xFF;
127}
128
129
130#define ASD_DDBSITE_WRITE(type, ord) \
131static inline void asd_ddbsite_write_##ord (struct asd_ha_struct *asd_ha, \
132 u16 ddb_site_no, \
133 u16 offs, type val) \
134{ \
135 asd_write_reg_word(asd_ha, ALTCIOADR, MnDDB_SITE + offs); \
136 asd_write_reg_word(asd_ha, ADDBPTR, ddb_site_no); \
137 asd_write_reg_##ord (asd_ha, CTXACCESS, val); \
138}
139
140ASD_DDBSITE_WRITE(u32, dword);
141ASD_DDBSITE_WRITE(u16, word);
142
143static inline void asd_ddbsite_write_byte(struct asd_ha_struct *asd_ha,
144 u16 ddb_site_no,
145 u16 offs, u8 val)
146{
147 u16 base = offs & ~1;
148 u16 rval = asd_ddbsite_read_word(asd_ha, ddb_site_no, base);
149 if (offs & 1)
150 rval = (val << 8) | (rval & 0xFF);
151 else
152 rval = (rval & 0xFF00) | val;
153 asd_ddbsite_write_word(asd_ha, ddb_site_no, base, rval);
154}
155
156
157#define ASD_SCBSITE_READ(type, ord) \
158static inline type asd_scbsite_read_##ord (struct asd_ha_struct *asd_ha, \
159 u16 scb_site_no, \
160 u16 offs) \
161{ \
162 asd_write_reg_word(asd_ha, ALTCIOADR, MnSCB_SITE + offs); \
163 asd_write_reg_word(asd_ha, ASCBPTR, scb_site_no); \
164 return asd_read_reg_##ord (asd_ha, CTXACCESS); \
165}
166
167ASD_SCBSITE_READ(u32, dword);
168ASD_SCBSITE_READ(u16, word);
169
170static inline u8 asd_scbsite_read_byte(struct asd_ha_struct *asd_ha,
171 u16 scb_site_no,
172 u16 offs)
173{
174 if (offs & 1)
175 return asd_scbsite_read_word(asd_ha, scb_site_no,
176 offs & ~1) >> 8;
177 else
178 return asd_scbsite_read_word(asd_ha, scb_site_no,
179 offs) & 0xFF;
180}
181
182
183#define ASD_SCBSITE_WRITE(type, ord) \
184static inline void asd_scbsite_write_##ord (struct asd_ha_struct *asd_ha, \
185 u16 scb_site_no, \
186 u16 offs, type val) \
187{ \
188 asd_write_reg_word(asd_ha, ALTCIOADR, MnSCB_SITE + offs); \
189 asd_write_reg_word(asd_ha, ASCBPTR, scb_site_no); \
190 asd_write_reg_##ord (asd_ha, CTXACCESS, val); \
191}
192
193ASD_SCBSITE_WRITE(u32, dword);
194ASD_SCBSITE_WRITE(u16, word);
195
196static inline void asd_scbsite_write_byte(struct asd_ha_struct *asd_ha,
197 u16 scb_site_no,
198 u16 offs, u8 val)
199{
200 u16 base = offs & ~1;
201 u16 rval = asd_scbsite_read_word(asd_ha, scb_site_no, base);
202 if (offs & 1)
203 rval = (val << 8) | (rval & 0xFF);
204 else
205 rval = (rval & 0xFF00) | val;
206 asd_scbsite_write_word(asd_ha, scb_site_no, base, rval);
207}
208
209/**
210 * asd_ddbsite_update_word -- atomically update a word in a ddb site
211 * @asd_ha: pointer to host adapter structure
212 * @ddb_site_no: the DDB site number
213 * @offs: the offset into the DDB
214 * @oldval: old value found in that offset
215 * @newval: the new value to replace it
216 *
217 * This function is used when the sequencers are running and we need to
218 * update a DDB site atomically without expensive pausing and upausing
219 * of the sequencers and accessing the DDB site through the CIO bus.
220 *
221 * Return 0 on success; -EFAULT on parity error; -EAGAIN if the old value
222 * is different than the current value at that offset.
223 */
224static inline int asd_ddbsite_update_word(struct asd_ha_struct *asd_ha,
225 u16 ddb_site_no, u16 offs,
226 u16 oldval, u16 newval)
227{
228 u8 done;
229 u16 oval = asd_ddbsite_read_word(asd_ha, ddb_site_no, offs);
230 if (oval != oldval)
231 return -EAGAIN;
232 asd_write_reg_word(asd_ha, AOLDDATA, oldval);
233 asd_write_reg_word(asd_ha, ANEWDATA, newval);
234 do {
235 done = asd_read_reg_byte(asd_ha, ATOMICSTATCTL);
236 } while (!(done & ATOMICDONE));
237 if (done & ATOMICERR)
238 return -EFAULT; /* parity error */
239 else if (done & ATOMICWIN)
240 return 0; /* success */
241 else
242 return -EAGAIN; /* oldval different than current value */
243}
244
245static inline int asd_ddbsite_update_byte(struct asd_ha_struct *asd_ha,
246 u16 ddb_site_no, u16 offs,
247 u8 _oldval, u8 _newval)
248{
249 u16 base = offs & ~1;
250 u16 oval;
251 u16 nval = asd_ddbsite_read_word(asd_ha, ddb_site_no, base);
252 if (offs & 1) {
253 if ((nval >> 8) != _oldval)
254 return -EAGAIN;
255 nval = (_newval << 8) | (nval & 0xFF);
256 oval = (_oldval << 8) | (nval & 0xFF);
257 } else {
258 if ((nval & 0xFF) != _oldval)
259 return -EAGAIN;
260 nval = (nval & 0xFF00) | _newval;
261 oval = (nval & 0xFF00) | _oldval;
262 }
263 return asd_ddbsite_update_word(asd_ha, ddb_site_no, base, oval, nval);
264}
265
266static inline void asd_write_reg_addr(struct asd_ha_struct *asd_ha, u32 reg,
267 dma_addr_t dma_handle)
268{
269 asd_write_reg_dword(asd_ha, reg, ASD_BUSADDR_LO(dma_handle));
270 asd_write_reg_dword(asd_ha, reg+4, ASD_BUSADDR_HI(dma_handle));
271}
272
273static inline u32 asd_get_cmdctx_size(struct asd_ha_struct *asd_ha)
274{
275 /* DCHREVISION returns 0, possibly broken */
276 u32 ctxmemsize = asd_read_reg_dword(asd_ha, LmMnINT(0,0)) & CTXMEMSIZE;
277 return ctxmemsize ? 65536 : 32768;
278}
279
280static inline u32 asd_get_devctx_size(struct asd_ha_struct *asd_ha)
281{
282 u32 ctxmemsize = asd_read_reg_dword(asd_ha, LmMnINT(0,0)) & CTXMEMSIZE;
283 return ctxmemsize ? 8192 : 4096;
284}
285
286static inline void asd_disable_ints(struct asd_ha_struct *asd_ha)
287{
288 asd_write_reg_dword(asd_ha, CHIMINTEN, RST_CHIMINTEN);
289}
290
291static inline void asd_enable_ints(struct asd_ha_struct *asd_ha)
292{
293 /* Enable COM SAS interrupt on errors, COMSTAT */
294 asd_write_reg_dword(asd_ha, COMSTATEN,
295 EN_CSBUFPERR | EN_CSERR | EN_OVLYERR);
296 /* Enable DCH SAS CFIFTOERR */
297 asd_write_reg_dword(asd_ha, DCHSTATUS, EN_CFIFTOERR);
298 /* Enable Host Device interrupts */
299 asd_write_reg_dword(asd_ha, CHIMINTEN, SET_CHIMINTEN);
300}
301
302#endif
diff --git a/drivers/scsi/aic94xx/aic94xx_reg_def.h b/drivers/scsi/aic94xx/aic94xx_reg_def.h
new file mode 100644
index 000000000000..b79f45f3ad47
--- /dev/null
+++ b/drivers/scsi/aic94xx/aic94xx_reg_def.h
@@ -0,0 +1,2398 @@
1/*
2 * Aic94xx SAS/SATA driver hardware registers defintions.
3 *
4 * Copyright (C) 2004 Adaptec, Inc. All rights reserved.
5 * Copyright (C) 2004 David Chaw <david_chaw@adaptec.com>
6 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
7 *
8 * Luben Tuikov: Some register value updates to make it work with the window
9 * agnostic register r/w functions. Some register corrections, sizes,
10 * etc.
11 *
12 * This file is licensed under GPLv2.
13 *
14 * This file is part of the aic94xx driver.
15 *
16 * The aic94xx driver is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License as
18 * published by the Free Software Foundation; version 2 of the
19 * License.
20 *
21 * The aic94xx driver is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 * General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with the aic94xx driver; if not, write to the Free Software
28 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 *
30 * $Id: //depot/aic94xx/aic94xx_reg_def.h#27 $
31 *
32 */
33
34#ifndef _ADP94XX_REG_DEF_H_
35#define _ADP94XX_REG_DEF_H_
36
37/*
38 * Common definitions.
39 */
40#define CSEQ_MODE_PAGE_SIZE 0x200 /* CSEQ mode page size */
41#define LmSEQ_MODE_PAGE_SIZE 0x200 /* LmSEQ mode page size */
42#define LmSEQ_HOST_REG_SIZE 0x4000 /* LmSEQ Host Register size */
43
44/********************* COM_SAS registers definition *************************/
45
46/* The base is REG_BASE_ADDR, defined in aic94xx_reg.h.
47 */
48
49/*
50 * CHIM Registers, Address Range : (0x00-0xFF)
51 */
52#define COMBIST (REG_BASE_ADDR + 0x00)
53
54/* bits 31:24 */
55#define L7BLKRST 0x80000000
56#define L6BLKRST 0x40000000
57#define L5BLKRST 0x20000000
58#define L4BLKRST 0x10000000
59#define L3BLKRST 0x08000000
60#define L2BLKRST 0x04000000
61#define L1BLKRST 0x02000000
62#define L0BLKRST 0x01000000
63#define LmBLKRST 0xFF000000
64#define LmBLKRST_COMBIST(phyid) (1 << (24 + phyid))
65
66#define OCMBLKRST 0x00400000
67#define CTXMEMBLKRST 0x00200000
68#define CSEQBLKRST 0x00100000
69#define EXSIBLKRST 0x00040000
70#define DPIBLKRST 0x00020000
71#define DFIFBLKRST 0x00010000
72#define HARDRST 0x00000200
73#define COMBLKRST 0x00000100
74#define FRCDFPERR 0x00000080
75#define FRCCIOPERR 0x00000020
76#define FRCBISTERR 0x00000010
77#define COMBISTEN 0x00000004
78#define COMBISTDONE 0x00000002 /* ro */
79#define COMBISTFAIL 0x00000001 /* ro */
80
81#define COMSTAT (REG_BASE_ADDR + 0x04)
82
83#define REQMBXREAD 0x00000040
84#define RSPMBXAVAIL 0x00000020
85#define CSBUFPERR 0x00000008
86#define OVLYERR 0x00000004
87#define CSERR 0x00000002
88#define OVLYDMADONE 0x00000001
89
90#define COMSTAT_MASK (REQMBXREAD | RSPMBXAVAIL | \
91 CSBUFPERR | OVLYERR | CSERR |\
92 OVLYDMADONE)
93
94#define COMSTATEN (REG_BASE_ADDR + 0x08)
95
96#define EN_REQMBXREAD 0x00000040
97#define EN_RSPMBXAVAIL 0x00000020
98#define EN_CSBUFPERR 0x00000008
99#define EN_OVLYERR 0x00000004
100#define EN_CSERR 0x00000002
101#define EN_OVLYDONE 0x00000001
102
103#define SCBPRO (REG_BASE_ADDR + 0x0C)
104
105#define SCBCONS_MASK 0xFFFF0000
106#define SCBPRO_MASK 0x0000FFFF
107
108#define CHIMREQMBX (REG_BASE_ADDR + 0x10)
109
110#define CHIMRSPMBX (REG_BASE_ADDR + 0x14)
111
112#define CHIMINT (REG_BASE_ADDR + 0x18)
113
114#define EXT_INT0 0x00000800
115#define EXT_INT1 0x00000400
116#define PORRSTDET 0x00000200
117#define HARDRSTDET 0x00000100
118#define DLAVAILQ 0x00000080 /* ro */
119#define HOSTERR 0x00000040
120#define INITERR 0x00000020
121#define DEVINT 0x00000010
122#define COMINT 0x00000008
123#define DEVTIMER2 0x00000004
124#define DEVTIMER1 0x00000002
125#define DLAVAIL 0x00000001
126
127#define CHIMINT_MASK (HOSTERR | INITERR | DEVINT | COMINT |\
128 DEVTIMER2 | DEVTIMER1 | DLAVAIL)
129
130#define DEVEXCEPT_MASK (HOSTERR | INITERR | DEVINT | COMINT)
131
132#define CHIMINTEN (REG_BASE_ADDR + 0x1C)
133
134#define RST_EN_EXT_INT1 0x01000000
135#define RST_EN_EXT_INT0 0x00800000
136#define RST_EN_HOSTERR 0x00400000
137#define RST_EN_INITERR 0x00200000
138#define RST_EN_DEVINT 0x00100000
139#define RST_EN_COMINT 0x00080000
140#define RST_EN_DEVTIMER2 0x00040000
141#define RST_EN_DEVTIMER1 0x00020000
142#define RST_EN_DLAVAIL 0x00010000
143#define SET_EN_EXT_INT1 0x00000100
144#define SET_EN_EXT_INT0 0x00000080
145#define SET_EN_HOSTERR 0x00000040
146#define SET_EN_INITERR 0x00000020
147#define SET_EN_DEVINT 0x00000010
148#define SET_EN_COMINT 0x00000008
149#define SET_EN_DEVTIMER2 0x00000004
150#define SET_EN_DEVTIMER1 0x00000002
151#define SET_EN_DLAVAIL 0x00000001
152
153#define RST_CHIMINTEN (RST_EN_HOSTERR | RST_EN_INITERR | \
154 RST_EN_DEVINT | RST_EN_COMINT | \
155 RST_EN_DEVTIMER2 | RST_EN_DEVTIMER1 |\
156 RST_EN_DLAVAIL)
157
158#define SET_CHIMINTEN (SET_EN_HOSTERR | SET_EN_INITERR |\
159 SET_EN_DEVINT | SET_EN_COMINT |\
160 SET_EN_DLAVAIL)
161
162#define OVLYDMACTL (REG_BASE_ADDR + 0x20)
163
164#define OVLYADR_MASK 0x07FF0000
165#define OVLYLSEQ_MASK 0x0000FF00
166#define OVLYCSEQ 0x00000080
167#define OVLYHALTERR 0x00000040
168#define PIOCMODE 0x00000020
169#define RESETOVLYDMA 0x00000008 /* wo */
170#define STARTOVLYDMA 0x00000004
171#define STOPOVLYDMA 0x00000002 /* wo */
172#define OVLYDMAACT 0x00000001 /* ro */
173
174#define OVLYDMACNT (REG_BASE_ADDR + 0x24)
175
176#define OVLYDOMAIN1 0x20000000 /* ro */
177#define OVLYDOMAIN0 0x10000000
178#define OVLYBUFADR_MASK 0x007F0000
179#define OVLYDMACNT_MASK 0x00003FFF
180
181#define OVLYDMAADR (REG_BASE_ADDR + 0x28)
182
183#define DMAERR (REG_BASE_ADDR + 0x30)
184
185#define OVLYERRSTAT_MASK 0x0000FF00 /* ro */
186#define CSERRSTAT_MASK 0x000000FF /* ro */
187
188#define SPIODATA (REG_BASE_ADDR + 0x34)
189
190/* 0x38 - 0x3C are reserved */
191
192#define T1CNTRLR (REG_BASE_ADDR + 0x40)
193
194#define T1DONE 0x00010000 /* ro */
195#define TIMER64 0x00000400
196#define T1ENABLE 0x00000200
197#define T1RELOAD 0x00000100
198#define T1PRESCALER_MASK 0x00000003
199
200#define T1CMPR (REG_BASE_ADDR + 0x44)
201
202#define T1CNTR (REG_BASE_ADDR + 0x48)
203
204#define T2CNTRLR (REG_BASE_ADDR + 0x4C)
205
206#define T2DONE 0x00010000 /* ro */
207#define T2ENABLE 0x00000200
208#define T2RELOAD 0x00000100
209#define T2PRESCALER_MASK 0x00000003
210
211#define T2CMPR (REG_BASE_ADDR + 0x50)
212
213#define T2CNTR (REG_BASE_ADDR + 0x54)
214
215/* 0x58h - 0xFCh are reserved */
216
217/*
218 * DCH_SAS Registers, Address Range : (0x800-0xFFF)
219 */
220#define CMDCTXBASE (REG_BASE_ADDR + 0x800)
221
222#define DEVCTXBASE (REG_BASE_ADDR + 0x808)
223
224#define CTXDOMAIN (REG_BASE_ADDR + 0x810)
225
226#define DEVCTXDOMAIN1 0x00000008 /* ro */
227#define DEVCTXDOMAIN0 0x00000004
228#define CMDCTXDOMAIN1 0x00000002 /* ro */
229#define CMDCTXDOMAIN0 0x00000001
230
231#define DCHCTL (REG_BASE_ADDR + 0x814)
232
233#define OCMBISTREPAIR 0x00080000
234#define OCMBISTEN 0x00040000
235#define OCMBISTDN 0x00020000 /* ro */
236#define OCMBISTFAIL 0x00010000 /* ro */
237#define DDBBISTEN 0x00004000
238#define DDBBISTDN 0x00002000 /* ro */
239#define DDBBISTFAIL 0x00001000 /* ro */
240#define SCBBISTEN 0x00000400
241#define SCBBISTDN 0x00000200 /* ro */
242#define SCBBISTFAIL 0x00000100 /* ro */
243
244#define MEMSEL_MASK 0x000000E0
245#define MEMSEL_CCM_LSEQ 0x00000000
246#define MEMSEL_CCM_IOP 0x00000020
247#define MEMSEL_CCM_SASCTL 0x00000040
248#define MEMSEL_DCM_LSEQ 0x00000060
249#define MEMSEL_DCM_IOP 0x00000080
250#define MEMSEL_OCM 0x000000A0
251
252#define FRCERR 0x00000010
253#define AUTORLS 0x00000001
254
255#define DCHREVISION (REG_BASE_ADDR + 0x818)
256
257#define DCHREVISION_MASK 0x000000FF
258
259#define DCHSTATUS (REG_BASE_ADDR + 0x81C)
260
261#define EN_CFIFTOERR 0x00020000
262#define CFIFTOERR 0x00000200
263#define CSEQINT 0x00000100 /* ro */
264#define LSEQ7INT 0x00000080 /* ro */
265#define LSEQ6INT 0x00000040 /* ro */
266#define LSEQ5INT 0x00000020 /* ro */
267#define LSEQ4INT 0x00000010 /* ro */
268#define LSEQ3INT 0x00000008 /* ro */
269#define LSEQ2INT 0x00000004 /* ro */
270#define LSEQ1INT 0x00000002 /* ro */
271#define LSEQ0INT 0x00000001 /* ro */
272
273#define LSEQINT_MASK (LSEQ7INT | LSEQ6INT | LSEQ5INT |\
274 LSEQ4INT | LSEQ3INT | LSEQ2INT |\
275 LSEQ1INT | LSEQ0INT)
276
277#define DCHDFIFDEBUG (REG_BASE_ADDR + 0x820)
278#define ENFAIRMST 0x00FF0000
279#define DISWRMST9 0x00000200
280#define DISWRMST8 0x00000100
281#define DISRDMST 0x000000FF
282
283#define ATOMICSTATCTL (REG_BASE_ADDR + 0x824)
284/* 8 bit wide */
285#define AUTOINC 0x80
286#define ATOMICERR 0x04
287#define ATOMICWIN 0x02
288#define ATOMICDONE 0x01
289
290
291#define ALTCIOADR (REG_BASE_ADDR + 0x828)
292/* 16 bit; bits 8:0 define CIO addr space of CSEQ */
293
294#define ASCBPTR (REG_BASE_ADDR + 0x82C)
295/* 16 bit wide */
296
297#define ADDBPTR (REG_BASE_ADDR + 0x82E)
298/* 16 bit wide */
299
300#define ANEWDATA (REG_BASE_ADDR + 0x830)
301/* 16 bit */
302
303#define AOLDDATA (REG_BASE_ADDR + 0x834)
304/* 16 bit */
305
306#define CTXACCESS (REG_BASE_ADDR + 0x838)
307/* 32 bit */
308
309/* 0x83Ch - 0xFFCh are reserved */
310
311/*
312 * ARP2 External Processor Registers, Address Range : (0x00-0x1F)
313 */
314#define ARP2CTL 0x00
315
316#define FRCSCRPERR 0x00040000
317#define FRCARP2PERR 0x00020000
318#define FRCARP2ILLOPC 0x00010000
319#define ENWAITTO 0x00008000
320#define PERRORDIS 0x00004000
321#define FAILDIS 0x00002000
322#define CIOPERRDIS 0x00001000
323#define BREAKEN3 0x00000800
324#define BREAKEN2 0x00000400
325#define BREAKEN1 0x00000200
326#define BREAKEN0 0x00000100
327#define EPAUSE 0x00000008
328#define PAUSED 0x00000004 /* ro */
329#define STEP 0x00000002
330#define ARP2RESET 0x00000001 /* wo */
331
332#define ARP2INT 0x04
333
334#define HALTCODE_MASK 0x00FF0000 /* ro */
335#define ARP2WAITTO 0x00000100
336#define ARP2HALTC 0x00000080
337#define ARP2ILLOPC 0x00000040
338#define ARP2PERR 0x00000020
339#define ARP2CIOPERR 0x00000010
340#define ARP2BREAK3 0x00000008
341#define ARP2BREAK2 0x00000004
342#define ARP2BREAK1 0x00000002
343#define ARP2BREAK0 0x00000001
344
345#define ARP2INTEN 0x08
346
347#define EN_ARP2WAITTO 0x00000100
348#define EN_ARP2HALTC 0x00000080
349#define EN_ARP2ILLOPC 0x00000040
350#define EN_ARP2PERR 0x00000020
351#define EN_ARP2CIOPERR 0x00000010
352#define EN_ARP2BREAK3 0x00000008
353#define EN_ARP2BREAK2 0x00000004
354#define EN_ARP2BREAK1 0x00000002
355#define EN_ARP2BREAK0 0x00000001
356
357#define ARP2BREAKADR01 0x0C
358
359#define BREAKADR1_MASK 0x0FFF0000
360#define BREAKADR0_MASK 0x00000FFF
361
362#define ARP2BREAKADR23 0x10
363
364#define BREAKADR3_MASK 0x0FFF0000
365#define BREAKADR2_MASK 0x00000FFF
366
367/* 0x14h - 0x1Ch are reserved */
368
369/*
370 * ARP2 Registers, Address Range : (0x00-0x1F)
371 * The definitions have the same address offset for CSEQ and LmSEQ
372 * CIO Bus Registers.
373 */
374#define MODEPTR 0x00
375
376#define DSTMODE 0xF0
377#define SRCMODE 0x0F
378
379#define ALTMODE 0x01
380
381#define ALTDMODE 0xF0
382#define ALTSMODE 0x0F
383
384#define ATOMICXCHG 0x02
385
386#define FLAG 0x04
387
388#define INTCODE_MASK 0xF0
389#define ALTMODEV2 0x04
390#define CARRY_INT 0x02
391#define CARRY 0x01
392
393#define ARP2INTCTL 0x05
394
395#define PAUSEDIS 0x80
396#define RSTINTCTL 0x40
397#define POPALTMODE 0x08
398#define ALTMODEV 0x04
399#define INTMASK 0x02
400#define IRET 0x01
401
402#define STACK 0x06
403
404#define FUNCTION1 0x07
405
406#define PRGMCNT 0x08
407
408#define ACCUM 0x0A
409
410#define SINDEX 0x0C
411
412#define DINDEX 0x0E
413
414#define ALLONES 0x10
415
416#define ALLZEROS 0x11
417
418#define SINDIR 0x12
419
420#define DINDIR 0x13
421
422#define JUMLDIR 0x14
423
424#define ARP2HALTCODE 0x15
425
426#define CURRADDR 0x16
427
428#define LASTADDR 0x18
429
430#define NXTLADDR 0x1A
431
432#define DBGPORTPTR 0x1C
433
434#define DBGPORT 0x1D
435
436/*
437 * CIO Registers.
438 * The definitions have the same address offset for CSEQ and LmSEQ
439 * CIO Bus Registers.
440 */
441#define MnSCBPTR 0x20
442
443#define MnDDBPTR 0x22
444
445#define SCRATCHPAGE 0x24
446
447#define MnSCRATCHPAGE 0x25
448
449#define SCRATCHPAGESV 0x26
450
451#define MnSCRATCHPAGESV 0x27
452
453#define MnDMAERRS 0x46
454
455#define MnSGDMAERRS 0x47
456
457#define MnSGBUF 0x53
458
459#define MnSGDMASTAT 0x5b
460
461#define MnDDMACTL 0x5c /* RAZOR.rspec.fm rev 1.5 is wrong */
462
463#define MnDDMASTAT 0x5d /* RAZOR.rspec.fm rev 1.5 is wrong */
464
465#define MnDDMAMODE 0x5e /* RAZOR.rspec.fm rev 1.5 is wrong */
466
467#define MnDMAENG 0x60
468
469#define MnPIPECTL 0x61
470
471#define MnSGBADR 0x65
472
473#define MnSCB_SITE 0x100
474
475#define MnDDB_SITE 0x180
476
477/*
478 * The common definitions below have the same address offset for both
479 * CSEQ and LmSEQ.
480 */
481#define BISTCTL0 0x4C
482
483#define BISTCTL1 0x50
484
485#define MAPPEDSCR 0x800
486
487/*
488 * CSEQ Host Register, Address Range : (0x000-0xFFC)
489 */
490#define CSEQ_HOST_REG_BASE_ADR 0xB8001000
491
492#define CARP2CTL (CSEQ_HOST_REG_BASE_ADR + ARP2CTL)
493
494#define CARP2INT (CSEQ_HOST_REG_BASE_ADR + ARP2INT)
495
496#define CARP2INTEN (CSEQ_HOST_REG_BASE_ADR + ARP2INTEN)
497
498#define CARP2BREAKADR01 (CSEQ_HOST_REG_BASE_ADR+ARP2BREAKADR01)
499
500#define CARP2BREAKADR23 (CSEQ_HOST_REG_BASE_ADR+ARP2BREAKADR23)
501
502#define CBISTCTL (CSEQ_HOST_REG_BASE_ADR + BISTCTL1)
503
504#define CSEQRAMBISTEN 0x00000040
505#define CSEQRAMBISTDN 0x00000020 /* ro */
506#define CSEQRAMBISTFAIL 0x00000010 /* ro */
507#define CSEQSCRBISTEN 0x00000004
508#define CSEQSCRBISTDN 0x00000002 /* ro */
509#define CSEQSCRBISTFAIL 0x00000001 /* ro */
510
511#define CMAPPEDSCR (CSEQ_HOST_REG_BASE_ADR + MAPPEDSCR)
512
513/*
514 * CSEQ CIO Bus Registers, Address Range : (0x0000-0x1FFC)
515 * 16 modes, each mode is 512 bytes.
516 * Unless specified, the register should valid for all modes.
517 */
518#define CSEQ_CIO_REG_BASE_ADR REG_BASE_ADDR_CSEQCIO
519
520#define CSEQm_CIO_REG(Mode, Reg) \
521 (CSEQ_CIO_REG_BASE_ADR + \
522 ((u32) (Mode) * CSEQ_MODE_PAGE_SIZE) + (u32) (Reg))
523
524#define CMODEPTR (CSEQ_CIO_REG_BASE_ADR + MODEPTR)
525
526#define CALTMODE (CSEQ_CIO_REG_BASE_ADR + ALTMODE)
527
528#define CATOMICXCHG (CSEQ_CIO_REG_BASE_ADR + ATOMICXCHG)
529
530#define CFLAG (CSEQ_CIO_REG_BASE_ADR + FLAG)
531
532#define CARP2INTCTL (CSEQ_CIO_REG_BASE_ADR + ARP2INTCTL)
533
534#define CSTACK (CSEQ_CIO_REG_BASE_ADR + STACK)
535
536#define CFUNCTION1 (CSEQ_CIO_REG_BASE_ADR + FUNCTION1)
537
538#define CPRGMCNT (CSEQ_CIO_REG_BASE_ADR + PRGMCNT)
539
540#define CACCUM (CSEQ_CIO_REG_BASE_ADR + ACCUM)
541
542#define CSINDEX (CSEQ_CIO_REG_BASE_ADR + SINDEX)
543
544#define CDINDEX (CSEQ_CIO_REG_BASE_ADR + DINDEX)
545
546#define CALLONES (CSEQ_CIO_REG_BASE_ADR + ALLONES)
547
548#define CALLZEROS (CSEQ_CIO_REG_BASE_ADR + ALLZEROS)
549
550#define CSINDIR (CSEQ_CIO_REG_BASE_ADR + SINDIR)
551
552#define CDINDIR (CSEQ_CIO_REG_BASE_ADR + DINDIR)
553
554#define CJUMLDIR (CSEQ_CIO_REG_BASE_ADR + JUMLDIR)
555
556#define CARP2HALTCODE (CSEQ_CIO_REG_BASE_ADR + ARP2HALTCODE)
557
558#define CCURRADDR (CSEQ_CIO_REG_BASE_ADR + CURRADDR)
559
560#define CLASTADDR (CSEQ_CIO_REG_BASE_ADR + LASTADDR)
561
562#define CNXTLADDR (CSEQ_CIO_REG_BASE_ADR + NXTLADDR)
563
564#define CDBGPORTPTR (CSEQ_CIO_REG_BASE_ADR + DBGPORTPTR)
565
566#define CDBGPORT (CSEQ_CIO_REG_BASE_ADR + DBGPORT)
567
568#define CSCRATCHPAGE (CSEQ_CIO_REG_BASE_ADR + SCRATCHPAGE)
569
570#define CMnSCBPTR(Mode) CSEQm_CIO_REG(Mode, MnSCBPTR)
571
572#define CMnDDBPTR(Mode) CSEQm_CIO_REG(Mode, MnDDBPTR)
573
574#define CMnSCRATCHPAGE(Mode) CSEQm_CIO_REG(Mode, MnSCRATCHPAGE)
575
576#define CLINKCON (CSEQ_CIO_REG_BASE_ADR + 0x28)
577
578#define CCIOAACESS (CSEQ_CIO_REG_BASE_ADR + 0x2C)
579
580/* mode 0-7 */
581#define MnREQMBX 0x30
582#define CMnREQMBX(Mode) CSEQm_CIO_REG(Mode, 0x30)
583
584/* mode 8 */
585#define CSEQCON CSEQm_CIO_REG(8, 0x30)
586
587/* mode 0-7 */
588#define MnRSPMBX 0x34
589#define CMnRSPMBX(Mode) CSEQm_CIO_REG(Mode, 0x34)
590
591/* mode 8 */
592#define CSEQCOMCTL CSEQm_CIO_REG(8, 0x34)
593
594/* mode 8 */
595#define CSEQCOMSTAT CSEQm_CIO_REG(8, 0x35)
596
597/* mode 8 */
598#define CSEQCOMINTEN CSEQm_CIO_REG(8, 0x36)
599
600/* mode 8 */
601#define CSEQCOMDMACTL CSEQm_CIO_REG(8, 0x37)
602
603#define CSHALTERR 0x10
604#define RESETCSDMA 0x08 /* wo */
605#define STARTCSDMA 0x04
606#define STOPCSDMA 0x02 /* wo */
607#define CSDMAACT 0x01 /* ro */
608
609/* mode 0-7 */
610#define MnINT 0x38
611#define CMnINT(Mode) CSEQm_CIO_REG(Mode, 0x38)
612
613#define CMnREQMBXE 0x02
614#define CMnRSPMBXF 0x01
615#define CMnINT_MASK 0x00000003
616
617/* mode 8 */
618#define CSEQREQMBX CSEQm_CIO_REG(8, 0x38)
619
620/* mode 0-7 */
621#define MnINTEN 0x3C
622#define CMnINTEN(Mode) CSEQm_CIO_REG(Mode, 0x3C)
623
624#define EN_CMnRSPMBXF 0x01
625
626/* mode 8 */
627#define CSEQRSPMBX CSEQm_CIO_REG(8, 0x3C)
628
629/* mode 8 */
630#define CSDMAADR CSEQm_CIO_REG(8, 0x40)
631
632/* mode 8 */
633#define CSDMACNT CSEQm_CIO_REG(8, 0x48)
634
635/* mode 8 */
636#define CSEQDLCTL CSEQm_CIO_REG(8, 0x4D)
637
638#define DONELISTEND 0x10
639#define DONELISTSIZE_MASK 0x0F
640#define DONELISTSIZE_8ELEM 0x01
641#define DONELISTSIZE_16ELEM 0x02
642#define DONELISTSIZE_32ELEM 0x03
643#define DONELISTSIZE_64ELEM 0x04
644#define DONELISTSIZE_128ELEM 0x05
645#define DONELISTSIZE_256ELEM 0x06
646#define DONELISTSIZE_512ELEM 0x07
647#define DONELISTSIZE_1024ELEM 0x08
648#define DONELISTSIZE_2048ELEM 0x09
649#define DONELISTSIZE_4096ELEM 0x0A
650#define DONELISTSIZE_8192ELEM 0x0B
651#define DONELISTSIZE_16384ELEM 0x0C
652
653/* mode 8 */
654#define CSEQDLOFFS CSEQm_CIO_REG(8, 0x4E)
655
656/* mode 11 */
657#define CM11INTVEC0 CSEQm_CIO_REG(11, 0x50)
658
659/* mode 11 */
660#define CM11INTVEC1 CSEQm_CIO_REG(11, 0x52)
661
662/* mode 11 */
663#define CM11INTVEC2 CSEQm_CIO_REG(11, 0x54)
664
665#define CCONMSK (CSEQ_CIO_REG_BASE_ADR + 0x60)
666
667#define CCONEXIST (CSEQ_CIO_REG_BASE_ADR + 0x61)
668
669#define CCONMODE (CSEQ_CIO_REG_BASE_ADR + 0x62)
670
671#define CTIMERCALC (CSEQ_CIO_REG_BASE_ADR + 0x64)
672
673#define CINTDIS (CSEQ_CIO_REG_BASE_ADR + 0x68)
674
675/* mode 8, 32x32 bits, 128 bytes of mapped buffer */
676#define CSBUFFER CSEQm_CIO_REG(8, 0x80)
677
678#define CSCRATCH (CSEQ_CIO_REG_BASE_ADR + 0x1C0)
679
680/* mode 0-8 */
681#define CMnSCRATCH(Mode) CSEQm_CIO_REG(Mode, 0x1E0)
682
683/*
684 * CSEQ Mapped Instruction RAM Page, Address Range : (0x0000-0x1FFC)
685 */
686#define CSEQ_RAM_REG_BASE_ADR 0xB8004000
687
688/*
689 * The common definitions below have the same address offset for all the Link
690 * sequencers.
691 */
692#define MODECTL 0x40
693
694#define DBGMODE 0x44
695
696#define CONTROL 0x48
697#define LEDTIMER 0x00010000
698#define LEDTIMERS_10us 0x00000000
699#define LEDTIMERS_1ms 0x00000800
700#define LEDTIMERS_100ms 0x00001000
701#define LEDMODE_TXRX 0x00000000
702#define LEDMODE_CONNECTED 0x00000200
703#define LEDPOL 0x00000100
704
705#define LSEQRAM 0x1000
706
707/*
708 * LmSEQ Host Registers, Address Range : (0x0000-0x3FFC)
709 */
710#define LSEQ0_HOST_REG_BASE_ADR 0xB8020000
711#define LSEQ1_HOST_REG_BASE_ADR 0xB8024000
712#define LSEQ2_HOST_REG_BASE_ADR 0xB8028000
713#define LSEQ3_HOST_REG_BASE_ADR 0xB802C000
714#define LSEQ4_HOST_REG_BASE_ADR 0xB8030000
715#define LSEQ5_HOST_REG_BASE_ADR 0xB8034000
716#define LSEQ6_HOST_REG_BASE_ADR 0xB8038000
717#define LSEQ7_HOST_REG_BASE_ADR 0xB803C000
718
719#define LmARP2CTL(LinkNum) (LSEQ0_HOST_REG_BASE_ADR + \
720 ((LinkNum)*LmSEQ_HOST_REG_SIZE) + \
721 ARP2CTL)
722
723#define LmARP2INT(LinkNum) (LSEQ0_HOST_REG_BASE_ADR + \
724 ((LinkNum)*LmSEQ_HOST_REG_SIZE) + \
725 ARP2INT)
726
727#define LmARP2INTEN(LinkNum) (LSEQ0_HOST_REG_BASE_ADR + \
728 ((LinkNum)*LmSEQ_HOST_REG_SIZE) + \
729 ARP2INTEN)
730
731#define LmDBGMODE(LinkNum) (LSEQ0_HOST_REG_BASE_ADR + \
732 ((LinkNum)*LmSEQ_HOST_REG_SIZE) + \
733 DBGMODE)
734
735#define LmCONTROL(LinkNum) (LSEQ0_HOST_REG_BASE_ADR + \
736 ((LinkNum)*LmSEQ_HOST_REG_SIZE) + \
737 CONTROL)
738
739#define LmARP2BREAKADR01(LinkNum) (LSEQ0_HOST_REG_BASE_ADR + \
740 ((LinkNum)*LmSEQ_HOST_REG_SIZE) + \
741 ARP2BREAKADR01)
742
743#define LmARP2BREAKADR23(LinkNum) (LSEQ0_HOST_REG_BASE_ADR + \
744 ((LinkNum)*LmSEQ_HOST_REG_SIZE) + \
745 ARP2BREAKADR23)
746
747#define LmMODECTL(LinkNum) (LSEQ0_HOST_REG_BASE_ADR + \
748 ((LinkNum)*LmSEQ_HOST_REG_SIZE) + \
749 MODECTL)
750
751#define LmAUTODISCI 0x08000000
752#define LmDSBLBITLT 0x04000000
753#define LmDSBLANTT 0x02000000
754#define LmDSBLCRTT 0x01000000
755#define LmDSBLCONT 0x00000100
756#define LmPRIMODE 0x00000080
757#define LmDSBLHOLD 0x00000040
758#define LmDISACK 0x00000020
759#define LmBLIND48 0x00000010
760#define LmRCVMODE_MASK 0x0000000C
761#define LmRCVMODE_PLD 0x00000000
762#define LmRCVMODE_HPC 0x00000004
763
764#define LmDBGMODE(LinkNum) (LSEQ0_HOST_REG_BASE_ADR + \
765 ((LinkNum)*LmSEQ_HOST_REG_SIZE) + \
766 DBGMODE)
767
768#define LmFRCPERR 0x80000000
769#define LmMEMSEL_MASK 0x30000000
770#define LmFRCRBPERR 0x00000000
771#define LmFRCTBPERR 0x10000000
772#define LmFRCSGBPERR 0x20000000
773#define LmFRCARBPERR 0x30000000
774#define LmRCVIDW 0x00080000
775#define LmINVDWERR 0x00040000
776#define LmRCVDISP 0x00004000
777#define LmDISPERR 0x00002000
778#define LmDSBLDSCR 0x00000800
779#define LmDSBLSCR 0x00000400
780#define LmFRCNAK 0x00000200
781#define LmFRCROFS 0x00000100
782#define LmFRCCRC 0x00000080
783#define LmFRMTYPE_MASK 0x00000070
784#define LmSG_DATA 0x00000000
785#define LmSG_COMMAND 0x00000010
786#define LmSG_TASK 0x00000020
787#define LmSG_TGTXFER 0x00000030
788#define LmSG_RESPONSE 0x00000040
789#define LmSG_IDENADDR 0x00000050
790#define LmSG_OPENADDR 0x00000060
791#define LmDISCRCGEN 0x00000008
792#define LmDISCRCCHK 0x00000004
793#define LmSSXMTFRM 0x00000002
794#define LmSSRCVFRM 0x00000001
795
796#define LmCONTROL(LinkNum) (LSEQ0_HOST_REG_BASE_ADR + \
797 ((LinkNum)*LmSEQ_HOST_REG_SIZE) + \
798 CONTROL)
799
800#define LmSTEPXMTFRM 0x00000002
801#define LmSTEPRCVFRM 0x00000001
802
803#define LmBISTCTL0(LinkNum) (LSEQ0_HOST_REG_BASE_ADR + \
804 ((LinkNum)*LmSEQ_HOST_REG_SIZE) + \
805 BISTCTL0)
806
807#define ARBBISTEN 0x40000000
808#define ARBBISTDN 0x20000000 /* ro */
809#define ARBBISTFAIL 0x10000000 /* ro */
810#define TBBISTEN 0x00000400
811#define TBBISTDN 0x00000200 /* ro */
812#define TBBISTFAIL 0x00000100 /* ro */
813#define RBBISTEN 0x00000040
814#define RBBISTDN 0x00000020 /* ro */
815#define RBBISTFAIL 0x00000010 /* ro */
816#define SGBISTEN 0x00000004
817#define SGBISTDN 0x00000002 /* ro */
818#define SGBISTFAIL 0x00000001 /* ro */
819
820#define LmBISTCTL1(LinkNum) (LSEQ0_HOST_REG_BASE_ADR + \
821 ((LinkNum)*LmSEQ_HOST_REG_SIZE) +\
822 BISTCTL1)
823
824#define LmRAMPAGE1 0x00000200
825#define LmRAMPAGE0 0x00000100
826#define LmIMEMBISTEN 0x00000040
827#define LmIMEMBISTDN 0x00000020 /* ro */
828#define LmIMEMBISTFAIL 0x00000010 /* ro */
829#define LmSCRBISTEN 0x00000004
830#define LmSCRBISTDN 0x00000002 /* ro */
831#define LmSCRBISTFAIL 0x00000001 /* ro */
832#define LmRAMPAGE (LmRAMPAGE1 + LmRAMPAGE0)
833#define LmRAMPAGE_LSHIFT 0x8
834
835#define LmSCRATCH(LinkNum) (LSEQ0_HOST_REG_BASE_ADR + \
836 ((LinkNum) * LmSEQ_HOST_REG_SIZE) +\
837 MAPPEDSCR)
838
839#define LmSEQRAM(LinkNum) (LSEQ0_HOST_REG_BASE_ADR + \
840 ((LinkNum) * LmSEQ_HOST_REG_SIZE) +\
841 LSEQRAM)
842
843/*
844 * LmSEQ CIO Bus Register, Address Range : (0x0000-0xFFC)
845 * 8 modes, each mode is 512 bytes.
846 * Unless specified, the register should valid for all modes.
847 */
848#define LmSEQ_CIOBUS_REG_BASE 0x2000
849
850#define LmSEQ_PHY_BASE(Mode, LinkNum) \
851 (LSEQ0_HOST_REG_BASE_ADR + \
852 (LmSEQ_HOST_REG_SIZE * (u32) (LinkNum)) + \
853 LmSEQ_CIOBUS_REG_BASE + \
854 ((u32) (Mode) * LmSEQ_MODE_PAGE_SIZE))
855
856#define LmSEQ_PHY_REG(Mode, LinkNum, Reg) \
857 (LmSEQ_PHY_BASE(Mode, LinkNum) + (u32) (Reg))
858
859#define LmMODEPTR(LinkNum) LmSEQ_PHY_REG(0, LinkNum, MODEPTR)
860
861#define LmALTMODE(LinkNum) LmSEQ_PHY_REG(0, LinkNum, ALTMODE)
862
863#define LmATOMICXCHG(LinkNum) LmSEQ_PHY_REG(0, LinkNum, ATOMICXCHG)
864
865#define LmFLAG(LinkNum) LmSEQ_PHY_REG(0, LinkNum, FLAG)
866
867#define LmARP2INTCTL(LinkNum) LmSEQ_PHY_REG(0, LinkNum, ARP2INTCTL)
868
869#define LmSTACK(LinkNum) LmSEQ_PHY_REG(0, LinkNum, STACK)
870
871#define LmFUNCTION1(LinkNum) LmSEQ_PHY_REG(0, LinkNum, FUNCTION1)
872
873#define LmPRGMCNT(LinkNum) LmSEQ_PHY_REG(0, LinkNum, PRGMCNT)
874
875#define LmACCUM(LinkNum) LmSEQ_PHY_REG(0, LinkNum, ACCUM)
876
877#define LmSINDEX(LinkNum) LmSEQ_PHY_REG(0, LinkNum, SINDEX)
878
879#define LmDINDEX(LinkNum) LmSEQ_PHY_REG(0, LinkNum, DINDEX)
880
881#define LmALLONES(LinkNum) LmSEQ_PHY_REG(0, LinkNum, ALLONES)
882
883#define LmALLZEROS(LinkNum) LmSEQ_PHY_REG(0, LinkNum, ALLZEROS)
884
885#define LmSINDIR(LinkNum) LmSEQ_PHY_REG(0, LinkNum, SINDIR)
886
887#define LmDINDIR(LinkNum) LmSEQ_PHY_REG(0, LinkNum, DINDIR)
888
889#define LmJUMLDIR(LinkNum) LmSEQ_PHY_REG(0, LinkNum, JUMLDIR)
890
891#define LmARP2HALTCODE(LinkNum) LmSEQ_PHY_REG(0, LinkNum, ARP2HALTCODE)
892
893#define LmCURRADDR(LinkNum) LmSEQ_PHY_REG(0, LinkNum, CURRADDR)
894
895#define LmLASTADDR(LinkNum) LmSEQ_PHY_REG(0, LinkNum, LASTADDR)
896
897#define LmNXTLADDR(LinkNum) LmSEQ_PHY_REG(0, LinkNum, NXTLADDR)
898
899#define LmDBGPORTPTR(LinkNum) LmSEQ_PHY_REG(0, LinkNum, DBGPORTPTR)
900
901#define LmDBGPORT(LinkNum) LmSEQ_PHY_REG(0, LinkNum, DBGPORT)
902
903#define LmSCRATCHPAGE(LinkNum) LmSEQ_PHY_REG(0, LinkNum, SCRATCHPAGE)
904
905#define LmMnSCRATCHPAGE(LinkNum, Mode) LmSEQ_PHY_REG(Mode, LinkNum, \
906 MnSCRATCHPAGE)
907
908#define LmTIMERCALC(LinkNum) LmSEQ_PHY_REG(0, LinkNum, 0x28)
909
910#define LmREQMBX(LinkNum) LmSEQ_PHY_REG(0, LinkNum, 0x30)
911
912#define LmRSPMBX(LinkNum) LmSEQ_PHY_REG(0, LinkNum, 0x34)
913
914#define LmMnINT(LinkNum, Mode) LmSEQ_PHY_REG(Mode, LinkNum, 0x38)
915
916#define CTXMEMSIZE 0x80000000 /* ro */
917#define LmACKREQ 0x08000000
918#define LmNAKREQ 0x04000000
919#define LmMnXMTERR 0x02000000
920#define LmM5OOBSVC 0x01000000
921#define LmHWTINT 0x00800000
922#define LmMnCTXDONE 0x00100000
923#define LmM2REQMBXF 0x00080000
924#define LmM2RSPMBXE 0x00040000
925#define LmMnDMAERR 0x00020000
926#define LmRCVPRIM 0x00010000
927#define LmRCVERR 0x00008000
928#define LmADDRRCV 0x00004000
929#define LmMnHDRMISS 0x00002000
930#define LmMnWAITSCB 0x00001000
931#define LmMnRLSSCB 0x00000800
932#define LmMnSAVECTX 0x00000400
933#define LmMnFETCHSG 0x00000200
934#define LmMnLOADCTX 0x00000100
935#define LmMnCFGICL 0x00000080
936#define LmMnCFGSATA 0x00000040
937#define LmMnCFGEXPSATA 0x00000020
938#define LmMnCFGCMPLT 0x00000010
939#define LmMnCFGRBUF 0x00000008
940#define LmMnSAVETTR 0x00000004
941#define LmMnCFGRDAT 0x00000002
942#define LmMnCFGHDR 0x00000001
943
944#define LmMnINTEN(LinkNum, Mode) LmSEQ_PHY_REG(Mode, LinkNum, 0x3C)
945
946#define EN_LmACKREQ 0x08000000
947#define EN_LmNAKREQ 0x04000000
948#define EN_LmMnXMTERR 0x02000000
949#define EN_LmM5OOBSVC 0x01000000
950#define EN_LmHWTINT 0x00800000
951#define EN_LmMnCTXDONE 0x00100000
952#define EN_LmM2REQMBXF 0x00080000
953#define EN_LmM2RSPMBXE 0x00040000
954#define EN_LmMnDMAERR 0x00020000
955#define EN_LmRCVPRIM 0x00010000
956#define EN_LmRCVERR 0x00008000
957#define EN_LmADDRRCV 0x00004000
958#define EN_LmMnHDRMISS 0x00002000
959#define EN_LmMnWAITSCB 0x00001000
960#define EN_LmMnRLSSCB 0x00000800
961#define EN_LmMnSAVECTX 0x00000400
962#define EN_LmMnFETCHSG 0x00000200
963#define EN_LmMnLOADCTX 0x00000100
964#define EN_LmMnCFGICL 0x00000080
965#define EN_LmMnCFGSATA 0x00000040
966#define EN_LmMnCFGEXPSATA 0x00000020
967#define EN_LmMnCFGCMPLT 0x00000010
968#define EN_LmMnCFGRBUF 0x00000008
969#define EN_LmMnSAVETTR 0x00000004
970#define EN_LmMnCFGRDAT 0x00000002
971#define EN_LmMnCFGHDR 0x00000001
972
973#define LmM0INTEN_MASK (EN_LmMnCFGCMPLT | EN_LmMnCFGRBUF | \
974 EN_LmMnSAVETTR | EN_LmMnCFGRDAT | \
975 EN_LmMnCFGHDR | EN_LmRCVERR | \
976 EN_LmADDRRCV | EN_LmMnHDRMISS | \
977 EN_LmMnRLSSCB | EN_LmMnSAVECTX | \
978 EN_LmMnFETCHSG | EN_LmMnLOADCTX | \
979 EN_LmHWTINT | EN_LmMnCTXDONE | \
980 EN_LmRCVPRIM | EN_LmMnCFGSATA | \
981 EN_LmMnCFGEXPSATA | EN_LmMnDMAERR)
982
983#define LmM1INTEN_MASK (EN_LmMnCFGCMPLT | EN_LmADDRRCV | \
984 EN_LmMnRLSSCB | EN_LmMnSAVECTX | \
985 EN_LmMnFETCHSG | EN_LmMnLOADCTX | \
986 EN_LmMnXMTERR | EN_LmHWTINT | \
987 EN_LmMnCTXDONE | EN_LmRCVPRIM | \
988 EN_LmRCVERR | EN_LmMnDMAERR)
989
990#define LmM2INTEN_MASK (EN_LmADDRRCV | EN_LmHWTINT | \
991 EN_LmM2REQMBXF | EN_LmRCVPRIM | \
992 EN_LmRCVERR)
993
994#define LmM5INTEN_MASK (EN_LmADDRRCV | EN_LmM5OOBSVC | \
995 EN_LmHWTINT | EN_LmRCVPRIM | \
996 EN_LmRCVERR)
997
998#define LmXMTPRIMD(LinkNum) LmSEQ_PHY_REG(0, LinkNum, 0x40)
999
1000#define LmXMTPRIMCS(LinkNum) LmSEQ_PHY_REG(0, LinkNum, 0x44)
1001
1002#define LmCONSTAT(LinkNum) LmSEQ_PHY_REG(0, LinkNum, 0x45)
1003
1004#define LmMnDMAERRS(LinkNum, Mode) LmSEQ_PHY_REG(Mode, LinkNum, 0x46)
1005
1006#define LmMnSGDMAERRS(LinkNum, Mode) LmSEQ_PHY_REG(Mode, LinkNum, 0x47)
1007
1008#define LmM0EXPHDRP(LinkNum) LmSEQ_PHY_REG(0, LinkNum, 0x48)
1009
1010#define LmM1SASALIGN(LinkNum) LmSEQ_PHY_REG(1, LinkNum, 0x48)
1011#define SAS_ALIGN_DEFAULT 0xFF
1012
1013#define LmM0MSKHDRP(LinkNum) LmSEQ_PHY_REG(0, LinkNum, 0x49)
1014
1015#define LmM1STPALIGN(LinkNum) LmSEQ_PHY_REG(1, LinkNum, 0x49)
1016#define STP_ALIGN_DEFAULT 0x1F
1017
1018#define LmM0RCVHDRP(LinkNum) LmSEQ_PHY_REG(0, LinkNum, 0x4A)
1019
1020#define LmM1XMTHDRP(LinkNum) LmSEQ_PHY_REG(1, LinkNum, 0x4A)
1021
1022#define LmM0ICLADR(LinkNum) LmSEQ_PHY_REG(0, LinkNum, 0x4B)
1023
1024#define LmM1ALIGNMODE(LinkNum) LmSEQ_PHY_REG(1, LinkNum, 0x4B)
1025
1026#define LmDISALIGN 0x20
1027#define LmROTSTPALIGN 0x10
1028#define LmSTPALIGN 0x08
1029#define LmROTNOTIFY 0x04
1030#define LmDUALALIGN 0x02
1031#define LmROTALIGN 0x01
1032
1033#define LmM0EXPRCVNT(LinkNum) LmSEQ_PHY_REG(0, LinkNum, 0x4C)
1034
1035#define LmM1XMTCNT(LinkNum) LmSEQ_PHY_REG(1, LinkNum, 0x4C)
1036
1037#define LmMnBUFSTAT(LinkNum, Mode) LmSEQ_PHY_REG(Mode, LinkNum, 0x4E)
1038
1039#define LmMnBUFPERR 0x01
1040
1041/* mode 0-1 */
1042#define LmMnXFRLVL(LinkNum, Mode) LmSEQ_PHY_REG(Mode, LinkNum, 0x59)
1043
1044#define LmMnXFRLVL_128 0x05
1045#define LmMnXFRLVL_256 0x04
1046#define LmMnXFRLVL_512 0x03
1047#define LmMnXFRLVL_1024 0x02
1048#define LmMnXFRLVL_1536 0x01
1049#define LmMnXFRLVL_2048 0x00
1050
1051 /* mode 0-1 */
1052#define LmMnSGDMACTL(LinkNum, Mode) LmSEQ_PHY_REG(Mode, LinkNum, 0x5A)
1053
1054#define LmMnRESETSG 0x04
1055#define LmMnSTOPSG 0x02
1056#define LmMnSTARTSG 0x01
1057
1058/* mode 0-1 */
1059#define LmMnSGDMASTAT(LinkNum, Mode) LmSEQ_PHY_REG(Mode, LinkNum, 0x5B)
1060
1061/* mode 0-1 */
1062#define LmMnDDMACTL(LinkNum, Mode) LmSEQ_PHY_REG(Mode, LinkNum, 0x5C)
1063
1064#define LmMnFLUSH 0x40 /* wo */
1065#define LmMnRLSRTRY 0x20 /* wo */
1066#define LmMnDISCARD 0x10 /* wo */
1067#define LmMnRESETDAT 0x08 /* wo */
1068#define LmMnSUSDAT 0x04 /* wo */
1069#define LmMnSTOPDAT 0x02 /* wo */
1070#define LmMnSTARTDAT 0x01 /* wo */
1071
1072/* mode 0-1 */
1073#define LmMnDDMASTAT(LinkNum, Mode) LmSEQ_PHY_REG(Mode, LinkNum, 0x5D)
1074
1075#define LmMnDPEMPTY 0x80
1076#define LmMnFLUSHING 0x40
1077#define LmMnDDMAREQ 0x20
1078#define LmMnHDMAREQ 0x10
1079#define LmMnDATFREE 0x08
1080#define LmMnDATSUS 0x04
1081#define LmMnDATACT 0x02
1082#define LmMnDATEN 0x01
1083
1084/* mode 0-1 */
1085#define LmMnDDMAMODE(LinkNum, Mode) LmSEQ_PHY_REG(Mode, LinkNum, 0x5E)
1086
1087#define LmMnDMATYPE_NORMAL 0x0000
1088#define LmMnDMATYPE_HOST_ONLY_TX 0x0001
1089#define LmMnDMATYPE_DEVICE_ONLY_TX 0x0002
1090#define LmMnDMATYPE_INVALID 0x0003
1091#define LmMnDMATYPE_MASK 0x0003
1092
1093#define LmMnDMAWRAP 0x0004
1094#define LmMnBITBUCKET 0x0008
1095#define LmMnDISHDR 0x0010
1096#define LmMnSTPCRC 0x0020
1097#define LmXTEST 0x0040
1098#define LmMnDISCRC 0x0080
1099#define LmMnENINTLK 0x0100
1100#define LmMnADDRFRM 0x0400
1101#define LmMnENXMTCRC 0x0800
1102
1103/* mode 0-1 */
1104#define LmMnXFRCNT(LinkNum, Mode) LmSEQ_PHY_REG(Mode, LinkNum, 0x70)
1105
1106/* mode 0-1 */
1107#define LmMnDPSEL(LinkNum, Mode) LmSEQ_PHY_REG(Mode, LinkNum, 0x7B)
1108#define LmMnDPSEL_MASK 0x07
1109#define LmMnEOLPRE 0x40
1110#define LmMnEOSPRE 0x80
1111
1112/* Registers used in conjunction with LmMnDPSEL and LmMnDPACC registers */
1113/* Receive Mode n = 0 */
1114#define LmMnHRADDR 0x00
1115#define LmMnHBYTECNT 0x01
1116#define LmMnHREWIND 0x02
1117#define LmMnDWADDR 0x03
1118#define LmMnDSPACECNT 0x04
1119#define LmMnDFRMSIZE 0x05
1120
1121/* Registers used in conjunction with LmMnDPSEL and LmMnDPACC registers */
1122/* Transmit Mode n = 1 */
1123#define LmMnHWADDR 0x00
1124#define LmMnHSPACECNT 0x01
1125/* #define LmMnHREWIND 0x02 */
1126#define LmMnDRADDR 0x03
1127#define LmMnDBYTECNT 0x04
1128/* #define LmMnDFRMSIZE 0x05 */
1129
1130/* mode 0-1 */
1131#define LmMnDPACC(LinkNum, Mode) LmSEQ_PHY_REG(Mode, LinkNum, 0x78)
1132#define LmMnDPACC_MASK 0x00FFFFFF
1133
1134/* mode 0-1 */
1135#define LmMnHOLDLVL(LinkNum, Mode) LmSEQ_PHY_REG(Mode, LinkNum, 0x7D)
1136
1137#define LmPRMSTAT0(LinkNum) LmSEQ_PHY_REG(0, LinkNum, 0x80)
1138#define LmPRMSTAT0BYTE0 0x80
1139#define LmPRMSTAT0BYTE1 0x81
1140#define LmPRMSTAT0BYTE2 0x82
1141#define LmPRMSTAT0BYTE3 0x83
1142
1143#define LmFRAMERCVD 0x80000000
1144#define LmXFRRDYRCVD 0x40000000
1145#define LmUNKNOWNP 0x20000000
1146#define LmBREAK 0x10000000
1147#define LmDONE 0x08000000
1148#define LmOPENACPT 0x04000000
1149#define LmOPENRJCT 0x02000000
1150#define LmOPENRTRY 0x01000000
1151#define LmCLOSERV1 0x00800000
1152#define LmCLOSERV0 0x00400000
1153#define LmCLOSENORM 0x00200000
1154#define LmCLOSECLAF 0x00100000
1155#define LmNOTIFYRV2 0x00080000
1156#define LmNOTIFYRV1 0x00040000
1157#define LmNOTIFYRV0 0x00020000
1158#define LmNOTIFYSPIN 0x00010000
1159#define LmBROADRV4 0x00008000
1160#define LmBROADRV3 0x00004000
1161#define LmBROADRV2 0x00002000
1162#define LmBROADRV1 0x00001000
1163#define LmBROADSES 0x00000800
1164#define LmBROADRVCH1 0x00000400
1165#define LmBROADRVCH0 0x00000200
1166#define LmBROADCH 0x00000100
1167#define LmAIPRVWP 0x00000080
1168#define LmAIPWP 0x00000040
1169#define LmAIPWD 0x00000020
1170#define LmAIPWC 0x00000010
1171#define LmAIPRV2 0x00000008
1172#define LmAIPRV1 0x00000004
1173#define LmAIPRV0 0x00000002
1174#define LmAIPNRML 0x00000001
1175
1176#define LmBROADCAST_MASK (LmBROADCH | LmBROADRVCH0 | \
1177 LmBROADRVCH1)
1178
1179#define LmPRMSTAT1(LinkNum) LmSEQ_PHY_REG(0, LinkNum, 0x84)
1180#define LmPRMSTAT1BYTE0 0x84
1181#define LmPRMSTAT1BYTE1 0x85
1182#define LmPRMSTAT1BYTE2 0x86
1183#define LmPRMSTAT1BYTE3 0x87
1184
1185#define LmFRMRCVDSTAT 0x80000000
1186#define LmBREAK_DET 0x04000000
1187#define LmCLOSE_DET 0x02000000
1188#define LmDONE_DET 0x01000000
1189#define LmXRDY 0x00040000
1190#define LmSYNCSRST 0x00020000
1191#define LmSYNC 0x00010000
1192#define LmXHOLD 0x00008000
1193#define LmRRDY 0x00004000
1194#define LmHOLD 0x00002000
1195#define LmROK 0x00001000
1196#define LmRIP 0x00000800
1197#define LmCRBLK 0x00000400
1198#define LmACK 0x00000200
1199#define LmNAK 0x00000100
1200#define LmHARDRST 0x00000080
1201#define LmERROR 0x00000040
1202#define LmRERR 0x00000020
1203#define LmPMREQP 0x00000010
1204#define LmPMREQS 0x00000008
1205#define LmPMACK 0x00000004
1206#define LmPMNAK 0x00000002
1207#define LmDMAT 0x00000001
1208
1209/* mode 1 */
1210#define LmMnSATAFS(LinkNum, Mode) LmSEQ_PHY_REG(Mode, LinkNum, 0x7E)
1211#define LmMnXMTSIZE(LinkNum, Mode) LmSEQ_PHY_REG(Mode, LinkNum, 0x93)
1212
1213/* mode 0 */
1214#define LmMnFRMERR(LinkNum, Mode) LmSEQ_PHY_REG(Mode, LinkNum, 0xB0)
1215
1216#define LmACRCERR 0x00000800
1217#define LmPHYOVRN 0x00000400
1218#define LmOBOVRN 0x00000200
1219#define LmMnZERODATA 0x00000100
1220#define LmSATAINTLK 0x00000080
1221#define LmMnCRCERR 0x00000020
1222#define LmRRDYOVRN 0x00000010
1223#define LmMISSSOAF 0x00000008
1224#define LmMISSSOF 0x00000004
1225#define LmMISSEOAF 0x00000002
1226#define LmMISSEOF 0x00000001
1227
1228#define LmFRMERREN(LinkNum) LmSEQ_PHY_REG(0, LinkNum, 0xB4)
1229
1230#define EN_LmACRCERR 0x00000800
1231#define EN_LmPHYOVRN 0x00000400
1232#define EN_LmOBOVRN 0x00000200
1233#define EN_LmMnZERODATA 0x00000100
1234#define EN_LmSATAINTLK 0x00000080
1235#define EN_LmFRMBAD 0x00000040
1236#define EN_LmMnCRCERR 0x00000020
1237#define EN_LmRRDYOVRN 0x00000010
1238#define EN_LmMISSSOAF 0x00000008
1239#define EN_LmMISSSOF 0x00000004
1240#define EN_LmMISSEOAF 0x00000002
1241#define EN_LmMISSEOF 0x00000001
1242
1243#define LmFRMERREN_MASK (EN_LmSATAINTLK | EN_LmMnCRCERR | \
1244 EN_LmRRDYOVRN | EN_LmMISSSOF | \
1245 EN_LmMISSEOAF | EN_LmMISSEOF | \
1246 EN_LmACRCERR | LmPHYOVRN | \
1247 EN_LmOBOVRN | EN_LmMnZERODATA)
1248
1249#define LmHWTSTATEN(LinkNum) LmSEQ_PHY_REG(0, LinkNum, 0xC5)
1250
1251#define EN_LmDONETO 0x80
1252#define EN_LmINVDISP 0x40
1253#define EN_LmINVDW 0x20
1254#define EN_LmDWSEVENT 0x08
1255#define EN_LmCRTTTO 0x04
1256#define EN_LmANTTTO 0x02
1257#define EN_LmBITLTTO 0x01
1258
1259#define LmHWTSTATEN_MASK (EN_LmINVDISP | EN_LmINVDW | \
1260 EN_LmDWSEVENT | EN_LmCRTTTO | \
1261 EN_LmANTTTO | EN_LmDONETO | \
1262 EN_LmBITLTTO)
1263
1264#define LmHWTSTAT(LinkNum) LmSEQ_PHY_REG(0, LinkNum, 0xC7)
1265
1266#define LmDONETO 0x80
1267#define LmINVDISP 0x40
1268#define LmINVDW 0x20
1269#define LmDWSEVENT 0x08
1270#define LmCRTTTO 0x04
1271#define LmANTTTO 0x02
1272#define LmBITLTTO 0x01
1273
1274#define LmMnDATABUFADR(LinkNum, Mode) LmSEQ_PHY_REG(Mode, LinkNum, 0xC8)
1275#define LmDATABUFADR_MASK 0x0FFF
1276
1277#define LmMnDATABUF(LinkNum, Mode) LmSEQ_PHY_REG(Mode, LinkNum, 0xCA)
1278
1279#define LmPRIMSTAT0EN(LinkNum) LmSEQ_PHY_REG(0, LinkNum, 0xE0)
1280
1281#define EN_LmUNKNOWNP 0x20000000
1282#define EN_LmBREAK 0x10000000
1283#define EN_LmDONE 0x08000000
1284#define EN_LmOPENACPT 0x04000000
1285#define EN_LmOPENRJCT 0x02000000
1286#define EN_LmOPENRTRY 0x01000000
1287#define EN_LmCLOSERV1 0x00800000
1288#define EN_LmCLOSERV0 0x00400000
1289#define EN_LmCLOSENORM 0x00200000
1290#define EN_LmCLOSECLAF 0x00100000
1291#define EN_LmNOTIFYRV2 0x00080000
1292#define EN_LmNOTIFYRV1 0x00040000
1293#define EN_LmNOTIFYRV0 0x00020000
1294#define EN_LmNOTIFYSPIN 0x00010000
1295#define EN_LmBROADRV4 0x00008000
1296#define EN_LmBROADRV3 0x00004000
1297#define EN_LmBROADRV2 0x00002000
1298#define EN_LmBROADRV1 0x00001000
1299#define EN_LmBROADRV0 0x00000800
1300#define EN_LmBROADRVCH1 0x00000400
1301#define EN_LmBROADRVCH0 0x00000200
1302#define EN_LmBROADCH 0x00000100
1303#define EN_LmAIPRVWP 0x00000080
1304#define EN_LmAIPWP 0x00000040
1305#define EN_LmAIPWD 0x00000020
1306#define EN_LmAIPWC 0x00000010
1307#define EN_LmAIPRV2 0x00000008
1308#define EN_LmAIPRV1 0x00000004
1309#define EN_LmAIPRV0 0x00000002
1310#define EN_LmAIPNRML 0x00000001
1311
1312#define LmPRIMSTAT0EN_MASK (EN_LmBREAK | \
1313 EN_LmDONE | EN_LmOPENACPT | \
1314 EN_LmOPENRJCT | EN_LmOPENRTRY | \
1315 EN_LmCLOSERV1 | EN_LmCLOSERV0 | \
1316 EN_LmCLOSENORM | EN_LmCLOSECLAF | \
1317 EN_LmBROADRV4 | EN_LmBROADRV3 | \
1318 EN_LmBROADRV2 | EN_LmBROADRV1 | \
1319 EN_LmBROADRV0 | EN_LmBROADRVCH1 | \
1320 EN_LmBROADRVCH0 | EN_LmBROADCH | \
1321 EN_LmAIPRVWP | EN_LmAIPWP | \
1322 EN_LmAIPWD | EN_LmAIPWC | \
1323 EN_LmAIPRV2 | EN_LmAIPRV1 | \
1324 EN_LmAIPRV0 | EN_LmAIPNRML)
1325
1326#define LmPRIMSTAT1EN(LinkNum) LmSEQ_PHY_REG(0, LinkNum, 0xE4)
1327
1328#define EN_LmXRDY 0x00040000
1329#define EN_LmSYNCSRST 0x00020000
1330#define EN_LmSYNC 0x00010000
1331#define EN_LmXHOLD 0x00008000
1332#define EN_LmRRDY 0x00004000
1333#define EN_LmHOLD 0x00002000
1334#define EN_LmROK 0x00001000
1335#define EN_LmRIP 0x00000800
1336#define EN_LmCRBLK 0x00000400
1337#define EN_LmACK 0x00000200
1338#define EN_LmNAK 0x00000100
1339#define EN_LmHARDRST 0x00000080
1340#define EN_LmERROR 0x00000040
1341#define EN_LmRERR 0x00000020
1342#define EN_LmPMREQP 0x00000010
1343#define EN_LmPMREQS 0x00000008
1344#define EN_LmPMACK 0x00000004
1345#define EN_LmPMNAK 0x00000002
1346#define EN_LmDMAT 0x00000001
1347
1348#define LmPRIMSTAT1EN_MASK (EN_LmHARDRST | \
1349 EN_LmSYNCSRST | \
1350 EN_LmPMREQP | EN_LmPMREQS | \
1351 EN_LmPMACK | EN_LmPMNAK)
1352
1353#define LmSMSTATE(LinkNum) LmSEQ_PHY_REG(0, LinkNum, 0xE8)
1354
1355#define LmSMSTATEBRK(LinkNum) LmSEQ_PHY_REG(0, LinkNum, 0xEC)
1356
1357#define LmSMDBGCTL(LinkNum) LmSEQ_PHY_REG(0, LinkNum, 0xF0)
1358
1359
1360/*
1361 * LmSEQ CIO Bus Mode 3 Register.
1362 * Mode 3: Configuration and Setup, IOP Context SCB.
1363 */
1364#define LmM3SATATIMER(LinkNum) LmSEQ_PHY_REG(3, LinkNum, 0x48)
1365
1366#define LmM3INTVEC0(LinkNum) LmSEQ_PHY_REG(3, LinkNum, 0x90)
1367
1368#define LmM3INTVEC1(LinkNum) LmSEQ_PHY_REG(3, LinkNum, 0x92)
1369
1370#define LmM3INTVEC2(LinkNum) LmSEQ_PHY_REG(3, LinkNum, 0x94)
1371
1372#define LmM3INTVEC3(LinkNum) LmSEQ_PHY_REG(3, LinkNum, 0x96)
1373
1374#define LmM3INTVEC4(LinkNum) LmSEQ_PHY_REG(3, LinkNum, 0x98)
1375
1376#define LmM3INTVEC5(LinkNum) LmSEQ_PHY_REG(3, LinkNum, 0x9A)
1377
1378#define LmM3INTVEC6(LinkNum) LmSEQ_PHY_REG(3, LinkNum, 0x9C)
1379
1380#define LmM3INTVEC7(LinkNum) LmSEQ_PHY_REG(3, LinkNum, 0x9E)
1381
1382#define LmM3INTVEC8(LinkNum) LmSEQ_PHY_REG(3, LinkNum, 0xA4)
1383
1384#define LmM3INTVEC9(LinkNum) LmSEQ_PHY_REG(3, LinkNum, 0xA6)
1385
1386#define LmM3INTVEC10(LinkNum) LmSEQ_PHY_REG(3, LinkNum, 0xB0)
1387
1388#define LmM3FRMGAP(LinkNum) LmSEQ_PHY_REG(3, LinkNum, 0xB4)
1389
1390#define LmBITL_TIMER(LinkNum) LmSEQ_PHY_REG(0, LinkNum, 0xA2)
1391
1392#define LmWWN(LinkNum) LmSEQ_PHY_REG(0, LinkNum, 0xA8)
1393
1394
1395/*
1396 * LmSEQ CIO Bus Mode 5 Registers.
1397 * Mode 5: Phy/OOB Control and Status.
1398 */
1399#define LmSEQ_OOB_REG(phy_id, reg) LmSEQ_PHY_REG(5, (phy_id), (reg))
1400
1401#define OOB_BFLTR 0x100
1402
1403#define BFLTR_THR_MASK 0xF0
1404#define BFLTR_TC_MASK 0x0F
1405
1406#define OOB_INIT_MIN 0x102
1407
1408#define OOB_INIT_MAX 0x104
1409
1410#define OOB_INIT_NEG 0x106
1411
1412#define OOB_SAS_MIN 0x108
1413
1414#define OOB_SAS_MAX 0x10A
1415
1416#define OOB_SAS_NEG 0x10C
1417
1418#define OOB_WAKE_MIN 0x10E
1419
1420#define OOB_WAKE_MAX 0x110
1421
1422#define OOB_WAKE_NEG 0x112
1423
1424#define OOB_IDLE_MAX 0x114
1425
1426#define OOB_BURST_MAX 0x116
1427
1428#define OOB_DATA_KBITS 0x126
1429
1430#define OOB_ALIGN_0_DATA 0x12C
1431
1432#define OOB_ALIGN_1_DATA 0x130
1433
1434#define D10_2_DATA_k 0x00
1435#define SYNC_DATA_k 0x02
1436#define ALIGN_1_DATA_k 0x04
1437#define ALIGN_0_DATA_k 0x08
1438#define BURST_DATA_k 0x10
1439
1440#define OOB_PHY_RESET_COUNT 0x13C
1441
1442#define OOB_SIG_GEN 0x140
1443
1444#define START_OOB 0x80
1445#define START_DWS 0x40
1446#define ALIGN_CNT3 0x30
1447#define ALIGN_CNT2 0x20
1448#define ALIGN_CNT1 0x10
1449#define ALIGN_CNT4 0x00
1450#define STOP_DWS 0x08
1451#define SEND_COMSAS 0x04
1452#define SEND_COMINIT 0x02
1453#define SEND_COMWAKE 0x01
1454
1455#define OOB_XMIT 0x141
1456
1457#define TX_ENABLE 0x80
1458#define XMIT_OOB_BURST 0x10
1459#define XMIT_D10_2 0x08
1460#define XMIT_SYNC 0x04
1461#define XMIT_ALIGN_1 0x02
1462#define XMIT_ALIGN_0 0x01
1463
1464#define FUNCTION_MASK 0x142
1465
1466#define SAS_MODE_DIS 0x80
1467#define SATA_MODE_DIS 0x40
1468#define SPINUP_HOLD_DIS 0x20
1469#define HOT_PLUG_DIS 0x10
1470#define SATA_PS_DIS 0x08
1471#define FUNCTION_MASK_DEFAULT (SPINUP_HOLD_DIS | SATA_PS_DIS)
1472
1473#define OOB_MODE 0x143
1474
1475#define SAS_MODE 0x80
1476#define SATA_MODE 0x40
1477#define SLOW_CLK 0x20
1478#define FORCE_XMIT_15 0x08
1479#define PHY_SPEED_60 0x04
1480#define PHY_SPEED_30 0x02
1481#define PHY_SPEED_15 0x01
1482
1483#define CURRENT_STATUS 0x144
1484
1485#define CURRENT_OOB_DONE 0x80
1486#define CURRENT_LOSS_OF_SIGNAL 0x40
1487#define CURRENT_SPINUP_HOLD 0x20
1488#define CURRENT_HOT_PLUG_CNCT 0x10
1489#define CURRENT_GTO_TIMEOUT 0x08
1490#define CURRENT_OOB_TIMEOUT 0x04
1491#define CURRENT_DEVICE_PRESENT 0x02
1492#define CURRENT_OOB_ERROR 0x01
1493
1494#define CURRENT_OOB1_ERROR (CURRENT_HOT_PLUG_CNCT | \
1495 CURRENT_GTO_TIMEOUT)
1496
1497#define CURRENT_OOB2_ERROR (CURRENT_HOT_PLUG_CNCT | \
1498 CURRENT_OOB_ERROR)
1499
1500#define DEVICE_ADDED_W_CNT (CURRENT_OOB_DONE | \
1501 CURRENT_HOT_PLUG_CNCT | \
1502 CURRENT_DEVICE_PRESENT)
1503
1504#define DEVICE_ADDED_WO_CNT (CURRENT_OOB_DONE | \
1505 CURRENT_DEVICE_PRESENT)
1506
1507#define DEVICE_REMOVED CURRENT_LOSS_OF_SIGNAL
1508
1509#define CURRENT_PHY_MASK (CURRENT_OOB_DONE | \
1510 CURRENT_LOSS_OF_SIGNAL | \
1511 CURRENT_SPINUP_HOLD | \
1512 CURRENT_HOT_PLUG_CNCT | \
1513 CURRENT_GTO_TIMEOUT | \
1514 CURRENT_DEVICE_PRESENT | \
1515 CURRENT_OOB_ERROR )
1516
1517#define CURRENT_ERR_MASK (CURRENT_LOSS_OF_SIGNAL | \
1518 CURRENT_GTO_TIMEOUT | \
1519 CURRENT_OOB_TIMEOUT | \
1520 CURRENT_OOB_ERROR )
1521
1522#define SPEED_MASK 0x145
1523
1524#define SATA_SPEED_30_DIS 0x10
1525#define SATA_SPEED_15_DIS 0x08
1526#define SAS_SPEED_60_DIS 0x04
1527#define SAS_SPEED_30_DIS 0x02
1528#define SAS_SPEED_15_DIS 0x01
1529#define SAS_SPEED_MASK_DEFAULT 0x00
1530
1531#define OOB_TIMER_ENABLE 0x14D
1532
1533#define HOT_PLUG_EN 0x80
1534#define RCD_EN 0x40
1535#define COMTIMER_EN 0x20
1536#define SNTT_EN 0x10
1537#define SNLT_EN 0x04
1538#define SNWT_EN 0x02
1539#define ALIGN_EN 0x01
1540
1541#define OOB_STATUS 0x14E
1542
1543#define OOB_DONE 0x80
1544#define LOSS_OF_SIGNAL 0x40 /* ro */
1545#define SPINUP_HOLD 0x20
1546#define HOT_PLUG_CNCT 0x10 /* ro */
1547#define GTO_TIMEOUT 0x08 /* ro */
1548#define OOB_TIMEOUT 0x04 /* ro */
1549#define DEVICE_PRESENT 0x02 /* ro */
1550#define OOB_ERROR 0x01 /* ro */
1551
1552#define OOB_STATUS_ERROR_MASK (LOSS_OF_SIGNAL | GTO_TIMEOUT | \
1553 OOB_TIMEOUT | OOB_ERROR)
1554
1555#define OOB_STATUS_CLEAR 0x14F
1556
1557#define OOB_DONE_CLR 0x80
1558#define LOSS_OF_SIGNAL_CLR 0x40
1559#define SPINUP_HOLD_CLR 0x20
1560#define HOT_PLUG_CNCT_CLR 0x10
1561#define GTO_TIMEOUT_CLR 0x08
1562#define OOB_TIMEOUT_CLR 0x04
1563#define OOB_ERROR_CLR 0x01
1564
1565#define HOT_PLUG_DELAY 0x150
1566/* In 5 ms units. 20 = 100 ms. */
1567#define HOTPLUG_DELAY_TIMEOUT 20
1568
1569
1570#define INT_ENABLE_2 0x15A
1571
1572#define OOB_DONE_EN 0x80
1573#define LOSS_OF_SIGNAL_EN 0x40
1574#define SPINUP_HOLD_EN 0x20
1575#define HOT_PLUG_CNCT_EN 0x10
1576#define GTO_TIMEOUT_EN 0x08
1577#define OOB_TIMEOUT_EN 0x04
1578#define DEVICE_PRESENT_EN 0x02
1579#define OOB_ERROR_EN 0x01
1580
1581#define PHY_CONTROL_0 0x160
1582
1583#define PHY_LOWPWREN_TX 0x80
1584#define PHY_LOWPWREN_RX 0x40
1585#define SPARE_REG_160_B5 0x20
1586#define OFFSET_CANCEL_RX 0x10
1587
1588/* bits 3:2 */
1589#define PHY_RXCOMCENTER_60V 0x00
1590#define PHY_RXCOMCENTER_70V 0x04
1591#define PHY_RXCOMCENTER_80V 0x08
1592#define PHY_RXCOMCENTER_90V 0x0C
1593#define PHY_RXCOMCENTER_MASK 0x0C
1594
1595#define PHY_RESET 0x02
1596#define SAS_DEFAULT_SEL 0x01
1597
1598#define PHY_CONTROL_1 0x161
1599
1600/* bits 2:0 */
1601#define SATA_PHY_DETLEVEL_50mv 0x00
1602#define SATA_PHY_DETLEVEL_75mv 0x01
1603#define SATA_PHY_DETLEVEL_100mv 0x02
1604#define SATA_PHY_DETLEVEL_125mv 0x03
1605#define SATA_PHY_DETLEVEL_150mv 0x04
1606#define SATA_PHY_DETLEVEL_175mv 0x05
1607#define SATA_PHY_DETLEVEL_200mv 0x06
1608#define SATA_PHY_DETLEVEL_225mv 0x07
1609#define SATA_PHY_DETLEVEL_MASK 0x07
1610
1611/* bits 5:3 */
1612#define SAS_PHY_DETLEVEL_50mv 0x00
1613#define SAS_PHY_DETLEVEL_75mv 0x08
1614#define SAS_PHY_DETLEVEL_100mv 0x10
1615#define SAS_PHY_DETLEVEL_125mv 0x11
1616#define SAS_PHY_DETLEVEL_150mv 0x20
1617#define SAS_PHY_DETLEVEL_175mv 0x21
1618#define SAS_PHY_DETLEVEL_200mv 0x30
1619#define SAS_PHY_DETLEVEL_225mv 0x31
1620#define SAS_PHY_DETLEVEL_MASK 0x38
1621
1622#define PHY_CONTROL_2 0x162
1623
1624/* bits 7:5 */
1625#define SATA_PHY_DRV_400mv 0x00
1626#define SATA_PHY_DRV_450mv 0x20
1627#define SATA_PHY_DRV_500mv 0x40
1628#define SATA_PHY_DRV_550mv 0x60
1629#define SATA_PHY_DRV_600mv 0x80
1630#define SATA_PHY_DRV_650mv 0xA0
1631#define SATA_PHY_DRV_725mv 0xC0
1632#define SATA_PHY_DRV_800mv 0xE0
1633#define SATA_PHY_DRV_MASK 0xE0
1634
1635/* bits 4:3 */
1636#define SATA_PREEMP_0 0x00
1637#define SATA_PREEMP_1 0x08
1638#define SATA_PREEMP_2 0x10
1639#define SATA_PREEMP_3 0x18
1640#define SATA_PREEMP_MASK 0x18
1641
1642#define SATA_CMSH1P5 0x04
1643
1644/* bits 1:0 */
1645#define SATA_SLEW_0 0x00
1646#define SATA_SLEW_1 0x01
1647#define SATA_SLEW_2 0x02
1648#define SATA_SLEW_3 0x03
1649#define SATA_SLEW_MASK 0x03
1650
1651#define PHY_CONTROL_3 0x163
1652
1653/* bits 7:5 */
1654#define SAS_PHY_DRV_400mv 0x00
1655#define SAS_PHY_DRV_450mv 0x20
1656#define SAS_PHY_DRV_500mv 0x40
1657#define SAS_PHY_DRV_550mv 0x60
1658#define SAS_PHY_DRV_600mv 0x80
1659#define SAS_PHY_DRV_650mv 0xA0
1660#define SAS_PHY_DRV_725mv 0xC0
1661#define SAS_PHY_DRV_800mv 0xE0
1662#define SAS_PHY_DRV_MASK 0xE0
1663
1664/* bits 4:3 */
1665#define SAS_PREEMP_0 0x00
1666#define SAS_PREEMP_1 0x08
1667#define SAS_PREEMP_2 0x10
1668#define SAS_PREEMP_3 0x18
1669#define SAS_PREEMP_MASK 0x18
1670
1671#define SAS_CMSH1P5 0x04
1672
1673/* bits 1:0 */
1674#define SAS_SLEW_0 0x00
1675#define SAS_SLEW_1 0x01
1676#define SAS_SLEW_2 0x02
1677#define SAS_SLEW_3 0x03
1678#define SAS_SLEW_MASK 0x03
1679
1680#define PHY_CONTROL_4 0x168
1681
1682#define PHY_DONE_CAL_TX 0x80
1683#define PHY_DONE_CAL_RX 0x40
1684#define RX_TERM_LOAD_DIS 0x20
1685#define TX_TERM_LOAD_DIS 0x10
1686#define AUTO_TERM_CAL_DIS 0x08
1687#define PHY_SIGDET_FLTR_EN 0x04
1688#define OSC_FREQ 0x02
1689#define PHY_START_CAL 0x01
1690
1691/*
1692 * HST_PCIX2 Registers, Addresss Range: (0x00-0xFC)
1693 */
1694#define PCIX_REG_BASE_ADR 0xB8040000
1695
1696#define PCIC_VENDOR_ID 0x00
1697
1698#define PCIC_DEVICE_ID 0x02
1699
1700#define PCIC_COMMAND 0x04
1701
1702#define INT_DIS 0x0400
1703#define FBB_EN 0x0200 /* ro */
1704#define SERR_EN 0x0100
1705#define STEP_EN 0x0080 /* ro */
1706#define PERR_EN 0x0040
1707#define VGA_EN 0x0020 /* ro */
1708#define MWI_EN 0x0010
1709#define SPC_EN 0x0008
1710#define MST_EN 0x0004
1711#define MEM_EN 0x0002
1712#define IO_EN 0x0001
1713
1714#define PCIC_STATUS 0x06
1715
1716#define PERR_DET 0x8000
1717#define SERR_GEN 0x4000
1718#define MABT_DET 0x2000
1719#define TABT_DET 0x1000
1720#define TABT_GEN 0x0800
1721#define DPERR_DET 0x0100
1722#define CAP_LIST 0x0010
1723#define INT_STAT 0x0008
1724
1725#define PCIC_DEVREV_ID 0x08
1726
1727#define PCIC_CLASS_CODE 0x09
1728
1729#define PCIC_CACHELINE_SIZE 0x0C
1730
1731#define PCIC_MBAR0 0x10
1732
1733#define PCIC_MBAR0_OFFSET 0
1734
1735#define PCIC_MBAR1 0x18
1736
1737#define PCIC_MBAR1_OFFSET 2
1738
1739#define PCIC_IOBAR 0x20
1740
1741#define PCIC_IOBAR_OFFSET 4
1742
1743#define PCIC_SUBVENDOR_ID 0x2C
1744
1745#define PCIC_SUBSYTEM_ID 0x2E
1746
1747#define PCIX_STATUS 0x44
1748#define RCV_SCE 0x20000000
1749#define UNEXP_SC 0x00080000
1750#define SC_DISCARD 0x00040000
1751
1752#define ECC_CTRL_STAT 0x48
1753#define UNCOR_ECCERR 0x00000008
1754
1755#define PCIC_PM_CSR 0x5C
1756
1757#define PWR_STATE_D0 0
1758#define PWR_STATE_D1 1 /* not supported */
1759#define PWR_STATE_D2 2 /* not supported */
1760#define PWR_STATE_D3 3
1761
1762#define PCIC_BASE1 0x6C /* internal use only */
1763
1764#define BASE1_RSVD 0xFFFFFFF8
1765
1766#define PCIC_BASEA 0x70 /* internal use only */
1767
1768#define BASEA_RSVD 0xFFFFFFC0
1769#define BASEA_START 0
1770
1771#define PCIC_BASEB 0x74 /* internal use only */
1772
1773#define BASEB_RSVD 0xFFFFFF80
1774#define BASEB_IOMAP_MASK 0x7F
1775#define BASEB_START 0x80
1776
1777#define PCIC_BASEC 0x78 /* internal use only */
1778
1779#define BASEC_RSVD 0xFFFFFFFC
1780#define BASEC_MASK 0x03
1781#define BASEC_START 0x58
1782
1783#define PCIC_MBAR_KEY 0x7C /* internal use only */
1784
1785#define MBAR_KEY_MASK 0xFFFFFFFF
1786
1787#define PCIC_HSTPCIX_CNTRL 0xA0
1788
1789#define REWIND_DIS 0x0800
1790#define SC_TMR_DIS 0x04000000
1791
1792#define PCIC_MBAR0_MASK 0xA8
1793#define PCIC_MBAR0_SIZE_MASK 0x1FFFE000
1794#define PCIC_MBAR0_SIZE_SHIFT 13
1795#define PCIC_MBAR0_SIZE(val) \
1796 (((val) & PCIC_MBAR0_SIZE_MASK) >> PCIC_MBAR0_SIZE_SHIFT)
1797
1798#define PCIC_FLASH_MBAR 0xB8
1799
1800#define PCIC_INTRPT_STAT 0xD4
1801
1802#define PCIC_TP_CTRL 0xFC
1803
1804/*
1805 * EXSI Registers, Addresss Range: (0x00-0xFC)
1806 */
1807#define EXSI_REG_BASE_ADR REG_BASE_ADDR_EXSI
1808
1809#define EXSICNFGR (EXSI_REG_BASE_ADR + 0x00)
1810
1811#define OCMINITIALIZED 0x80000000
1812#define ASIEN 0x00400000
1813#define HCMODE 0x00200000
1814#define PCIDEF 0x00100000
1815#define COMSTOCK 0x00080000
1816#define SEEPROMEND 0x00040000
1817#define MSTTIMEN 0x00020000
1818#define XREGEX 0x00000200
1819#define NVRAMW 0x00000100
1820#define NVRAMEX 0x00000080
1821#define SRAMW 0x00000040
1822#define SRAMEX 0x00000020
1823#define FLASHW 0x00000010
1824#define FLASHEX 0x00000008
1825#define SEEPROMCFG 0x00000004
1826#define SEEPROMTYP 0x00000002
1827#define SEEPROMEX 0x00000001
1828
1829
1830#define EXSICNTRLR (EXSI_REG_BASE_ADR + 0x04)
1831
1832#define MODINT_EN 0x00000001
1833
1834
1835#define PMSTATR (EXSI_REG_BASE_ADR + 0x10)
1836
1837#define FLASHRST 0x00000002
1838#define FLASHRDY 0x00000001
1839
1840
1841#define FLCNFGR (EXSI_REG_BASE_ADR + 0x14)
1842
1843#define FLWEH_MASK 0x30000000
1844#define FLWESU_MASK 0x0C000000
1845#define FLWEPW_MASK 0x03F00000
1846#define FLOEH_MASK 0x000C0000
1847#define FLOESU_MASK 0x00030000
1848#define FLOEPW_MASK 0x0000FC00
1849#define FLCSH_MASK 0x00000300
1850#define FLCSSU_MASK 0x000000C0
1851#define FLCSPW_MASK 0x0000003F
1852
1853#define SRCNFGR (EXSI_REG_BASE_ADR + 0x18)
1854
1855#define SRWEH_MASK 0x30000000
1856#define SRWESU_MASK 0x0C000000
1857#define SRWEPW_MASK 0x03F00000
1858
1859#define SROEH_MASK 0x000C0000
1860#define SROESU_MASK 0x00030000
1861#define SROEPW_MASK 0x0000FC00
1862#define SRCSH_MASK 0x00000300
1863#define SRCSSU_MASK 0x000000C0
1864#define SRCSPW_MASK 0x0000003F
1865
1866#define NVCNFGR (EXSI_REG_BASE_ADR + 0x1C)
1867
1868#define NVWEH_MASK 0x30000000
1869#define NVWESU_MASK 0x0C000000
1870#define NVWEPW_MASK 0x03F00000
1871#define NVOEH_MASK 0x000C0000
1872#define NVOESU_MASK 0x00030000
1873#define NVOEPW_MASK 0x0000FC00
1874#define NVCSH_MASK 0x00000300
1875#define NVCSSU_MASK 0x000000C0
1876#define NVCSPW_MASK 0x0000003F
1877
1878#define XRCNFGR (EXSI_REG_BASE_ADR + 0x20)
1879
1880#define XRWEH_MASK 0x30000000
1881#define XRWESU_MASK 0x0C000000
1882#define XRWEPW_MASK 0x03F00000
1883#define XROEH_MASK 0x000C0000
1884#define XROESU_MASK 0x00030000
1885#define XROEPW_MASK 0x0000FC00
1886#define XRCSH_MASK 0x00000300
1887#define XRCSSU_MASK 0x000000C0
1888#define XRCSPW_MASK 0x0000003F
1889
1890#define XREGADDR (EXSI_REG_BASE_ADR + 0x24)
1891
1892#define XRADDRINCEN 0x80000000
1893#define XREGADD_MASK 0x007FFFFF
1894
1895
1896#define XREGDATAR (EXSI_REG_BASE_ADR + 0x28)
1897
1898#define XREGDATA_MASK 0x0000FFFF
1899
1900#define GPIOOER (EXSI_REG_BASE_ADR + 0x40)
1901
1902#define GPIOODENR (EXSI_REG_BASE_ADR + 0x44)
1903
1904#define GPIOINVR (EXSI_REG_BASE_ADR + 0x48)
1905
1906#define GPIODATAOR (EXSI_REG_BASE_ADR + 0x4C)
1907
1908#define GPIODATAIR (EXSI_REG_BASE_ADR + 0x50)
1909
1910#define GPIOCNFGR (EXSI_REG_BASE_ADR + 0x54)
1911
1912#define GPIO_EXTSRC 0x00000001
1913
1914#define SCNTRLR (EXSI_REG_BASE_ADR + 0xA0)
1915
1916#define SXFERDONE 0x00000100
1917#define SXFERCNT_MASK 0x000000E0
1918#define SCMDTYP_MASK 0x0000001C
1919#define SXFERSTART 0x00000002
1920#define SXFEREN 0x00000001
1921
1922#define SRATER (EXSI_REG_BASE_ADR + 0xA4)
1923
1924#define SADDRR (EXSI_REG_BASE_ADR + 0xA8)
1925
1926#define SADDR_MASK 0x0000FFFF
1927
1928#define SDATAOR (EXSI_REG_BASE_ADR + 0xAC)
1929
1930#define SDATAOR0 (EXSI_REG_BASE_ADR + 0xAC)
1931#define SDATAOR1 (EXSI_REG_BASE_ADR + 0xAD)
1932#define SDATAOR2 (EXSI_REG_BASE_ADR + 0xAE)
1933#define SDATAOR3 (EXSI_REG_BASE_ADR + 0xAF)
1934
1935#define SDATAIR (EXSI_REG_BASE_ADR + 0xB0)
1936
1937#define SDATAIR0 (EXSI_REG_BASE_ADR + 0xB0)
1938#define SDATAIR1 (EXSI_REG_BASE_ADR + 0xB1)
1939#define SDATAIR2 (EXSI_REG_BASE_ADR + 0xB2)
1940#define SDATAIR3 (EXSI_REG_BASE_ADR + 0xB3)
1941
1942#define ASISTAT0R (EXSI_REG_BASE_ADR + 0xD0)
1943#define ASIFMTERR 0x00000400
1944#define ASISEECHKERR 0x00000200
1945#define ASIERR 0x00000100
1946
1947#define ASISTAT1R (EXSI_REG_BASE_ADR + 0xD4)
1948#define CHECKSUM_MASK 0x0000FFFF
1949
1950#define ASIERRADDR (EXSI_REG_BASE_ADR + 0xD8)
1951#define ASIERRDATAR (EXSI_REG_BASE_ADR + 0xDC)
1952#define ASIERRSTATR (EXSI_REG_BASE_ADR + 0xE0)
1953#define CPI2ASIBYTECNT_MASK 0x00070000
1954#define CPI2ASIBYTEEN_MASK 0x0000F000
1955#define CPI2ASITARGERR_MASK 0x00000F00
1956#define CPI2ASITARGMID_MASK 0x000000F0
1957#define CPI2ASIMSTERR_MASK 0x0000000F
1958
1959/*
1960 * XSRAM, External SRAM (DWord and any BE pattern accessible)
1961 */
1962#define XSRAM_REG_BASE_ADDR 0xB8100000
1963#define XSRAM_SIZE 0x100000
1964
1965/*
1966 * NVRAM Registers, Address Range: (0x00000 - 0x3FFFF).
1967 */
1968#define NVRAM_REG_BASE_ADR 0xBF800000
1969#define NVRAM_MAX_BASE_ADR 0x003FFFFF
1970
1971/* OCM base address */
1972#define OCM_BASE_ADDR 0xA0000000
1973#define OCM_MAX_SIZE 0x20000
1974
1975/*
1976 * Sequencers (Central and Link) Scratch RAM page definitions.
1977 */
1978
1979/*
1980 * The Central Management Sequencer (CSEQ) Scratch Memory is a 1024
1981 * byte memory. It is dword accessible and has byte parity
1982 * protection. The CSEQ accesses it in 32 byte windows, either as mode
1983 * dependent or mode independent memory. Each mode has 96 bytes,
1984 * (three 32 byte pages 0-2, not contiguous), leaving 128 bytes of
1985 * Mode Independent memory (four 32 byte pages 3-7). Note that mode
1986 * dependent scratch memory, Mode 8, page 0-3 overlaps mode
1987 * independent scratch memory, pages 0-3.
1988 * - 896 bytes of mode dependent scratch, 96 bytes per Modes 0-7, and
1989 * 128 bytes in mode 8,
1990 * - 259 bytes of mode independent scratch, common to modes 0-15.
1991 *
1992 * Sequencer scratch RAM is 1024 bytes. This scratch memory is
1993 * divided into mode dependent and mode independent scratch with this
1994 * memory further subdivided into pages of size 32 bytes. There are 5
1995 * pages (160 bytes) of mode independent scratch and 3 pages of
1996 * dependent scratch memory for modes 0-7 (768 bytes). Mode 8 pages
1997 * 0-2 dependent scratch overlap with pages 0-2 of mode independent
1998 * scratch memory.
1999 *
2000 * The host accesses this scratch in a different manner from the
2001 * central sequencer. The sequencer has to use CSEQ registers CSCRPAGE
2002 * and CMnSCRPAGE to access the scratch memory. A flat mapping of the
2003 * scratch memory is avaliable for software convenience and to prevent
2004 * corruption while the sequencer is running. This memory is mapped
2005 * onto addresses 800h - BFFh, total of 400h bytes.
2006 *
2007 * These addresses are mapped as follows:
2008 *
2009 * 800h-83Fh Mode Dependent Scratch Mode 0 Pages 0-1
2010 * 840h-87Fh Mode Dependent Scratch Mode 1 Pages 0-1
2011 * 880h-8BFh Mode Dependent Scratch Mode 2 Pages 0-1
2012 * 8C0h-8FFh Mode Dependent Scratch Mode 3 Pages 0-1
2013 * 900h-93Fh Mode Dependent Scratch Mode 4 Pages 0-1
2014 * 940h-97Fh Mode Dependent Scratch Mode 5 Pages 0-1
2015 * 980h-9BFh Mode Dependent Scratch Mode 6 Pages 0-1
2016 * 9C0h-9FFh Mode Dependent Scratch Mode 7 Pages 0-1
2017 * A00h-A5Fh Mode Dependent Scratch Mode 8 Pages 0-2
2018 * Mode Independent Scratch Pages 0-2
2019 * A60h-A7Fh Mode Dependent Scratch Mode 8 Page 3
2020 * Mode Independent Scratch Page 3
2021 * A80h-AFFh Mode Independent Scratch Pages 4-7
2022 * B00h-B1Fh Mode Dependent Scratch Mode 0 Page 2
2023 * B20h-B3Fh Mode Dependent Scratch Mode 1 Page 2
2024 * B40h-B5Fh Mode Dependent Scratch Mode 2 Page 2
2025 * B60h-B7Fh Mode Dependent Scratch Mode 3 Page 2
2026 * B80h-B9Fh Mode Dependent Scratch Mode 4 Page 2
2027 * BA0h-BBFh Mode Dependent Scratch Mode 5 Page 2
2028 * BC0h-BDFh Mode Dependent Scratch Mode 6 Page 2
2029 * BE0h-BFFh Mode Dependent Scratch Mode 7 Page 2
2030 */
2031
2032/* General macros */
2033#define CSEQ_PAGE_SIZE 32 /* Scratch page size (in bytes) */
2034
2035/* All macros start with offsets from base + 0x800 (CMAPPEDSCR).
2036 * Mode dependent scratch page 0, mode 0.
2037 * For modes 1-7 you have to do arithmetic. */
2038#define CSEQ_LRM_SAVE_SINDEX (CMAPPEDSCR + 0x0000)
2039#define CSEQ_LRM_SAVE_SCBPTR (CMAPPEDSCR + 0x0002)
2040#define CSEQ_Q_LINK_HEAD (CMAPPEDSCR + 0x0004)
2041#define CSEQ_Q_LINK_TAIL (CMAPPEDSCR + 0x0006)
2042#define CSEQ_LRM_SAVE_SCRPAGE (CMAPPEDSCR + 0x0008)
2043
2044/* Mode dependent scratch page 0 mode 8 macros. */
2045#define CSEQ_RET_ADDR (CMAPPEDSCR + 0x0200)
2046#define CSEQ_RET_SCBPTR (CMAPPEDSCR + 0x0202)
2047#define CSEQ_SAVE_SCBPTR (CMAPPEDSCR + 0x0204)
2048#define CSEQ_EMPTY_TRANS_CTX (CMAPPEDSCR + 0x0206)
2049#define CSEQ_RESP_LEN (CMAPPEDSCR + 0x0208)
2050#define CSEQ_TMF_SCBPTR (CMAPPEDSCR + 0x020A)
2051#define CSEQ_GLOBAL_PREV_SCB (CMAPPEDSCR + 0x020C)
2052#define CSEQ_GLOBAL_HEAD (CMAPPEDSCR + 0x020E)
2053#define CSEQ_CLEAR_LU_HEAD (CMAPPEDSCR + 0x0210)
2054#define CSEQ_TMF_OPCODE (CMAPPEDSCR + 0x0212)
2055#define CSEQ_SCRATCH_FLAGS (CMAPPEDSCR + 0x0213)
2056#define CSEQ_HSB_SITE (CMAPPEDSCR + 0x021A)
2057#define CSEQ_FIRST_INV_SCB_SITE (CMAPPEDSCR + 0x021C)
2058#define CSEQ_FIRST_INV_DDB_SITE (CMAPPEDSCR + 0x021E)
2059
2060/* Mode dependent scratch page 1 mode 8 macros. */
2061#define CSEQ_LUN_TO_CLEAR (CMAPPEDSCR + 0x0220)
2062#define CSEQ_LUN_TO_CHECK (CMAPPEDSCR + 0x0228)
2063
2064/* Mode dependent scratch page 2 mode 8 macros */
2065#define CSEQ_HQ_NEW_POINTER (CMAPPEDSCR + 0x0240)
2066#define CSEQ_HQ_DONE_BASE (CMAPPEDSCR + 0x0248)
2067#define CSEQ_HQ_DONE_POINTER (CMAPPEDSCR + 0x0250)
2068#define CSEQ_HQ_DONE_PASS (CMAPPEDSCR + 0x0254)
2069
2070/* Mode independent scratch page 4 macros. */
2071#define CSEQ_Q_EXE_HEAD (CMAPPEDSCR + 0x0280)
2072#define CSEQ_Q_EXE_TAIL (CMAPPEDSCR + 0x0282)
2073#define CSEQ_Q_DONE_HEAD (CMAPPEDSCR + 0x0284)
2074#define CSEQ_Q_DONE_TAIL (CMAPPEDSCR + 0x0286)
2075#define CSEQ_Q_SEND_HEAD (CMAPPEDSCR + 0x0288)
2076#define CSEQ_Q_SEND_TAIL (CMAPPEDSCR + 0x028A)
2077#define CSEQ_Q_DMA2CHIM_HEAD (CMAPPEDSCR + 0x028C)
2078#define CSEQ_Q_DMA2CHIM_TAIL (CMAPPEDSCR + 0x028E)
2079#define CSEQ_Q_COPY_HEAD (CMAPPEDSCR + 0x0290)
2080#define CSEQ_Q_COPY_TAIL (CMAPPEDSCR + 0x0292)
2081#define CSEQ_REG0 (CMAPPEDSCR + 0x0294)
2082#define CSEQ_REG1 (CMAPPEDSCR + 0x0296)
2083#define CSEQ_REG2 (CMAPPEDSCR + 0x0298)
2084#define CSEQ_LINK_CTL_Q_MAP (CMAPPEDSCR + 0x029C)
2085#define CSEQ_MAX_CSEQ_MODE (CMAPPEDSCR + 0x029D)
2086#define CSEQ_FREE_LIST_HACK_COUNT (CMAPPEDSCR + 0x029E)
2087
2088/* Mode independent scratch page 5 macros. */
2089#define CSEQ_EST_NEXUS_REQ_QUEUE (CMAPPEDSCR + 0x02A0)
2090#define CSEQ_EST_NEXUS_REQ_COUNT (CMAPPEDSCR + 0x02A8)
2091#define CSEQ_Q_EST_NEXUS_HEAD (CMAPPEDSCR + 0x02B0)
2092#define CSEQ_Q_EST_NEXUS_TAIL (CMAPPEDSCR + 0x02B2)
2093#define CSEQ_NEED_EST_NEXUS_SCB (CMAPPEDSCR + 0x02B4)
2094#define CSEQ_EST_NEXUS_REQ_HEAD (CMAPPEDSCR + 0x02B6)
2095#define CSEQ_EST_NEXUS_REQ_TAIL (CMAPPEDSCR + 0x02B7)
2096#define CSEQ_EST_NEXUS_SCB_OFFSET (CMAPPEDSCR + 0x02B8)
2097
2098/* Mode independent scratch page 6 macros. */
2099#define CSEQ_INT_ROUT_RET_ADDR0 (CMAPPEDSCR + 0x02C0)
2100#define CSEQ_INT_ROUT_RET_ADDR1 (CMAPPEDSCR + 0x02C2)
2101#define CSEQ_INT_ROUT_SCBPTR (CMAPPEDSCR + 0x02C4)
2102#define CSEQ_INT_ROUT_MODE (CMAPPEDSCR + 0x02C6)
2103#define CSEQ_ISR_SCRATCH_FLAGS (CMAPPEDSCR + 0x02C7)
2104#define CSEQ_ISR_SAVE_SINDEX (CMAPPEDSCR + 0x02C8)
2105#define CSEQ_ISR_SAVE_DINDEX (CMAPPEDSCR + 0x02CA)
2106#define CSEQ_Q_MONIRTT_HEAD (CMAPPEDSCR + 0x02D0)
2107#define CSEQ_Q_MONIRTT_TAIL (CMAPPEDSCR + 0x02D2)
2108#define CSEQ_FREE_SCB_MASK (CMAPPEDSCR + 0x02D5)
2109#define CSEQ_BUILTIN_FREE_SCB_HEAD (CMAPPEDSCR + 0x02D6)
2110#define CSEQ_BUILTIN_FREE_SCB_TAIL (CMAPPEDSCR + 0x02D8)
2111#define CSEQ_EXTENDED_FREE_SCB_HEAD (CMAPPEDSCR + 0x02DA)
2112#define CSEQ_EXTENDED_FREE_SCB_TAIL (CMAPPEDSCR + 0x02DC)
2113
2114/* Mode independent scratch page 7 macros. */
2115#define CSEQ_EMPTY_REQ_QUEUE (CMAPPEDSCR + 0x02E0)
2116#define CSEQ_EMPTY_REQ_COUNT (CMAPPEDSCR + 0x02E8)
2117#define CSEQ_Q_EMPTY_HEAD (CMAPPEDSCR + 0x02F0)
2118#define CSEQ_Q_EMPTY_TAIL (CMAPPEDSCR + 0x02F2)
2119#define CSEQ_NEED_EMPTY_SCB (CMAPPEDSCR + 0x02F4)
2120#define CSEQ_EMPTY_REQ_HEAD (CMAPPEDSCR + 0x02F6)
2121#define CSEQ_EMPTY_REQ_TAIL (CMAPPEDSCR + 0x02F7)
2122#define CSEQ_EMPTY_SCB_OFFSET (CMAPPEDSCR + 0x02F8)
2123#define CSEQ_PRIMITIVE_DATA (CMAPPEDSCR + 0x02FA)
2124#define CSEQ_TIMEOUT_CONST (CMAPPEDSCR + 0x02FC)
2125
2126/***************************************************************************
2127* Link m Sequencer scratch RAM is 512 bytes.
2128* This scratch memory is divided into mode dependent and mode
2129* independent scratch with this memory further subdivided into
2130* pages of size 32 bytes. There are 4 pages (128 bytes) of
2131* mode independent scratch and 4 pages of dependent scratch
2132* memory for modes 0-2 (384 bytes).
2133*
2134* The host accesses this scratch in a different manner from the
2135* link sequencer. The sequencer has to use LSEQ registers
2136* LmSCRPAGE and LmMnSCRPAGE to access the scratch memory. A flat
2137* mapping of the scratch memory is avaliable for software
2138* convenience and to prevent corruption while the sequencer is
2139* running. This memory is mapped onto addresses 800h - 9FFh.
2140*
2141* These addresses are mapped as follows:
2142*
2143* 800h-85Fh Mode Dependent Scratch Mode 0 Pages 0-2
2144* 860h-87Fh Mode Dependent Scratch Mode 0 Page 3
2145* Mode Dependent Scratch Mode 5 Page 0
2146* 880h-8DFh Mode Dependent Scratch Mode 1 Pages 0-2
2147* 8E0h-8FFh Mode Dependent Scratch Mode 1 Page 3
2148* Mode Dependent Scratch Mode 5 Page 1
2149* 900h-95Fh Mode Dependent Scratch Mode 2 Pages 0-2
2150* 960h-97Fh Mode Dependent Scratch Mode 2 Page 3
2151* Mode Dependent Scratch Mode 5 Page 2
2152* 980h-9DFh Mode Independent Scratch Pages 0-3
2153* 9E0h-9FFh Mode Independent Scratch Page 3
2154* Mode Dependent Scratch Mode 5 Page 3
2155*
2156****************************************************************************/
2157/* General macros */
2158#define LSEQ_MODE_SCRATCH_SIZE 0x80 /* Size of scratch RAM per mode */
2159#define LSEQ_PAGE_SIZE 0x20 /* Scratch page size (in bytes) */
2160#define LSEQ_MODE5_PAGE0_OFFSET 0x60
2161
2162/* Common mode dependent scratch page 0 macros for modes 0,1,2, and 5 */
2163/* Indexed using LSEQ_MODE_SCRATCH_SIZE * mode, for modes 0,1,2. */
2164#define LmSEQ_RET_ADDR(LinkNum) (LmSCRATCH(LinkNum) + 0x0000)
2165#define LmSEQ_REG0_MODE(LinkNum) (LmSCRATCH(LinkNum) + 0x0002)
2166#define LmSEQ_MODE_FLAGS(LinkNum) (LmSCRATCH(LinkNum) + 0x0004)
2167
2168/* Mode flag macros (byte 0) */
2169#define SAS_SAVECTX_OCCURRED 0x80
2170#define SAS_OOBSVC_OCCURRED 0x40
2171#define SAS_OOB_DEVICE_PRESENT 0x20
2172#define SAS_CFGHDR_OCCURRED 0x10
2173#define SAS_RCV_INTS_ARE_DISABLED 0x08
2174#define SAS_OOB_HOT_PLUG_CNCT 0x04
2175#define SAS_AWAIT_OPEN_CONNECTION 0x02
2176#define SAS_CFGCMPLT_OCCURRED 0x01
2177
2178/* Mode flag macros (byte 1) */
2179#define SAS_RLSSCB_OCCURRED 0x80
2180#define SAS_FORCED_HEADER_MISS 0x40
2181
2182#define LmSEQ_RET_ADDR2(LinkNum) (LmSCRATCH(LinkNum) + 0x0006)
2183#define LmSEQ_RET_ADDR1(LinkNum) (LmSCRATCH(LinkNum) + 0x0008)
2184#define LmSEQ_OPCODE_TO_CSEQ(LinkNum) (LmSCRATCH(LinkNum) + 0x000B)
2185#define LmSEQ_DATA_TO_CSEQ(LinkNum) (LmSCRATCH(LinkNum) + 0x000C)
2186
2187/* Mode dependent scratch page 0 macros for mode 0 (non-common) */
2188/* Absolute offsets */
2189#define LmSEQ_FIRST_INV_DDB_SITE(LinkNum) (LmSCRATCH(LinkNum) + 0x000E)
2190#define LmSEQ_EMPTY_TRANS_CTX(LinkNum) (LmSCRATCH(LinkNum) + 0x0010)
2191#define LmSEQ_RESP_LEN(LinkNum) (LmSCRATCH(LinkNum) + 0x0012)
2192#define LmSEQ_FIRST_INV_SCB_SITE(LinkNum) (LmSCRATCH(LinkNum) + 0x0014)
2193#define LmSEQ_INTEN_SAVE(LinkNum) (LmSCRATCH(LinkNum) + 0x0016)
2194#define LmSEQ_LINK_RST_FRM_LEN(LinkNum) (LmSCRATCH(LinkNum) + 0x001A)
2195#define LmSEQ_LINK_RST_PROTOCOL(LinkNum) (LmSCRATCH(LinkNum) + 0x001B)
2196#define LmSEQ_RESP_STATUS(LinkNum) (LmSCRATCH(LinkNum) + 0x001C)
2197#define LmSEQ_LAST_LOADED_SGE(LinkNum) (LmSCRATCH(LinkNum) + 0x001D)
2198#define LmSEQ_SAVE_SCBPTR(LinkNum) (LmSCRATCH(LinkNum) + 0x001E)
2199
2200/* Mode dependent scratch page 0 macros for mode 1 (non-common) */
2201/* Absolute offsets */
2202#define LmSEQ_Q_XMIT_HEAD(LinkNum) (LmSCRATCH(LinkNum) + 0x008E)
2203#define LmSEQ_M1_EMPTY_TRANS_CTX(LinkNum) (LmSCRATCH(LinkNum) + 0x0090)
2204#define LmSEQ_INI_CONN_TAG(LinkNum) (LmSCRATCH(LinkNum) + 0x0092)
2205#define LmSEQ_FAILED_OPEN_STATUS(LinkNum) (LmSCRATCH(LinkNum) + 0x009A)
2206#define LmSEQ_XMIT_REQUEST_TYPE(LinkNum) (LmSCRATCH(LinkNum) + 0x009B)
2207#define LmSEQ_M1_RESP_STATUS(LinkNum) (LmSCRATCH(LinkNum) + 0x009C)
2208#define LmSEQ_M1_LAST_LOADED_SGE(LinkNum) (LmSCRATCH(LinkNum) + 0x009D)
2209#define LmSEQ_M1_SAVE_SCBPTR(LinkNum) (LmSCRATCH(LinkNum) + 0x009E)
2210
2211/* Mode dependent scratch page 0 macros for mode 2 (non-common) */
2212#define LmSEQ_PORT_COUNTER(LinkNum) (LmSCRATCH(LinkNum) + 0x010E)
2213#define LmSEQ_PM_TABLE_PTR(LinkNum) (LmSCRATCH(LinkNum) + 0x0110)
2214#define LmSEQ_SATA_INTERLOCK_TMR_SAVE(LinkNum) (LmSCRATCH(LinkNum) + 0x0112)
2215#define LmSEQ_IP_BITL(LinkNum) (LmSCRATCH(LinkNum) + 0x0114)
2216#define LmSEQ_COPY_SMP_CONN_TAG(LinkNum) (LmSCRATCH(LinkNum) + 0x0116)
2217#define LmSEQ_P0M2_OFFS1AH(LinkNum) (LmSCRATCH(LinkNum) + 0x011A)
2218
2219/* Mode dependent scratch page 0 macros for modes 4/5 (non-common) */
2220/* Absolute offsets */
2221#define LmSEQ_SAVED_OOB_STATUS(LinkNum) (LmSCRATCH(LinkNum) + 0x006E)
2222#define LmSEQ_SAVED_OOB_MODE(LinkNum) (LmSCRATCH(LinkNum) + 0x006F)
2223#define LmSEQ_Q_LINK_HEAD(LinkNum) (LmSCRATCH(LinkNum) + 0x0070)
2224#define LmSEQ_LINK_RST_ERR(LinkNum) (LmSCRATCH(LinkNum) + 0x0072)
2225#define LmSEQ_SAVED_OOB_SIGNALS(LinkNum) (LmSCRATCH(LinkNum) + 0x0073)
2226#define LmSEQ_SAS_RESET_MODE(LinkNum) (LmSCRATCH(LinkNum) + 0x0074)
2227#define LmSEQ_LINK_RESET_RETRY_COUNT(LinkNum) (LmSCRATCH(LinkNum) + 0x0075)
2228#define LmSEQ_NUM_LINK_RESET_RETRIES(LinkNum) (LmSCRATCH(LinkNum) + 0x0076)
2229#define LmSEQ_OOB_INT_ENABLES(LinkNum) (LmSCRATCH(LinkNum) + 0x007A)
2230#define LmSEQ_NOTIFY_TIMER_TIMEOUT(LinkNum) (LmSCRATCH(LinkNum) + 0x007C)
2231#define LmSEQ_NOTIFY_TIMER_DOWN_COUNT(LinkNum) (LmSCRATCH(LinkNum) + 0x007E)
2232
2233/* Mode dependent scratch page 1, mode 0 and mode 1 */
2234#define LmSEQ_SG_LIST_PTR_ADDR0(LinkNum) (LmSCRATCH(LinkNum) + 0x0020)
2235#define LmSEQ_SG_LIST_PTR_ADDR1(LinkNum) (LmSCRATCH(LinkNum) + 0x0030)
2236#define LmSEQ_M1_SG_LIST_PTR_ADDR0(LinkNum) (LmSCRATCH(LinkNum) + 0x00A0)
2237#define LmSEQ_M1_SG_LIST_PTR_ADDR1(LinkNum) (LmSCRATCH(LinkNum) + 0x00B0)
2238
2239/* Mode dependent scratch page 1 macros for mode 2 */
2240/* Absolute offsets */
2241#define LmSEQ_INVALID_DWORD_COUNT(LinkNum) (LmSCRATCH(LinkNum) + 0x0120)
2242#define LmSEQ_DISPARITY_ERROR_COUNT(LinkNum) (LmSCRATCH(LinkNum) + 0x0124)
2243#define LmSEQ_LOSS_OF_SYNC_COUNT(LinkNum) (LmSCRATCH(LinkNum) + 0x0128)
2244
2245/* Mode dependent scratch page 1 macros for mode 4/5 */
2246#define LmSEQ_FRAME_TYPE_MASK(LinkNum) (LmSCRATCH(LinkNum) + 0x00E0)
2247#define LmSEQ_HASHED_DEST_ADDR_MASK(LinkNum) (LmSCRATCH(LinkNum) + 0x00E1)
2248#define LmSEQ_HASHED_SRC_ADDR_MASK_PRINT(LinkNum) (LmSCRATCH(LinkNum) + 0x00E4)
2249#define LmSEQ_HASHED_SRC_ADDR_MASK(LinkNum) (LmSCRATCH(LinkNum) + 0x00E5)
2250#define LmSEQ_NUM_FILL_BYTES_MASK(LinkNum) (LmSCRATCH(LinkNum) + 0x00EB)
2251#define LmSEQ_TAG_MASK(LinkNum) (LmSCRATCH(LinkNum) + 0x00F0)
2252#define LmSEQ_TARGET_PORT_XFER_TAG(LinkNum) (LmSCRATCH(LinkNum) + 0x00F2)
2253#define LmSEQ_DATA_OFFSET(LinkNum) (LmSCRATCH(LinkNum) + 0x00F4)
2254
2255/* Mode dependent scratch page 2 macros for mode 0 */
2256/* Absolute offsets */
2257#define LmSEQ_SMP_RCV_TIMER_TERM_TS(LinkNum) (LmSCRATCH(LinkNum) + 0x0040)
2258#define LmSEQ_DEVICE_BITS(LinkNum) (LmSCRATCH(LinkNum) + 0x005B)
2259#define LmSEQ_SDB_DDB(LinkNum) (LmSCRATCH(LinkNum) + 0x005C)
2260#define LmSEQ_SDB_NUM_TAGS(LinkNum) (LmSCRATCH(LinkNum) + 0x005E)
2261#define LmSEQ_SDB_CURR_TAG(LinkNum) (LmSCRATCH(LinkNum) + 0x005F)
2262
2263/* Mode dependent scratch page 2 macros for mode 1 */
2264/* Absolute offsets */
2265/* byte 0 bits 1-0 are domain select. */
2266#define LmSEQ_TX_ID_ADDR_FRAME(LinkNum) (LmSCRATCH(LinkNum) + 0x00C0)
2267#define LmSEQ_OPEN_TIMER_TERM_TS(LinkNum) (LmSCRATCH(LinkNum) + 0x00C8)
2268#define LmSEQ_SRST_AS_TIMER_TERM_TS(LinkNum) (LmSCRATCH(LinkNum) + 0x00CC)
2269#define LmSEQ_LAST_LOADED_SG_EL(LinkNum) (LmSCRATCH(LinkNum) + 0x00D4)
2270
2271/* Mode dependent scratch page 2 macros for mode 2 */
2272/* Absolute offsets */
2273#define LmSEQ_STP_SHUTDOWN_TIMER_TERM_TS(LinkNum) (LmSCRATCH(LinkNum) + 0x0140)
2274#define LmSEQ_CLOSE_TIMER_TERM_TS(LinkNum) (LmSCRATCH(LinkNum) + 0x0144)
2275#define LmSEQ_BREAK_TIMER_TERM_TS(LinkNum) (LmSCRATCH(LinkNum) + 0x0148)
2276#define LmSEQ_DWS_RESET_TIMER_TERM_TS(LinkNum) (LmSCRATCH(LinkNum) + 0x014C)
2277#define LmSEQ_SATA_INTERLOCK_TIMER_TERM_TS(LinkNum) \
2278 (LmSCRATCH(LinkNum) + 0x0150)
2279#define LmSEQ_MCTL_TIMER_TERM_TS(LinkNum) (LmSCRATCH(LinkNum) + 0x0154)
2280
2281/* Mode dependent scratch page 2 macros for mode 5 */
2282#define LmSEQ_COMINIT_TIMER_TERM_TS(LinkNum) (LmSCRATCH(LinkNum) + 0x0160)
2283#define LmSEQ_RCV_ID_TIMER_TERM_TS(LinkNum) (LmSCRATCH(LinkNum) + 0x0164)
2284#define LmSEQ_RCV_FIS_TIMER_TERM_TS(LinkNum) (LmSCRATCH(LinkNum) + 0x0168)
2285#define LmSEQ_DEV_PRES_TIMER_TERM_TS(LinkNum) (LmSCRATCH(LinkNum) + 0x016C)
2286
2287/* Mode dependent scratch page 3 macros for modes 0 and 1 */
2288/* None defined */
2289
2290/* Mode dependent scratch page 3 macros for modes 2 and 5 */
2291/* None defined */
2292
2293/* Mode Independent Scratch page 0 macros. */
2294#define LmSEQ_Q_TGTXFR_HEAD(LinkNum) (LmSCRATCH(LinkNum) + 0x0180)
2295#define LmSEQ_Q_TGTXFR_TAIL(LinkNum) (LmSCRATCH(LinkNum) + 0x0182)
2296#define LmSEQ_LINK_NUMBER(LinkNum) (LmSCRATCH(LinkNum) + 0x0186)
2297#define LmSEQ_SCRATCH_FLAGS(LinkNum) (LmSCRATCH(LinkNum) + 0x0187)
2298/*
2299 * Currently only bit 0, SAS_DWSAQD, is used.
2300 */
2301#define SAS_DWSAQD 0x01 /*
2302 * DWSSTATUS: DWSAQD
2303 * bit las read in ISR.
2304 */
2305#define LmSEQ_CONNECTION_STATE(LinkNum) (LmSCRATCH(LinkNum) + 0x0188)
2306/* Connection states (byte 0) */
2307#define SAS_WE_OPENED_CS 0x01
2308#define SAS_DEVICE_OPENED_CS 0x02
2309#define SAS_WE_SENT_DONE_CS 0x04
2310#define SAS_DEVICE_SENT_DONE_CS 0x08
2311#define SAS_WE_SENT_CLOSE_CS 0x10
2312#define SAS_DEVICE_SENT_CLOSE_CS 0x20
2313#define SAS_WE_SENT_BREAK_CS 0x40
2314#define SAS_DEVICE_SENT_BREAK_CS 0x80
2315/* Connection states (byte 1) */
2316#define SAS_OPN_TIMEOUT_OR_OPN_RJCT_CS 0x01
2317#define SAS_AIP_RECEIVED_CS 0x02
2318#define SAS_CREDIT_TIMEOUT_OCCURRED_CS 0x04
2319#define SAS_ACKNAK_TIMEOUT_OCCURRED_CS 0x08
2320#define SAS_SMPRSP_TIMEOUT_OCCURRED_CS 0x10
2321#define SAS_DONE_TIMEOUT_OCCURRED_CS 0x20
2322/* Connection states (byte 2) */
2323#define SAS_SMP_RESPONSE_RECEIVED_CS 0x01
2324#define SAS_INTLK_TIMEOUT_OCCURRED_CS 0x02
2325#define SAS_DEVICE_SENT_DMAT_CS 0x04
2326#define SAS_DEVICE_SENT_SYNCSRST_CS 0x08
2327#define SAS_CLEARING_AFFILIATION_CS 0x20
2328#define SAS_RXTASK_ACTIVE_CS 0x40
2329#define SAS_TXTASK_ACTIVE_CS 0x80
2330/* Connection states (byte 3) */
2331#define SAS_PHY_LOSS_OF_SIGNAL_CS 0x01
2332#define SAS_DWS_TIMER_EXPIRED_CS 0x02
2333#define SAS_LINK_RESET_NOT_COMPLETE_CS 0x04
2334#define SAS_PHY_DISABLED_CS 0x08
2335#define SAS_LINK_CTL_TASK_ACTIVE_CS 0x10
2336#define SAS_PHY_EVENT_TASK_ACTIVE_CS 0x20
2337#define SAS_DEVICE_SENT_ID_FRAME_CS 0x40
2338#define SAS_DEVICE_SENT_REG_FIS_CS 0x40
2339#define SAS_DEVICE_SENT_HARD_RESET_CS 0x80
2340#define SAS_PHY_IS_DOWN_FLAGS (SAS_PHY_LOSS_OF_SIGNAL_CS|\
2341 SAS_DWS_TIMER_EXPIRED_CS |\
2342 SAS_LINK_RESET_NOT_COMPLETE_CS|\
2343 SAS_PHY_DISABLED_CS)
2344
2345#define SAS_LINK_CTL_PHY_EVENT_FLAGS (SAS_LINK_CTL_TASK_ACTIVE_CS |\
2346 SAS_PHY_EVENT_TASK_ACTIVE_CS |\
2347 SAS_DEVICE_SENT_ID_FRAME_CS |\
2348 SAS_DEVICE_SENT_HARD_RESET_CS)
2349
2350#define LmSEQ_CONCTL(LinkNum) (LmSCRATCH(LinkNum) + 0x018C)
2351#define LmSEQ_CONSTAT(LinkNum) (LmSCRATCH(LinkNum) + 0x018E)
2352#define LmSEQ_CONNECTION_MODES(LinkNum) (LmSCRATCH(LinkNum) + 0x018F)
2353#define LmSEQ_REG1_ISR(LinkNum) (LmSCRATCH(LinkNum) + 0x0192)
2354#define LmSEQ_REG2_ISR(LinkNum) (LmSCRATCH(LinkNum) + 0x0194)
2355#define LmSEQ_REG3_ISR(LinkNum) (LmSCRATCH(LinkNum) + 0x0196)
2356#define LmSEQ_REG0_ISR(LinkNum) (LmSCRATCH(LinkNum) + 0x0198)
2357
2358/* Mode independent scratch page 1 macros. */
2359#define LmSEQ_EST_NEXUS_SCBPTR0(LinkNum) (LmSCRATCH(LinkNum) + 0x01A0)
2360#define LmSEQ_EST_NEXUS_SCBPTR1(LinkNum) (LmSCRATCH(LinkNum) + 0x01A2)
2361#define LmSEQ_EST_NEXUS_SCBPTR2(LinkNum) (LmSCRATCH(LinkNum) + 0x01A4)
2362#define LmSEQ_EST_NEXUS_SCBPTR3(LinkNum) (LmSCRATCH(LinkNum) + 0x01A6)
2363#define LmSEQ_EST_NEXUS_SCB_OPCODE0(LinkNum) (LmSCRATCH(LinkNum) + 0x01A8)
2364#define LmSEQ_EST_NEXUS_SCB_OPCODE1(LinkNum) (LmSCRATCH(LinkNum) + 0x01A9)
2365#define LmSEQ_EST_NEXUS_SCB_OPCODE2(LinkNum) (LmSCRATCH(LinkNum) + 0x01AA)
2366#define LmSEQ_EST_NEXUS_SCB_OPCODE3(LinkNum) (LmSCRATCH(LinkNum) + 0x01AB)
2367#define LmSEQ_EST_NEXUS_SCB_HEAD(LinkNum) (LmSCRATCH(LinkNum) + 0x01AC)
2368#define LmSEQ_EST_NEXUS_SCB_TAIL(LinkNum) (LmSCRATCH(LinkNum) + 0x01AD)
2369#define LmSEQ_EST_NEXUS_BUF_AVAIL(LinkNum) (LmSCRATCH(LinkNum) + 0x01AE)
2370#define LmSEQ_TIMEOUT_CONST(LinkNum) (LmSCRATCH(LinkNum) + 0x01B8)
2371#define LmSEQ_ISR_SAVE_SINDEX(LinkNum) (LmSCRATCH(LinkNum) + 0x01BC)
2372#define LmSEQ_ISR_SAVE_DINDEX(LinkNum) (LmSCRATCH(LinkNum) + 0x01BE)
2373
2374/* Mode independent scratch page 2 macros. */
2375#define LmSEQ_EMPTY_SCB_PTR0(LinkNum) (LmSCRATCH(LinkNum) + 0x01C0)
2376#define LmSEQ_EMPTY_SCB_PTR1(LinkNum) (LmSCRATCH(LinkNum) + 0x01C2)
2377#define LmSEQ_EMPTY_SCB_PTR2(LinkNum) (LmSCRATCH(LinkNum) + 0x01C4)
2378#define LmSEQ_EMPTY_SCB_PTR3(LinkNum) (LmSCRATCH(LinkNum) + 0x01C6)
2379#define LmSEQ_EMPTY_SCB_OPCD0(LinkNum) (LmSCRATCH(LinkNum) + 0x01C8)
2380#define LmSEQ_EMPTY_SCB_OPCD1(LinkNum) (LmSCRATCH(LinkNum) + 0x01C9)
2381#define LmSEQ_EMPTY_SCB_OPCD2(LinkNum) (LmSCRATCH(LinkNum) + 0x01CA)
2382#define LmSEQ_EMPTY_SCB_OPCD3(LinkNum) (LmSCRATCH(LinkNum) + 0x01CB)
2383#define LmSEQ_EMPTY_SCB_HEAD(LinkNum) (LmSCRATCH(LinkNum) + 0x01CC)
2384#define LmSEQ_EMPTY_SCB_TAIL(LinkNum) (LmSCRATCH(LinkNum) + 0x01CD)
2385#define LmSEQ_EMPTY_BUFS_AVAIL(LinkNum) (LmSCRATCH(LinkNum) + 0x01CE)
2386#define LmSEQ_ATA_SCR_REGS(LinkNum) (LmSCRATCH(LinkNum) + 0x01D4)
2387
2388/* Mode independent scratch page 3 macros. */
2389#define LmSEQ_DEV_PRES_TMR_TOUT_CONST(LinkNum) (LmSCRATCH(LinkNum) + 0x01E0)
2390#define LmSEQ_SATA_INTERLOCK_TIMEOUT(LinkNum) (LmSCRATCH(LinkNum) + 0x01E4)
2391#define LmSEQ_STP_SHUTDOWN_TIMEOUT(LinkNum) (LmSCRATCH(LinkNum) + 0x01E8)
2392#define LmSEQ_SRST_ASSERT_TIMEOUT(LinkNum) (LmSCRATCH(LinkNum) + 0x01EC)
2393#define LmSEQ_RCV_FIS_TIMEOUT(LinkNum) (LmSCRATCH(LinkNum) + 0x01F0)
2394#define LmSEQ_ONE_MILLISEC_TIMEOUT(LinkNum) (LmSCRATCH(LinkNum) + 0x01F4)
2395#define LmSEQ_TEN_MS_COMINIT_TIMEOUT(LinkNum) (LmSCRATCH(LinkNum) + 0x01F8)
2396#define LmSEQ_SMP_RCV_TIMEOUT(LinkNum) (LmSCRATCH(LinkNum) + 0x01FC)
2397
2398#endif
diff --git a/drivers/scsi/aic94xx/aic94xx_sas.h b/drivers/scsi/aic94xx/aic94xx_sas.h
new file mode 100644
index 000000000000..64d231712345
--- /dev/null
+++ b/drivers/scsi/aic94xx/aic94xx_sas.h
@@ -0,0 +1,785 @@
1/*
2 * Aic94xx SAS/SATA driver SAS definitions and hardware interface header file.
3 *
4 * Copyright (C) 2005 Adaptec, Inc. All rights reserved.
5 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
6 *
7 * This file is licensed under GPLv2.
8 *
9 * This file is part of the aic94xx driver.
10 *
11 * The aic94xx driver is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; version 2 of the
14 * License.
15 *
16 * The aic94xx driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with the aic94xx driver; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 *
25 */
26
27#ifndef _AIC94XX_SAS_H_
28#define _AIC94XX_SAS_H_
29
30#include <scsi/libsas.h>
31
32/* ---------- DDBs ---------- */
33/* DDBs are device descriptor blocks which describe a device in the
34 * domain that this sequencer can maintain low-level connections for
35 * us. They are be 64 bytes.
36 */
37
38struct asd_ddb_ssp_smp_target_port {
39 u8 conn_type; /* byte 0 */
40#define DDB_TP_CONN_TYPE 0x81 /* Initiator port and addr frame type 0x01 */
41
42 u8 conn_rate;
43 __be16 init_conn_tag;
44 u8 dest_sas_addr[8]; /* bytes 4-11 */
45
46 __le16 send_queue_head;
47 u8 sq_suspended;
48 u8 ddb_type; /* DDB_TYPE_TARGET */
49#define DDB_TYPE_UNUSED 0xFF
50#define DDB_TYPE_TARGET 0xFE
51#define DDB_TYPE_INITIATOR 0xFD
52#define DDB_TYPE_PM_PORT 0xFC
53
54 __le16 _r_a;
55 __be16 awt_def;
56
57 u8 compat_features; /* byte 20 */
58 u8 pathway_blocked_count;
59 __be16 arb_wait_time;
60 __be32 more_compat_features; /* byte 24 */
61
62 u8 conn_mask;
63 u8 flags; /* concurrent conn:2,2 and open:0(1) */
64#define CONCURRENT_CONN_SUPP 0x04
65#define OPEN_REQUIRED 0x01
66
67 u16 _r_b;
68 __le16 exec_queue_tail;
69 __le16 send_queue_tail;
70 __le16 sister_ddb;
71
72 __le16 _r_c;
73
74 u8 max_concurrent_conn;
75 u8 num_concurrent_conn;
76 u8 num_contexts;
77
78 u8 _r_d;
79
80 __le16 active_task_count;
81
82 u8 _r_e[9];
83
84 u8 itnl_reason; /* I_T nexus loss reason */
85
86 __le16 _r_f;
87
88 __le16 itnl_timeout;
89#define ITNL_TIMEOUT_CONST 0x7D0 /* 2 seconds */
90
91 __le32 itnl_timestamp;
92} __attribute__ ((packed));
93
94struct asd_ddb_stp_sata_target_port {
95 u8 conn_type; /* byte 0 */
96 u8 conn_rate;
97 __be16 init_conn_tag;
98 u8 dest_sas_addr[8]; /* bytes 4-11 */
99
100 __le16 send_queue_head;
101 u8 sq_suspended;
102 u8 ddb_type; /* DDB_TYPE_TARGET */
103
104 __le16 _r_a;
105
106 __be16 awt_def;
107 u8 compat_features; /* byte 20 */
108 u8 pathway_blocked_count;
109 __be16 arb_wait_time;
110 __be32 more_compat_features; /* byte 24 */
111
112 u8 conn_mask;
113 u8 flags; /* concurrent conn:2,2 and open:0(1) */
114#define SATA_MULTIPORT 0x80
115#define SUPPORTS_AFFIL 0x40
116#define STP_AFFIL_POL 0x20
117
118 u8 _r_b;
119 u8 flags2; /* STP close policy:0 */
120#define STP_CL_POL_NO_TX 0x00
121#define STP_CL_POL_BTW_CMDS 0x01
122
123 __le16 exec_queue_tail;
124 __le16 send_queue_tail;
125 __le16 sister_ddb;
126 __le16 ata_cmd_scbptr;
127 __le32 sata_tag_alloc_mask;
128 __le16 active_task_count;
129 __le16 _r_c;
130 __le32 sata_sactive;
131 u8 num_sata_tags;
132 u8 sata_status;
133 u8 sata_ending_status;
134 u8 itnl_reason; /* I_T nexus loss reason */
135 __le16 ncq_data_scb_ptr;
136 __le16 itnl_timeout;
137 __le32 itnl_timestamp;
138} __attribute__ ((packed));
139
140/* This struct asd_ddb_init_port, describes the device descriptor block
141 * of an initiator port (when the sequencer is operating in target mode).
142 * Bytes [0,11] and [20,27] are from the OPEN address frame.
143 * The sequencer allocates an initiator port DDB entry.
144 */
145struct asd_ddb_init_port {
146 u8 conn_type; /* byte 0 */
147 u8 conn_rate;
148 __be16 init_conn_tag; /* BE */
149 u8 dest_sas_addr[8];
150 __le16 send_queue_head; /* LE, byte 12 */
151 u8 sq_suspended;
152 u8 ddb_type; /* DDB_TYPE_INITIATOR */
153 __le16 _r_a;
154 __be16 awt_def; /* BE */
155 u8 compat_features;
156 u8 pathway_blocked_count;
157 __be16 arb_wait_time; /* BE */
158 __be32 more_compat_features; /* BE */
159 u8 conn_mask;
160 u8 flags; /* == 5 */
161 u16 _r_b;
162 __le16 exec_queue_tail; /* execution queue tail */
163 __le16 send_queue_tail;
164 __le16 sister_ddb;
165 __le16 init_resp_timeout; /* initiator response timeout */
166 __le32 _r_c;
167 __le16 active_tasks; /* active task count */
168 __le16 init_list; /* initiator list link pointer */
169 __le32 _r_d;
170 u8 max_conn_to[3]; /* from Conn-Disc mode page, in us, LE */
171 u8 itnl_reason; /* I_T nexus loss reason */
172 __le16 bus_inact_to; /* from Conn-Disc mode page, in 100 us, LE */
173 __le16 itnl_to; /* from the Protocol Specific Port Ctrl MP */
174 __le32 itnl_timestamp;
175} __attribute__ ((packed));
176
177/* This struct asd_ddb_sata_tag, describes a look-up table to be used
178 * by the sequencers. SATA II, IDENTIFY DEVICE data, word 76, bit 8:
179 * NCQ support. This table is used by the sequencers to find the
180 * corresponding SCB, given a SATA II tag value.
181 */
182struct asd_ddb_sata_tag {
183 __le16 scb_pointer[32];
184} __attribute__ ((packed));
185
186/* This struct asd_ddb_sata_pm_table, describes a port number to
187 * connection handle look-up table. SATA targets attached to a port
188 * multiplier require a 4-bit port number value. There is one DDB
189 * entry of this type for each SATA port multiplier (sister DDB).
190 * Given a SATA PM port number, this table gives us the SATA PM Port
191 * DDB of the SATA port multiplier port (i.e. the SATA target
192 * discovered on the port).
193 */
194struct asd_ddb_sata_pm_table {
195 __le16 ddb_pointer[16];
196 __le16 _r_a[16];
197} __attribute__ ((packed));
198
199/* This struct asd_ddb_sata_pm_port, describes the SATA port multiplier
200 * port format DDB.
201 */
202struct asd_ddb_sata_pm_port {
203 u8 _r_a[15];
204 u8 ddb_type;
205 u8 _r_b[13];
206 u8 pm_port_flags;
207#define PM_PORT_MASK 0xF0
208#define PM_PORT_SET 0x02
209 u8 _r_c[6];
210 __le16 sister_ddb;
211 __le16 ata_cmd_scbptr;
212 __le32 sata_tag_alloc_mask;
213 __le16 active_task_count;
214 __le16 parent_ddb;
215 __le32 sata_sactive;
216 u8 num_sata_tags;
217 u8 sata_status;
218 u8 sata_ending_status;
219 u8 _r_d[9];
220} __attribute__ ((packed));
221
222/* This struct asd_ddb_seq_shared, describes a DDB shared by the
223 * central and link sequencers. port_map_by_links is indexed phy
224 * number [0,7]; each byte is a bit mask of all the phys that are in
225 * the same port as the indexed phy.
226 */
227struct asd_ddb_seq_shared {
228 __le16 q_free_ddb_head;
229 __le16 q_free_ddb_tail;
230 __le16 q_free_ddb_cnt;
231 __le16 q_used_ddb_head;
232 __le16 q_used_ddb_tail;
233 __le16 shared_mem_lock;
234 __le16 smp_conn_tag;
235 __le16 est_nexus_buf_cnt;
236 __le16 est_nexus_buf_thresh;
237 u32 _r_a;
238 u8 settable_max_contexts;
239 u8 _r_b[23];
240 u8 conn_not_active;
241 u8 phy_is_up;
242 u8 _r_c[8];
243 u8 port_map_by_links[8];
244} __attribute__ ((packed));
245
246/* ---------- SG Element ---------- */
247
248/* This struct sg_el, describes the hardware scatter gather buffer
249 * element. All entries are little endian. In an SCB, there are 2 of
250 * this, plus one more, called a link element of this indicating a
251 * sublist if needed.
252 *
253 * A link element has only the bus address set and the flags (DS) bit
254 * valid. The bus address points to the start of the sublist.
255 *
256 * If a sublist is needed, then that sublist should also include the 2
257 * sg_el embedded in the SCB, in which case next_sg_offset is 32,
258 * since sizeof(sg_el) = 16; EOS should be 1 and EOL 0 in this case.
259 */
260struct sg_el {
261 __le64 bus_addr;
262 __le32 size;
263 __le16 _r;
264 u8 next_sg_offs;
265 u8 flags;
266#define ASD_SG_EL_DS_MASK 0x30
267#define ASD_SG_EL_DS_OCM 0x10
268#define ASD_SG_EL_DS_HM 0x00
269#define ASD_SG_EL_LIST_MASK 0xC0
270#define ASD_SG_EL_LIST_EOL 0x40
271#define ASD_SG_EL_LIST_EOS 0x80
272} __attribute__ ((packed));
273
274/* ---------- SCBs ---------- */
275
276/* An SCB (sequencer control block) is comprised of a common header
277 * and a task part, for a total of 128 bytes. All fields are in LE
278 * order, unless otherwise noted.
279 */
280
281/* This struct scb_header, defines the SCB header format.
282 */
283struct scb_header {
284 __le64 next_scb;
285 __le16 index; /* transaction context */
286 u8 opcode;
287} __attribute__ ((packed));
288
289/* SCB opcodes: Execution queue
290 */
291#define INITIATE_SSP_TASK 0x00
292#define INITIATE_LONG_SSP_TASK 0x01
293#define INITIATE_BIDIR_SSP_TASK 0x02
294#define ABORT_TASK 0x03
295#define INITIATE_SSP_TMF 0x04
296#define SSP_TARG_GET_DATA 0x05
297#define SSP_TARG_GET_DATA_GOOD 0x06
298#define SSP_TARG_SEND_RESP 0x07
299#define QUERY_SSP_TASK 0x08
300#define INITIATE_ATA_TASK 0x09
301#define INITIATE_ATAPI_TASK 0x0a
302#define CONTROL_ATA_DEV 0x0b
303#define INITIATE_SMP_TASK 0x0c
304#define SMP_TARG_SEND_RESP 0x0f
305
306/* SCB opcodes: Send Queue
307 */
308#define SSP_TARG_SEND_DATA 0x40
309#define SSP_TARG_SEND_DATA_GOOD 0x41
310
311/* SCB opcodes: Link Queue
312 */
313#define CONTROL_PHY 0x80
314#define SEND_PRIMITIVE 0x81
315#define INITIATE_LINK_ADM_TASK 0x82
316
317/* SCB opcodes: other
318 */
319#define EMPTY_SCB 0xc0
320#define INITIATE_SEQ_ADM_TASK 0xc1
321#define EST_ICL_TARG_WINDOW 0xc2
322#define COPY_MEM 0xc3
323#define CLEAR_NEXUS 0xc4
324#define INITIATE_DDB_ADM_TASK 0xc6
325#define ESTABLISH_NEXUS_ESCB 0xd0
326
327#define LUN_SIZE 8
328
329/* See SAS spec, task IU
330 */
331struct ssp_task_iu {
332 u8 lun[LUN_SIZE]; /* BE */
333 u16 _r_a;
334 u8 tmf;
335 u8 _r_b;
336 __be16 tag; /* BE */
337 u8 _r_c[14];
338} __attribute__ ((packed));
339
340/* See SAS spec, command IU
341 */
342struct ssp_command_iu {
343 u8 lun[LUN_SIZE];
344 u8 _r_a;
345 u8 efb_prio_attr; /* enable first burst, task prio & attr */
346#define EFB_MASK 0x80
347#define TASK_PRIO_MASK 0x78
348#define TASK_ATTR_MASK 0x07
349
350 u8 _r_b;
351 u8 add_cdb_len; /* in dwords, since bit 0,1 are reserved */
352 union {
353 u8 cdb[16];
354 struct {
355 __le64 long_cdb_addr; /* bus address, LE */
356 __le32 long_cdb_size; /* LE */
357 u8 _r_c[3];
358 u8 eol_ds; /* eol:6,6, ds:5,4 */
359 } long_cdb; /* sequencer extension */
360 };
361} __attribute__ ((packed));
362
363struct xfer_rdy_iu {
364 __be32 requested_offset; /* BE */
365 __be32 write_data_len; /* BE */
366 __be32 _r_a;
367} __attribute__ ((packed));
368
369/* ---------- SCB tasks ---------- */
370
371/* This is both ssp_task and long_ssp_task
372 */
373struct initiate_ssp_task {
374 u8 proto_conn_rate; /* proto:6,4, conn_rate:3,0 */
375 __le32 total_xfer_len;
376 struct ssp_frame_hdr ssp_frame;
377 struct ssp_command_iu ssp_cmd;
378 __le16 sister_scb; /* 0xFFFF */
379 __le16 conn_handle; /* index to DDB for the intended target */
380 u8 data_dir; /* :1,0 */
381#define DATA_DIR_NONE 0x00
382#define DATA_DIR_IN 0x01
383#define DATA_DIR_OUT 0x02
384#define DATA_DIR_BYRECIPIENT 0x03
385
386 u8 _r_a;
387 u8 retry_count;
388 u8 _r_b[5];
389 struct sg_el sg_element[3]; /* 2 real and 1 link */
390} __attribute__ ((packed));
391
392/* This defines both ata_task and atapi_task.
393 * ata: C bit of FIS should be 1,
394 * atapi: C bit of FIS should be 1, and command register should be 0xA0,
395 * to indicate a packet command.
396 */
397struct initiate_ata_task {
398 u8 proto_conn_rate;
399 __le32 total_xfer_len;
400 struct host_to_dev_fis fis;
401 __le32 data_offs;
402 u8 atapi_packet[16];
403 u8 _r_a[12];
404 __le16 sister_scb;
405 __le16 conn_handle;
406 u8 ata_flags; /* CSMI:6,6, DTM:4,4, QT:3,3, data dir:1,0 */
407#define CSMI_TASK 0x40
408#define DATA_XFER_MODE_DMA 0x10
409#define ATA_Q_TYPE_MASK 0x08
410#define ATA_Q_TYPE_UNTAGGED 0x00
411#define ATA_Q_TYPE_NCQ 0x08
412
413 u8 _r_b;
414 u8 retry_count;
415 u8 _r_c;
416 u8 flags;
417#define STP_AFFIL_POLICY 0x20
418#define SET_AFFIL_POLICY 0x10
419#define RET_PARTIAL_SGLIST 0x02
420
421 u8 _r_d[3];
422 struct sg_el sg_element[3];
423} __attribute__ ((packed));
424
425struct initiate_smp_task {
426 u8 proto_conn_rate;
427 u8 _r_a[40];
428 struct sg_el smp_req;
429 __le16 sister_scb;
430 __le16 conn_handle;
431 u8 _r_c[8];
432 struct sg_el smp_resp;
433 u8 _r_d[32];
434} __attribute__ ((packed));
435
436struct control_phy {
437 u8 phy_id;
438 u8 sub_func;
439#define DISABLE_PHY 0x00
440#define ENABLE_PHY 0x01
441#define RELEASE_SPINUP_HOLD 0x02
442#define ENABLE_PHY_NO_SAS_OOB 0x03
443#define ENABLE_PHY_NO_SATA_OOB 0x04
444#define PHY_NO_OP 0x05
445#define EXECUTE_HARD_RESET 0x81
446
447 u8 func_mask;
448 u8 speed_mask;
449 u8 hot_plug_delay;
450 u8 port_type;
451 u8 flags;
452#define DEV_PRES_TIMER_OVERRIDE_ENABLE 0x01
453#define DISABLE_PHY_IF_OOB_FAILS 0x02
454
455 __le32 timeout_override;
456 u8 link_reset_retries;
457 u8 _r_a[47];
458 __le16 conn_handle;
459 u8 _r_b[56];
460} __attribute__ ((packed));
461
462struct control_ata_dev {
463 u8 proto_conn_rate;
464 __le32 _r_a;
465 struct host_to_dev_fis fis;
466 u8 _r_b[32];
467 __le16 sister_scb;
468 __le16 conn_handle;
469 u8 ata_flags; /* 0 */
470 u8 _r_c[55];
471} __attribute__ ((packed));
472
473struct empty_scb {
474 u8 num_valid;
475 __le32 _r_a;
476#define ASD_EDBS_PER_SCB 7
477/* header+data+CRC+DMA suffix data */
478#define ASD_EDB_SIZE (24+1024+4+16)
479 struct sg_el eb[ASD_EDBS_PER_SCB];
480#define ELEMENT_NOT_VALID 0xC0
481} __attribute__ ((packed));
482
483struct initiate_link_adm {
484 u8 phy_id;
485 u8 sub_func;
486#define GET_LINK_ERROR_COUNT 0x00
487#define RESET_LINK_ERROR_COUNT 0x01
488#define ENABLE_NOTIFY_SPINUP_INTS 0x02
489
490 u8 _r_a[57];
491 __le16 conn_handle;
492 u8 _r_b[56];
493} __attribute__ ((packed));
494
495struct copy_memory {
496 u8 _r_a;
497 __le16 xfer_len;
498 __le16 _r_b;
499 __le64 src_busaddr;
500 u8 src_ds; /* See definition of sg_el */
501 u8 _r_c[45];
502 __le16 conn_handle;
503 __le64 _r_d;
504 __le64 dest_busaddr;
505 u8 dest_ds; /* See definition of sg_el */
506 u8 _r_e[39];
507} __attribute__ ((packed));
508
509struct abort_task {
510 u8 proto_conn_rate;
511 __le32 _r_a;
512 struct ssp_frame_hdr ssp_frame;
513 struct ssp_task_iu ssp_task;
514 __le16 sister_scb;
515 __le16 conn_handle;
516 u8 flags; /* ovrd_itnl_timer:3,3, suspend_data_trans:2,2 */
517#define SUSPEND_DATA_TRANS 0x04
518
519 u8 _r_b;
520 u8 retry_count;
521 u8 _r_c[5];
522 __le16 index; /* Transaction context of task to be queried */
523 __le16 itnl_to;
524 u8 _r_d[44];
525} __attribute__ ((packed));
526
527struct clear_nexus {
528 u8 nexus;
529#define NEXUS_ADAPTER 0x00
530#define NEXUS_PORT 0x01
531#define NEXUS_I_T 0x02
532#define NEXUS_I_T_L 0x03
533#define NEXUS_TAG 0x04
534#define NEXUS_TRANS_CX 0x05
535#define NEXUS_SATA_TAG 0x06
536#define NEXUS_T_L 0x07
537#define NEXUS_L 0x08
538#define NEXUS_T_TAG 0x09
539
540 __le32 _r_a;
541 u8 flags;
542#define SUSPEND_TX 0x80
543#define RESUME_TX 0x40
544#define SEND_Q 0x04
545#define EXEC_Q 0x02
546#define NOTINQ 0x01
547
548 u8 _r_b[3];
549 u8 conn_mask;
550 u8 _r_c[19];
551 struct ssp_task_iu ssp_task; /* LUN and TAG */
552 __le16 _r_d;
553 __le16 conn_handle;
554 __le64 _r_e;
555 __le16 index; /* Transaction context of task to be cleared */
556 __le16 context; /* Clear nexus context */
557 u8 _r_f[44];
558} __attribute__ ((packed));
559
560struct initiate_ssp_tmf {
561 u8 proto_conn_rate;
562 __le32 _r_a;
563 struct ssp_frame_hdr ssp_frame;
564 struct ssp_task_iu ssp_task;
565 __le16 sister_scb;
566 __le16 conn_handle;
567 u8 flags; /* itnl override and suspend data tx */
568#define OVERRIDE_ITNL_TIMER 8
569
570 u8 _r_b;
571 u8 retry_count;
572 u8 _r_c[5];
573 __le16 index; /* Transaction context of task to be queried */
574 __le16 itnl_to;
575 u8 _r_d[44];
576} __attribute__ ((packed));
577
578/* Transmits an arbitrary primitive on the link.
579 * Used for NOTIFY and BROADCAST.
580 */
581struct send_prim {
582 u8 phy_id;
583 u8 wait_transmit; /* :0,0 */
584 u8 xmit_flags;
585#define XMTPSIZE_MASK 0xF0
586#define XMTPSIZE_SINGLE 0x10
587#define XMTPSIZE_REPEATED 0x20
588#define XMTPSIZE_CONT 0x20
589#define XMTPSIZE_TRIPLE 0x30
590#define XMTPSIZE_REDUNDANT 0x60
591#define XMTPSIZE_INF 0
592
593#define XMTCONTEN 0x04
594#define XMTPFRM 0x02 /* Transmit at the next frame boundary */
595#define XMTPIMM 0x01 /* Transmit immediately */
596
597 __le16 _r_a;
598 u8 prim[4]; /* K, D0, D1, D2 */
599 u8 _r_b[50];
600 __le16 conn_handle;
601 u8 _r_c[56];
602} __attribute__ ((packed));
603
604/* This describes both SSP Target Get Data and SSP Target Get Data And
605 * Send Good Response SCBs. Used when the sequencer is operating in
606 * target mode...
607 */
608struct ssp_targ_get_data {
609 u8 proto_conn_rate;
610 __le32 total_xfer_len;
611 struct ssp_frame_hdr ssp_frame;
612 struct xfer_rdy_iu xfer_rdy;
613 u8 lun[LUN_SIZE];
614 __le64 _r_a;
615 __le16 sister_scb;
616 __le16 conn_handle;
617 u8 data_dir; /* 01b */
618 u8 _r_b;
619 u8 retry_count;
620 u8 _r_c[5];
621 struct sg_el sg_element[3];
622} __attribute__ ((packed));
623
624/* ---------- The actual SCB struct ---------- */
625
626struct scb {
627 struct scb_header header;
628 union {
629 struct initiate_ssp_task ssp_task;
630 struct initiate_ata_task ata_task;
631 struct initiate_smp_task smp_task;
632 struct control_phy control_phy;
633 struct control_ata_dev control_ata_dev;
634 struct empty_scb escb;
635 struct initiate_link_adm link_adm;
636 struct copy_memory cp_mem;
637 struct abort_task abort_task;
638 struct clear_nexus clear_nexus;
639 struct initiate_ssp_tmf ssp_tmf;
640 };
641} __attribute__ ((packed));
642
643/* ---------- Done List ---------- */
644/* The done list entry opcode field is defined below.
645 * The mnemonic encoding and meaning is as follows:
646 * TC - Task Complete, status was received and acknowledged
647 * TF - Task Failed, indicates an error prior to receiving acknowledgment
648 * for the command:
649 * - no conn,
650 * - NACK or R_ERR received in response to this command,
651 * - credit blocked or not available, or in the case of SMP request,
652 * - no SMP response was received.
653 * In these four cases it is known that the target didn't receive the
654 * command.
655 * TI - Task Interrupted, error after the command was acknowledged. It is
656 * known that the command was received by the target.
657 * TU - Task Unacked, command was transmitted but neither ACK (R_OK) nor NAK
658 * (R_ERR) was received due to loss of signal, broken connection, loss of
659 * dword sync or other reason. The application client should send the
660 * appropriate task query.
661 * TA - Task Aborted, see TF.
662 * _RESP - The completion includes an empty buffer containing status.
663 * TO - Timeout.
664 */
665#define TC_NO_ERROR 0x00
666#define TC_UNDERRUN 0x01
667#define TC_OVERRUN 0x02
668#define TF_OPEN_TO 0x03
669#define TF_OPEN_REJECT 0x04
670#define TI_BREAK 0x05
671#define TI_PROTO_ERR 0x06
672#define TC_SSP_RESP 0x07
673#define TI_PHY_DOWN 0x08
674#define TF_PHY_DOWN 0x09
675#define TC_LINK_ADM_RESP 0x0a
676#define TC_CSMI 0x0b
677#define TC_ATA_RESP 0x0c
678#define TU_PHY_DOWN 0x0d
679#define TU_BREAK 0x0e
680#define TI_SATA_TO 0x0f
681#define TI_NAK 0x10
682#define TC_CONTROL_PHY 0x11
683#define TF_BREAK 0x12
684#define TC_RESUME 0x13
685#define TI_ACK_NAK_TO 0x14
686#define TF_SMPRSP_TO 0x15
687#define TF_SMP_XMIT_RCV_ERR 0x16
688#define TC_PARTIAL_SG_LIST 0x17
689#define TU_ACK_NAK_TO 0x18
690#define TU_SATA_TO 0x19
691#define TF_NAK_RECV 0x1a
692#define TA_I_T_NEXUS_LOSS 0x1b
693#define TC_ATA_R_ERR_RECV 0x1c
694#define TF_TMF_NO_CTX 0x1d
695#define TA_ON_REQ 0x1e
696#define TF_TMF_NO_TAG 0x1f
697#define TF_TMF_TAG_FREE 0x20
698#define TF_TMF_TASK_DONE 0x21
699#define TF_TMF_NO_CONN_HANDLE 0x22
700#define TC_TASK_CLEARED 0x23
701#define TI_SYNCS_RECV 0x24
702#define TU_SYNCS_RECV 0x25
703#define TF_IRTT_TO 0x26
704#define TF_NO_SMP_CONN 0x27
705#define TF_IU_SHORT 0x28
706#define TF_DATA_OFFS_ERR 0x29
707#define TF_INV_CONN_HANDLE 0x2a
708#define TF_REQUESTED_N_PENDING 0x2b
709
710/* 0xc1 - 0xc7: empty buffer received,
711 0xd1 - 0xd7: establish nexus empty buffer received
712*/
713/* This is the ESCB mask */
714#define ESCB_RECVD 0xC0
715
716
717/* This struct done_list_struct defines the done list entry.
718 * All fields are LE.
719 */
720struct done_list_struct {
721 __le16 index; /* aka transaction context */
722 u8 opcode;
723 u8 status_block[4];
724 u8 toggle; /* bit 0 */
725#define DL_TOGGLE_MASK 0x01
726} __attribute__ ((packed));
727
728/* ---------- PHYS ---------- */
729
730struct asd_phy {
731 struct asd_sas_phy sas_phy;
732 struct asd_phy_desc *phy_desc; /* hw profile */
733
734 struct sas_identify_frame *identify_frame;
735 struct asd_dma_tok *id_frm_tok;
736
737 u8 frame_rcvd[ASD_EDB_SIZE];
738};
739
740
741#define ASD_SCB_SIZE sizeof(struct scb)
742#define ASD_DDB_SIZE sizeof(struct asd_ddb_ssp_smp_target_port)
743
744/* Define this to 0 if you do not want NOTIFY (ENABLE SPINIP) sent.
745 * Default: 0x10 (it's a mask)
746 */
747#define ASD_NOTIFY_ENABLE_SPINUP 0x10
748
749/* If enabled, set this to the interval between transmission
750 * of NOTIFY (ENABLE SPINUP). In units of 200 us.
751 */
752#define ASD_NOTIFY_TIMEOUT 2500
753
754/* Initial delay after OOB, before we transmit NOTIFY (ENABLE SPINUP).
755 * If 0, transmit immediately. In milliseconds.
756 */
757#define ASD_NOTIFY_DOWN_COUNT 0
758
759/* Device present timer timeout constant, 10 ms. */
760#define ASD_DEV_PRESENT_TIMEOUT 0x2710
761
762#define ASD_SATA_INTERLOCK_TIMEOUT 0
763
764/* How long to wait before shutting down an STP connection, unless
765 * an STP target sent frame(s). 50 usec.
766 * IGNORED by the sequencer (i.e. value 0 always).
767 */
768#define ASD_STP_SHUTDOWN_TIMEOUT 0x0
769
770/* ATA soft reset timer timeout. 5 usec. */
771#define ASD_SRST_ASSERT_TIMEOUT 0x05
772
773/* 31 sec */
774#define ASD_RCV_FIS_TIMEOUT 0x01D905C0
775
776#define ASD_ONE_MILLISEC_TIMEOUT 0x03e8
777
778/* COMINIT timer */
779#define ASD_TEN_MILLISEC_TIMEOUT 0x2710
780#define ASD_COMINIT_TIMEOUT ASD_TEN_MILLISEC_TIMEOUT
781
782/* 1 sec */
783#define ASD_SMP_RCV_TIMEOUT 0x000F4240
784
785#endif
diff --git a/drivers/scsi/aic94xx/aic94xx_scb.c b/drivers/scsi/aic94xx/aic94xx_scb.c
new file mode 100644
index 000000000000..fc1b7438a913
--- /dev/null
+++ b/drivers/scsi/aic94xx/aic94xx_scb.c
@@ -0,0 +1,732 @@
1/*
2 * Aic94xx SAS/SATA driver SCB management.
3 *
4 * Copyright (C) 2005 Adaptec, Inc. All rights reserved.
5 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
6 *
7 * This file is licensed under GPLv2.
8 *
9 * This file is part of the aic94xx driver.
10 *
11 * The aic94xx driver is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; version 2 of the
14 * License.
15 *
16 * The aic94xx driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with the aic94xx driver; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 *
25 */
26
27#include <linux/pci.h>
28
29#include "aic94xx.h"
30#include "aic94xx_reg.h"
31#include "aic94xx_hwi.h"
32#include "aic94xx_seq.h"
33
34#include "aic94xx_dump.h"
35
36/* ---------- EMPTY SCB ---------- */
37
38#define DL_PHY_MASK 7
39#define BYTES_DMAED 0
40#define PRIMITIVE_RECVD 0x08
41#define PHY_EVENT 0x10
42#define LINK_RESET_ERROR 0x18
43#define TIMER_EVENT 0x20
44#define REQ_TASK_ABORT 0xF0
45#define REQ_DEVICE_RESET 0xF1
46#define SIGNAL_NCQ_ERROR 0xF2
47#define CLEAR_NCQ_ERROR 0xF3
48
49#define PHY_EVENTS_STATUS (CURRENT_LOSS_OF_SIGNAL | CURRENT_OOB_DONE \
50 | CURRENT_SPINUP_HOLD | CURRENT_GTO_TIMEOUT \
51 | CURRENT_OOB_ERROR)
52
53static inline void get_lrate_mode(struct asd_phy *phy, u8 oob_mode)
54{
55 switch (oob_mode & 7) {
56 case PHY_SPEED_60:
57 /* FIXME: sas transport class doesn't have this */
58 phy->sas_phy.linkrate = PHY_LINKRATE_6;
59 phy->sas_phy.phy->negotiated_linkrate = SAS_LINK_RATE_6_0_GBPS;
60 break;
61 case PHY_SPEED_30:
62 phy->sas_phy.linkrate = PHY_LINKRATE_3;
63 phy->sas_phy.phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
64 break;
65 case PHY_SPEED_15:
66 phy->sas_phy.linkrate = PHY_LINKRATE_1_5;
67 phy->sas_phy.phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
68 break;
69 }
70 if (oob_mode & SAS_MODE)
71 phy->sas_phy.oob_mode = SAS_OOB_MODE;
72 else if (oob_mode & SATA_MODE)
73 phy->sas_phy.oob_mode = SATA_OOB_MODE;
74}
75
76static inline void asd_phy_event_tasklet(struct asd_ascb *ascb,
77 struct done_list_struct *dl)
78{
79 struct asd_ha_struct *asd_ha = ascb->ha;
80 struct sas_ha_struct *sas_ha = &asd_ha->sas_ha;
81 int phy_id = dl->status_block[0] & DL_PHY_MASK;
82 struct asd_phy *phy = &asd_ha->phys[phy_id];
83
84 u8 oob_status = dl->status_block[1] & PHY_EVENTS_STATUS;
85 u8 oob_mode = dl->status_block[2];
86
87 switch (oob_status) {
88 case CURRENT_LOSS_OF_SIGNAL:
89 /* directly attached device was removed */
90 ASD_DPRINTK("phy%d: device unplugged\n", phy_id);
91 asd_turn_led(asd_ha, phy_id, 0);
92 sas_phy_disconnected(&phy->sas_phy);
93 sas_ha->notify_phy_event(&phy->sas_phy, PHYE_LOSS_OF_SIGNAL);
94 break;
95 case CURRENT_OOB_DONE:
96 /* hot plugged device */
97 asd_turn_led(asd_ha, phy_id, 1);
98 get_lrate_mode(phy, oob_mode);
99 ASD_DPRINTK("phy%d device plugged: lrate:0x%x, proto:0x%x\n",
100 phy_id, phy->sas_phy.linkrate, phy->sas_phy.iproto);
101 sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE);
102 break;
103 case CURRENT_SPINUP_HOLD:
104 /* hot plug SATA, no COMWAKE sent */
105 asd_turn_led(asd_ha, phy_id, 1);
106 sas_ha->notify_phy_event(&phy->sas_phy, PHYE_SPINUP_HOLD);
107 break;
108 case CURRENT_GTO_TIMEOUT:
109 case CURRENT_OOB_ERROR:
110 ASD_DPRINTK("phy%d error while OOB: oob status:0x%x\n", phy_id,
111 dl->status_block[1]);
112 asd_turn_led(asd_ha, phy_id, 0);
113 sas_phy_disconnected(&phy->sas_phy);
114 sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_ERROR);
115 break;
116 }
117}
118
119/* If phys are enabled sparsely, this will do the right thing. */
120static inline unsigned ord_phy(struct asd_ha_struct *asd_ha,
121 struct asd_phy *phy)
122{
123 u8 enabled_mask = asd_ha->hw_prof.enabled_phys;
124 int i, k = 0;
125
126 for_each_phy(enabled_mask, enabled_mask, i) {
127 if (&asd_ha->phys[i] == phy)
128 return k;
129 k++;
130 }
131 return 0;
132}
133
134/**
135 * asd_get_attached_sas_addr -- extract/generate attached SAS address
136 * phy: pointer to asd_phy
137 * sas_addr: pointer to buffer where the SAS address is to be written
138 *
139 * This function extracts the SAS address from an IDENTIFY frame
140 * received. If OOB is SATA, then a SAS address is generated from the
141 * HA tables.
142 *
143 * LOCKING: the frame_rcvd_lock needs to be held since this parses the frame
144 * buffer.
145 */
146static inline void asd_get_attached_sas_addr(struct asd_phy *phy, u8 *sas_addr)
147{
148 if (phy->sas_phy.frame_rcvd[0] == 0x34
149 && phy->sas_phy.oob_mode == SATA_OOB_MODE) {
150 struct asd_ha_struct *asd_ha = phy->sas_phy.ha->lldd_ha;
151 /* FIS device-to-host */
152 u64 addr = be64_to_cpu(*(__be64 *)phy->phy_desc->sas_addr);
153
154 addr += asd_ha->hw_prof.sata_name_base + ord_phy(asd_ha, phy);
155 *(__be64 *)sas_addr = cpu_to_be64(addr);
156 } else {
157 struct sas_identify_frame *idframe =
158 (void *) phy->sas_phy.frame_rcvd;
159 memcpy(sas_addr, idframe->sas_addr, SAS_ADDR_SIZE);
160 }
161}
162
163static inline void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb,
164 struct done_list_struct *dl,
165 int edb_id, int phy_id)
166{
167 unsigned long flags;
168 int edb_el = edb_id + ascb->edb_index;
169 struct asd_dma_tok *edb = ascb->ha->seq.edb_arr[edb_el];
170 struct asd_phy *phy = &ascb->ha->phys[phy_id];
171 struct sas_ha_struct *sas_ha = phy->sas_phy.ha;
172 u16 size = ((dl->status_block[3] & 7) << 8) | dl->status_block[2];
173
174 size = min(size, (u16) sizeof(phy->frame_rcvd));
175
176 spin_lock_irqsave(&phy->sas_phy.frame_rcvd_lock, flags);
177 memcpy(phy->sas_phy.frame_rcvd, edb->vaddr, size);
178 phy->sas_phy.frame_rcvd_size = size;
179 asd_get_attached_sas_addr(phy, phy->sas_phy.attached_sas_addr);
180 spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags);
181 asd_dump_frame_rcvd(phy, dl);
182 sas_ha->notify_port_event(&phy->sas_phy, PORTE_BYTES_DMAED);
183}
184
185static inline void asd_link_reset_err_tasklet(struct asd_ascb *ascb,
186 struct done_list_struct *dl,
187 int phy_id)
188{
189 struct asd_ha_struct *asd_ha = ascb->ha;
190 struct sas_ha_struct *sas_ha = &asd_ha->sas_ha;
191 struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id];
192 u8 lr_error = dl->status_block[1];
193 u8 retries_left = dl->status_block[2];
194
195 switch (lr_error) {
196 case 0:
197 ASD_DPRINTK("phy%d: Receive ID timer expired\n", phy_id);
198 break;
199 case 1:
200 ASD_DPRINTK("phy%d: Loss of signal\n", phy_id);
201 break;
202 case 2:
203 ASD_DPRINTK("phy%d: Loss of dword sync\n", phy_id);
204 break;
205 case 3:
206 ASD_DPRINTK("phy%d: Receive FIS timeout\n", phy_id);
207 break;
208 default:
209 ASD_DPRINTK("phy%d: unknown link reset error code: 0x%x\n",
210 phy_id, lr_error);
211 break;
212 }
213
214 asd_turn_led(asd_ha, phy_id, 0);
215 sas_phy_disconnected(sas_phy);
216 sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
217
218 if (retries_left == 0) {
219 int num = 1;
220 struct asd_ascb *cp = asd_ascb_alloc_list(ascb->ha, &num,
221 GFP_ATOMIC);
222 if (!cp) {
223 asd_printk("%s: out of memory\n", __FUNCTION__);
224 goto out;
225 }
226 ASD_DPRINTK("phy%d: retries:0 performing link reset seq\n",
227 phy_id);
228 asd_build_control_phy(cp, phy_id, ENABLE_PHY);
229 if (asd_post_ascb_list(ascb->ha, cp, 1) != 0)
230 asd_ascb_free(cp);
231 }
232out:
233 ;
234}
235
236static inline void asd_primitive_rcvd_tasklet(struct asd_ascb *ascb,
237 struct done_list_struct *dl,
238 int phy_id)
239{
240 unsigned long flags;
241 struct sas_ha_struct *sas_ha = &ascb->ha->sas_ha;
242 struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id];
243 u8 reg = dl->status_block[1];
244 u32 cont = dl->status_block[2] << ((reg & 3)*8);
245
246 reg &= ~3;
247 switch (reg) {
248 case LmPRMSTAT0BYTE0:
249 switch (cont) {
250 case LmBROADCH:
251 case LmBROADRVCH0:
252 case LmBROADRVCH1:
253 case LmBROADSES:
254 ASD_DPRINTK("phy%d: BROADCAST change received:%d\n",
255 phy_id, cont);
256 spin_lock_irqsave(&sas_phy->sas_prim_lock, flags);
257 sas_phy->sas_prim = ffs(cont);
258 spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags);
259 sas_ha->notify_port_event(sas_phy,PORTE_BROADCAST_RCVD);
260 break;
261
262 case LmUNKNOWNP:
263 ASD_DPRINTK("phy%d: unknown BREAK\n", phy_id);
264 break;
265
266 default:
267 ASD_DPRINTK("phy%d: primitive reg:0x%x, cont:0x%04x\n",
268 phy_id, reg, cont);
269 break;
270 }
271 break;
272 case LmPRMSTAT1BYTE0:
273 switch (cont) {
274 case LmHARDRST:
275 ASD_DPRINTK("phy%d: HARD_RESET primitive rcvd\n",
276 phy_id);
277 /* The sequencer disables all phys on that port.
278 * We have to re-enable the phys ourselves. */
279 sas_ha->notify_port_event(sas_phy, PORTE_HARD_RESET);
280 break;
281
282 default:
283 ASD_DPRINTK("phy%d: primitive reg:0x%x, cont:0x%04x\n",
284 phy_id, reg, cont);
285 break;
286 }
287 break;
288 default:
289 ASD_DPRINTK("unknown primitive register:0x%x\n",
290 dl->status_block[1]);
291 break;
292 }
293}
294
295/**
296 * asd_invalidate_edb -- invalidate an EDB and if necessary post the ESCB
297 * @ascb: pointer to Empty SCB
298 * @edb_id: index [0,6] to the empty data buffer which is to be invalidated
299 *
300 * After an EDB has been invalidated, if all EDBs in this ESCB have been
301 * invalidated, the ESCB is posted back to the sequencer.
302 * Context is tasklet/IRQ.
303 */
304void asd_invalidate_edb(struct asd_ascb *ascb, int edb_id)
305{
306 struct asd_seq_data *seq = &ascb->ha->seq;
307 struct empty_scb *escb = &ascb->scb->escb;
308 struct sg_el *eb = &escb->eb[edb_id];
309 struct asd_dma_tok *edb = seq->edb_arr[ascb->edb_index + edb_id];
310
311 memset(edb->vaddr, 0, ASD_EDB_SIZE);
312 eb->flags |= ELEMENT_NOT_VALID;
313 escb->num_valid--;
314
315 if (escb->num_valid == 0) {
316 int i;
317 /* ASD_DPRINTK("reposting escb: vaddr: 0x%p, "
318 "dma_handle: 0x%08llx, next: 0x%08llx, "
319 "index:%d, opcode:0x%02x\n",
320 ascb->dma_scb.vaddr,
321 (u64)ascb->dma_scb.dma_handle,
322 le64_to_cpu(ascb->scb->header.next_scb),
323 le16_to_cpu(ascb->scb->header.index),
324 ascb->scb->header.opcode);
325 */
326 escb->num_valid = ASD_EDBS_PER_SCB;
327 for (i = 0; i < ASD_EDBS_PER_SCB; i++)
328 escb->eb[i].flags = 0;
329 if (!list_empty(&ascb->list))
330 list_del_init(&ascb->list);
331 i = asd_post_escb_list(ascb->ha, ascb, 1);
332 if (i)
333 asd_printk("couldn't post escb, err:%d\n", i);
334 }
335}
336
337static void escb_tasklet_complete(struct asd_ascb *ascb,
338 struct done_list_struct *dl)
339{
340 struct asd_ha_struct *asd_ha = ascb->ha;
341 struct sas_ha_struct *sas_ha = &asd_ha->sas_ha;
342 int edb = (dl->opcode & DL_PHY_MASK) - 1; /* [0xc1,0xc7] -> [0,6] */
343 u8 sb_opcode = dl->status_block[0];
344 int phy_id = sb_opcode & DL_PHY_MASK;
345 struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id];
346
347 if (edb > 6 || edb < 0) {
348 ASD_DPRINTK("edb is 0x%x! dl->opcode is 0x%x\n",
349 edb, dl->opcode);
350 ASD_DPRINTK("sb_opcode : 0x%x, phy_id: 0x%x\n",
351 sb_opcode, phy_id);
352 ASD_DPRINTK("escb: vaddr: 0x%p, "
353 "dma_handle: 0x%llx, next: 0x%llx, "
354 "index:%d, opcode:0x%02x\n",
355 ascb->dma_scb.vaddr,
356 (unsigned long long)ascb->dma_scb.dma_handle,
357 (unsigned long long)
358 le64_to_cpu(ascb->scb->header.next_scb),
359 le16_to_cpu(ascb->scb->header.index),
360 ascb->scb->header.opcode);
361 }
362
363 sb_opcode &= ~DL_PHY_MASK;
364
365 switch (sb_opcode) {
366 case BYTES_DMAED:
367 ASD_DPRINTK("%s: phy%d: BYTES_DMAED\n", __FUNCTION__, phy_id);
368 asd_bytes_dmaed_tasklet(ascb, dl, edb, phy_id);
369 break;
370 case PRIMITIVE_RECVD:
371 ASD_DPRINTK("%s: phy%d: PRIMITIVE_RECVD\n", __FUNCTION__,
372 phy_id);
373 asd_primitive_rcvd_tasklet(ascb, dl, phy_id);
374 break;
375 case PHY_EVENT:
376 ASD_DPRINTK("%s: phy%d: PHY_EVENT\n", __FUNCTION__, phy_id);
377 asd_phy_event_tasklet(ascb, dl);
378 break;
379 case LINK_RESET_ERROR:
380 ASD_DPRINTK("%s: phy%d: LINK_RESET_ERROR\n", __FUNCTION__,
381 phy_id);
382 asd_link_reset_err_tasklet(ascb, dl, phy_id);
383 break;
384 case TIMER_EVENT:
385 ASD_DPRINTK("%s: phy%d: TIMER_EVENT, lost dw sync\n",
386 __FUNCTION__, phy_id);
387 asd_turn_led(asd_ha, phy_id, 0);
388 /* the device is gone */
389 sas_phy_disconnected(sas_phy);
390 sas_ha->notify_port_event(sas_phy, PORTE_TIMER_EVENT);
391 break;
392 case REQ_TASK_ABORT:
393 ASD_DPRINTK("%s: phy%d: REQ_TASK_ABORT\n", __FUNCTION__,
394 phy_id);
395 break;
396 case REQ_DEVICE_RESET:
397 ASD_DPRINTK("%s: phy%d: REQ_DEVICE_RESET\n", __FUNCTION__,
398 phy_id);
399 break;
400 case SIGNAL_NCQ_ERROR:
401 ASD_DPRINTK("%s: phy%d: SIGNAL_NCQ_ERROR\n", __FUNCTION__,
402 phy_id);
403 break;
404 case CLEAR_NCQ_ERROR:
405 ASD_DPRINTK("%s: phy%d: CLEAR_NCQ_ERROR\n", __FUNCTION__,
406 phy_id);
407 break;
408 default:
409 ASD_DPRINTK("%s: phy%d: unknown event:0x%x\n", __FUNCTION__,
410 phy_id, sb_opcode);
411 ASD_DPRINTK("edb is 0x%x! dl->opcode is 0x%x\n",
412 edb, dl->opcode);
413 ASD_DPRINTK("sb_opcode : 0x%x, phy_id: 0x%x\n",
414 sb_opcode, phy_id);
415 ASD_DPRINTK("escb: vaddr: 0x%p, "
416 "dma_handle: 0x%llx, next: 0x%llx, "
417 "index:%d, opcode:0x%02x\n",
418 ascb->dma_scb.vaddr,
419 (unsigned long long)ascb->dma_scb.dma_handle,
420 (unsigned long long)
421 le64_to_cpu(ascb->scb->header.next_scb),
422 le16_to_cpu(ascb->scb->header.index),
423 ascb->scb->header.opcode);
424
425 break;
426 }
427
428 asd_invalidate_edb(ascb, edb);
429}
430
431int asd_init_post_escbs(struct asd_ha_struct *asd_ha)
432{
433 struct asd_seq_data *seq = &asd_ha->seq;
434 int i;
435
436 for (i = 0; i < seq->num_escbs; i++)
437 seq->escb_arr[i]->tasklet_complete = escb_tasklet_complete;
438
439 ASD_DPRINTK("posting %d escbs\n", i);
440 return asd_post_escb_list(asd_ha, seq->escb_arr[0], seq->num_escbs);
441}
442
443/* ---------- CONTROL PHY ---------- */
444
445#define CONTROL_PHY_STATUS (CURRENT_DEVICE_PRESENT | CURRENT_OOB_DONE \
446 | CURRENT_SPINUP_HOLD | CURRENT_GTO_TIMEOUT \
447 | CURRENT_OOB_ERROR)
448
449/**
450 * control_phy_tasklet_complete -- tasklet complete for CONTROL PHY ascb
451 * @ascb: pointer to an ascb
452 * @dl: pointer to the done list entry
453 *
454 * This function completes a CONTROL PHY scb and frees the ascb.
455 * A note on LEDs:
456 * - an LED blinks if there is IO though it,
457 * - if a device is connected to the LED, it is lit,
458 * - if no device is connected to the LED, is is dimmed (off).
459 */
460static void control_phy_tasklet_complete(struct asd_ascb *ascb,
461 struct done_list_struct *dl)
462{
463 struct asd_ha_struct *asd_ha = ascb->ha;
464 struct scb *scb = ascb->scb;
465 struct control_phy *control_phy = &scb->control_phy;
466 u8 phy_id = control_phy->phy_id;
467 struct asd_phy *phy = &ascb->ha->phys[phy_id];
468
469 u8 status = dl->status_block[0];
470 u8 oob_status = dl->status_block[1];
471 u8 oob_mode = dl->status_block[2];
472 /* u8 oob_signals= dl->status_block[3]; */
473
474 if (status != 0) {
475 ASD_DPRINTK("%s: phy%d status block opcode:0x%x\n",
476 __FUNCTION__, phy_id, status);
477 goto out;
478 }
479
480 switch (control_phy->sub_func) {
481 case DISABLE_PHY:
482 asd_ha->hw_prof.enabled_phys &= ~(1 << phy_id);
483 asd_turn_led(asd_ha, phy_id, 0);
484 asd_control_led(asd_ha, phy_id, 0);
485 ASD_DPRINTK("%s: disable phy%d\n", __FUNCTION__, phy_id);
486 break;
487
488 case ENABLE_PHY:
489 asd_control_led(asd_ha, phy_id, 1);
490 if (oob_status & CURRENT_OOB_DONE) {
491 asd_ha->hw_prof.enabled_phys |= (1 << phy_id);
492 get_lrate_mode(phy, oob_mode);
493 asd_turn_led(asd_ha, phy_id, 1);
494 ASD_DPRINTK("%s: phy%d, lrate:0x%x, proto:0x%x\n",
495 __FUNCTION__, phy_id,phy->sas_phy.linkrate,
496 phy->sas_phy.iproto);
497 } else if (oob_status & CURRENT_SPINUP_HOLD) {
498 asd_ha->hw_prof.enabled_phys |= (1 << phy_id);
499 asd_turn_led(asd_ha, phy_id, 1);
500 ASD_DPRINTK("%s: phy%d, spinup hold\n", __FUNCTION__,
501 phy_id);
502 } else if (oob_status & CURRENT_ERR_MASK) {
503 asd_turn_led(asd_ha, phy_id, 0);
504 ASD_DPRINTK("%s: phy%d: error: oob status:0x%02x\n",
505 __FUNCTION__, phy_id, oob_status);
506 } else if (oob_status & (CURRENT_HOT_PLUG_CNCT
507 | CURRENT_DEVICE_PRESENT)) {
508 asd_ha->hw_prof.enabled_phys |= (1 << phy_id);
509 asd_turn_led(asd_ha, phy_id, 1);
510 ASD_DPRINTK("%s: phy%d: hot plug or device present\n",
511 __FUNCTION__, phy_id);
512 } else {
513 asd_ha->hw_prof.enabled_phys |= (1 << phy_id);
514 asd_turn_led(asd_ha, phy_id, 0);
515 ASD_DPRINTK("%s: phy%d: no device present: "
516 "oob_status:0x%x\n",
517 __FUNCTION__, phy_id, oob_status);
518 }
519 break;
520 case RELEASE_SPINUP_HOLD:
521 case PHY_NO_OP:
522 case EXECUTE_HARD_RESET:
523 ASD_DPRINTK("%s: phy%d: sub_func:0x%x\n", __FUNCTION__,
524 phy_id, control_phy->sub_func);
525 /* XXX finish */
526 break;
527 default:
528 ASD_DPRINTK("%s: phy%d: sub_func:0x%x?\n", __FUNCTION__,
529 phy_id, control_phy->sub_func);
530 break;
531 }
532out:
533 asd_ascb_free(ascb);
534}
535
536static inline void set_speed_mask(u8 *speed_mask, struct asd_phy_desc *pd)
537{
538 /* disable all speeds, then enable defaults */
539 *speed_mask = SAS_SPEED_60_DIS | SAS_SPEED_30_DIS | SAS_SPEED_15_DIS
540 | SATA_SPEED_30_DIS | SATA_SPEED_15_DIS;
541
542 switch (pd->max_sas_lrate) {
543 case PHY_LINKRATE_6:
544 *speed_mask &= ~SAS_SPEED_60_DIS;
545 default:
546 case PHY_LINKRATE_3:
547 *speed_mask &= ~SAS_SPEED_30_DIS;
548 case PHY_LINKRATE_1_5:
549 *speed_mask &= ~SAS_SPEED_15_DIS;
550 }
551
552 switch (pd->min_sas_lrate) {
553 case PHY_LINKRATE_6:
554 *speed_mask |= SAS_SPEED_30_DIS;
555 case PHY_LINKRATE_3:
556 *speed_mask |= SAS_SPEED_15_DIS;
557 default:
558 case PHY_LINKRATE_1_5:
559 /* nothing to do */
560 ;
561 }
562
563 switch (pd->max_sata_lrate) {
564 case PHY_LINKRATE_3:
565 *speed_mask &= ~SATA_SPEED_30_DIS;
566 default:
567 case PHY_LINKRATE_1_5:
568 *speed_mask &= ~SATA_SPEED_15_DIS;
569 }
570
571 switch (pd->min_sata_lrate) {
572 case PHY_LINKRATE_3:
573 *speed_mask |= SATA_SPEED_15_DIS;
574 default:
575 case PHY_LINKRATE_1_5:
576 /* nothing to do */
577 ;
578 }
579}
580
581/**
582 * asd_build_control_phy -- build a CONTROL PHY SCB
583 * @ascb: pointer to an ascb
584 * @phy_id: phy id to control, integer
585 * @subfunc: subfunction, what to actually to do the phy
586 *
587 * This function builds a CONTROL PHY scb. No allocation of any kind
588 * is performed. @ascb is allocated with the list function.
589 * The caller can override the ascb->tasklet_complete to point
590 * to its own callback function. It must call asd_ascb_free()
591 * at its tasklet complete function.
592 * See the default implementation.
593 */
594void asd_build_control_phy(struct asd_ascb *ascb, int phy_id, u8 subfunc)
595{
596 struct asd_phy *phy = &ascb->ha->phys[phy_id];
597 struct scb *scb = ascb->scb;
598 struct control_phy *control_phy = &scb->control_phy;
599
600 scb->header.opcode = CONTROL_PHY;
601 control_phy->phy_id = (u8) phy_id;
602 control_phy->sub_func = subfunc;
603
604 switch (subfunc) {
605 case EXECUTE_HARD_RESET: /* 0x81 */
606 case ENABLE_PHY: /* 0x01 */
607 /* decide hot plug delay */
608 control_phy->hot_plug_delay = HOTPLUG_DELAY_TIMEOUT;
609
610 /* decide speed mask */
611 set_speed_mask(&control_phy->speed_mask, phy->phy_desc);
612
613 /* initiator port settings are in the hi nibble */
614 if (phy->sas_phy.role == PHY_ROLE_INITIATOR)
615 control_phy->port_type = SAS_PROTO_ALL << 4;
616 else if (phy->sas_phy.role == PHY_ROLE_TARGET)
617 control_phy->port_type = SAS_PROTO_ALL;
618 else
619 control_phy->port_type =
620 (SAS_PROTO_ALL << 4) | SAS_PROTO_ALL;
621
622 /* link reset retries, this should be nominal */
623 control_phy->link_reset_retries = 10;
624
625 case RELEASE_SPINUP_HOLD: /* 0x02 */
626 /* decide the func_mask */
627 control_phy->func_mask = FUNCTION_MASK_DEFAULT;
628 if (phy->phy_desc->flags & ASD_SATA_SPINUP_HOLD)
629 control_phy->func_mask &= ~SPINUP_HOLD_DIS;
630 else
631 control_phy->func_mask |= SPINUP_HOLD_DIS;
632 }
633
634 control_phy->conn_handle = cpu_to_le16(0xFFFF);
635
636 ascb->tasklet_complete = control_phy_tasklet_complete;
637}
638
639/* ---------- INITIATE LINK ADM TASK ---------- */
640
641static void link_adm_tasklet_complete(struct asd_ascb *ascb,
642 struct done_list_struct *dl)
643{
644 u8 opcode = dl->opcode;
645 struct initiate_link_adm *link_adm = &ascb->scb->link_adm;
646 u8 phy_id = link_adm->phy_id;
647
648 if (opcode != TC_NO_ERROR) {
649 asd_printk("phy%d: link adm task 0x%x completed with error "
650 "0x%x\n", phy_id, link_adm->sub_func, opcode);
651 }
652 ASD_DPRINTK("phy%d: link adm task 0x%x: 0x%x\n",
653 phy_id, link_adm->sub_func, opcode);
654
655 asd_ascb_free(ascb);
656}
657
658void asd_build_initiate_link_adm_task(struct asd_ascb *ascb, int phy_id,
659 u8 subfunc)
660{
661 struct scb *scb = ascb->scb;
662 struct initiate_link_adm *link_adm = &scb->link_adm;
663
664 scb->header.opcode = INITIATE_LINK_ADM_TASK;
665
666 link_adm->phy_id = phy_id;
667 link_adm->sub_func = subfunc;
668 link_adm->conn_handle = cpu_to_le16(0xFFFF);
669
670 ascb->tasklet_complete = link_adm_tasklet_complete;
671}
672
673/* ---------- SCB timer ---------- */
674
675/**
676 * asd_ascb_timedout -- called when a pending SCB's timer has expired
677 * @data: unsigned long, a pointer to the ascb in question
678 *
679 * This is the default timeout function which does the most necessary.
680 * Upper layers can implement their own timeout function, say to free
681 * resources they have with this SCB, and then call this one at the
682 * end of their timeout function. To do this, one should initialize
683 * the ascb->timer.{function, data, expires} prior to calling the post
684 * funcion. The timer is started by the post function.
685 */
686void asd_ascb_timedout(unsigned long data)
687{
688 struct asd_ascb *ascb = (void *) data;
689 struct asd_seq_data *seq = &ascb->ha->seq;
690 unsigned long flags;
691
692 ASD_DPRINTK("scb:0x%x timed out\n", ascb->scb->header.opcode);
693
694 spin_lock_irqsave(&seq->pend_q_lock, flags);
695 seq->pending--;
696 list_del_init(&ascb->list);
697 spin_unlock_irqrestore(&seq->pend_q_lock, flags);
698
699 asd_ascb_free(ascb);
700}
701
702/* ---------- CONTROL PHY ---------- */
703
704/* Given the spec value, return a driver value. */
705static const int phy_func_table[] = {
706 [PHY_FUNC_NOP] = PHY_NO_OP,
707 [PHY_FUNC_LINK_RESET] = ENABLE_PHY,
708 [PHY_FUNC_HARD_RESET] = EXECUTE_HARD_RESET,
709 [PHY_FUNC_DISABLE] = DISABLE_PHY,
710 [PHY_FUNC_RELEASE_SPINUP_HOLD] = RELEASE_SPINUP_HOLD,
711};
712
713int asd_control_phy(struct asd_sas_phy *phy, enum phy_func func)
714{
715 struct asd_ha_struct *asd_ha = phy->ha->lldd_ha;
716 struct asd_ascb *ascb;
717 int res = 1;
718
719 if (func == PHY_FUNC_CLEAR_ERROR_LOG)
720 return -ENOSYS;
721
722 ascb = asd_ascb_alloc_list(asd_ha, &res, GFP_KERNEL);
723 if (!ascb)
724 return -ENOMEM;
725
726 asd_build_control_phy(ascb, phy->id, phy_func_table[func]);
727 res = asd_post_ascb_list(asd_ha, ascb , 1);
728 if (res)
729 asd_ascb_free(ascb);
730
731 return res;
732}
diff --git a/drivers/scsi/aic94xx/aic94xx_sds.c b/drivers/scsi/aic94xx/aic94xx_sds.c
new file mode 100644
index 000000000000..eec1e0db0e0f
--- /dev/null
+++ b/drivers/scsi/aic94xx/aic94xx_sds.c
@@ -0,0 +1,1136 @@
1/*
2 * Aic94xx SAS/SATA driver access to shared data structures and memory
3 * maps.
4 *
5 * Copyright (C) 2005 Adaptec, Inc. All rights reserved.
6 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
7 *
8 * This file is licensed under GPLv2.
9 *
10 * This file is part of the aic94xx driver.
11 *
12 * The aic94xx driver is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License as
14 * published by the Free Software Foundation; version 2 of the
15 * License.
16 *
17 * The aic94xx driver is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with the aic94xx driver; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 *
26 */
27
28#include <linux/pci.h>
29#include <linux/delay.h>
30
31#include "aic94xx.h"
32#include "aic94xx_reg.h"
33
34/* ---------- OCM stuff ---------- */
35
36struct asd_ocm_dir_ent {
37 u8 type;
38 u8 offs[3];
39 u8 _r1;
40 u8 size[3];
41} __attribute__ ((packed));
42
43struct asd_ocm_dir {
44 char sig[2];
45 u8 _r1[2];
46 u8 major; /* 0 */
47 u8 minor; /* 0 */
48 u8 _r2;
49 u8 num_de;
50 struct asd_ocm_dir_ent entry[15];
51} __attribute__ ((packed));
52
53#define OCM_DE_OCM_DIR 0x00
54#define OCM_DE_WIN_DRVR 0x01
55#define OCM_DE_BIOS_CHIM 0x02
56#define OCM_DE_RAID_ENGN 0x03
57#define OCM_DE_BIOS_INTL 0x04
58#define OCM_DE_BIOS_CHIM_OSM 0x05
59#define OCM_DE_BIOS_CHIM_DYNAMIC 0x06
60#define OCM_DE_ADDC2C_RES0 0x07
61#define OCM_DE_ADDC2C_RES1 0x08
62#define OCM_DE_ADDC2C_RES2 0x09
63#define OCM_DE_ADDC2C_RES3 0x0A
64
65#define OCM_INIT_DIR_ENTRIES 5
66/***************************************************************************
67* OCM dircetory default
68***************************************************************************/
69static struct asd_ocm_dir OCMDirInit =
70{
71 .sig = {0x4D, 0x4F}, /* signature */
72 .num_de = OCM_INIT_DIR_ENTRIES, /* no. of directory entries */
73};
74
75/***************************************************************************
76* OCM dircetory Entries default
77***************************************************************************/
78static struct asd_ocm_dir_ent OCMDirEntriesInit[OCM_INIT_DIR_ENTRIES] =
79{
80 {
81 .type = (OCM_DE_ADDC2C_RES0), /* Entry type */
82 .offs = {128}, /* Offset */
83 .size = {0, 4}, /* size */
84 },
85 {
86 .type = (OCM_DE_ADDC2C_RES1), /* Entry type */
87 .offs = {128, 4}, /* Offset */
88 .size = {0, 4}, /* size */
89 },
90 {
91 .type = (OCM_DE_ADDC2C_RES2), /* Entry type */
92 .offs = {128, 8}, /* Offset */
93 .size = {0, 4}, /* size */
94 },
95 {
96 .type = (OCM_DE_ADDC2C_RES3), /* Entry type */
97 .offs = {128, 12}, /* Offset */
98 .size = {0, 4}, /* size */
99 },
100 {
101 .type = (OCM_DE_WIN_DRVR), /* Entry type */
102 .offs = {128, 16}, /* Offset */
103 .size = {128, 235, 1}, /* size */
104 },
105};
106
107struct asd_bios_chim_struct {
108 char sig[4];
109 u8 major; /* 1 */
110 u8 minor; /* 0 */
111 u8 bios_major;
112 u8 bios_minor;
113 __le32 bios_build;
114 u8 flags;
115 u8 pci_slot;
116 __le16 ue_num;
117 __le16 ue_size;
118 u8 _r[14];
119 /* The unit element array is right here.
120 */
121} __attribute__ ((packed));
122
123/**
124 * asd_read_ocm_seg - read an on chip memory (OCM) segment
125 * @asd_ha: pointer to the host adapter structure
126 * @buffer: where to write the read data
127 * @offs: offset into OCM where to read from
128 * @size: how many bytes to read
129 *
130 * Return the number of bytes not read. Return 0 on success.
131 */
132static int asd_read_ocm_seg(struct asd_ha_struct *asd_ha, void *buffer,
133 u32 offs, int size)
134{
135 u8 *p = buffer;
136 if (unlikely(asd_ha->iospace))
137 asd_read_reg_string(asd_ha, buffer, offs+OCM_BASE_ADDR, size);
138 else {
139 for ( ; size > 0; size--, offs++, p++)
140 *p = asd_read_ocm_byte(asd_ha, offs);
141 }
142 return size;
143}
144
145static int asd_read_ocm_dir(struct asd_ha_struct *asd_ha,
146 struct asd_ocm_dir *dir, u32 offs)
147{
148 int err = asd_read_ocm_seg(asd_ha, dir, offs, sizeof(*dir));
149 if (err) {
150 ASD_DPRINTK("couldn't read ocm segment\n");
151 return err;
152 }
153
154 if (dir->sig[0] != 'M' || dir->sig[1] != 'O') {
155 ASD_DPRINTK("no valid dir signature(%c%c) at start of OCM\n",
156 dir->sig[0], dir->sig[1]);
157 return -ENOENT;
158 }
159 if (dir->major != 0) {
160 asd_printk("unsupported major version of ocm dir:0x%x\n",
161 dir->major);
162 return -ENOENT;
163 }
164 dir->num_de &= 0xf;
165 return 0;
166}
167
168/**
169 * asd_write_ocm_seg - write an on chip memory (OCM) segment
170 * @asd_ha: pointer to the host adapter structure
171 * @buffer: where to read the write data
172 * @offs: offset into OCM to write to
173 * @size: how many bytes to write
174 *
175 * Return the number of bytes not written. Return 0 on success.
176 */
177static void asd_write_ocm_seg(struct asd_ha_struct *asd_ha, void *buffer,
178 u32 offs, int size)
179{
180 u8 *p = buffer;
181 if (unlikely(asd_ha->iospace))
182 asd_write_reg_string(asd_ha, buffer, offs+OCM_BASE_ADDR, size);
183 else {
184 for ( ; size > 0; size--, offs++, p++)
185 asd_write_ocm_byte(asd_ha, offs, *p);
186 }
187 return;
188}
189
190#define THREE_TO_NUM(X) ((X)[0] | ((X)[1] << 8) | ((X)[2] << 16))
191
192static int asd_find_dir_entry(struct asd_ocm_dir *dir, u8 type,
193 u32 *offs, u32 *size)
194{
195 int i;
196 struct asd_ocm_dir_ent *ent;
197
198 for (i = 0; i < dir->num_de; i++) {
199 if (dir->entry[i].type == type)
200 break;
201 }
202 if (i >= dir->num_de)
203 return -ENOENT;
204 ent = &dir->entry[i];
205 *offs = (u32) THREE_TO_NUM(ent->offs);
206 *size = (u32) THREE_TO_NUM(ent->size);
207 return 0;
208}
209
210#define OCM_BIOS_CHIM_DE 2
211#define BC_BIOS_PRESENT 1
212
213static int asd_get_bios_chim(struct asd_ha_struct *asd_ha,
214 struct asd_ocm_dir *dir)
215{
216 int err;
217 struct asd_bios_chim_struct *bc_struct;
218 u32 offs, size;
219
220 err = asd_find_dir_entry(dir, OCM_BIOS_CHIM_DE, &offs, &size);
221 if (err) {
222 ASD_DPRINTK("couldn't find BIOS_CHIM dir ent\n");
223 goto out;
224 }
225 err = -ENOMEM;
226 bc_struct = kmalloc(sizeof(*bc_struct), GFP_KERNEL);
227 if (!bc_struct) {
228 asd_printk("no memory for bios_chim struct\n");
229 goto out;
230 }
231 err = asd_read_ocm_seg(asd_ha, (void *)bc_struct, offs,
232 sizeof(*bc_struct));
233 if (err) {
234 ASD_DPRINTK("couldn't read ocm segment\n");
235 goto out2;
236 }
237 if (strncmp(bc_struct->sig, "SOIB", 4)
238 && strncmp(bc_struct->sig, "IPSA", 4)) {
239 ASD_DPRINTK("BIOS_CHIM entry has no valid sig(%c%c%c%c)\n",
240 bc_struct->sig[0], bc_struct->sig[1],
241 bc_struct->sig[2], bc_struct->sig[3]);
242 err = -ENOENT;
243 goto out2;
244 }
245 if (bc_struct->major != 1) {
246 asd_printk("BIOS_CHIM unsupported major version:0x%x\n",
247 bc_struct->major);
248 err = -ENOENT;
249 goto out2;
250 }
251 if (bc_struct->flags & BC_BIOS_PRESENT) {
252 asd_ha->hw_prof.bios.present = 1;
253 asd_ha->hw_prof.bios.maj = bc_struct->bios_major;
254 asd_ha->hw_prof.bios.min = bc_struct->bios_minor;
255 asd_ha->hw_prof.bios.bld = le32_to_cpu(bc_struct->bios_build);
256 ASD_DPRINTK("BIOS present (%d,%d), %d\n",
257 asd_ha->hw_prof.bios.maj,
258 asd_ha->hw_prof.bios.min,
259 asd_ha->hw_prof.bios.bld);
260 }
261 asd_ha->hw_prof.ue.num = le16_to_cpu(bc_struct->ue_num);
262 asd_ha->hw_prof.ue.size= le16_to_cpu(bc_struct->ue_size);
263 ASD_DPRINTK("ue num:%d, ue size:%d\n", asd_ha->hw_prof.ue.num,
264 asd_ha->hw_prof.ue.size);
265 size = asd_ha->hw_prof.ue.num * asd_ha->hw_prof.ue.size;
266 if (size > 0) {
267 err = -ENOMEM;
268 asd_ha->hw_prof.ue.area = kmalloc(size, GFP_KERNEL);
269 if (!asd_ha->hw_prof.ue.area)
270 goto out2;
271 err = asd_read_ocm_seg(asd_ha, (void *)asd_ha->hw_prof.ue.area,
272 offs + sizeof(*bc_struct), size);
273 if (err) {
274 kfree(asd_ha->hw_prof.ue.area);
275 asd_ha->hw_prof.ue.area = NULL;
276 asd_ha->hw_prof.ue.num = 0;
277 asd_ha->hw_prof.ue.size = 0;
278 ASD_DPRINTK("couldn't read ue entries(%d)\n", err);
279 }
280 }
281out2:
282 kfree(bc_struct);
283out:
284 return err;
285}
286
287static void
288asd_hwi_initialize_ocm_dir (struct asd_ha_struct *asd_ha)
289{
290 int i;
291
292 /* Zero OCM */
293 for (i = 0; i < OCM_MAX_SIZE; i += 4)
294 asd_write_ocm_dword(asd_ha, i, 0);
295
296 /* Write Dir */
297 asd_write_ocm_seg(asd_ha, &OCMDirInit, 0,
298 sizeof(struct asd_ocm_dir));
299
300 /* Write Dir Entries */
301 for (i = 0; i < OCM_INIT_DIR_ENTRIES; i++)
302 asd_write_ocm_seg(asd_ha, &OCMDirEntriesInit[i],
303 sizeof(struct asd_ocm_dir) +
304 (i * sizeof(struct asd_ocm_dir_ent))
305 , sizeof(struct asd_ocm_dir_ent));
306
307}
308
309static int
310asd_hwi_check_ocm_access (struct asd_ha_struct *asd_ha)
311{
312 struct pci_dev *pcidev = asd_ha->pcidev;
313 u32 reg;
314 int err = 0;
315 u32 v;
316
317 /* check if OCM has been initialized by BIOS */
318 reg = asd_read_reg_dword(asd_ha, EXSICNFGR);
319
320 if (!(reg & OCMINITIALIZED)) {
321 err = pci_read_config_dword(pcidev, PCIC_INTRPT_STAT, &v);
322 if (err) {
323 asd_printk("couldn't access PCIC_INTRPT_STAT of %s\n",
324 pci_name(pcidev));
325 goto out;
326 }
327
328 printk(KERN_INFO "OCM is not initialized by BIOS,"
329 "reinitialize it and ignore it, current IntrptStatus"
330 "is 0x%x\n", v);
331
332 if (v)
333 err = pci_write_config_dword(pcidev,
334 PCIC_INTRPT_STAT, v);
335 if (err) {
336 asd_printk("couldn't write PCIC_INTRPT_STAT of %s\n",
337 pci_name(pcidev));
338 goto out;
339 }
340
341 asd_hwi_initialize_ocm_dir(asd_ha);
342
343 }
344out:
345 return err;
346}
347
348/**
349 * asd_read_ocm - read on chip memory (OCM)
350 * @asd_ha: pointer to the host adapter structure
351 */
352int asd_read_ocm(struct asd_ha_struct *asd_ha)
353{
354 int err;
355 struct asd_ocm_dir *dir;
356
357 if (asd_hwi_check_ocm_access(asd_ha))
358 return -1;
359
360 dir = kmalloc(sizeof(*dir), GFP_KERNEL);
361 if (!dir) {
362 asd_printk("no memory for ocm dir\n");
363 return -ENOMEM;
364 }
365
366 err = asd_read_ocm_dir(asd_ha, dir, 0);
367 if (err)
368 goto out;
369
370 err = asd_get_bios_chim(asd_ha, dir);
371out:
372 kfree(dir);
373 return err;
374}
375
376/* ---------- FLASH stuff ---------- */
377
378#define FLASH_RESET 0xF0
379#define FLASH_MANUF_AMD 1
380
381#define FLASH_SIZE 0x200000
382#define FLASH_DIR_COOKIE "*** ADAPTEC FLASH DIRECTORY *** "
383#define FLASH_NEXT_ENTRY_OFFS 0x2000
384#define FLASH_MAX_DIR_ENTRIES 32
385
386#define FLASH_DE_TYPE_MASK 0x3FFFFFFF
387#define FLASH_DE_MS 0x120
388#define FLASH_DE_CTRL_A_USER 0xE0
389
390struct asd_flash_de {
391 __le32 type;
392 __le32 offs;
393 __le32 pad_size;
394 __le32 image_size;
395 __le32 chksum;
396 u8 _r[12];
397 u8 version[32];
398} __attribute__ ((packed));
399
400struct asd_flash_dir {
401 u8 cookie[32];
402 __le32 rev; /* 2 */
403 __le32 chksum;
404 __le32 chksum_antidote;
405 __le32 bld;
406 u8 bld_id[32]; /* build id data */
407 u8 ver_data[32]; /* date and time of build */
408 __le32 ae_mask;
409 __le32 v_mask;
410 __le32 oc_mask;
411 u8 _r[20];
412 struct asd_flash_de dir_entry[FLASH_MAX_DIR_ENTRIES];
413} __attribute__ ((packed));
414
415struct asd_manuf_sec {
416 char sig[2]; /* 'S', 'M' */
417 u16 offs_next;
418 u8 maj; /* 0 */
419 u8 min; /* 0 */
420 u16 chksum;
421 u16 size;
422 u8 _r[6];
423 u8 sas_addr[SAS_ADDR_SIZE];
424 u8 pcba_sn[ASD_PCBA_SN_SIZE];
425 /* Here start the other segments */
426 u8 linked_list[0];
427} __attribute__ ((packed));
428
429struct asd_manuf_phy_desc {
430 u8 state; /* low 4 bits */
431#define MS_PHY_STATE_ENABLEABLE 0
432#define MS_PHY_STATE_REPORTED 1
433#define MS_PHY_STATE_HIDDEN 2
434 u8 phy_id;
435 u16 _r;
436 u8 phy_control_0; /* mode 5 reg 0x160 */
437 u8 phy_control_1; /* mode 5 reg 0x161 */
438 u8 phy_control_2; /* mode 5 reg 0x162 */
439 u8 phy_control_3; /* mode 5 reg 0x163 */
440} __attribute__ ((packed));
441
442struct asd_manuf_phy_param {
443 char sig[2]; /* 'P', 'M' */
444 u16 next;
445 u8 maj; /* 0 */
446 u8 min; /* 2 */
447 u8 num_phy_desc; /* 8 */
448 u8 phy_desc_size; /* 8 */
449 u8 _r[3];
450 u8 usage_model_id;
451 u32 _r2;
452 struct asd_manuf_phy_desc phy_desc[ASD_MAX_PHYS];
453} __attribute__ ((packed));
454
455#if 0
456static const char *asd_sb_type[] = {
457 "unknown",
458 "SGPIO",
459 [2 ... 0x7F] = "unknown",
460 [0x80] = "ADPT_I2C",
461 [0x81 ... 0xFF] = "VENDOR_UNIQUExx"
462};
463#endif
464
465struct asd_ms_sb_desc {
466 u8 type;
467 u8 node_desc_index;
468 u8 conn_desc_index;
469 u8 _recvd[0];
470} __attribute__ ((packed));
471
472#if 0
473static const char *asd_conn_type[] = {
474 [0 ... 7] = "unknown",
475 "SFF8470",
476 "SFF8482",
477 "SFF8484",
478 [0x80] = "PCIX_DAUGHTER0",
479 [0x81] = "SAS_DAUGHTER0",
480 [0x82 ... 0xFF] = "VENDOR_UNIQUExx"
481};
482
483static const char *asd_conn_location[] = {
484 "unknown",
485 "internal",
486 "external",
487 "board_to_board",
488};
489#endif
490
491struct asd_ms_conn_desc {
492 u8 type;
493 u8 location;
494 u8 num_sideband_desc;
495 u8 size_sideband_desc;
496 u32 _resvd;
497 u8 name[16];
498 struct asd_ms_sb_desc sb_desc[0];
499} __attribute__ ((packed));
500
501struct asd_nd_phy_desc {
502 u8 vp_attch_type;
503 u8 attch_specific[0];
504} __attribute__ ((packed));
505
506#if 0
507static const char *asd_node_type[] = {
508 "IOP",
509 "IO_CONTROLLER",
510 "EXPANDER",
511 "PORT_MULTIPLIER",
512 "PORT_MULTIPLEXER",
513 "MULTI_DROP_I2C_BUS",
514};
515#endif
516
517struct asd_ms_node_desc {
518 u8 type;
519 u8 num_phy_desc;
520 u8 size_phy_desc;
521 u8 _resvd;
522 u8 name[16];
523 struct asd_nd_phy_desc phy_desc[0];
524} __attribute__ ((packed));
525
526struct asd_ms_conn_map {
527 char sig[2]; /* 'M', 'C' */
528 __le16 next;
529 u8 maj; /* 0 */
530 u8 min; /* 0 */
531 __le16 cm_size; /* size of this struct */
532 u8 num_conn;
533 u8 conn_size;
534 u8 num_nodes;
535 u8 usage_model_id;
536 u32 _resvd;
537 struct asd_ms_conn_desc conn_desc[0];
538 struct asd_ms_node_desc node_desc[0];
539} __attribute__ ((packed));
540
541struct asd_ctrla_phy_entry {
542 u8 sas_addr[SAS_ADDR_SIZE];
543 u8 sas_link_rates; /* max in hi bits, min in low bits */
544 u8 flags;
545 u8 sata_link_rates;
546 u8 _r[5];
547} __attribute__ ((packed));
548
549struct asd_ctrla_phy_settings {
550 u8 id0; /* P'h'y */
551 u8 _r;
552 u16 next;
553 u8 num_phys; /* number of PHYs in the PCI function */
554 u8 _r2[3];
555 struct asd_ctrla_phy_entry phy_ent[ASD_MAX_PHYS];
556} __attribute__ ((packed));
557
558struct asd_ll_el {
559 u8 id0;
560 u8 id1;
561 __le16 next;
562 u8 something_here[0];
563} __attribute__ ((packed));
564
565static int asd_poll_flash(struct asd_ha_struct *asd_ha)
566{
567 int c;
568 u8 d;
569
570 for (c = 5000; c > 0; c--) {
571 d = asd_read_reg_byte(asd_ha, asd_ha->hw_prof.flash.bar);
572 d ^= asd_read_reg_byte(asd_ha, asd_ha->hw_prof.flash.bar);
573 if (!d)
574 return 0;
575 udelay(5);
576 }
577 return -ENOENT;
578}
579
580static int asd_reset_flash(struct asd_ha_struct *asd_ha)
581{
582 int err;
583
584 err = asd_poll_flash(asd_ha);
585 if (err)
586 return err;
587 asd_write_reg_byte(asd_ha, asd_ha->hw_prof.flash.bar, FLASH_RESET);
588 err = asd_poll_flash(asd_ha);
589
590 return err;
591}
592
593static inline int asd_read_flash_seg(struct asd_ha_struct *asd_ha,
594 void *buffer, u32 offs, int size)
595{
596 asd_read_reg_string(asd_ha, buffer, asd_ha->hw_prof.flash.bar+offs,
597 size);
598 return 0;
599}
600
601/**
602 * asd_find_flash_dir - finds and reads the flash directory
603 * @asd_ha: pointer to the host adapter structure
604 * @flash_dir: pointer to flash directory structure
605 *
606 * If found, the flash directory segment will be copied to
607 * @flash_dir. Return 1 if found, 0 if not.
608 */
609static int asd_find_flash_dir(struct asd_ha_struct *asd_ha,
610 struct asd_flash_dir *flash_dir)
611{
612 u32 v;
613 for (v = 0; v < FLASH_SIZE; v += FLASH_NEXT_ENTRY_OFFS) {
614 asd_read_flash_seg(asd_ha, flash_dir, v,
615 sizeof(FLASH_DIR_COOKIE)-1);
616 if (memcmp(flash_dir->cookie, FLASH_DIR_COOKIE,
617 sizeof(FLASH_DIR_COOKIE)-1) == 0) {
618 asd_ha->hw_prof.flash.dir_offs = v;
619 asd_read_flash_seg(asd_ha, flash_dir, v,
620 sizeof(*flash_dir));
621 return 1;
622 }
623 }
624 return 0;
625}
626
627static int asd_flash_getid(struct asd_ha_struct *asd_ha)
628{
629 int err = 0;
630 u32 reg, inc;
631
632 reg = asd_read_reg_dword(asd_ha, EXSICNFGR);
633
634 if (!(reg & FLASHEX)) {
635 ASD_DPRINTK("flash doesn't exist\n");
636 return -ENOENT;
637 }
638 if (pci_read_config_dword(asd_ha->pcidev, PCI_CONF_FLSH_BAR,
639 &asd_ha->hw_prof.flash.bar)) {
640 asd_printk("couldn't read PCI_CONF_FLSH_BAR of %s\n",
641 pci_name(asd_ha->pcidev));
642 return -ENOENT;
643 }
644 asd_ha->hw_prof.flash.present = 1;
645 asd_ha->hw_prof.flash.wide = reg & FLASHW ? 1 : 0;
646 err = asd_reset_flash(asd_ha);
647 if (err) {
648 ASD_DPRINTK("couldn't reset flash(%d)\n", err);
649 return err;
650 }
651 /* Get flash info. This would most likely be AMD Am29LV family flash.
652 * First try the sequence for word mode. It is the same as for
653 * 008B (byte mode only), 160B (word mode) and 800D (word mode).
654 */
655 reg = asd_ha->hw_prof.flash.bar;
656 inc = asd_ha->hw_prof.flash.wide ? 2 : 1;
657 asd_write_reg_byte(asd_ha, reg + 0x555, 0xAA);
658 asd_write_reg_byte(asd_ha, reg + 0x2AA, 0x55);
659 asd_write_reg_byte(asd_ha, reg + 0x555, 0x90);
660 asd_ha->hw_prof.flash.manuf = asd_read_reg_byte(asd_ha, reg);
661 asd_ha->hw_prof.flash.dev_id= asd_read_reg_byte(asd_ha,reg+inc);
662 asd_ha->hw_prof.flash.sec_prot = asd_read_reg_byte(asd_ha,reg+inc+inc);
663 /* Get out of autoselect mode. */
664 err = asd_reset_flash(asd_ha);
665
666 if (asd_ha->hw_prof.flash.manuf == FLASH_MANUF_AMD) {
667 ASD_DPRINTK("0Found FLASH(%d) manuf:%d, dev_id:0x%x, "
668 "sec_prot:%d\n",
669 asd_ha->hw_prof.flash.wide ? 16 : 8,
670 asd_ha->hw_prof.flash.manuf,
671 asd_ha->hw_prof.flash.dev_id,
672 asd_ha->hw_prof.flash.sec_prot);
673 return 0;
674 }
675
676 /* Ok, try the sequence for byte mode of 160B and 800D.
677 * We may actually never need this.
678 */
679 asd_write_reg_byte(asd_ha, reg + 0xAAA, 0xAA);
680 asd_write_reg_byte(asd_ha, reg + 0x555, 0x55);
681 asd_write_reg_byte(asd_ha, reg + 0xAAA, 0x90);
682 asd_ha->hw_prof.flash.manuf = asd_read_reg_byte(asd_ha, reg);
683 asd_ha->hw_prof.flash.dev_id = asd_read_reg_byte(asd_ha, reg + 2);
684 asd_ha->hw_prof.flash.sec_prot = asd_read_reg_byte(asd_ha, reg + 4);
685 err = asd_reset_flash(asd_ha);
686
687 if (asd_ha->hw_prof.flash.manuf == FLASH_MANUF_AMD) {
688 ASD_DPRINTK("1Found FLASH(%d) manuf:%d, dev_id:0x%x, "
689 "sec_prot:%d\n",
690 asd_ha->hw_prof.flash.wide ? 16 : 8,
691 asd_ha->hw_prof.flash.manuf,
692 asd_ha->hw_prof.flash.dev_id,
693 asd_ha->hw_prof.flash.sec_prot);
694 return 0;
695 }
696
697 return -ENOENT;
698}
699
700static u16 asd_calc_flash_chksum(u16 *p, int size)
701{
702 u16 chksum = 0;
703
704 while (size-- > 0)
705 chksum += *p++;
706
707 return chksum;
708}
709
710
711static int asd_find_flash_de(struct asd_flash_dir *flash_dir, u32 entry_type,
712 u32 *offs, u32 *size)
713{
714 int i;
715 struct asd_flash_de *de;
716
717 for (i = 0; i < FLASH_MAX_DIR_ENTRIES; i++) {
718 u32 type = le32_to_cpu(flash_dir->dir_entry[i].type);
719
720 type &= FLASH_DE_TYPE_MASK;
721 if (type == entry_type)
722 break;
723 }
724 if (i >= FLASH_MAX_DIR_ENTRIES)
725 return -ENOENT;
726 de = &flash_dir->dir_entry[i];
727 *offs = le32_to_cpu(de->offs);
728 *size = le32_to_cpu(de->pad_size);
729 return 0;
730}
731
732static int asd_validate_ms(struct asd_manuf_sec *ms)
733{
734 if (ms->sig[0] != 'S' || ms->sig[1] != 'M') {
735 ASD_DPRINTK("manuf sec: no valid sig(%c%c)\n",
736 ms->sig[0], ms->sig[1]);
737 return -ENOENT;
738 }
739 if (ms->maj != 0) {
740 asd_printk("unsupported manuf. sector. major version:%x\n",
741 ms->maj);
742 return -ENOENT;
743 }
744 ms->offs_next = le16_to_cpu((__force __le16) ms->offs_next);
745 ms->chksum = le16_to_cpu((__force __le16) ms->chksum);
746 ms->size = le16_to_cpu((__force __le16) ms->size);
747
748 if (asd_calc_flash_chksum((u16 *)ms, ms->size/2)) {
749 asd_printk("failed manuf sector checksum\n");
750 }
751
752 return 0;
753}
754
755static int asd_ms_get_sas_addr(struct asd_ha_struct *asd_ha,
756 struct asd_manuf_sec *ms)
757{
758 memcpy(asd_ha->hw_prof.sas_addr, ms->sas_addr, SAS_ADDR_SIZE);
759 return 0;
760}
761
762static int asd_ms_get_pcba_sn(struct asd_ha_struct *asd_ha,
763 struct asd_manuf_sec *ms)
764{
765 memcpy(asd_ha->hw_prof.pcba_sn, ms->pcba_sn, ASD_PCBA_SN_SIZE);
766 asd_ha->hw_prof.pcba_sn[ASD_PCBA_SN_SIZE] = '\0';
767 return 0;
768}
769
770/**
771 * asd_find_ll_by_id - find a linked list entry by its id
772 * @start: void pointer to the first element in the linked list
773 * @id0: the first byte of the id (offs 0)
774 * @id1: the second byte of the id (offs 1)
775 *
776 * @start has to be the _base_ element start, since the
777 * linked list entries's offset is from this pointer.
778 * Some linked list entries use only the first id, in which case
779 * you can pass 0xFF for the second.
780 */
781static void *asd_find_ll_by_id(void * const start, const u8 id0, const u8 id1)
782{
783 struct asd_ll_el *el = start;
784
785 do {
786 switch (id1) {
787 default:
788 if (el->id1 == id1)
789 case 0xFF:
790 if (el->id0 == id0)
791 return el;
792 }
793 el = start + le16_to_cpu(el->next);
794 } while (el != start);
795
796 return NULL;
797}
798
799/**
800 * asd_ms_get_phy_params - get phy parameters from the manufacturing sector
801 * @asd_ha: pointer to the host adapter structure
802 * @manuf_sec: pointer to the manufacturing sector
803 *
804 * The manufacturing sector contans also the linked list of sub-segments,
805 * since when it was read, its size was taken from the flash directory,
806 * not from the structure size.
807 *
808 * HIDDEN phys do not count in the total count. REPORTED phys cannot
809 * be enabled but are reported and counted towards the total.
810 * ENEBLEABLE phys are enabled by default and count towards the total.
811 * The absolute total phy number is ASD_MAX_PHYS. hw_prof->num_phys
812 * merely specifies the number of phys the host adapter decided to
813 * report. E.g., it is possible for phys 0, 1 and 2 to be HIDDEN,
814 * phys 3, 4 and 5 to be REPORTED and phys 6 and 7 to be ENEBLEABLE.
815 * In this case ASD_MAX_PHYS is 8, hw_prof->num_phys is 5, and only 2
816 * are actually enabled (enabled by default, max number of phys
817 * enableable in this case).
818 */
819static int asd_ms_get_phy_params(struct asd_ha_struct *asd_ha,
820 struct asd_manuf_sec *manuf_sec)
821{
822 int i;
823 int en_phys = 0;
824 int rep_phys = 0;
825 struct asd_manuf_phy_param *phy_param;
826 struct asd_manuf_phy_param dflt_phy_param;
827
828 phy_param = asd_find_ll_by_id(manuf_sec, 'P', 'M');
829 if (!phy_param) {
830 ASD_DPRINTK("ms: no phy parameters found\n");
831 ASD_DPRINTK("ms: Creating default phy parameters\n");
832 dflt_phy_param.sig[0] = 'P';
833 dflt_phy_param.sig[1] = 'M';
834 dflt_phy_param.maj = 0;
835 dflt_phy_param.min = 2;
836 dflt_phy_param.num_phy_desc = 8;
837 dflt_phy_param.phy_desc_size = sizeof(struct asd_manuf_phy_desc);
838 for (i =0; i < ASD_MAX_PHYS; i++) {
839 dflt_phy_param.phy_desc[i].state = 0;
840 dflt_phy_param.phy_desc[i].phy_id = i;
841 dflt_phy_param.phy_desc[i].phy_control_0 = 0xf6;
842 dflt_phy_param.phy_desc[i].phy_control_1 = 0x10;
843 dflt_phy_param.phy_desc[i].phy_control_2 = 0x43;
844 dflt_phy_param.phy_desc[i].phy_control_3 = 0xeb;
845 }
846
847 phy_param = &dflt_phy_param;
848
849 }
850
851 if (phy_param->maj != 0) {
852 asd_printk("unsupported manuf. phy param major version:0x%x\n",
853 phy_param->maj);
854 return -ENOENT;
855 }
856
857 ASD_DPRINTK("ms: num_phy_desc: %d\n", phy_param->num_phy_desc);
858 asd_ha->hw_prof.enabled_phys = 0;
859 for (i = 0; i < phy_param->num_phy_desc; i++) {
860 struct asd_manuf_phy_desc *pd = &phy_param->phy_desc[i];
861 switch (pd->state & 0xF) {
862 case MS_PHY_STATE_HIDDEN:
863 ASD_DPRINTK("ms: phy%d: HIDDEN\n", i);
864 continue;
865 case MS_PHY_STATE_REPORTED:
866 ASD_DPRINTK("ms: phy%d: REPORTED\n", i);
867 asd_ha->hw_prof.enabled_phys &= ~(1 << i);
868 rep_phys++;
869 continue;
870 case MS_PHY_STATE_ENABLEABLE:
871 ASD_DPRINTK("ms: phy%d: ENEBLEABLE\n", i);
872 asd_ha->hw_prof.enabled_phys |= (1 << i);
873 en_phys++;
874 break;
875 }
876 asd_ha->hw_prof.phy_desc[i].phy_control_0 = pd->phy_control_0;
877 asd_ha->hw_prof.phy_desc[i].phy_control_1 = pd->phy_control_1;
878 asd_ha->hw_prof.phy_desc[i].phy_control_2 = pd->phy_control_2;
879 asd_ha->hw_prof.phy_desc[i].phy_control_3 = pd->phy_control_3;
880 }
881 asd_ha->hw_prof.max_phys = rep_phys + en_phys;
882 asd_ha->hw_prof.num_phys = en_phys;
883 ASD_DPRINTK("ms: max_phys:0x%x, num_phys:0x%x\n",
884 asd_ha->hw_prof.max_phys, asd_ha->hw_prof.num_phys);
885 ASD_DPRINTK("ms: enabled_phys:0x%x\n", asd_ha->hw_prof.enabled_phys);
886 return 0;
887}
888
889static int asd_ms_get_connector_map(struct asd_ha_struct *asd_ha,
890 struct asd_manuf_sec *manuf_sec)
891{
892 struct asd_ms_conn_map *cm;
893
894 cm = asd_find_ll_by_id(manuf_sec, 'M', 'C');
895 if (!cm) {
896 ASD_DPRINTK("ms: no connector map found\n");
897 return 0;
898 }
899
900 if (cm->maj != 0) {
901 ASD_DPRINTK("ms: unsupported: connector map major version 0x%x"
902 "\n", cm->maj);
903 return -ENOENT;
904 }
905
906 /* XXX */
907
908 return 0;
909}
910
911
912/**
913 * asd_process_ms - find and extract information from the manufacturing sector
914 * @asd_ha: pointer to the host adapter structure
915 * @flash_dir: pointer to the flash directory
916 */
917static int asd_process_ms(struct asd_ha_struct *asd_ha,
918 struct asd_flash_dir *flash_dir)
919{
920 int err;
921 struct asd_manuf_sec *manuf_sec;
922 u32 offs, size;
923
924 err = asd_find_flash_de(flash_dir, FLASH_DE_MS, &offs, &size);
925 if (err) {
926 ASD_DPRINTK("Couldn't find the manuf. sector\n");
927 goto out;
928 }
929
930 if (size == 0)
931 goto out;
932
933 err = -ENOMEM;
934 manuf_sec = kmalloc(size, GFP_KERNEL);
935 if (!manuf_sec) {
936 ASD_DPRINTK("no mem for manuf sector\n");
937 goto out;
938 }
939
940 err = asd_read_flash_seg(asd_ha, (void *)manuf_sec, offs, size);
941 if (err) {
942 ASD_DPRINTK("couldn't read manuf sector at 0x%x, size 0x%x\n",
943 offs, size);
944 goto out2;
945 }
946
947 err = asd_validate_ms(manuf_sec);
948 if (err) {
949 ASD_DPRINTK("couldn't validate manuf sector\n");
950 goto out2;
951 }
952
953 err = asd_ms_get_sas_addr(asd_ha, manuf_sec);
954 if (err) {
955 ASD_DPRINTK("couldn't read the SAS_ADDR\n");
956 goto out2;
957 }
958 ASD_DPRINTK("manuf sect SAS_ADDR %llx\n",
959 SAS_ADDR(asd_ha->hw_prof.sas_addr));
960
961 err = asd_ms_get_pcba_sn(asd_ha, manuf_sec);
962 if (err) {
963 ASD_DPRINTK("couldn't read the PCBA SN\n");
964 goto out2;
965 }
966 ASD_DPRINTK("manuf sect PCBA SN %s\n", asd_ha->hw_prof.pcba_sn);
967
968 err = asd_ms_get_phy_params(asd_ha, manuf_sec);
969 if (err) {
970 ASD_DPRINTK("ms: couldn't get phy parameters\n");
971 goto out2;
972 }
973
974 err = asd_ms_get_connector_map(asd_ha, manuf_sec);
975 if (err) {
976 ASD_DPRINTK("ms: couldn't get connector map\n");
977 goto out2;
978 }
979
980out2:
981 kfree(manuf_sec);
982out:
983 return err;
984}
985
986static int asd_process_ctrla_phy_settings(struct asd_ha_struct *asd_ha,
987 struct asd_ctrla_phy_settings *ps)
988{
989 int i;
990 for (i = 0; i < ps->num_phys; i++) {
991 struct asd_ctrla_phy_entry *pe = &ps->phy_ent[i];
992
993 if (!PHY_ENABLED(asd_ha, i))
994 continue;
995 if (*(u64 *)pe->sas_addr == 0) {
996 asd_ha->hw_prof.enabled_phys &= ~(1 << i);
997 continue;
998 }
999 /* This is the SAS address which should be sent in IDENTIFY. */
1000 memcpy(asd_ha->hw_prof.phy_desc[i].sas_addr, pe->sas_addr,
1001 SAS_ADDR_SIZE);
1002 asd_ha->hw_prof.phy_desc[i].max_sas_lrate =
1003 (pe->sas_link_rates & 0xF0) >> 4;
1004 asd_ha->hw_prof.phy_desc[i].min_sas_lrate =
1005 (pe->sas_link_rates & 0x0F);
1006 asd_ha->hw_prof.phy_desc[i].max_sata_lrate =
1007 (pe->sata_link_rates & 0xF0) >> 4;
1008 asd_ha->hw_prof.phy_desc[i].min_sata_lrate =
1009 (pe->sata_link_rates & 0x0F);
1010 asd_ha->hw_prof.phy_desc[i].flags = pe->flags;
1011 ASD_DPRINTK("ctrla: phy%d: sas_addr: %llx, sas rate:0x%x-0x%x,"
1012 " sata rate:0x%x-0x%x, flags:0x%x\n",
1013 i,
1014 SAS_ADDR(asd_ha->hw_prof.phy_desc[i].sas_addr),
1015 asd_ha->hw_prof.phy_desc[i].max_sas_lrate,
1016 asd_ha->hw_prof.phy_desc[i].min_sas_lrate,
1017 asd_ha->hw_prof.phy_desc[i].max_sata_lrate,
1018 asd_ha->hw_prof.phy_desc[i].min_sata_lrate,
1019 asd_ha->hw_prof.phy_desc[i].flags);
1020 }
1021
1022 return 0;
1023}
1024
1025/**
1026 * asd_process_ctrl_a_user - process CTRL-A user settings
1027 * @asd_ha: pointer to the host adapter structure
1028 * @flash_dir: pointer to the flash directory
1029 */
1030static int asd_process_ctrl_a_user(struct asd_ha_struct *asd_ha,
1031 struct asd_flash_dir *flash_dir)
1032{
1033 int err, i;
1034 u32 offs, size;
1035 struct asd_ll_el *el;
1036 struct asd_ctrla_phy_settings *ps;
1037 struct asd_ctrla_phy_settings dflt_ps;
1038
1039 err = asd_find_flash_de(flash_dir, FLASH_DE_CTRL_A_USER, &offs, &size);
1040 if (err) {
1041 ASD_DPRINTK("couldn't find CTRL-A user settings section\n");
1042 ASD_DPRINTK("Creating default CTRL-A user settings section\n");
1043
1044 dflt_ps.id0 = 'h';
1045 dflt_ps.num_phys = 8;
1046 for (i =0; i < ASD_MAX_PHYS; i++) {
1047 memcpy(dflt_ps.phy_ent[i].sas_addr,
1048 asd_ha->hw_prof.sas_addr, SAS_ADDR_SIZE);
1049 dflt_ps.phy_ent[i].sas_link_rates = 0x98;
1050 dflt_ps.phy_ent[i].flags = 0x0;
1051 dflt_ps.phy_ent[i].sata_link_rates = 0x0;
1052 }
1053
1054 size = sizeof(struct asd_ctrla_phy_settings);
1055 ps = &dflt_ps;
1056 }
1057
1058 if (size == 0)
1059 goto out;
1060
1061 err = -ENOMEM;
1062 el = kmalloc(size, GFP_KERNEL);
1063 if (!el) {
1064 ASD_DPRINTK("no mem for ctrla user settings section\n");
1065 goto out;
1066 }
1067
1068 err = asd_read_flash_seg(asd_ha, (void *)el, offs, size);
1069 if (err) {
1070 ASD_DPRINTK("couldn't read ctrla phy settings section\n");
1071 goto out2;
1072 }
1073
1074 err = -ENOENT;
1075 ps = asd_find_ll_by_id(el, 'h', 0xFF);
1076 if (!ps) {
1077 ASD_DPRINTK("couldn't find ctrla phy settings struct\n");
1078 goto out2;
1079 }
1080
1081 err = asd_process_ctrla_phy_settings(asd_ha, ps);
1082 if (err) {
1083 ASD_DPRINTK("couldn't process ctrla phy settings\n");
1084 goto out2;
1085 }
1086out2:
1087 kfree(el);
1088out:
1089 return err;
1090}
1091
1092/**
1093 * asd_read_flash - read flash memory
1094 * @asd_ha: pointer to the host adapter structure
1095 */
1096int asd_read_flash(struct asd_ha_struct *asd_ha)
1097{
1098 int err;
1099 struct asd_flash_dir *flash_dir;
1100
1101 err = asd_flash_getid(asd_ha);
1102 if (err)
1103 return err;
1104
1105 flash_dir = kmalloc(sizeof(*flash_dir), GFP_KERNEL);
1106 if (!flash_dir)
1107 return -ENOMEM;
1108
1109 err = -ENOENT;
1110 if (!asd_find_flash_dir(asd_ha, flash_dir)) {
1111 ASD_DPRINTK("couldn't find flash directory\n");
1112 goto out;
1113 }
1114
1115 if (le32_to_cpu(flash_dir->rev) != 2) {
1116 asd_printk("unsupported flash dir version:0x%x\n",
1117 le32_to_cpu(flash_dir->rev));
1118 goto out;
1119 }
1120
1121 err = asd_process_ms(asd_ha, flash_dir);
1122 if (err) {
1123 ASD_DPRINTK("couldn't process manuf sector settings\n");
1124 goto out;
1125 }
1126
1127 err = asd_process_ctrl_a_user(asd_ha, flash_dir);
1128 if (err) {
1129 ASD_DPRINTK("couldn't process CTRL-A user settings\n");
1130 goto out;
1131 }
1132
1133out:
1134 kfree(flash_dir);
1135 return err;
1136}
diff --git a/drivers/scsi/aic94xx/aic94xx_seq.c b/drivers/scsi/aic94xx/aic94xx_seq.c
new file mode 100644
index 000000000000..9050c6f3f6bd
--- /dev/null
+++ b/drivers/scsi/aic94xx/aic94xx_seq.c
@@ -0,0 +1,1401 @@
1/*
2 * Aic94xx SAS/SATA driver sequencer interface.
3 *
4 * Copyright (C) 2005 Adaptec, Inc. All rights reserved.
5 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
6 *
7 * Parts of this code adapted from David Chaw's adp94xx_seq.c.
8 *
9 * This file is licensed under GPLv2.
10 *
11 * This file is part of the aic94xx driver.
12 *
13 * The aic94xx driver is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation; version 2 of the
16 * License.
17 *
18 * The aic94xx driver is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with the aic94xx driver; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 *
27 */
28
29#include <linux/delay.h>
30#include <linux/pci.h>
31#include <linux/firmware.h>
32#include "aic94xx_reg.h"
33#include "aic94xx_hwi.h"
34
35#include "aic94xx_seq.h"
36#include "aic94xx_dump.h"
37
38/* It takes no more than 0.05 us for an instruction
39 * to complete. So waiting for 1 us should be more than
40 * plenty.
41 */
42#define PAUSE_DELAY 1
43#define PAUSE_TRIES 1000
44
45static const struct firmware *sequencer_fw;
46static const char *sequencer_version;
47static u16 cseq_vecs[CSEQ_NUM_VECS], lseq_vecs[LSEQ_NUM_VECS], mode2_task,
48 cseq_idle_loop, lseq_idle_loop;
49static u8 *cseq_code, *lseq_code;
50static u32 cseq_code_size, lseq_code_size;
51
52static u16 first_scb_site_no = 0xFFFF;
53static u16 last_scb_site_no;
54
55/* ---------- Pause/Unpause CSEQ/LSEQ ---------- */
56
57/**
58 * asd_pause_cseq - pause the central sequencer
59 * @asd_ha: pointer to host adapter structure
60 *
61 * Return 0 on success, negative on failure.
62 */
63int asd_pause_cseq(struct asd_ha_struct *asd_ha)
64{
65 int count = PAUSE_TRIES;
66 u32 arp2ctl;
67
68 arp2ctl = asd_read_reg_dword(asd_ha, CARP2CTL);
69 if (arp2ctl & PAUSED)
70 return 0;
71
72 asd_write_reg_dword(asd_ha, CARP2CTL, arp2ctl | EPAUSE);
73 do {
74 arp2ctl = asd_read_reg_dword(asd_ha, CARP2CTL);
75 if (arp2ctl & PAUSED)
76 return 0;
77 udelay(PAUSE_DELAY);
78 } while (--count > 0);
79
80 ASD_DPRINTK("couldn't pause CSEQ\n");
81 return -1;
82}
83
84/**
85 * asd_unpause_cseq - unpause the central sequencer.
86 * @asd_ha: pointer to host adapter structure.
87 *
88 * Return 0 on success, negative on error.
89 */
90int asd_unpause_cseq(struct asd_ha_struct *asd_ha)
91{
92 u32 arp2ctl;
93 int count = PAUSE_TRIES;
94
95 arp2ctl = asd_read_reg_dword(asd_ha, CARP2CTL);
96 if (!(arp2ctl & PAUSED))
97 return 0;
98
99 asd_write_reg_dword(asd_ha, CARP2CTL, arp2ctl & ~EPAUSE);
100 do {
101 arp2ctl = asd_read_reg_dword(asd_ha, CARP2CTL);
102 if (!(arp2ctl & PAUSED))
103 return 0;
104 udelay(PAUSE_DELAY);
105 } while (--count > 0);
106
107 ASD_DPRINTK("couldn't unpause the CSEQ\n");
108 return -1;
109}
110
111/**
112 * asd_seq_pause_lseq - pause a link sequencer
113 * @asd_ha: pointer to a host adapter structure
114 * @lseq: link sequencer of interest
115 *
116 * Return 0 on success, negative on error.
117 */
118static inline int asd_seq_pause_lseq(struct asd_ha_struct *asd_ha, int lseq)
119{
120 u32 arp2ctl;
121 int count = PAUSE_TRIES;
122
123 arp2ctl = asd_read_reg_dword(asd_ha, LmARP2CTL(lseq));
124 if (arp2ctl & PAUSED)
125 return 0;
126
127 asd_write_reg_dword(asd_ha, LmARP2CTL(lseq), arp2ctl | EPAUSE);
128 do {
129 arp2ctl = asd_read_reg_dword(asd_ha, LmARP2CTL(lseq));
130 if (arp2ctl & PAUSED)
131 return 0;
132 udelay(PAUSE_DELAY);
133 } while (--count > 0);
134
135 ASD_DPRINTK("couldn't pause LSEQ %d\n", lseq);
136 return -1;
137}
138
139/**
140 * asd_pause_lseq - pause the link sequencer(s)
141 * @asd_ha: pointer to host adapter structure
142 * @lseq_mask: mask of link sequencers of interest
143 *
144 * Return 0 on success, negative on failure.
145 */
146int asd_pause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask)
147{
148 int lseq;
149 int err = 0;
150
151 for_each_sequencer(lseq_mask, lseq_mask, lseq) {
152 err = asd_seq_pause_lseq(asd_ha, lseq);
153 if (err)
154 return err;
155 }
156
157 return err;
158}
159
160/**
161 * asd_seq_unpause_lseq - unpause a link sequencer
162 * @asd_ha: pointer to host adapter structure
163 * @lseq: link sequencer of interest
164 *
165 * Return 0 on success, negative on error.
166 */
167static inline int asd_seq_unpause_lseq(struct asd_ha_struct *asd_ha, int lseq)
168{
169 u32 arp2ctl;
170 int count = PAUSE_TRIES;
171
172 arp2ctl = asd_read_reg_dword(asd_ha, LmARP2CTL(lseq));
173 if (!(arp2ctl & PAUSED))
174 return 0;
175
176 asd_write_reg_dword(asd_ha, LmARP2CTL(lseq), arp2ctl & ~EPAUSE);
177 do {
178 arp2ctl = asd_read_reg_dword(asd_ha, LmARP2CTL(lseq));
179 if (!(arp2ctl & PAUSED))
180 return 0;
181 udelay(PAUSE_DELAY);
182 } while (--count > 0);
183
184 ASD_DPRINTK("couldn't unpause LSEQ %d\n", lseq);
185 return 0;
186}
187
188
189/**
190 * asd_unpause_lseq - unpause the link sequencer(s)
191 * @asd_ha: pointer to host adapter structure
192 * @lseq_mask: mask of link sequencers of interest
193 *
194 * Return 0 on success, negative on failure.
195 */
196int asd_unpause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask)
197{
198 int lseq;
199 int err = 0;
200
201 for_each_sequencer(lseq_mask, lseq_mask, lseq) {
202 err = asd_seq_unpause_lseq(asd_ha, lseq);
203 if (err)
204 return err;
205 }
206
207 return err;
208}
209
210/* ---------- Downloading CSEQ/LSEQ microcode ---------- */
211
212static int asd_verify_cseq(struct asd_ha_struct *asd_ha, const u8 *_prog,
213 u32 size)
214{
215 u32 addr = CSEQ_RAM_REG_BASE_ADR;
216 const u32 *prog = (u32 *) _prog;
217 u32 i;
218
219 for (i = 0; i < size; i += 4, prog++, addr += 4) {
220 u32 val = asd_read_reg_dword(asd_ha, addr);
221
222 if (le32_to_cpu(*prog) != val) {
223 asd_printk("%s: cseq verify failed at %u "
224 "read:0x%x, wanted:0x%x\n",
225 pci_name(asd_ha->pcidev),
226 i, val, le32_to_cpu(*prog));
227 return -1;
228 }
229 }
230 ASD_DPRINTK("verified %d bytes, passed\n", size);
231 return 0;
232}
233
234/**
235 * asd_verify_lseq - verify the microcode of a link sequencer
236 * @asd_ha: pointer to host adapter structure
237 * @_prog: pointer to the microcode
238 * @size: size of the microcode in bytes
239 * @lseq: link sequencer of interest
240 *
241 * The link sequencer code is accessed in 4 KB pages, which are selected
242 * by setting LmRAMPAGE (bits 8 and 9) of the LmBISTCTL1 register.
243 * The 10 KB LSEQm instruction code is mapped, page at a time, at
244 * LmSEQRAM address.
245 */
246static int asd_verify_lseq(struct asd_ha_struct *asd_ha, const u8 *_prog,
247 u32 size, int lseq)
248{
249#define LSEQ_CODEPAGE_SIZE 4096
250 int pages = (size + LSEQ_CODEPAGE_SIZE - 1) / LSEQ_CODEPAGE_SIZE;
251 u32 page;
252 const u32 *prog = (u32 *) _prog;
253
254 for (page = 0; page < pages; page++) {
255 u32 i;
256
257 asd_write_reg_dword(asd_ha, LmBISTCTL1(lseq),
258 page << LmRAMPAGE_LSHIFT);
259 for (i = 0; size > 0 && i < LSEQ_CODEPAGE_SIZE;
260 i += 4, prog++, size-=4) {
261
262 u32 val = asd_read_reg_dword(asd_ha, LmSEQRAM(lseq)+i);
263
264 if (le32_to_cpu(*prog) != val) {
265 asd_printk("%s: LSEQ%d verify failed "
266 "page:%d, offs:%d\n",
267 pci_name(asd_ha->pcidev),
268 lseq, page, i);
269 return -1;
270 }
271 }
272 }
273 ASD_DPRINTK("LSEQ%d verified %d bytes, passed\n", lseq,
274 (int)((u8 *)prog-_prog));
275 return 0;
276}
277
278/**
279 * asd_verify_seq -- verify CSEQ/LSEQ microcode
280 * @asd_ha: pointer to host adapter structure
281 * @prog: pointer to microcode
282 * @size: size of the microcode
283 * @lseq_mask: if 0, verify CSEQ microcode, else mask of LSEQs of interest
284 *
285 * Return 0 if microcode is correct, negative on mismatch.
286 */
287static int asd_verify_seq(struct asd_ha_struct *asd_ha, const u8 *prog,
288 u32 size, u8 lseq_mask)
289{
290 if (lseq_mask == 0)
291 return asd_verify_cseq(asd_ha, prog, size);
292 else {
293 int lseq, err;
294
295 for_each_sequencer(lseq_mask, lseq_mask, lseq) {
296 err = asd_verify_lseq(asd_ha, prog, size, lseq);
297 if (err)
298 return err;
299 }
300 }
301
302 return 0;
303}
304#define ASD_DMA_MODE_DOWNLOAD
305#ifdef ASD_DMA_MODE_DOWNLOAD
306/* This is the size of the CSEQ Mapped instruction page */
307#define MAX_DMA_OVLY_COUNT ((1U << 14)-1)
308static int asd_download_seq(struct asd_ha_struct *asd_ha,
309 const u8 * const prog, u32 size, u8 lseq_mask)
310{
311 u32 comstaten;
312 u32 reg;
313 int page;
314 const int pages = (size + MAX_DMA_OVLY_COUNT - 1) / MAX_DMA_OVLY_COUNT;
315 struct asd_dma_tok *token;
316 int err = 0;
317
318 if (size % 4) {
319 asd_printk("sequencer program not multiple of 4\n");
320 return -1;
321 }
322
323 asd_pause_cseq(asd_ha);
324 asd_pause_lseq(asd_ha, 0xFF);
325
326 /* save, disable and clear interrupts */
327 comstaten = asd_read_reg_dword(asd_ha, COMSTATEN);
328 asd_write_reg_dword(asd_ha, COMSTATEN, 0);
329 asd_write_reg_dword(asd_ha, COMSTAT, COMSTAT_MASK);
330
331 asd_write_reg_dword(asd_ha, CHIMINTEN, RST_CHIMINTEN);
332 asd_write_reg_dword(asd_ha, CHIMINT, CHIMINT_MASK);
333
334 token = asd_alloc_coherent(asd_ha, MAX_DMA_OVLY_COUNT, GFP_KERNEL);
335 if (!token) {
336 asd_printk("out of memory for dma SEQ download\n");
337 err = -ENOMEM;
338 goto out;
339 }
340 ASD_DPRINTK("dma-ing %d bytes\n", size);
341
342 for (page = 0; page < pages; page++) {
343 int i;
344 u32 left = min(size-page*MAX_DMA_OVLY_COUNT,
345 (u32)MAX_DMA_OVLY_COUNT);
346
347 memcpy(token->vaddr, prog + page*MAX_DMA_OVLY_COUNT, left);
348 asd_write_reg_addr(asd_ha, OVLYDMAADR, token->dma_handle);
349 asd_write_reg_dword(asd_ha, OVLYDMACNT, left);
350 reg = !page ? RESETOVLYDMA : 0;
351 reg |= (STARTOVLYDMA | OVLYHALTERR);
352 reg |= (lseq_mask ? (((u32)lseq_mask) << 8) : OVLYCSEQ);
353 /* Start DMA. */
354 asd_write_reg_dword(asd_ha, OVLYDMACTL, reg);
355
356 for (i = PAUSE_TRIES*100; i > 0; i--) {
357 u32 dmadone = asd_read_reg_dword(asd_ha, OVLYDMACTL);
358 if (!(dmadone & OVLYDMAACT))
359 break;
360 udelay(PAUSE_DELAY);
361 }
362 }
363
364 reg = asd_read_reg_dword(asd_ha, COMSTAT);
365 if (!(reg & OVLYDMADONE) || (reg & OVLYERR)
366 || (asd_read_reg_dword(asd_ha, CHIMINT) & DEVEXCEPT_MASK)){
367 asd_printk("%s: error DMA-ing sequencer code\n",
368 pci_name(asd_ha->pcidev));
369 err = -ENODEV;
370 }
371
372 asd_free_coherent(asd_ha, token);
373 out:
374 asd_write_reg_dword(asd_ha, COMSTATEN, comstaten);
375
376 return err ? : asd_verify_seq(asd_ha, prog, size, lseq_mask);
377}
378#else /* ASD_DMA_MODE_DOWNLOAD */
379static int asd_download_seq(struct asd_ha_struct *asd_ha, const u8 *_prog,
380 u32 size, u8 lseq_mask)
381{
382 int i;
383 u32 reg = 0;
384 const u32 *prog = (u32 *) _prog;
385
386 if (size % 4) {
387 asd_printk("sequencer program not multiple of 4\n");
388 return -1;
389 }
390
391 asd_pause_cseq(asd_ha);
392 asd_pause_lseq(asd_ha, 0xFF);
393
394 reg |= (lseq_mask ? (((u32)lseq_mask) << 8) : OVLYCSEQ);
395 reg |= PIOCMODE;
396
397 asd_write_reg_dword(asd_ha, OVLYDMACNT, size);
398 asd_write_reg_dword(asd_ha, OVLYDMACTL, reg);
399
400 ASD_DPRINTK("downloading %s sequencer%s in PIO mode...\n",
401 lseq_mask ? "LSEQ" : "CSEQ", lseq_mask ? "s" : "");
402
403 for (i = 0; i < size; i += 4, prog++)
404 asd_write_reg_dword(asd_ha, SPIODATA, *prog);
405
406 reg = (reg & ~PIOCMODE) | OVLYHALTERR;
407 asd_write_reg_dword(asd_ha, OVLYDMACTL, reg);
408
409 return asd_verify_seq(asd_ha, _prog, size, lseq_mask);
410}
411#endif /* ASD_DMA_MODE_DOWNLOAD */
412
413/**
414 * asd_seq_download_seqs - download the sequencer microcode
415 * @asd_ha: pointer to host adapter structure
416 *
417 * Download the central and link sequencer microcode.
418 */
419static int asd_seq_download_seqs(struct asd_ha_struct *asd_ha)
420{
421 int err;
422
423 if (!asd_ha->hw_prof.enabled_phys) {
424 asd_printk("%s: no enabled phys!\n", pci_name(asd_ha->pcidev));
425 return -ENODEV;
426 }
427
428 /* Download the CSEQ */
429 ASD_DPRINTK("downloading CSEQ...\n");
430 err = asd_download_seq(asd_ha, cseq_code, cseq_code_size, 0);
431 if (err) {
432 asd_printk("CSEQ download failed:%d\n", err);
433 return err;
434 }
435
436 /* Download the Link Sequencers code. All of the Link Sequencers
437 * microcode can be downloaded at the same time.
438 */
439 ASD_DPRINTK("downloading LSEQs...\n");
440 err = asd_download_seq(asd_ha, lseq_code, lseq_code_size,
441 asd_ha->hw_prof.enabled_phys);
442 if (err) {
443 /* Try it one at a time */
444 u8 lseq;
445 u8 lseq_mask = asd_ha->hw_prof.enabled_phys;
446
447 for_each_sequencer(lseq_mask, lseq_mask, lseq) {
448 err = asd_download_seq(asd_ha, lseq_code,
449 lseq_code_size, 1<<lseq);
450 if (err)
451 break;
452 }
453 }
454 if (err)
455 asd_printk("LSEQs download failed:%d\n", err);
456
457 return err;
458}
459
460/* ---------- Initializing the chip, chip memory, etc. ---------- */
461
462/**
463 * asd_init_cseq_mip - initialize CSEQ mode independent pages 4-7
464 * @asd_ha: pointer to host adapter structure
465 */
466static void asd_init_cseq_mip(struct asd_ha_struct *asd_ha)
467{
468 /* CSEQ Mode Independent, page 4 setup. */
469 asd_write_reg_word(asd_ha, CSEQ_Q_EXE_HEAD, 0xFFFF);
470 asd_write_reg_word(asd_ha, CSEQ_Q_EXE_TAIL, 0xFFFF);
471 asd_write_reg_word(asd_ha, CSEQ_Q_DONE_HEAD, 0xFFFF);
472 asd_write_reg_word(asd_ha, CSEQ_Q_DONE_TAIL, 0xFFFF);
473 asd_write_reg_word(asd_ha, CSEQ_Q_SEND_HEAD, 0xFFFF);
474 asd_write_reg_word(asd_ha, CSEQ_Q_SEND_TAIL, 0xFFFF);
475 asd_write_reg_word(asd_ha, CSEQ_Q_DMA2CHIM_HEAD, 0xFFFF);
476 asd_write_reg_word(asd_ha, CSEQ_Q_DMA2CHIM_TAIL, 0xFFFF);
477 asd_write_reg_word(asd_ha, CSEQ_Q_COPY_HEAD, 0xFFFF);
478 asd_write_reg_word(asd_ha, CSEQ_Q_COPY_TAIL, 0xFFFF);
479 asd_write_reg_word(asd_ha, CSEQ_REG0, 0);
480 asd_write_reg_word(asd_ha, CSEQ_REG1, 0);
481 asd_write_reg_dword(asd_ha, CSEQ_REG2, 0);
482 asd_write_reg_byte(asd_ha, CSEQ_LINK_CTL_Q_MAP, 0);
483 {
484 u8 con = asd_read_reg_byte(asd_ha, CCONEXIST);
485 u8 val = hweight8(con);
486 asd_write_reg_byte(asd_ha, CSEQ_MAX_CSEQ_MODE, (val<<4)|val);
487 }
488 asd_write_reg_word(asd_ha, CSEQ_FREE_LIST_HACK_COUNT, 0);
489
490 /* CSEQ Mode independent, page 5 setup. */
491 asd_write_reg_dword(asd_ha, CSEQ_EST_NEXUS_REQ_QUEUE, 0);
492 asd_write_reg_dword(asd_ha, CSEQ_EST_NEXUS_REQ_QUEUE+4, 0);
493 asd_write_reg_dword(asd_ha, CSEQ_EST_NEXUS_REQ_COUNT, 0);
494 asd_write_reg_dword(asd_ha, CSEQ_EST_NEXUS_REQ_COUNT+4, 0);
495 asd_write_reg_word(asd_ha, CSEQ_Q_EST_NEXUS_HEAD, 0xFFFF);
496 asd_write_reg_word(asd_ha, CSEQ_Q_EST_NEXUS_TAIL, 0xFFFF);
497 asd_write_reg_word(asd_ha, CSEQ_NEED_EST_NEXUS_SCB, 0);
498 asd_write_reg_byte(asd_ha, CSEQ_EST_NEXUS_REQ_HEAD, 0);
499 asd_write_reg_byte(asd_ha, CSEQ_EST_NEXUS_REQ_TAIL, 0);
500 asd_write_reg_byte(asd_ha, CSEQ_EST_NEXUS_SCB_OFFSET, 0);
501
502 /* CSEQ Mode independent, page 6 setup. */
503 asd_write_reg_word(asd_ha, CSEQ_INT_ROUT_RET_ADDR0, 0);
504 asd_write_reg_word(asd_ha, CSEQ_INT_ROUT_RET_ADDR1, 0);
505 asd_write_reg_word(asd_ha, CSEQ_INT_ROUT_SCBPTR, 0);
506 asd_write_reg_byte(asd_ha, CSEQ_INT_ROUT_MODE, 0);
507 asd_write_reg_byte(asd_ha, CSEQ_ISR_SCRATCH_FLAGS, 0);
508 asd_write_reg_word(asd_ha, CSEQ_ISR_SAVE_SINDEX, 0);
509 asd_write_reg_word(asd_ha, CSEQ_ISR_SAVE_DINDEX, 0);
510 asd_write_reg_word(asd_ha, CSEQ_Q_MONIRTT_HEAD, 0xFFFF);
511 asd_write_reg_word(asd_ha, CSEQ_Q_MONIRTT_TAIL, 0xFFFF);
512 /* Calculate the free scb mask. */
513 {
514 u16 cmdctx = asd_get_cmdctx_size(asd_ha);
515 cmdctx = (~((cmdctx/128)-1)) >> 8;
516 asd_write_reg_byte(asd_ha, CSEQ_FREE_SCB_MASK, (u8)cmdctx);
517 }
518 asd_write_reg_word(asd_ha, CSEQ_BUILTIN_FREE_SCB_HEAD,
519 first_scb_site_no);
520 asd_write_reg_word(asd_ha, CSEQ_BUILTIN_FREE_SCB_TAIL,
521 last_scb_site_no);
522 asd_write_reg_word(asd_ha, CSEQ_EXTENDED_FREE_SCB_HEAD, 0xFFFF);
523 asd_write_reg_word(asd_ha, CSEQ_EXTENDED_FREE_SCB_TAIL, 0xFFFF);
524
525 /* CSEQ Mode independent, page 7 setup. */
526 asd_write_reg_dword(asd_ha, CSEQ_EMPTY_REQ_QUEUE, 0);
527 asd_write_reg_dword(asd_ha, CSEQ_EMPTY_REQ_QUEUE+4, 0);
528 asd_write_reg_dword(asd_ha, CSEQ_EMPTY_REQ_COUNT, 0);
529 asd_write_reg_dword(asd_ha, CSEQ_EMPTY_REQ_COUNT+4, 0);
530 asd_write_reg_word(asd_ha, CSEQ_Q_EMPTY_HEAD, 0xFFFF);
531 asd_write_reg_word(asd_ha, CSEQ_Q_EMPTY_TAIL, 0xFFFF);
532 asd_write_reg_word(asd_ha, CSEQ_NEED_EMPTY_SCB, 0);
533 asd_write_reg_byte(asd_ha, CSEQ_EMPTY_REQ_HEAD, 0);
534 asd_write_reg_byte(asd_ha, CSEQ_EMPTY_REQ_TAIL, 0);
535 asd_write_reg_byte(asd_ha, CSEQ_EMPTY_SCB_OFFSET, 0);
536 asd_write_reg_word(asd_ha, CSEQ_PRIMITIVE_DATA, 0);
537 asd_write_reg_dword(asd_ha, CSEQ_TIMEOUT_CONST, 0);
538}
539
540/**
541 * asd_init_cseq_mdp - initialize CSEQ Mode dependent pages
542 * @asd_ha: pointer to host adapter structure
543 */
544static void asd_init_cseq_mdp(struct asd_ha_struct *asd_ha)
545{
546 int i;
547 int moffs;
548
549 moffs = CSEQ_PAGE_SIZE * 2;
550
551 /* CSEQ Mode dependent, modes 0-7, page 0 setup. */
552 for (i = 0; i < 8; i++) {
553 asd_write_reg_word(asd_ha, i*moffs+CSEQ_LRM_SAVE_SINDEX, 0);
554 asd_write_reg_word(asd_ha, i*moffs+CSEQ_LRM_SAVE_SCBPTR, 0);
555 asd_write_reg_word(asd_ha, i*moffs+CSEQ_Q_LINK_HEAD, 0xFFFF);
556 asd_write_reg_word(asd_ha, i*moffs+CSEQ_Q_LINK_TAIL, 0xFFFF);
557 asd_write_reg_byte(asd_ha, i*moffs+CSEQ_LRM_SAVE_SCRPAGE, 0);
558 }
559
560 /* CSEQ Mode dependent, mode 0-7, page 1 and 2 shall be ignored. */
561
562 /* CSEQ Mode dependent, mode 8, page 0 setup. */
563 asd_write_reg_word(asd_ha, CSEQ_RET_ADDR, 0xFFFF);
564 asd_write_reg_word(asd_ha, CSEQ_RET_SCBPTR, 0);
565 asd_write_reg_word(asd_ha, CSEQ_SAVE_SCBPTR, 0);
566 asd_write_reg_word(asd_ha, CSEQ_EMPTY_TRANS_CTX, 0);
567 asd_write_reg_word(asd_ha, CSEQ_RESP_LEN, 0);
568 asd_write_reg_word(asd_ha, CSEQ_TMF_SCBPTR, 0);
569 asd_write_reg_word(asd_ha, CSEQ_GLOBAL_PREV_SCB, 0);
570 asd_write_reg_word(asd_ha, CSEQ_GLOBAL_HEAD, 0);
571 asd_write_reg_word(asd_ha, CSEQ_CLEAR_LU_HEAD, 0);
572 asd_write_reg_byte(asd_ha, CSEQ_TMF_OPCODE, 0);
573 asd_write_reg_byte(asd_ha, CSEQ_SCRATCH_FLAGS, 0);
574 asd_write_reg_word(asd_ha, CSEQ_HSB_SITE, 0);
575 asd_write_reg_word(asd_ha, CSEQ_FIRST_INV_SCB_SITE,
576 (u16)last_scb_site_no+1);
577 asd_write_reg_word(asd_ha, CSEQ_FIRST_INV_DDB_SITE,
578 (u16)asd_ha->hw_prof.max_ddbs);
579
580 /* CSEQ Mode dependent, mode 8, page 1 setup. */
581 asd_write_reg_dword(asd_ha, CSEQ_LUN_TO_CLEAR, 0);
582 asd_write_reg_dword(asd_ha, CSEQ_LUN_TO_CLEAR + 4, 0);
583 asd_write_reg_dword(asd_ha, CSEQ_LUN_TO_CHECK, 0);
584 asd_write_reg_dword(asd_ha, CSEQ_LUN_TO_CHECK + 4, 0);
585
586 /* CSEQ Mode dependent, mode 8, page 2 setup. */
587 /* Tell the sequencer the bus address of the first SCB. */
588 asd_write_reg_addr(asd_ha, CSEQ_HQ_NEW_POINTER,
589 asd_ha->seq.next_scb.dma_handle);
590 ASD_DPRINTK("First SCB dma_handle: 0x%llx\n",
591 (unsigned long long)asd_ha->seq.next_scb.dma_handle);
592
593 /* Tell the sequencer the first Done List entry address. */
594 asd_write_reg_addr(asd_ha, CSEQ_HQ_DONE_BASE,
595 asd_ha->seq.actual_dl->dma_handle);
596
597 /* Initialize the Q_DONE_POINTER with the least significant
598 * 4 bytes of the first Done List address. */
599 asd_write_reg_dword(asd_ha, CSEQ_HQ_DONE_POINTER,
600 ASD_BUSADDR_LO(asd_ha->seq.actual_dl->dma_handle));
601
602 asd_write_reg_byte(asd_ha, CSEQ_HQ_DONE_PASS, ASD_DEF_DL_TOGGLE);
603
604 /* CSEQ Mode dependent, mode 8, page 3 shall be ignored. */
605}
606
607/**
608 * asd_init_cseq_scratch -- setup and init CSEQ
609 * @asd_ha: pointer to host adapter structure
610 *
611 * Setup and initialize Central sequencers. Initialiaze the mode
612 * independent and dependent scratch page to the default settings.
613 */
614static void asd_init_cseq_scratch(struct asd_ha_struct *asd_ha)
615{
616 asd_init_cseq_mip(asd_ha);
617 asd_init_cseq_mdp(asd_ha);
618}
619
620/**
621 * asd_init_lseq_mip -- initialize LSEQ Mode independent pages 0-3
622 * @asd_ha: pointer to host adapter structure
623 */
624static void asd_init_lseq_mip(struct asd_ha_struct *asd_ha, u8 lseq)
625{
626 int i;
627
628 /* LSEQ Mode independent page 0 setup. */
629 asd_write_reg_word(asd_ha, LmSEQ_Q_TGTXFR_HEAD(lseq), 0xFFFF);
630 asd_write_reg_word(asd_ha, LmSEQ_Q_TGTXFR_TAIL(lseq), 0xFFFF);
631 asd_write_reg_byte(asd_ha, LmSEQ_LINK_NUMBER(lseq), lseq);
632 asd_write_reg_byte(asd_ha, LmSEQ_SCRATCH_FLAGS(lseq),
633 ASD_NOTIFY_ENABLE_SPINUP);
634 asd_write_reg_dword(asd_ha, LmSEQ_CONNECTION_STATE(lseq),0x08000000);
635 asd_write_reg_word(asd_ha, LmSEQ_CONCTL(lseq), 0);
636 asd_write_reg_byte(asd_ha, LmSEQ_CONSTAT(lseq), 0);
637 asd_write_reg_byte(asd_ha, LmSEQ_CONNECTION_MODES(lseq), 0);
638 asd_write_reg_word(asd_ha, LmSEQ_REG1_ISR(lseq), 0);
639 asd_write_reg_word(asd_ha, LmSEQ_REG2_ISR(lseq), 0);
640 asd_write_reg_word(asd_ha, LmSEQ_REG3_ISR(lseq), 0);
641 asd_write_reg_dword(asd_ha, LmSEQ_REG0_ISR(lseq), 0);
642 asd_write_reg_dword(asd_ha, LmSEQ_REG0_ISR(lseq)+4, 0);
643
644 /* LSEQ Mode independent page 1 setup. */
645 asd_write_reg_word(asd_ha, LmSEQ_EST_NEXUS_SCBPTR0(lseq), 0xFFFF);
646 asd_write_reg_word(asd_ha, LmSEQ_EST_NEXUS_SCBPTR1(lseq), 0xFFFF);
647 asd_write_reg_word(asd_ha, LmSEQ_EST_NEXUS_SCBPTR2(lseq), 0xFFFF);
648 asd_write_reg_word(asd_ha, LmSEQ_EST_NEXUS_SCBPTR3(lseq), 0xFFFF);
649 asd_write_reg_byte(asd_ha, LmSEQ_EST_NEXUS_SCB_OPCODE0(lseq), 0);
650 asd_write_reg_byte(asd_ha, LmSEQ_EST_NEXUS_SCB_OPCODE1(lseq), 0);
651 asd_write_reg_byte(asd_ha, LmSEQ_EST_NEXUS_SCB_OPCODE2(lseq), 0);
652 asd_write_reg_byte(asd_ha, LmSEQ_EST_NEXUS_SCB_OPCODE3(lseq), 0);
653 asd_write_reg_byte(asd_ha, LmSEQ_EST_NEXUS_SCB_HEAD(lseq), 0);
654 asd_write_reg_byte(asd_ha, LmSEQ_EST_NEXUS_SCB_TAIL(lseq), 0);
655 asd_write_reg_byte(asd_ha, LmSEQ_EST_NEXUS_BUF_AVAIL(lseq), 0);
656 asd_write_reg_dword(asd_ha, LmSEQ_TIMEOUT_CONST(lseq), 0);
657 asd_write_reg_word(asd_ha, LmSEQ_ISR_SAVE_SINDEX(lseq), 0);
658 asd_write_reg_word(asd_ha, LmSEQ_ISR_SAVE_DINDEX(lseq), 0);
659
660 /* LSEQ Mode Independent page 2 setup. */
661 asd_write_reg_word(asd_ha, LmSEQ_EMPTY_SCB_PTR0(lseq), 0xFFFF);
662 asd_write_reg_word(asd_ha, LmSEQ_EMPTY_SCB_PTR1(lseq), 0xFFFF);
663 asd_write_reg_word(asd_ha, LmSEQ_EMPTY_SCB_PTR2(lseq), 0xFFFF);
664 asd_write_reg_word(asd_ha, LmSEQ_EMPTY_SCB_PTR3(lseq), 0xFFFF);
665 asd_write_reg_byte(asd_ha, LmSEQ_EMPTY_SCB_OPCD0(lseq), 0);
666 asd_write_reg_byte(asd_ha, LmSEQ_EMPTY_SCB_OPCD1(lseq), 0);
667 asd_write_reg_byte(asd_ha, LmSEQ_EMPTY_SCB_OPCD2(lseq), 0);
668 asd_write_reg_byte(asd_ha, LmSEQ_EMPTY_SCB_OPCD3(lseq), 0);
669 asd_write_reg_byte(asd_ha, LmSEQ_EMPTY_SCB_HEAD(lseq), 0);
670 asd_write_reg_byte(asd_ha, LmSEQ_EMPTY_SCB_TAIL(lseq), 0);
671 asd_write_reg_byte(asd_ha, LmSEQ_EMPTY_BUFS_AVAIL(lseq), 0);
672 for (i = 0; i < 12; i += 4)
673 asd_write_reg_dword(asd_ha, LmSEQ_ATA_SCR_REGS(lseq) + i, 0);
674
675 /* LSEQ Mode Independent page 3 setup. */
676
677 /* Device present timer timeout */
678 asd_write_reg_dword(asd_ha, LmSEQ_DEV_PRES_TMR_TOUT_CONST(lseq),
679 ASD_DEV_PRESENT_TIMEOUT);
680
681 /* SATA interlock timer disabled */
682 asd_write_reg_dword(asd_ha, LmSEQ_SATA_INTERLOCK_TIMEOUT(lseq),
683 ASD_SATA_INTERLOCK_TIMEOUT);
684
685 /* STP shutdown timer timeout constant, IGNORED by the sequencer,
686 * always 0. */
687 asd_write_reg_dword(asd_ha, LmSEQ_STP_SHUTDOWN_TIMEOUT(lseq),
688 ASD_STP_SHUTDOWN_TIMEOUT);
689
690 asd_write_reg_dword(asd_ha, LmSEQ_SRST_ASSERT_TIMEOUT(lseq),
691 ASD_SRST_ASSERT_TIMEOUT);
692
693 asd_write_reg_dword(asd_ha, LmSEQ_RCV_FIS_TIMEOUT(lseq),
694 ASD_RCV_FIS_TIMEOUT);
695
696 asd_write_reg_dword(asd_ha, LmSEQ_ONE_MILLISEC_TIMEOUT(lseq),
697 ASD_ONE_MILLISEC_TIMEOUT);
698
699 /* COM_INIT timer */
700 asd_write_reg_dword(asd_ha, LmSEQ_TEN_MS_COMINIT_TIMEOUT(lseq),
701 ASD_TEN_MILLISEC_TIMEOUT);
702
703 asd_write_reg_dword(asd_ha, LmSEQ_SMP_RCV_TIMEOUT(lseq),
704 ASD_SMP_RCV_TIMEOUT);
705}
706
707/**
708 * asd_init_lseq_mdp -- initialize LSEQ mode dependent pages.
709 * @asd_ha: pointer to host adapter structure
710 */
711static void asd_init_lseq_mdp(struct asd_ha_struct *asd_ha, int lseq)
712{
713 int i;
714 u32 moffs;
715 u16 ret_addr[] = {
716 0xFFFF, /* mode 0 */
717 0xFFFF, /* mode 1 */
718 mode2_task, /* mode 2 */
719 0,
720 0xFFFF, /* mode 4/5 */
721 0xFFFF, /* mode 4/5 */
722 };
723
724 /*
725 * Mode 0,1,2 and 4/5 have common field on page 0 for the first
726 * 14 bytes.
727 */
728 for (i = 0; i < 3; i++) {
729 moffs = i * LSEQ_MODE_SCRATCH_SIZE;
730 asd_write_reg_word(asd_ha, LmSEQ_RET_ADDR(lseq)+moffs,
731 ret_addr[i]);
732 asd_write_reg_word(asd_ha, LmSEQ_REG0_MODE(lseq)+moffs, 0);
733 asd_write_reg_word(asd_ha, LmSEQ_MODE_FLAGS(lseq)+moffs, 0);
734 asd_write_reg_word(asd_ha, LmSEQ_RET_ADDR2(lseq)+moffs,0xFFFF);
735 asd_write_reg_word(asd_ha, LmSEQ_RET_ADDR1(lseq)+moffs,0xFFFF);
736 asd_write_reg_byte(asd_ha, LmSEQ_OPCODE_TO_CSEQ(lseq)+moffs,0);
737 asd_write_reg_word(asd_ha, LmSEQ_DATA_TO_CSEQ(lseq)+moffs,0);
738 }
739 /*
740 * Mode 5 page 0 overlaps the same scratch page with Mode 0 page 3.
741 */
742 asd_write_reg_word(asd_ha,
743 LmSEQ_RET_ADDR(lseq)+LSEQ_MODE5_PAGE0_OFFSET,
744 ret_addr[5]);
745 asd_write_reg_word(asd_ha,
746 LmSEQ_REG0_MODE(lseq)+LSEQ_MODE5_PAGE0_OFFSET,0);
747 asd_write_reg_word(asd_ha,
748 LmSEQ_MODE_FLAGS(lseq)+LSEQ_MODE5_PAGE0_OFFSET, 0);
749 asd_write_reg_word(asd_ha,
750 LmSEQ_RET_ADDR2(lseq)+LSEQ_MODE5_PAGE0_OFFSET,0xFFFF);
751 asd_write_reg_word(asd_ha,
752 LmSEQ_RET_ADDR1(lseq)+LSEQ_MODE5_PAGE0_OFFSET,0xFFFF);
753 asd_write_reg_byte(asd_ha,
754 LmSEQ_OPCODE_TO_CSEQ(lseq)+LSEQ_MODE5_PAGE0_OFFSET,0);
755 asd_write_reg_word(asd_ha,
756 LmSEQ_DATA_TO_CSEQ(lseq)+LSEQ_MODE5_PAGE0_OFFSET, 0);
757
758 /* LSEQ Mode dependent 0, page 0 setup. */
759 asd_write_reg_word(asd_ha, LmSEQ_FIRST_INV_DDB_SITE(lseq),
760 (u16)asd_ha->hw_prof.max_ddbs);
761 asd_write_reg_word(asd_ha, LmSEQ_EMPTY_TRANS_CTX(lseq), 0);
762 asd_write_reg_word(asd_ha, LmSEQ_RESP_LEN(lseq), 0);
763 asd_write_reg_word(asd_ha, LmSEQ_FIRST_INV_SCB_SITE(lseq),
764 (u16)last_scb_site_no+1);
765 asd_write_reg_word(asd_ha, LmSEQ_INTEN_SAVE(lseq),
766 (u16) LmM0INTEN_MASK & 0xFFFF0000 >> 16);
767 asd_write_reg_word(asd_ha, LmSEQ_INTEN_SAVE(lseq) + 2,
768 (u16) LmM0INTEN_MASK & 0xFFFF);
769 asd_write_reg_byte(asd_ha, LmSEQ_LINK_RST_FRM_LEN(lseq), 0);
770 asd_write_reg_byte(asd_ha, LmSEQ_LINK_RST_PROTOCOL(lseq), 0);
771 asd_write_reg_byte(asd_ha, LmSEQ_RESP_STATUS(lseq), 0);
772 asd_write_reg_byte(asd_ha, LmSEQ_LAST_LOADED_SGE(lseq), 0);
773 asd_write_reg_word(asd_ha, LmSEQ_SAVE_SCBPTR(lseq), 0);
774
775 /* LSEQ mode dependent, mode 1, page 0 setup. */
776 asd_write_reg_word(asd_ha, LmSEQ_Q_XMIT_HEAD(lseq), 0xFFFF);
777 asd_write_reg_word(asd_ha, LmSEQ_M1_EMPTY_TRANS_CTX(lseq), 0);
778 asd_write_reg_word(asd_ha, LmSEQ_INI_CONN_TAG(lseq), 0);
779 asd_write_reg_byte(asd_ha, LmSEQ_FAILED_OPEN_STATUS(lseq), 0);
780 asd_write_reg_byte(asd_ha, LmSEQ_XMIT_REQUEST_TYPE(lseq), 0);
781 asd_write_reg_byte(asd_ha, LmSEQ_M1_RESP_STATUS(lseq), 0);
782 asd_write_reg_byte(asd_ha, LmSEQ_M1_LAST_LOADED_SGE(lseq), 0);
783 asd_write_reg_word(asd_ha, LmSEQ_M1_SAVE_SCBPTR(lseq), 0);
784
785 /* LSEQ Mode dependent mode 2, page 0 setup */
786 asd_write_reg_word(asd_ha, LmSEQ_PORT_COUNTER(lseq), 0);
787 asd_write_reg_word(asd_ha, LmSEQ_PM_TABLE_PTR(lseq), 0);
788 asd_write_reg_word(asd_ha, LmSEQ_SATA_INTERLOCK_TMR_SAVE(lseq), 0);
789 asd_write_reg_word(asd_ha, LmSEQ_IP_BITL(lseq), 0);
790 asd_write_reg_word(asd_ha, LmSEQ_COPY_SMP_CONN_TAG(lseq), 0);
791 asd_write_reg_byte(asd_ha, LmSEQ_P0M2_OFFS1AH(lseq), 0);
792
793 /* LSEQ Mode dependent, mode 4/5, page 0 setup. */
794 asd_write_reg_byte(asd_ha, LmSEQ_SAVED_OOB_STATUS(lseq), 0);
795 asd_write_reg_byte(asd_ha, LmSEQ_SAVED_OOB_MODE(lseq), 0);
796 asd_write_reg_word(asd_ha, LmSEQ_Q_LINK_HEAD(lseq), 0xFFFF);
797 asd_write_reg_byte(asd_ha, LmSEQ_LINK_RST_ERR(lseq), 0);
798 asd_write_reg_byte(asd_ha, LmSEQ_SAVED_OOB_SIGNALS(lseq), 0);
799 asd_write_reg_byte(asd_ha, LmSEQ_SAS_RESET_MODE(lseq), 0);
800 asd_write_reg_byte(asd_ha, LmSEQ_LINK_RESET_RETRY_COUNT(lseq), 0);
801 asd_write_reg_byte(asd_ha, LmSEQ_NUM_LINK_RESET_RETRIES(lseq), 0);
802 asd_write_reg_word(asd_ha, LmSEQ_OOB_INT_ENABLES(lseq), 0);
803 /*
804 * Set the desired interval between transmissions of the NOTIFY
805 * (ENABLE SPINUP) primitive. Must be initilized to val - 1.
806 */
807 asd_write_reg_word(asd_ha, LmSEQ_NOTIFY_TIMER_TIMEOUT(lseq),
808 ASD_NOTIFY_TIMEOUT - 1);
809 /* No delay for the first NOTIFY to be sent to the attached target. */
810 asd_write_reg_word(asd_ha, LmSEQ_NOTIFY_TIMER_DOWN_COUNT(lseq),
811 ASD_NOTIFY_DOWN_COUNT);
812
813 /* LSEQ Mode dependent, mode 0 and 1, page 1 setup. */
814 for (i = 0; i < 2; i++) {
815 int j;
816 /* Start from Page 1 of Mode 0 and 1. */
817 moffs = LSEQ_PAGE_SIZE + i*LSEQ_MODE_SCRATCH_SIZE;
818 /* All the fields of page 1 can be intialized to 0. */
819 for (j = 0; j < LSEQ_PAGE_SIZE; j += 4)
820 asd_write_reg_dword(asd_ha, LmSCRATCH(lseq)+moffs+j,0);
821 }
822
823 /* LSEQ Mode dependent, mode 2, page 1 setup. */
824 asd_write_reg_dword(asd_ha, LmSEQ_INVALID_DWORD_COUNT(lseq), 0);
825 asd_write_reg_dword(asd_ha, LmSEQ_DISPARITY_ERROR_COUNT(lseq), 0);
826 asd_write_reg_dword(asd_ha, LmSEQ_LOSS_OF_SYNC_COUNT(lseq), 0);
827
828 /* LSEQ Mode dependent, mode 4/5, page 1. */
829 for (i = 0; i < LSEQ_PAGE_SIZE; i+=4)
830 asd_write_reg_dword(asd_ha, LmSEQ_FRAME_TYPE_MASK(lseq)+i, 0);
831 asd_write_reg_byte(asd_ha, LmSEQ_FRAME_TYPE_MASK(lseq), 0xFF);
832 asd_write_reg_byte(asd_ha, LmSEQ_HASHED_DEST_ADDR_MASK(lseq), 0xFF);
833 asd_write_reg_byte(asd_ha, LmSEQ_HASHED_DEST_ADDR_MASK(lseq)+1,0xFF);
834 asd_write_reg_byte(asd_ha, LmSEQ_HASHED_DEST_ADDR_MASK(lseq)+2,0xFF);
835 asd_write_reg_byte(asd_ha, LmSEQ_HASHED_SRC_ADDR_MASK(lseq), 0xFF);
836 asd_write_reg_byte(asd_ha, LmSEQ_HASHED_SRC_ADDR_MASK(lseq)+1, 0xFF);
837 asd_write_reg_byte(asd_ha, LmSEQ_HASHED_SRC_ADDR_MASK(lseq)+2, 0xFF);
838 asd_write_reg_dword(asd_ha, LmSEQ_DATA_OFFSET(lseq), 0xFFFFFFFF);
839
840 /* LSEQ Mode dependent, mode 0, page 2 setup. */
841 asd_write_reg_dword(asd_ha, LmSEQ_SMP_RCV_TIMER_TERM_TS(lseq), 0);
842 asd_write_reg_byte(asd_ha, LmSEQ_DEVICE_BITS(lseq), 0);
843 asd_write_reg_word(asd_ha, LmSEQ_SDB_DDB(lseq), 0);
844 asd_write_reg_byte(asd_ha, LmSEQ_SDB_NUM_TAGS(lseq), 0);
845 asd_write_reg_byte(asd_ha, LmSEQ_SDB_CURR_TAG(lseq), 0);
846
847 /* LSEQ Mode Dependent 1, page 2 setup. */
848 asd_write_reg_dword(asd_ha, LmSEQ_TX_ID_ADDR_FRAME(lseq), 0);
849 asd_write_reg_dword(asd_ha, LmSEQ_TX_ID_ADDR_FRAME(lseq)+4, 0);
850 asd_write_reg_dword(asd_ha, LmSEQ_OPEN_TIMER_TERM_TS(lseq), 0);
851 asd_write_reg_dword(asd_ha, LmSEQ_SRST_AS_TIMER_TERM_TS(lseq), 0);
852 asd_write_reg_dword(asd_ha, LmSEQ_LAST_LOADED_SG_EL(lseq), 0);
853
854 /* LSEQ Mode Dependent 2, page 2 setup. */
855 /* The LmSEQ_STP_SHUTDOWN_TIMER_TERM_TS is IGNORED by the sequencer,
856 * i.e. always 0. */
857 asd_write_reg_dword(asd_ha, LmSEQ_STP_SHUTDOWN_TIMER_TERM_TS(lseq),0);
858 asd_write_reg_dword(asd_ha, LmSEQ_CLOSE_TIMER_TERM_TS(lseq), 0);
859 asd_write_reg_dword(asd_ha, LmSEQ_BREAK_TIMER_TERM_TS(lseq), 0);
860 asd_write_reg_dword(asd_ha, LmSEQ_DWS_RESET_TIMER_TERM_TS(lseq), 0);
861 asd_write_reg_dword(asd_ha,LmSEQ_SATA_INTERLOCK_TIMER_TERM_TS(lseq),0);
862 asd_write_reg_dword(asd_ha, LmSEQ_MCTL_TIMER_TERM_TS(lseq), 0);
863
864 /* LSEQ Mode Dependent 4/5, page 2 setup. */
865 asd_write_reg_dword(asd_ha, LmSEQ_COMINIT_TIMER_TERM_TS(lseq), 0);
866 asd_write_reg_dword(asd_ha, LmSEQ_RCV_ID_TIMER_TERM_TS(lseq), 0);
867 asd_write_reg_dword(asd_ha, LmSEQ_RCV_FIS_TIMER_TERM_TS(lseq), 0);
868 asd_write_reg_dword(asd_ha, LmSEQ_DEV_PRES_TIMER_TERM_TS(lseq), 0);
869}
870
871/**
872 * asd_init_lseq_scratch -- setup and init link sequencers
873 * @asd_ha: pointer to host adapter struct
874 */
875static void asd_init_lseq_scratch(struct asd_ha_struct *asd_ha)
876{
877 u8 lseq;
878 u8 lseq_mask;
879
880 lseq_mask = asd_ha->hw_prof.enabled_phys;
881 for_each_sequencer(lseq_mask, lseq_mask, lseq) {
882 asd_init_lseq_mip(asd_ha, lseq);
883 asd_init_lseq_mdp(asd_ha, lseq);
884 }
885}
886
887/**
888 * asd_init_scb_sites -- initialize sequencer SCB sites (memory).
889 * @asd_ha: pointer to host adapter structure
890 *
891 * This should be done before initializing common CSEQ and LSEQ
892 * scratch since those areas depend on some computed values here,
893 * last_scb_site_no, etc.
894 */
895static void asd_init_scb_sites(struct asd_ha_struct *asd_ha)
896{
897 u16 site_no;
898 u16 max_scbs = 0;
899
900 for (site_no = asd_ha->hw_prof.max_scbs-1;
901 site_no != (u16) -1;
902 site_no--) {
903 u16 i;
904
905 /* Initialize all fields in the SCB site to 0. */
906 for (i = 0; i < ASD_SCB_SIZE; i += 4)
907 asd_scbsite_write_dword(asd_ha, site_no, i, 0);
908
909 /* Workaround needed by SEQ to fix a SATA issue is to exclude
910 * certain SCB sites from the free list. */
911 if (!SCB_SITE_VALID(site_no))
912 continue;
913
914 if (last_scb_site_no == 0)
915 last_scb_site_no = site_no;
916
917 /* For every SCB site, we need to initialize the
918 * following fields: Q_NEXT, SCB_OPCODE, SCB_FLAGS,
919 * and SG Element Flag. */
920
921 /* Q_NEXT field of the last SCB is invalidated. */
922 asd_scbsite_write_word(asd_ha, site_no, 0, first_scb_site_no);
923
924 /* Initialize SCB Site Opcode field to invalid. */
925 asd_scbsite_write_byte(asd_ha, site_no,
926 offsetof(struct scb_header, opcode),
927 0xFF);
928
929 /* Initialize SCB Site Flags field to mean a response
930 * frame has been received. This means inadvertent
931 * frames received to be dropped. */
932 asd_scbsite_write_byte(asd_ha, site_no, 0x49, 0x01);
933
934 first_scb_site_no = site_no;
935 max_scbs++;
936 }
937 asd_ha->hw_prof.max_scbs = max_scbs;
938 ASD_DPRINTK("max_scbs:%d\n", asd_ha->hw_prof.max_scbs);
939 ASD_DPRINTK("first_scb_site_no:0x%x\n", first_scb_site_no);
940 ASD_DPRINTK("last_scb_site_no:0x%x\n", last_scb_site_no);
941}
942
943/**
944 * asd_init_cseq_cio - initialize CSEQ CIO registers
945 * @asd_ha: pointer to host adapter structure
946 */
947static void asd_init_cseq_cio(struct asd_ha_struct *asd_ha)
948{
949 int i;
950
951 asd_write_reg_byte(asd_ha, CSEQCOMINTEN, 0);
952 asd_write_reg_byte(asd_ha, CSEQDLCTL, ASD_DL_SIZE_BITS);
953 asd_write_reg_byte(asd_ha, CSEQDLOFFS, 0);
954 asd_write_reg_byte(asd_ha, CSEQDLOFFS+1, 0);
955 asd_ha->seq.scbpro = 0;
956 asd_write_reg_dword(asd_ha, SCBPRO, 0);
957 asd_write_reg_dword(asd_ha, CSEQCON, 0);
958
959 /* Intialize CSEQ Mode 11 Interrupt Vectors.
960 * The addresses are 16 bit wide and in dword units.
961 * The values of their macros are in byte units.
962 * Thus we have to divide by 4. */
963 asd_write_reg_word(asd_ha, CM11INTVEC0, cseq_vecs[0]);
964 asd_write_reg_word(asd_ha, CM11INTVEC1, cseq_vecs[1]);
965 asd_write_reg_word(asd_ha, CM11INTVEC2, cseq_vecs[2]);
966
967 /* Enable ARP2HALTC (ARP2 Halted from Halt Code Write). */
968 asd_write_reg_byte(asd_ha, CARP2INTEN, EN_ARP2HALTC);
969
970 /* Initialize CSEQ Scratch Page to 0x04. */
971 asd_write_reg_byte(asd_ha, CSCRATCHPAGE, 0x04);
972
973 /* Initialize CSEQ Mode[0-8] Dependent registers. */
974 /* Initialize Scratch Page to 0. */
975 for (i = 0; i < 9; i++)
976 asd_write_reg_byte(asd_ha, CMnSCRATCHPAGE(i), 0);
977
978 /* Reset the ARP2 Program Count. */
979 asd_write_reg_word(asd_ha, CPRGMCNT, cseq_idle_loop);
980
981 for (i = 0; i < 8; i++) {
982 /* Intialize Mode n Link m Interrupt Enable. */
983 asd_write_reg_dword(asd_ha, CMnINTEN(i), EN_CMnRSPMBXF);
984 /* Initialize Mode n Request Mailbox. */
985 asd_write_reg_dword(asd_ha, CMnREQMBX(i), 0);
986 }
987}
988
989/**
990 * asd_init_lseq_cio -- initialize LmSEQ CIO registers
991 * @asd_ha: pointer to host adapter structure
992 */
993static void asd_init_lseq_cio(struct asd_ha_struct *asd_ha, int lseq)
994{
995 u8 *sas_addr;
996 int i;
997
998 /* Enable ARP2HALTC (ARP2 Halted from Halt Code Write). */
999 asd_write_reg_dword(asd_ha, LmARP2INTEN(lseq), EN_ARP2HALTC);
1000
1001 asd_write_reg_byte(asd_ha, LmSCRATCHPAGE(lseq), 0);
1002
1003 /* Initialize Mode 0,1, and 2 SCRATCHPAGE to 0. */
1004 for (i = 0; i < 3; i++)
1005 asd_write_reg_byte(asd_ha, LmMnSCRATCHPAGE(lseq, i), 0);
1006
1007 /* Initialize Mode 5 SCRATCHPAGE to 0. */
1008 asd_write_reg_byte(asd_ha, LmMnSCRATCHPAGE(lseq, 5), 0);
1009
1010 asd_write_reg_dword(asd_ha, LmRSPMBX(lseq), 0);
1011 /* Initialize Mode 0,1,2 and 5 Interrupt Enable and
1012 * Interrupt registers. */
1013 asd_write_reg_dword(asd_ha, LmMnINTEN(lseq, 0), LmM0INTEN_MASK);
1014 asd_write_reg_dword(asd_ha, LmMnINT(lseq, 0), 0xFFFFFFFF);
1015 /* Mode 1 */
1016 asd_write_reg_dword(asd_ha, LmMnINTEN(lseq, 1), LmM1INTEN_MASK);
1017 asd_write_reg_dword(asd_ha, LmMnINT(lseq, 1), 0xFFFFFFFF);
1018 /* Mode 2 */
1019 asd_write_reg_dword(asd_ha, LmMnINTEN(lseq, 2), LmM2INTEN_MASK);
1020 asd_write_reg_dword(asd_ha, LmMnINT(lseq, 2), 0xFFFFFFFF);
1021 /* Mode 5 */
1022 asd_write_reg_dword(asd_ha, LmMnINTEN(lseq, 5), LmM5INTEN_MASK);
1023 asd_write_reg_dword(asd_ha, LmMnINT(lseq, 5), 0xFFFFFFFF);
1024
1025 /* Enable HW Timer status. */
1026 asd_write_reg_byte(asd_ha, LmHWTSTATEN(lseq), LmHWTSTATEN_MASK);
1027
1028 /* Enable Primitive Status 0 and 1. */
1029 asd_write_reg_dword(asd_ha, LmPRIMSTAT0EN(lseq), LmPRIMSTAT0EN_MASK);
1030 asd_write_reg_dword(asd_ha, LmPRIMSTAT1EN(lseq), LmPRIMSTAT1EN_MASK);
1031
1032 /* Enable Frame Error. */
1033 asd_write_reg_dword(asd_ha, LmFRMERREN(lseq), LmFRMERREN_MASK);
1034 asd_write_reg_byte(asd_ha, LmMnHOLDLVL(lseq, 0), 0x50);
1035
1036 /* Initialize Mode 0 Transfer Level to 512. */
1037 asd_write_reg_byte(asd_ha, LmMnXFRLVL(lseq, 0), LmMnXFRLVL_512);
1038 /* Initialize Mode 1 Transfer Level to 256. */
1039 asd_write_reg_byte(asd_ha, LmMnXFRLVL(lseq, 1), LmMnXFRLVL_256);
1040
1041 /* Initialize Program Count. */
1042 asd_write_reg_word(asd_ha, LmPRGMCNT(lseq), lseq_idle_loop);
1043
1044 /* Enable Blind SG Move. */
1045 asd_write_reg_dword(asd_ha, LmMODECTL(lseq), LmBLIND48);
1046 asd_write_reg_word(asd_ha, LmM3SATATIMER(lseq),
1047 ASD_SATA_INTERLOCK_TIMEOUT);
1048
1049 (void) asd_read_reg_dword(asd_ha, LmREQMBX(lseq));
1050
1051 /* Clear Primitive Status 0 and 1. */
1052 asd_write_reg_dword(asd_ha, LmPRMSTAT0(lseq), 0xFFFFFFFF);
1053 asd_write_reg_dword(asd_ha, LmPRMSTAT1(lseq), 0xFFFFFFFF);
1054
1055 /* Clear HW Timer status. */
1056 asd_write_reg_byte(asd_ha, LmHWTSTAT(lseq), 0xFF);
1057
1058 /* Clear DMA Errors for Mode 0 and 1. */
1059 asd_write_reg_byte(asd_ha, LmMnDMAERRS(lseq, 0), 0xFF);
1060 asd_write_reg_byte(asd_ha, LmMnDMAERRS(lseq, 1), 0xFF);
1061
1062 /* Clear SG DMA Errors for Mode 0 and 1. */
1063 asd_write_reg_byte(asd_ha, LmMnSGDMAERRS(lseq, 0), 0xFF);
1064 asd_write_reg_byte(asd_ha, LmMnSGDMAERRS(lseq, 1), 0xFF);
1065
1066 /* Clear Mode 0 Buffer Parity Error. */
1067 asd_write_reg_byte(asd_ha, LmMnBUFSTAT(lseq, 0), LmMnBUFPERR);
1068
1069 /* Clear Mode 0 Frame Error register. */
1070 asd_write_reg_dword(asd_ha, LmMnFRMERR(lseq, 0), 0xFFFFFFFF);
1071
1072 /* Reset LSEQ external interrupt arbiter. */
1073 asd_write_reg_byte(asd_ha, LmARP2INTCTL(lseq), RSTINTCTL);
1074
1075 /* Set the Phy SAS for the LmSEQ WWN. */
1076 sas_addr = asd_ha->phys[lseq].phy_desc->sas_addr;
1077 for (i = 0; i < SAS_ADDR_SIZE; i++)
1078 asd_write_reg_byte(asd_ha, LmWWN(lseq) + i, sas_addr[i]);
1079
1080 /* Set the Transmit Size to 1024 bytes, 0 = 256 Dwords. */
1081 asd_write_reg_byte(asd_ha, LmMnXMTSIZE(lseq, 1), 0);
1082
1083 /* Set the Bus Inactivity Time Limit Timer. */
1084 asd_write_reg_word(asd_ha, LmBITL_TIMER(lseq), 9);
1085
1086 /* Enable SATA Port Multiplier. */
1087 asd_write_reg_byte(asd_ha, LmMnSATAFS(lseq, 1), 0x80);
1088
1089 /* Initialize Interrupt Vector[0-10] address in Mode 3.
1090 * See the comment on CSEQ_INT_* */
1091 asd_write_reg_word(asd_ha, LmM3INTVEC0(lseq), lseq_vecs[0]);
1092 asd_write_reg_word(asd_ha, LmM3INTVEC1(lseq), lseq_vecs[1]);
1093 asd_write_reg_word(asd_ha, LmM3INTVEC2(lseq), lseq_vecs[2]);
1094 asd_write_reg_word(asd_ha, LmM3INTVEC3(lseq), lseq_vecs[3]);
1095 asd_write_reg_word(asd_ha, LmM3INTVEC4(lseq), lseq_vecs[4]);
1096 asd_write_reg_word(asd_ha, LmM3INTVEC5(lseq), lseq_vecs[5]);
1097 asd_write_reg_word(asd_ha, LmM3INTVEC6(lseq), lseq_vecs[6]);
1098 asd_write_reg_word(asd_ha, LmM3INTVEC7(lseq), lseq_vecs[7]);
1099 asd_write_reg_word(asd_ha, LmM3INTVEC8(lseq), lseq_vecs[8]);
1100 asd_write_reg_word(asd_ha, LmM3INTVEC9(lseq), lseq_vecs[9]);
1101 asd_write_reg_word(asd_ha, LmM3INTVEC10(lseq), lseq_vecs[10]);
1102 /*
1103 * Program the Link LED control, applicable only for
1104 * Chip Rev. B or later.
1105 */
1106 asd_write_reg_dword(asd_ha, LmCONTROL(lseq),
1107 (LEDTIMER | LEDMODE_TXRX | LEDTIMERS_100ms));
1108
1109 /* Set the Align Rate for SAS and STP mode. */
1110 asd_write_reg_byte(asd_ha, LmM1SASALIGN(lseq), SAS_ALIGN_DEFAULT);
1111 asd_write_reg_byte(asd_ha, LmM1STPALIGN(lseq), STP_ALIGN_DEFAULT);
1112}
1113
1114
1115/**
1116 * asd_post_init_cseq -- clear CSEQ Mode n Int. status and Response mailbox
1117 * @asd_ha: pointer to host adapter struct
1118 */
1119static void asd_post_init_cseq(struct asd_ha_struct *asd_ha)
1120{
1121 int i;
1122
1123 for (i = 0; i < 8; i++)
1124 asd_write_reg_dword(asd_ha, CMnINT(i), 0xFFFFFFFF);
1125 for (i = 0; i < 8; i++)
1126 asd_read_reg_dword(asd_ha, CMnRSPMBX(i));
1127 /* Reset the external interrupt arbiter. */
1128 asd_write_reg_byte(asd_ha, CARP2INTCTL, RSTINTCTL);
1129}
1130
1131/**
1132 * asd_init_ddb_0 -- initialize DDB 0
1133 * @asd_ha: pointer to host adapter structure
1134 *
1135 * Initialize DDB site 0 which is used internally by the sequencer.
1136 */
1137static void asd_init_ddb_0(struct asd_ha_struct *asd_ha)
1138{
1139 int i;
1140
1141 /* Zero out the DDB explicitly */
1142 for (i = 0; i < sizeof(struct asd_ddb_seq_shared); i+=4)
1143 asd_ddbsite_write_dword(asd_ha, 0, i, 0);
1144
1145 asd_ddbsite_write_word(asd_ha, 0,
1146 offsetof(struct asd_ddb_seq_shared, q_free_ddb_head), 0);
1147 asd_ddbsite_write_word(asd_ha, 0,
1148 offsetof(struct asd_ddb_seq_shared, q_free_ddb_tail),
1149 asd_ha->hw_prof.max_ddbs-1);
1150 asd_ddbsite_write_word(asd_ha, 0,
1151 offsetof(struct asd_ddb_seq_shared, q_free_ddb_cnt), 0);
1152 asd_ddbsite_write_word(asd_ha, 0,
1153 offsetof(struct asd_ddb_seq_shared, q_used_ddb_head), 0xFFFF);
1154 asd_ddbsite_write_word(asd_ha, 0,
1155 offsetof(struct asd_ddb_seq_shared, q_used_ddb_tail), 0xFFFF);
1156 asd_ddbsite_write_word(asd_ha, 0,
1157 offsetof(struct asd_ddb_seq_shared, shared_mem_lock), 0);
1158 asd_ddbsite_write_word(asd_ha, 0,
1159 offsetof(struct asd_ddb_seq_shared, smp_conn_tag), 0);
1160 asd_ddbsite_write_word(asd_ha, 0,
1161 offsetof(struct asd_ddb_seq_shared, est_nexus_buf_cnt), 0);
1162 asd_ddbsite_write_word(asd_ha, 0,
1163 offsetof(struct asd_ddb_seq_shared, est_nexus_buf_thresh),
1164 asd_ha->hw_prof.num_phys * 2);
1165 asd_ddbsite_write_byte(asd_ha, 0,
1166 offsetof(struct asd_ddb_seq_shared, settable_max_contexts),0);
1167 asd_ddbsite_write_byte(asd_ha, 0,
1168 offsetof(struct asd_ddb_seq_shared, conn_not_active), 0xFF);
1169 asd_ddbsite_write_byte(asd_ha, 0,
1170 offsetof(struct asd_ddb_seq_shared, phy_is_up), 0x00);
1171 /* DDB 0 is reserved */
1172 set_bit(0, asd_ha->hw_prof.ddb_bitmap);
1173}
1174
1175/**
1176 * asd_seq_setup_seqs -- setup and initialize central and link sequencers
1177 * @asd_ha: pointer to host adapter structure
1178 */
1179static void asd_seq_setup_seqs(struct asd_ha_struct *asd_ha)
1180{
1181 int lseq;
1182 u8 lseq_mask;
1183
1184 /* Initialize SCB sites. Done first to compute some values which
1185 * the rest of the init code depends on. */
1186 asd_init_scb_sites(asd_ha);
1187
1188 /* Initialize CSEQ Scratch RAM registers. */
1189 asd_init_cseq_scratch(asd_ha);
1190
1191 /* Initialize LmSEQ Scratch RAM registers. */
1192 asd_init_lseq_scratch(asd_ha);
1193
1194 /* Initialize CSEQ CIO registers. */
1195 asd_init_cseq_cio(asd_ha);
1196
1197 asd_init_ddb_0(asd_ha);
1198
1199 /* Initialize LmSEQ CIO registers. */
1200 lseq_mask = asd_ha->hw_prof.enabled_phys;
1201 for_each_sequencer(lseq_mask, lseq_mask, lseq)
1202 asd_init_lseq_cio(asd_ha, lseq);
1203 asd_post_init_cseq(asd_ha);
1204}
1205
1206
1207/**
1208 * asd_seq_start_cseq -- start the central sequencer, CSEQ
1209 * @asd_ha: pointer to host adapter structure
1210 */
1211static int asd_seq_start_cseq(struct asd_ha_struct *asd_ha)
1212{
1213 /* Reset the ARP2 instruction to location zero. */
1214 asd_write_reg_word(asd_ha, CPRGMCNT, cseq_idle_loop);
1215
1216 /* Unpause the CSEQ */
1217 return asd_unpause_cseq(asd_ha);
1218}
1219
1220/**
1221 * asd_seq_start_lseq -- start a link sequencer
1222 * @asd_ha: pointer to host adapter structure
1223 * @lseq: the link sequencer of interest
1224 */
1225static int asd_seq_start_lseq(struct asd_ha_struct *asd_ha, int lseq)
1226{
1227 /* Reset the ARP2 instruction to location zero. */
1228 asd_write_reg_word(asd_ha, LmPRGMCNT(lseq), lseq_idle_loop);
1229
1230 /* Unpause the LmSEQ */
1231 return asd_seq_unpause_lseq(asd_ha, lseq);
1232}
1233
1234static int asd_request_firmware(struct asd_ha_struct *asd_ha)
1235{
1236 int err, i;
1237 struct sequencer_file_header header, *hdr_ptr;
1238 u32 csum = 0;
1239 u16 *ptr_cseq_vecs, *ptr_lseq_vecs;
1240
1241 if (sequencer_fw)
1242 /* already loaded */
1243 return 0;
1244
1245 err = request_firmware(&sequencer_fw,
1246 SAS_RAZOR_SEQUENCER_FW_FILE,
1247 &asd_ha->pcidev->dev);
1248 if (err)
1249 return err;
1250
1251 hdr_ptr = (struct sequencer_file_header *)sequencer_fw->data;
1252
1253 header.csum = le32_to_cpu(hdr_ptr->csum);
1254 header.major = le32_to_cpu(hdr_ptr->major);
1255 header.minor = le32_to_cpu(hdr_ptr->minor);
1256 sequencer_version = hdr_ptr->version;
1257 header.cseq_table_offset = le32_to_cpu(hdr_ptr->cseq_table_offset);
1258 header.cseq_table_size = le32_to_cpu(hdr_ptr->cseq_table_size);
1259 header.lseq_table_offset = le32_to_cpu(hdr_ptr->lseq_table_offset);
1260 header.lseq_table_size = le32_to_cpu(hdr_ptr->lseq_table_size);
1261 header.cseq_code_offset = le32_to_cpu(hdr_ptr->cseq_code_offset);
1262 header.cseq_code_size = le32_to_cpu(hdr_ptr->cseq_code_size);
1263 header.lseq_code_offset = le32_to_cpu(hdr_ptr->lseq_code_offset);
1264 header.lseq_code_size = le32_to_cpu(hdr_ptr->lseq_code_size);
1265 header.mode2_task = le16_to_cpu(hdr_ptr->mode2_task);
1266 header.cseq_idle_loop = le16_to_cpu(hdr_ptr->cseq_idle_loop);
1267 header.lseq_idle_loop = le16_to_cpu(hdr_ptr->lseq_idle_loop);
1268
1269 for (i = sizeof(header.csum); i < sequencer_fw->size; i++)
1270 csum += sequencer_fw->data[i];
1271
1272 if (csum != header.csum) {
1273 asd_printk("Firmware file checksum mismatch\n");
1274 return -EINVAL;
1275 }
1276
1277 if (header.cseq_table_size != CSEQ_NUM_VECS ||
1278 header.lseq_table_size != LSEQ_NUM_VECS) {
1279 asd_printk("Firmware file table size mismatch\n");
1280 return -EINVAL;
1281 }
1282
1283 ptr_cseq_vecs = (u16 *)&sequencer_fw->data[header.cseq_table_offset];
1284 ptr_lseq_vecs = (u16 *)&sequencer_fw->data[header.lseq_table_offset];
1285 mode2_task = header.mode2_task;
1286 cseq_idle_loop = header.cseq_idle_loop;
1287 lseq_idle_loop = header.lseq_idle_loop;
1288
1289 for (i = 0; i < CSEQ_NUM_VECS; i++)
1290 cseq_vecs[i] = le16_to_cpu(ptr_cseq_vecs[i]);
1291
1292 for (i = 0; i < LSEQ_NUM_VECS; i++)
1293 lseq_vecs[i] = le16_to_cpu(ptr_lseq_vecs[i]);
1294
1295 cseq_code = &sequencer_fw->data[header.cseq_code_offset];
1296 cseq_code_size = header.cseq_code_size;
1297 lseq_code = &sequencer_fw->data[header.lseq_code_offset];
1298 lseq_code_size = header.lseq_code_size;
1299
1300 return 0;
1301}
1302
1303int asd_init_seqs(struct asd_ha_struct *asd_ha)
1304{
1305 int err;
1306
1307 err = asd_request_firmware(asd_ha);
1308
1309 if (err) {
1310 asd_printk("Failed to load sequencer firmware file %s, error %d\n",
1311 SAS_RAZOR_SEQUENCER_FW_FILE, err);
1312 return err;
1313 }
1314
1315 asd_printk("using sequencer %s\n", sequencer_version);
1316 err = asd_seq_download_seqs(asd_ha);
1317 if (err) {
1318 asd_printk("couldn't download sequencers for %s\n",
1319 pci_name(asd_ha->pcidev));
1320 return err;
1321 }
1322
1323 asd_seq_setup_seqs(asd_ha);
1324
1325 return 0;
1326}
1327
1328int asd_start_seqs(struct asd_ha_struct *asd_ha)
1329{
1330 int err;
1331 u8 lseq_mask;
1332 int lseq;
1333
1334 err = asd_seq_start_cseq(asd_ha);
1335 if (err) {
1336 asd_printk("couldn't start CSEQ for %s\n",
1337 pci_name(asd_ha->pcidev));
1338 return err;
1339 }
1340
1341 lseq_mask = asd_ha->hw_prof.enabled_phys;
1342 for_each_sequencer(lseq_mask, lseq_mask, lseq) {
1343 err = asd_seq_start_lseq(asd_ha, lseq);
1344 if (err) {
1345 asd_printk("coudln't start LSEQ %d for %s\n", lseq,
1346 pci_name(asd_ha->pcidev));
1347 return err;
1348 }
1349 }
1350
1351 return 0;
1352}
1353
1354/**
1355 * asd_update_port_links -- update port_map_by_links and phy_is_up
1356 * @sas_phy: pointer to the phy which has been added to a port
1357 *
1358 * 1) When a link reset has completed and we got BYTES DMAED with a
1359 * valid frame we call this function for that phy, to indicate that
1360 * the phy is up, i.e. we update the phy_is_up in DDB 0. The
1361 * sequencer checks phy_is_up when pending SCBs are to be sent, and
1362 * when an open address frame has been received.
1363 *
1364 * 2) When we know of ports, we call this function to update the map
1365 * of phys participaing in that port, i.e. we update the
1366 * port_map_by_links in DDB 0. When a HARD_RESET primitive has been
1367 * received, the sequencer disables all phys in that port.
1368 * port_map_by_links is also used as the conn_mask byte in the
1369 * initiator/target port DDB.
1370 */
1371void asd_update_port_links(struct asd_sas_phy *sas_phy)
1372{
1373 struct asd_ha_struct *asd_ha = sas_phy->ha->lldd_ha;
1374 const u8 phy_mask = (u8) sas_phy->port->phy_mask;
1375 u8 phy_is_up;
1376 u8 mask;
1377 int i, err;
1378
1379 for_each_phy(phy_mask, mask, i)
1380 asd_ddbsite_write_byte(asd_ha, 0,
1381 offsetof(struct asd_ddb_seq_shared,
1382 port_map_by_links)+i,phy_mask);
1383
1384 for (i = 0; i < 12; i++) {
1385 phy_is_up = asd_ddbsite_read_byte(asd_ha, 0,
1386 offsetof(struct asd_ddb_seq_shared, phy_is_up));
1387 err = asd_ddbsite_update_byte(asd_ha, 0,
1388 offsetof(struct asd_ddb_seq_shared, phy_is_up),
1389 phy_is_up,
1390 phy_is_up | phy_mask);
1391 if (!err)
1392 break;
1393 else if (err == -EFAULT) {
1394 asd_printk("phy_is_up: parity error in DDB 0\n");
1395 break;
1396 }
1397 }
1398
1399 if (err)
1400 asd_printk("couldn't update DDB 0:error:%d\n", err);
1401}
diff --git a/drivers/scsi/aic94xx/aic94xx_seq.h b/drivers/scsi/aic94xx/aic94xx_seq.h
new file mode 100644
index 000000000000..42281c36153b
--- /dev/null
+++ b/drivers/scsi/aic94xx/aic94xx_seq.h
@@ -0,0 +1,70 @@
1/*
2 * Aic94xx SAS/SATA driver sequencer interface header file.
3 *
4 * Copyright (C) 2005 Adaptec, Inc. All rights reserved.
5 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
6 *
7 * This file is licensed under GPLv2.
8 *
9 * This file is part of the aic94xx driver.
10 *
11 * The aic94xx driver is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; version 2 of the
14 * License.
15 *
16 * The aic94xx driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with the aic94xx driver; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 *
25 */
26
27#ifndef _AIC94XX_SEQ_H_
28#define _AIC94XX_SEQ_H_
29
30#define CSEQ_NUM_VECS 3
31#define LSEQ_NUM_VECS 11
32
33#define SAS_RAZOR_SEQUENCER_FW_FILE "aic94xx-seq.fw"
34
35/* Note: All quantites in the sequencer file are little endian */
36struct sequencer_file_header {
37 /* Checksum of the entire contents of the sequencer excluding
38 * these four bytes */
39 u32 csum;
40 /* numeric major version */
41 u32 major;
42 /* numeric minor version */
43 u32 minor;
44 /* version string printed by driver */
45 char version[16];
46 u32 cseq_table_offset;
47 u32 cseq_table_size;
48 u32 lseq_table_offset;
49 u32 lseq_table_size;
50 u32 cseq_code_offset;
51 u32 cseq_code_size;
52 u32 lseq_code_offset;
53 u32 lseq_code_size;
54 u16 mode2_task;
55 u16 cseq_idle_loop;
56 u16 lseq_idle_loop;
57} __attribute__((packed));
58
59#ifdef __KERNEL__
60int asd_pause_cseq(struct asd_ha_struct *asd_ha);
61int asd_unpause_cseq(struct asd_ha_struct *asd_ha);
62int asd_pause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask);
63int asd_unpause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask);
64int asd_init_seqs(struct asd_ha_struct *asd_ha);
65int asd_start_seqs(struct asd_ha_struct *asd_ha);
66
67void asd_update_port_links(struct asd_sas_phy *phy);
68#endif
69
70#endif
diff --git a/drivers/scsi/aic94xx/aic94xx_task.c b/drivers/scsi/aic94xx/aic94xx_task.c
new file mode 100644
index 000000000000..285e70dae933
--- /dev/null
+++ b/drivers/scsi/aic94xx/aic94xx_task.c
@@ -0,0 +1,642 @@
1/*
2 * Aic94xx SAS/SATA Tasks
3 *
4 * Copyright (C) 2005 Adaptec, Inc. All rights reserved.
5 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
6 *
7 * This file is licensed under GPLv2.
8 *
9 * This file is part of the aic94xx driver.
10 *
11 * The aic94xx driver is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; version 2 of the
14 * License.
15 *
16 * The aic94xx driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with the aic94xx driver; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 *
25 */
26
27#include <linux/spinlock.h>
28#include "aic94xx.h"
29#include "aic94xx_sas.h"
30#include "aic94xx_hwi.h"
31
32static void asd_unbuild_ata_ascb(struct asd_ascb *a);
33static void asd_unbuild_smp_ascb(struct asd_ascb *a);
34static void asd_unbuild_ssp_ascb(struct asd_ascb *a);
35
36static inline void asd_can_dequeue(struct asd_ha_struct *asd_ha, int num)
37{
38 unsigned long flags;
39
40 spin_lock_irqsave(&asd_ha->seq.pend_q_lock, flags);
41 asd_ha->seq.can_queue += num;
42 spin_unlock_irqrestore(&asd_ha->seq.pend_q_lock, flags);
43}
44
45/* PCI_DMA_... to our direction translation.
46 */
47static const u8 data_dir_flags[] = {
48 [PCI_DMA_BIDIRECTIONAL] = DATA_DIR_BYRECIPIENT, /* UNSPECIFIED */
49 [PCI_DMA_TODEVICE] = DATA_DIR_OUT, /* OUTBOUND */
50 [PCI_DMA_FROMDEVICE] = DATA_DIR_IN, /* INBOUND */
51 [PCI_DMA_NONE] = DATA_DIR_NONE, /* NO TRANSFER */
52};
53
54static inline int asd_map_scatterlist(struct sas_task *task,
55 struct sg_el *sg_arr,
56 unsigned long gfp_flags)
57{
58 struct asd_ascb *ascb = task->lldd_task;
59 struct asd_ha_struct *asd_ha = ascb->ha;
60 struct scatterlist *sc;
61 int num_sg, res;
62
63 if (task->data_dir == PCI_DMA_NONE)
64 return 0;
65
66 if (task->num_scatter == 0) {
67 void *p = task->scatter;
68 dma_addr_t dma = pci_map_single(asd_ha->pcidev, p,
69 task->total_xfer_len,
70 task->data_dir);
71 sg_arr[0].bus_addr = cpu_to_le64((u64)dma);
72 sg_arr[0].size = cpu_to_le32(task->total_xfer_len);
73 sg_arr[0].flags |= ASD_SG_EL_LIST_EOL;
74 return 0;
75 }
76
77 num_sg = pci_map_sg(asd_ha->pcidev, task->scatter, task->num_scatter,
78 task->data_dir);
79 if (num_sg == 0)
80 return -ENOMEM;
81
82 if (num_sg > 3) {
83 int i;
84
85 ascb->sg_arr = asd_alloc_coherent(asd_ha,
86 num_sg*sizeof(struct sg_el),
87 gfp_flags);
88 if (!ascb->sg_arr) {
89 res = -ENOMEM;
90 goto err_unmap;
91 }
92 for (sc = task->scatter, i = 0; i < num_sg; i++, sc++) {
93 struct sg_el *sg =
94 &((struct sg_el *)ascb->sg_arr->vaddr)[i];
95 sg->bus_addr = cpu_to_le64((u64)sg_dma_address(sc));
96 sg->size = cpu_to_le32((u32)sg_dma_len(sc));
97 if (i == num_sg-1)
98 sg->flags |= ASD_SG_EL_LIST_EOL;
99 }
100
101 for (sc = task->scatter, i = 0; i < 2; i++, sc++) {
102 sg_arr[i].bus_addr =
103 cpu_to_le64((u64)sg_dma_address(sc));
104 sg_arr[i].size = cpu_to_le32((u32)sg_dma_len(sc));
105 }
106 sg_arr[1].next_sg_offs = 2 * sizeof(*sg_arr);
107 sg_arr[1].flags |= ASD_SG_EL_LIST_EOS;
108
109 memset(&sg_arr[2], 0, sizeof(*sg_arr));
110 sg_arr[2].bus_addr=cpu_to_le64((u64)ascb->sg_arr->dma_handle);
111 } else {
112 int i;
113 for (sc = task->scatter, i = 0; i < num_sg; i++, sc++) {
114 sg_arr[i].bus_addr =
115 cpu_to_le64((u64)sg_dma_address(sc));
116 sg_arr[i].size = cpu_to_le32((u32)sg_dma_len(sc));
117 }
118 sg_arr[i-1].flags |= ASD_SG_EL_LIST_EOL;
119 }
120
121 return 0;
122err_unmap:
123 pci_unmap_sg(asd_ha->pcidev, task->scatter, task->num_scatter,
124 task->data_dir);
125 return res;
126}
127
128static inline void asd_unmap_scatterlist(struct asd_ascb *ascb)
129{
130 struct asd_ha_struct *asd_ha = ascb->ha;
131 struct sas_task *task = ascb->uldd_task;
132
133 if (task->data_dir == PCI_DMA_NONE)
134 return;
135
136 if (task->num_scatter == 0) {
137 dma_addr_t dma = (dma_addr_t)
138 le64_to_cpu(ascb->scb->ssp_task.sg_element[0].bus_addr);
139 pci_unmap_single(ascb->ha->pcidev, dma, task->total_xfer_len,
140 task->data_dir);
141 return;
142 }
143
144 asd_free_coherent(asd_ha, ascb->sg_arr);
145 pci_unmap_sg(asd_ha->pcidev, task->scatter, task->num_scatter,
146 task->data_dir);
147}
148
149/* ---------- Task complete tasklet ---------- */
150
151static void asd_get_response_tasklet(struct asd_ascb *ascb,
152 struct done_list_struct *dl)
153{
154 struct asd_ha_struct *asd_ha = ascb->ha;
155 struct sas_task *task = ascb->uldd_task;
156 struct task_status_struct *ts = &task->task_status;
157 unsigned long flags;
158 struct tc_resp_sb_struct {
159 __le16 index_escb;
160 u8 len_lsb;
161 u8 flags;
162 } __attribute__ ((packed)) *resp_sb = (void *) dl->status_block;
163
164/* int size = ((resp_sb->flags & 7) << 8) | resp_sb->len_lsb; */
165 int edb_id = ((resp_sb->flags & 0x70) >> 4)-1;
166 struct asd_ascb *escb;
167 struct asd_dma_tok *edb;
168 void *r;
169
170 spin_lock_irqsave(&asd_ha->seq.tc_index_lock, flags);
171 escb = asd_tc_index_find(&asd_ha->seq,
172 (int)le16_to_cpu(resp_sb->index_escb));
173 spin_unlock_irqrestore(&asd_ha->seq.tc_index_lock, flags);
174
175 if (!escb) {
176 ASD_DPRINTK("Uh-oh! No escb for this dl?!\n");
177 return;
178 }
179
180 ts->buf_valid_size = 0;
181 edb = asd_ha->seq.edb_arr[edb_id + escb->edb_index];
182 r = edb->vaddr;
183 if (task->task_proto == SAS_PROTO_SSP) {
184 struct ssp_response_iu *iu =
185 r + 16 + sizeof(struct ssp_frame_hdr);
186
187 ts->residual = le32_to_cpu(*(__le32 *)r);
188 ts->resp = SAS_TASK_COMPLETE;
189 if (iu->datapres == 0)
190 ts->stat = iu->status;
191 else if (iu->datapres == 1)
192 ts->stat = iu->resp_data[3];
193 else if (iu->datapres == 2) {
194 ts->stat = SAM_CHECK_COND;
195 ts->buf_valid_size = min((u32) SAS_STATUS_BUF_SIZE,
196 be32_to_cpu(iu->sense_data_len));
197 memcpy(ts->buf, iu->sense_data, ts->buf_valid_size);
198 if (iu->status != SAM_CHECK_COND) {
199 ASD_DPRINTK("device %llx sent sense data, but "
200 "stat(0x%x) is not CHECK_CONDITION"
201 "\n",
202 SAS_ADDR(task->dev->sas_addr),
203 ts->stat);
204 }
205 }
206 } else {
207 struct ata_task_resp *resp = (void *) &ts->buf[0];
208
209 ts->residual = le32_to_cpu(*(__le32 *)r);
210
211 if (SAS_STATUS_BUF_SIZE >= sizeof(*resp)) {
212 resp->frame_len = le16_to_cpu(*(__le16 *)(r+6));
213 memcpy(&resp->ending_fis[0], r+16, 24);
214 ts->buf_valid_size = sizeof(*resp);
215 }
216 }
217
218 asd_invalidate_edb(escb, edb_id);
219}
220
221static void asd_task_tasklet_complete(struct asd_ascb *ascb,
222 struct done_list_struct *dl)
223{
224 struct sas_task *task = ascb->uldd_task;
225 struct task_status_struct *ts = &task->task_status;
226 unsigned long flags;
227 u8 opcode = dl->opcode;
228
229 asd_can_dequeue(ascb->ha, 1);
230
231Again:
232 switch (opcode) {
233 case TC_NO_ERROR:
234 ts->resp = SAS_TASK_COMPLETE;
235 ts->stat = SAM_GOOD;
236 break;
237 case TC_UNDERRUN:
238 ts->resp = SAS_TASK_COMPLETE;
239 ts->stat = SAS_DATA_UNDERRUN;
240 ts->residual = le32_to_cpu(*(__le32 *)dl->status_block);
241 break;
242 case TC_OVERRUN:
243 ts->resp = SAS_TASK_COMPLETE;
244 ts->stat = SAS_DATA_OVERRUN;
245 ts->residual = 0;
246 break;
247 case TC_SSP_RESP:
248 case TC_ATA_RESP:
249 ts->resp = SAS_TASK_COMPLETE;
250 ts->stat = SAS_PROTO_RESPONSE;
251 asd_get_response_tasklet(ascb, dl);
252 break;
253 case TF_OPEN_REJECT:
254 ts->resp = SAS_TASK_UNDELIVERED;
255 ts->stat = SAS_OPEN_REJECT;
256 if (dl->status_block[1] & 2)
257 ts->open_rej_reason = 1 + dl->status_block[2];
258 else if (dl->status_block[1] & 1)
259 ts->open_rej_reason = (dl->status_block[2] >> 4)+10;
260 else
261 ts->open_rej_reason = SAS_OREJ_UNKNOWN;
262 break;
263 case TF_OPEN_TO:
264 ts->resp = SAS_TASK_UNDELIVERED;
265 ts->stat = SAS_OPEN_TO;
266 break;
267 case TF_PHY_DOWN:
268 case TU_PHY_DOWN:
269 ts->resp = SAS_TASK_UNDELIVERED;
270 ts->stat = SAS_PHY_DOWN;
271 break;
272 case TI_PHY_DOWN:
273 ts->resp = SAS_TASK_COMPLETE;
274 ts->stat = SAS_PHY_DOWN;
275 break;
276 case TI_BREAK:
277 case TI_PROTO_ERR:
278 case TI_NAK:
279 case TI_ACK_NAK_TO:
280 case TF_SMP_XMIT_RCV_ERR:
281 case TC_ATA_R_ERR_RECV:
282 ts->resp = SAS_TASK_COMPLETE;
283 ts->stat = SAS_INTERRUPTED;
284 break;
285 case TF_BREAK:
286 case TU_BREAK:
287 case TU_ACK_NAK_TO:
288 case TF_SMPRSP_TO:
289 ts->resp = SAS_TASK_UNDELIVERED;
290 ts->stat = SAS_DEV_NO_RESPONSE;
291 break;
292 case TF_NAK_RECV:
293 ts->resp = SAS_TASK_COMPLETE;
294 ts->stat = SAS_NAK_R_ERR;
295 break;
296 case TA_I_T_NEXUS_LOSS:
297 opcode = dl->status_block[0];
298 goto Again;
299 break;
300 case TF_INV_CONN_HANDLE:
301 ts->resp = SAS_TASK_UNDELIVERED;
302 ts->stat = SAS_DEVICE_UNKNOWN;
303 break;
304 case TF_REQUESTED_N_PENDING:
305 ts->resp = SAS_TASK_UNDELIVERED;
306 ts->stat = SAS_PENDING;
307 break;
308 case TC_TASK_CLEARED:
309 case TA_ON_REQ:
310 ts->resp = SAS_TASK_COMPLETE;
311 ts->stat = SAS_ABORTED_TASK;
312 break;
313
314 case TF_NO_SMP_CONN:
315 case TF_TMF_NO_CTX:
316 case TF_TMF_NO_TAG:
317 case TF_TMF_TAG_FREE:
318 case TF_TMF_TASK_DONE:
319 case TF_TMF_NO_CONN_HANDLE:
320 case TF_IRTT_TO:
321 case TF_IU_SHORT:
322 case TF_DATA_OFFS_ERR:
323 ts->resp = SAS_TASK_UNDELIVERED;
324 ts->stat = SAS_DEV_NO_RESPONSE;
325 break;
326
327 case TC_LINK_ADM_RESP:
328 case TC_CONTROL_PHY:
329 case TC_RESUME:
330 case TC_PARTIAL_SG_LIST:
331 default:
332 ASD_DPRINTK("%s: dl opcode: 0x%x?\n", __FUNCTION__, opcode);
333 break;
334 }
335
336 switch (task->task_proto) {
337 case SATA_PROTO:
338 case SAS_PROTO_STP:
339 asd_unbuild_ata_ascb(ascb);
340 break;
341 case SAS_PROTO_SMP:
342 asd_unbuild_smp_ascb(ascb);
343 break;
344 case SAS_PROTO_SSP:
345 asd_unbuild_ssp_ascb(ascb);
346 default:
347 break;
348 }
349
350 spin_lock_irqsave(&task->task_state_lock, flags);
351 task->task_state_flags &= ~SAS_TASK_STATE_PENDING;
352 task->task_state_flags |= SAS_TASK_STATE_DONE;
353 if (unlikely((task->task_state_flags & SAS_TASK_STATE_ABORTED))) {
354 spin_unlock_irqrestore(&task->task_state_lock, flags);
355 ASD_DPRINTK("task 0x%p done with opcode 0x%x resp 0x%x "
356 "stat 0x%x but aborted by upper layer!\n",
357 task, opcode, ts->resp, ts->stat);
358 complete(&ascb->completion);
359 } else {
360 spin_unlock_irqrestore(&task->task_state_lock, flags);
361 task->lldd_task = NULL;
362 asd_ascb_free(ascb);
363 mb();
364 task->task_done(task);
365 }
366}
367
368/* ---------- ATA ---------- */
369
370static int asd_build_ata_ascb(struct asd_ascb *ascb, struct sas_task *task,
371 unsigned long gfp_flags)
372{
373 struct domain_device *dev = task->dev;
374 struct scb *scb;
375 u8 flags;
376 int res = 0;
377
378 scb = ascb->scb;
379
380 if (unlikely(task->ata_task.device_control_reg_update))
381 scb->header.opcode = CONTROL_ATA_DEV;
382 else if (dev->sata_dev.command_set == ATA_COMMAND_SET)
383 scb->header.opcode = INITIATE_ATA_TASK;
384 else
385 scb->header.opcode = INITIATE_ATAPI_TASK;
386
387 scb->ata_task.proto_conn_rate = (1 << 5); /* STP */
388 if (dev->port->oob_mode == SAS_OOB_MODE)
389 scb->ata_task.proto_conn_rate |= dev->linkrate;
390
391 scb->ata_task.total_xfer_len = cpu_to_le32(task->total_xfer_len);
392 scb->ata_task.fis = task->ata_task.fis;
393 scb->ata_task.fis.fis_type = 0x27;
394 if (likely(!task->ata_task.device_control_reg_update))
395 scb->ata_task.fis.flags |= 0x80; /* C=1: update ATA cmd reg */
396 scb->ata_task.fis.flags &= 0xF0; /* PM_PORT field shall be 0 */
397 if (dev->sata_dev.command_set == ATAPI_COMMAND_SET)
398 memcpy(scb->ata_task.atapi_packet, task->ata_task.atapi_packet,
399 16);
400 scb->ata_task.sister_scb = cpu_to_le16(0xFFFF);
401 scb->ata_task.conn_handle = cpu_to_le16(
402 (u16)(unsigned long)dev->lldd_dev);
403
404 if (likely(!task->ata_task.device_control_reg_update)) {
405 flags = 0;
406 if (task->ata_task.dma_xfer)
407 flags |= DATA_XFER_MODE_DMA;
408 if (task->ata_task.use_ncq &&
409 dev->sata_dev.command_set != ATAPI_COMMAND_SET)
410 flags |= ATA_Q_TYPE_NCQ;
411 flags |= data_dir_flags[task->data_dir];
412 scb->ata_task.ata_flags = flags;
413
414 scb->ata_task.retry_count = task->ata_task.retry_count;
415
416 flags = 0;
417 if (task->ata_task.set_affil_pol)
418 flags |= SET_AFFIL_POLICY;
419 if (task->ata_task.stp_affil_pol)
420 flags |= STP_AFFIL_POLICY;
421 scb->ata_task.flags = flags;
422 }
423 ascb->tasklet_complete = asd_task_tasklet_complete;
424
425 if (likely(!task->ata_task.device_control_reg_update))
426 res = asd_map_scatterlist(task, scb->ata_task.sg_element,
427 gfp_flags);
428
429 return res;
430}
431
432static void asd_unbuild_ata_ascb(struct asd_ascb *a)
433{
434 asd_unmap_scatterlist(a);
435}
436
437/* ---------- SMP ---------- */
438
439static int asd_build_smp_ascb(struct asd_ascb *ascb, struct sas_task *task,
440 unsigned long gfp_flags)
441{
442 struct asd_ha_struct *asd_ha = ascb->ha;
443 struct domain_device *dev = task->dev;
444 struct scb *scb;
445
446 pci_map_sg(asd_ha->pcidev, &task->smp_task.smp_req, 1,
447 PCI_DMA_FROMDEVICE);
448 pci_map_sg(asd_ha->pcidev, &task->smp_task.smp_resp, 1,
449 PCI_DMA_FROMDEVICE);
450
451 scb = ascb->scb;
452
453 scb->header.opcode = INITIATE_SMP_TASK;
454
455 scb->smp_task.proto_conn_rate = dev->linkrate;
456
457 scb->smp_task.smp_req.bus_addr =
458 cpu_to_le64((u64)sg_dma_address(&task->smp_task.smp_req));
459 scb->smp_task.smp_req.size =
460 cpu_to_le32((u32)sg_dma_len(&task->smp_task.smp_req)-4);
461
462 scb->smp_task.smp_resp.bus_addr =
463 cpu_to_le64((u64)sg_dma_address(&task->smp_task.smp_resp));
464 scb->smp_task.smp_resp.size =
465 cpu_to_le32((u32)sg_dma_len(&task->smp_task.smp_resp)-4);
466
467 scb->smp_task.sister_scb = cpu_to_le16(0xFFFF);
468 scb->smp_task.conn_handle = cpu_to_le16((u16)
469 (unsigned long)dev->lldd_dev);
470
471 ascb->tasklet_complete = asd_task_tasklet_complete;
472
473 return 0;
474}
475
476static void asd_unbuild_smp_ascb(struct asd_ascb *a)
477{
478 struct sas_task *task = a->uldd_task;
479
480 BUG_ON(!task);
481 pci_unmap_sg(a->ha->pcidev, &task->smp_task.smp_req, 1,
482 PCI_DMA_FROMDEVICE);
483 pci_unmap_sg(a->ha->pcidev, &task->smp_task.smp_resp, 1,
484 PCI_DMA_FROMDEVICE);
485}
486
487/* ---------- SSP ---------- */
488
489static int asd_build_ssp_ascb(struct asd_ascb *ascb, struct sas_task *task,
490 unsigned long gfp_flags)
491{
492 struct domain_device *dev = task->dev;
493 struct scb *scb;
494 int res = 0;
495
496 scb = ascb->scb;
497
498 scb->header.opcode = INITIATE_SSP_TASK;
499
500 scb->ssp_task.proto_conn_rate = (1 << 4); /* SSP */
501 scb->ssp_task.proto_conn_rate |= dev->linkrate;
502 scb->ssp_task.total_xfer_len = cpu_to_le32(task->total_xfer_len);
503 scb->ssp_task.ssp_frame.frame_type = SSP_DATA;
504 memcpy(scb->ssp_task.ssp_frame.hashed_dest_addr, dev->hashed_sas_addr,
505 HASHED_SAS_ADDR_SIZE);
506 memcpy(scb->ssp_task.ssp_frame.hashed_src_addr,
507 dev->port->ha->hashed_sas_addr, HASHED_SAS_ADDR_SIZE);
508 scb->ssp_task.ssp_frame.tptt = cpu_to_be16(0xFFFF);
509
510 memcpy(scb->ssp_task.ssp_cmd.lun, task->ssp_task.LUN, 8);
511 if (task->ssp_task.enable_first_burst)
512 scb->ssp_task.ssp_cmd.efb_prio_attr |= EFB_MASK;
513 scb->ssp_task.ssp_cmd.efb_prio_attr |= (task->ssp_task.task_prio << 3);
514 scb->ssp_task.ssp_cmd.efb_prio_attr |= (task->ssp_task.task_attr & 7);
515 memcpy(scb->ssp_task.ssp_cmd.cdb, task->ssp_task.cdb, 16);
516
517 scb->ssp_task.sister_scb = cpu_to_le16(0xFFFF);
518 scb->ssp_task.conn_handle = cpu_to_le16(
519 (u16)(unsigned long)dev->lldd_dev);
520 scb->ssp_task.data_dir = data_dir_flags[task->data_dir];
521 scb->ssp_task.retry_count = scb->ssp_task.retry_count;
522
523 ascb->tasklet_complete = asd_task_tasklet_complete;
524
525 res = asd_map_scatterlist(task, scb->ssp_task.sg_element, gfp_flags);
526
527 return res;
528}
529
530static void asd_unbuild_ssp_ascb(struct asd_ascb *a)
531{
532 asd_unmap_scatterlist(a);
533}
534
535/* ---------- Execute Task ---------- */
536
537static inline int asd_can_queue(struct asd_ha_struct *asd_ha, int num)
538{
539 int res = 0;
540 unsigned long flags;
541
542 spin_lock_irqsave(&asd_ha->seq.pend_q_lock, flags);
543 if ((asd_ha->seq.can_queue - num) < 0)
544 res = -SAS_QUEUE_FULL;
545 else
546 asd_ha->seq.can_queue -= num;
547 spin_unlock_irqrestore(&asd_ha->seq.pend_q_lock, flags);
548
549 return res;
550}
551
552int asd_execute_task(struct sas_task *task, const int num,
553 unsigned long gfp_flags)
554{
555 int res = 0;
556 LIST_HEAD(alist);
557 struct sas_task *t = task;
558 struct asd_ascb *ascb = NULL, *a;
559 struct asd_ha_struct *asd_ha = task->dev->port->ha->lldd_ha;
560
561 res = asd_can_queue(asd_ha, num);
562 if (res)
563 return res;
564
565 res = num;
566 ascb = asd_ascb_alloc_list(asd_ha, &res, gfp_flags);
567 if (res) {
568 res = -ENOMEM;
569 goto out_err;
570 }
571
572 __list_add(&alist, ascb->list.prev, &ascb->list);
573 list_for_each_entry(a, &alist, list) {
574 a->uldd_task = t;
575 t->lldd_task = a;
576 t = list_entry(t->list.next, struct sas_task, list);
577 }
578 list_for_each_entry(a, &alist, list) {
579 t = a->uldd_task;
580 a->uldd_timer = 1;
581 if (t->task_proto & SAS_PROTO_STP)
582 t->task_proto = SAS_PROTO_STP;
583 switch (t->task_proto) {
584 case SATA_PROTO:
585 case SAS_PROTO_STP:
586 res = asd_build_ata_ascb(a, t, gfp_flags);
587 break;
588 case SAS_PROTO_SMP:
589 res = asd_build_smp_ascb(a, t, gfp_flags);
590 break;
591 case SAS_PROTO_SSP:
592 res = asd_build_ssp_ascb(a, t, gfp_flags);
593 break;
594 default:
595 asd_printk("unknown sas_task proto: 0x%x\n",
596 t->task_proto);
597 res = -ENOMEM;
598 break;
599 }
600 if (res)
601 goto out_err_unmap;
602 }
603 list_del_init(&alist);
604
605 res = asd_post_ascb_list(asd_ha, ascb, num);
606 if (unlikely(res)) {
607 a = NULL;
608 __list_add(&alist, ascb->list.prev, &ascb->list);
609 goto out_err_unmap;
610 }
611
612 return 0;
613out_err_unmap:
614 {
615 struct asd_ascb *b = a;
616 list_for_each_entry(a, &alist, list) {
617 if (a == b)
618 break;
619 t = a->uldd_task;
620 switch (t->task_proto) {
621 case SATA_PROTO:
622 case SAS_PROTO_STP:
623 asd_unbuild_ata_ascb(a);
624 break;
625 case SAS_PROTO_SMP:
626 asd_unbuild_smp_ascb(a);
627 break;
628 case SAS_PROTO_SSP:
629 asd_unbuild_ssp_ascb(a);
630 default:
631 break;
632 }
633 t->lldd_task = NULL;
634 }
635 }
636 list_del_init(&alist);
637out_err:
638 if (ascb)
639 asd_ascb_free_list(ascb);
640 asd_can_dequeue(asd_ha, num);
641 return res;
642}
diff --git a/drivers/scsi/aic94xx/aic94xx_tmf.c b/drivers/scsi/aic94xx/aic94xx_tmf.c
new file mode 100644
index 000000000000..61234384503b
--- /dev/null
+++ b/drivers/scsi/aic94xx/aic94xx_tmf.c
@@ -0,0 +1,636 @@
1/*
2 * Aic94xx Task Management Functions
3 *
4 * Copyright (C) 2005 Adaptec, Inc. All rights reserved.
5 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
6 *
7 * This file is licensed under GPLv2.
8 *
9 * This file is part of the aic94xx driver.
10 *
11 * The aic94xx driver is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; version 2 of the
14 * License.
15 *
16 * The aic94xx driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with the aic94xx driver; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 *
25 */
26
27#include <linux/spinlock.h>
28#include "aic94xx.h"
29#include "aic94xx_sas.h"
30#include "aic94xx_hwi.h"
31
32/* ---------- Internal enqueue ---------- */
33
34static int asd_enqueue_internal(struct asd_ascb *ascb,
35 void (*tasklet_complete)(struct asd_ascb *,
36 struct done_list_struct *),
37 void (*timed_out)(unsigned long))
38{
39 int res;
40
41 ascb->tasklet_complete = tasklet_complete;
42 ascb->uldd_timer = 1;
43
44 ascb->timer.data = (unsigned long) ascb;
45 ascb->timer.function = timed_out;
46 ascb->timer.expires = jiffies + AIC94XX_SCB_TIMEOUT;
47
48 add_timer(&ascb->timer);
49
50 res = asd_post_ascb_list(ascb->ha, ascb, 1);
51 if (unlikely(res))
52 del_timer(&ascb->timer);
53 return res;
54}
55
56static inline void asd_timedout_common(unsigned long data)
57{
58 struct asd_ascb *ascb = (void *) data;
59 struct asd_seq_data *seq = &ascb->ha->seq;
60 unsigned long flags;
61
62 spin_lock_irqsave(&seq->pend_q_lock, flags);
63 seq->pending--;
64 list_del_init(&ascb->list);
65 spin_unlock_irqrestore(&seq->pend_q_lock, flags);
66}
67
68/* ---------- CLEAR NEXUS ---------- */
69
70static void asd_clear_nexus_tasklet_complete(struct asd_ascb *ascb,
71 struct done_list_struct *dl)
72{
73 ASD_DPRINTK("%s: here\n", __FUNCTION__);
74 if (!del_timer(&ascb->timer)) {
75 ASD_DPRINTK("%s: couldn't delete timer\n", __FUNCTION__);
76 return;
77 }
78 ASD_DPRINTK("%s: opcode: 0x%x\n", __FUNCTION__, dl->opcode);
79 ascb->uldd_task = (void *) (unsigned long) dl->opcode;
80 complete(&ascb->completion);
81}
82
83static void asd_clear_nexus_timedout(unsigned long data)
84{
85 struct asd_ascb *ascb = (void *) data;
86
87 ASD_DPRINTK("%s: here\n", __FUNCTION__);
88 asd_timedout_common(data);
89 ascb->uldd_task = (void *) TMF_RESP_FUNC_FAILED;
90 complete(&ascb->completion);
91}
92
93#define CLEAR_NEXUS_PRE \
94 ASD_DPRINTK("%s: PRE\n", __FUNCTION__); \
95 res = 1; \
96 ascb = asd_ascb_alloc_list(asd_ha, &res, GFP_KERNEL); \
97 if (!ascb) \
98 return -ENOMEM; \
99 \
100 scb = ascb->scb; \
101 scb->header.opcode = CLEAR_NEXUS
102
103#define CLEAR_NEXUS_POST \
104 ASD_DPRINTK("%s: POST\n", __FUNCTION__); \
105 res = asd_enqueue_internal(ascb, asd_clear_nexus_tasklet_complete, \
106 asd_clear_nexus_timedout); \
107 if (res) \
108 goto out_err; \
109 ASD_DPRINTK("%s: clear nexus posted, waiting...\n", __FUNCTION__); \
110 wait_for_completion(&ascb->completion); \
111 res = (int) (unsigned long) ascb->uldd_task; \
112 if (res == TC_NO_ERROR) \
113 res = TMF_RESP_FUNC_COMPLETE; \
114out_err: \
115 asd_ascb_free(ascb); \
116 return res
117
118int asd_clear_nexus_ha(struct sas_ha_struct *sas_ha)
119{
120 struct asd_ha_struct *asd_ha = sas_ha->lldd_ha;
121 struct asd_ascb *ascb;
122 struct scb *scb;
123 int res;
124
125 CLEAR_NEXUS_PRE;
126 scb->clear_nexus.nexus = NEXUS_ADAPTER;
127 CLEAR_NEXUS_POST;
128}
129
130int asd_clear_nexus_port(struct asd_sas_port *port)
131{
132 struct asd_ha_struct *asd_ha = port->ha->lldd_ha;
133 struct asd_ascb *ascb;
134 struct scb *scb;
135 int res;
136
137 CLEAR_NEXUS_PRE;
138 scb->clear_nexus.nexus = NEXUS_PORT;
139 scb->clear_nexus.conn_mask = port->phy_mask;
140 CLEAR_NEXUS_POST;
141}
142
143#if 0
144static int asd_clear_nexus_I_T(struct domain_device *dev)
145{
146 struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha;
147 struct asd_ascb *ascb;
148 struct scb *scb;
149 int res;
150
151 CLEAR_NEXUS_PRE;
152 scb->clear_nexus.nexus = NEXUS_I_T;
153 scb->clear_nexus.flags = SEND_Q | EXEC_Q | NOTINQ;
154 if (dev->tproto)
155 scb->clear_nexus.flags |= SUSPEND_TX;
156 scb->clear_nexus.conn_handle = cpu_to_le16((u16)(unsigned long)
157 dev->lldd_dev);
158 CLEAR_NEXUS_POST;
159}
160#endif
161
162static int asd_clear_nexus_I_T_L(struct domain_device *dev, u8 *lun)
163{
164 struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha;
165 struct asd_ascb *ascb;
166 struct scb *scb;
167 int res;
168
169 CLEAR_NEXUS_PRE;
170 scb->clear_nexus.nexus = NEXUS_I_T_L;
171 scb->clear_nexus.flags = SEND_Q | EXEC_Q | NOTINQ;
172 if (dev->tproto)
173 scb->clear_nexus.flags |= SUSPEND_TX;
174 memcpy(scb->clear_nexus.ssp_task.lun, lun, 8);
175 scb->clear_nexus.conn_handle = cpu_to_le16((u16)(unsigned long)
176 dev->lldd_dev);
177 CLEAR_NEXUS_POST;
178}
179
180static int asd_clear_nexus_tag(struct sas_task *task)
181{
182 struct asd_ha_struct *asd_ha = task->dev->port->ha->lldd_ha;
183 struct asd_ascb *tascb = task->lldd_task;
184 struct asd_ascb *ascb;
185 struct scb *scb;
186 int res;
187
188 CLEAR_NEXUS_PRE;
189 scb->clear_nexus.nexus = NEXUS_TAG;
190 memcpy(scb->clear_nexus.ssp_task.lun, task->ssp_task.LUN, 8);
191 scb->clear_nexus.ssp_task.tag = tascb->tag;
192 if (task->dev->tproto)
193 scb->clear_nexus.conn_handle = cpu_to_le16((u16)(unsigned long)
194 task->dev->lldd_dev);
195 CLEAR_NEXUS_POST;
196}
197
198static int asd_clear_nexus_index(struct sas_task *task)
199{
200 struct asd_ha_struct *asd_ha = task->dev->port->ha->lldd_ha;
201 struct asd_ascb *tascb = task->lldd_task;
202 struct asd_ascb *ascb;
203 struct scb *scb;
204 int res;
205
206 CLEAR_NEXUS_PRE;
207 scb->clear_nexus.nexus = NEXUS_TRANS_CX;
208 if (task->dev->tproto)
209 scb->clear_nexus.conn_handle = cpu_to_le16((u16)(unsigned long)
210 task->dev->lldd_dev);
211 scb->clear_nexus.index = cpu_to_le16(tascb->tc_index);
212 CLEAR_NEXUS_POST;
213}
214
215/* ---------- TMFs ---------- */
216
217static void asd_tmf_timedout(unsigned long data)
218{
219 struct asd_ascb *ascb = (void *) data;
220
221 ASD_DPRINTK("tmf timed out\n");
222 asd_timedout_common(data);
223 ascb->uldd_task = (void *) TMF_RESP_FUNC_FAILED;
224 complete(&ascb->completion);
225}
226
227static int asd_get_tmf_resp_tasklet(struct asd_ascb *ascb,
228 struct done_list_struct *dl)
229{
230 struct asd_ha_struct *asd_ha = ascb->ha;
231 unsigned long flags;
232 struct tc_resp_sb_struct {
233 __le16 index_escb;
234 u8 len_lsb;
235 u8 flags;
236 } __attribute__ ((packed)) *resp_sb = (void *) dl->status_block;
237
238 int edb_id = ((resp_sb->flags & 0x70) >> 4)-1;
239 struct asd_ascb *escb;
240 struct asd_dma_tok *edb;
241 struct ssp_frame_hdr *fh;
242 struct ssp_response_iu *ru;
243 int res = TMF_RESP_FUNC_FAILED;
244
245 ASD_DPRINTK("tmf resp tasklet\n");
246
247 spin_lock_irqsave(&asd_ha->seq.tc_index_lock, flags);
248 escb = asd_tc_index_find(&asd_ha->seq,
249 (int)le16_to_cpu(resp_sb->index_escb));
250 spin_unlock_irqrestore(&asd_ha->seq.tc_index_lock, flags);
251
252 if (!escb) {
253 ASD_DPRINTK("Uh-oh! No escb for this dl?!\n");
254 return res;
255 }
256
257 edb = asd_ha->seq.edb_arr[edb_id + escb->edb_index];
258 ascb->tag = *(__be16 *)(edb->vaddr+4);
259 fh = edb->vaddr + 16;
260 ru = edb->vaddr + 16 + sizeof(*fh);
261 res = ru->status;
262 if (ru->datapres == 1) /* Response data present */
263 res = ru->resp_data[3];
264#if 0
265 ascb->tag = fh->tag;
266#endif
267 ascb->tag_valid = 1;
268
269 asd_invalidate_edb(escb, edb_id);
270 return res;
271}
272
273static void asd_tmf_tasklet_complete(struct asd_ascb *ascb,
274 struct done_list_struct *dl)
275{
276 if (!del_timer(&ascb->timer))
277 return;
278
279 ASD_DPRINTK("tmf tasklet complete\n");
280
281 if (dl->opcode == TC_SSP_RESP)
282 ascb->uldd_task = (void *) (unsigned long)
283 asd_get_tmf_resp_tasklet(ascb, dl);
284 else
285 ascb->uldd_task = (void *) 0xFF00 + (unsigned long) dl->opcode;
286
287 complete(&ascb->completion);
288}
289
290static inline int asd_clear_nexus(struct sas_task *task)
291{
292 int res = TMF_RESP_FUNC_FAILED;
293 struct asd_ascb *tascb = task->lldd_task;
294 unsigned long flags;
295
296 ASD_DPRINTK("task not done, clearing nexus\n");
297 if (tascb->tag_valid)
298 res = asd_clear_nexus_tag(task);
299 else
300 res = asd_clear_nexus_index(task);
301 wait_for_completion_timeout(&tascb->completion,
302 AIC94XX_SCB_TIMEOUT);
303 ASD_DPRINTK("came back from clear nexus\n");
304 spin_lock_irqsave(&task->task_state_lock, flags);
305 if (task->task_state_flags & SAS_TASK_STATE_DONE)
306 res = TMF_RESP_FUNC_COMPLETE;
307 spin_unlock_irqrestore(&task->task_state_lock, flags);
308
309 return res;
310}
311
312/**
313 * asd_abort_task -- ABORT TASK TMF
314 * @task: the task to be aborted
315 *
316 * Before calling ABORT TASK the task state flags should be ORed with
317 * SAS_TASK_STATE_ABORTED (unless SAS_TASK_STATE_DONE is set) under
318 * the task_state_lock IRQ spinlock, then ABORT TASK *must* be called.
319 *
320 * Implements the ABORT TASK TMF, I_T_L_Q nexus.
321 * Returns: SAS TMF responses (see sas_task.h),
322 * -ENOMEM,
323 * -SAS_QUEUE_FULL.
324 *
325 * When ABORT TASK returns, the caller of ABORT TASK checks first the
326 * task->task_state_flags, and then the return value of ABORT TASK.
327 *
328 * If the task has task state bit SAS_TASK_STATE_DONE set, then the
329 * task was completed successfully prior to it being aborted. The
330 * caller of ABORT TASK has responsibility to call task->task_done()
331 * xor free the task, depending on their framework. The return code
332 * is TMF_RESP_FUNC_FAILED in this case.
333 *
334 * Else the SAS_TASK_STATE_DONE bit is not set,
335 * If the return code is TMF_RESP_FUNC_COMPLETE, then
336 * the task was aborted successfully. The caller of
337 * ABORT TASK has responsibility to call task->task_done()
338 * to finish the task, xor free the task depending on their
339 * framework.
340 * else
341 * the ABORT TASK returned some kind of error. The task
342 * was _not_ cancelled. Nothing can be assumed.
343 * The caller of ABORT TASK may wish to retry.
344 */
345int asd_abort_task(struct sas_task *task)
346{
347 struct asd_ascb *tascb = task->lldd_task;
348 struct asd_ha_struct *asd_ha = tascb->ha;
349 int res = 1;
350 unsigned long flags;
351 struct asd_ascb *ascb = NULL;
352 struct scb *scb;
353
354 spin_lock_irqsave(&task->task_state_lock, flags);
355 if (task->task_state_flags & SAS_TASK_STATE_DONE) {
356 spin_unlock_irqrestore(&task->task_state_lock, flags);
357 res = TMF_RESP_FUNC_COMPLETE;
358 ASD_DPRINTK("%s: task 0x%p done\n", __FUNCTION__, task);
359 goto out_done;
360 }
361 spin_unlock_irqrestore(&task->task_state_lock, flags);
362
363 ascb = asd_ascb_alloc_list(asd_ha, &res, GFP_KERNEL);
364 if (!ascb)
365 return -ENOMEM;
366 scb = ascb->scb;
367
368 scb->header.opcode = ABORT_TASK;
369
370 switch (task->task_proto) {
371 case SATA_PROTO:
372 case SAS_PROTO_STP:
373 scb->abort_task.proto_conn_rate = (1 << 5); /* STP */
374 break;
375 case SAS_PROTO_SSP:
376 scb->abort_task.proto_conn_rate = (1 << 4); /* SSP */
377 scb->abort_task.proto_conn_rate |= task->dev->linkrate;
378 break;
379 case SAS_PROTO_SMP:
380 break;
381 default:
382 break;
383 }
384
385 if (task->task_proto == SAS_PROTO_SSP) {
386 scb->abort_task.ssp_frame.frame_type = SSP_TASK;
387 memcpy(scb->abort_task.ssp_frame.hashed_dest_addr,
388 task->dev->hashed_sas_addr, HASHED_SAS_ADDR_SIZE);
389 memcpy(scb->abort_task.ssp_frame.hashed_src_addr,
390 task->dev->port->ha->hashed_sas_addr,
391 HASHED_SAS_ADDR_SIZE);
392 scb->abort_task.ssp_frame.tptt = cpu_to_be16(0xFFFF);
393
394 memcpy(scb->abort_task.ssp_task.lun, task->ssp_task.LUN, 8);
395 scb->abort_task.ssp_task.tmf = TMF_ABORT_TASK;
396 scb->abort_task.ssp_task.tag = cpu_to_be16(0xFFFF);
397 }
398
399 scb->abort_task.sister_scb = cpu_to_le16(0xFFFF);
400 scb->abort_task.conn_handle = cpu_to_le16(
401 (u16)(unsigned long)task->dev->lldd_dev);
402 scb->abort_task.retry_count = 1;
403 scb->abort_task.index = cpu_to_le16((u16)tascb->tc_index);
404 scb->abort_task.itnl_to = cpu_to_le16(ITNL_TIMEOUT_CONST);
405
406 res = asd_enqueue_internal(ascb, asd_tmf_tasklet_complete,
407 asd_tmf_timedout);
408 if (res)
409 goto out;
410 wait_for_completion(&ascb->completion);
411 ASD_DPRINTK("tmf came back\n");
412
413 res = (int) (unsigned long) ascb->uldd_task;
414 tascb->tag = ascb->tag;
415 tascb->tag_valid = ascb->tag_valid;
416
417 spin_lock_irqsave(&task->task_state_lock, flags);
418 if (task->task_state_flags & SAS_TASK_STATE_DONE) {
419 spin_unlock_irqrestore(&task->task_state_lock, flags);
420 res = TMF_RESP_FUNC_COMPLETE;
421 ASD_DPRINTK("%s: task 0x%p done\n", __FUNCTION__, task);
422 goto out_done;
423 }
424 spin_unlock_irqrestore(&task->task_state_lock, flags);
425
426 switch (res) {
427 /* The task to be aborted has been sent to the device.
428 * We got a Response IU for the ABORT TASK TMF. */
429 case TC_NO_ERROR + 0xFF00:
430 case TMF_RESP_FUNC_COMPLETE:
431 case TMF_RESP_FUNC_FAILED:
432 res = asd_clear_nexus(task);
433 break;
434 case TMF_RESP_INVALID_FRAME:
435 case TMF_RESP_OVERLAPPED_TAG:
436 case TMF_RESP_FUNC_ESUPP:
437 case TMF_RESP_NO_LUN:
438 goto out_done; break;
439 }
440 /* In the following we assume that the managing layer
441 * will _never_ make a mistake, when issuing ABORT TASK.
442 */
443 switch (res) {
444 default:
445 res = asd_clear_nexus(task);
446 /* fallthrough */
447 case TC_NO_ERROR + 0xFF00:
448 case TMF_RESP_FUNC_COMPLETE:
449 break;
450 /* The task hasn't been sent to the device xor we never got
451 * a (sane) Response IU for the ABORT TASK TMF.
452 */
453 case TF_NAK_RECV + 0xFF00:
454 res = TMF_RESP_INVALID_FRAME;
455 break;
456 case TF_TMF_TASK_DONE + 0xFF00: /* done but not reported yet */
457 res = TMF_RESP_FUNC_FAILED;
458 wait_for_completion_timeout(&tascb->completion,
459 AIC94XX_SCB_TIMEOUT);
460 spin_lock_irqsave(&task->task_state_lock, flags);
461 if (task->task_state_flags & SAS_TASK_STATE_DONE)
462 res = TMF_RESP_FUNC_COMPLETE;
463 spin_unlock_irqrestore(&task->task_state_lock, flags);
464 goto out_done;
465 case TF_TMF_NO_TAG + 0xFF00:
466 case TF_TMF_TAG_FREE + 0xFF00: /* the tag is in the free list */
467 case TF_TMF_NO_CONN_HANDLE + 0xFF00: /* no such device */
468 res = TMF_RESP_FUNC_COMPLETE;
469 goto out_done;
470 case TF_TMF_NO_CTX + 0xFF00: /* not in seq, or proto != SSP */
471 res = TMF_RESP_FUNC_ESUPP;
472 goto out;
473 }
474out_done:
475 if (res == TMF_RESP_FUNC_COMPLETE) {
476 task->lldd_task = NULL;
477 mb();
478 asd_ascb_free(tascb);
479 }
480out:
481 asd_ascb_free(ascb);
482 ASD_DPRINTK("task 0x%p aborted, res: 0x%x\n", task, res);
483 return res;
484}
485
486/**
487 * asd_initiate_ssp_tmf -- send a TMF to an I_T_L or I_T_L_Q nexus
488 * @dev: pointer to struct domain_device of interest
489 * @lun: pointer to u8[8] which is the LUN
490 * @tmf: the TMF to be performed (see sas_task.h or the SAS spec)
491 * @index: the transaction context of the task to be queried if QT TMF
492 *
493 * This function is used to send ABORT TASK SET, CLEAR ACA,
494 * CLEAR TASK SET, LU RESET and QUERY TASK TMFs.
495 *
496 * No SCBs should be queued to the I_T_L nexus when this SCB is
497 * pending.
498 *
499 * Returns: TMF response code (see sas_task.h or the SAS spec)
500 */
501static int asd_initiate_ssp_tmf(struct domain_device *dev, u8 *lun,
502 int tmf, int index)
503{
504 struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha;
505 struct asd_ascb *ascb;
506 int res = 1;
507 struct scb *scb;
508
509 if (!(dev->tproto & SAS_PROTO_SSP))
510 return TMF_RESP_FUNC_ESUPP;
511
512 ascb = asd_ascb_alloc_list(asd_ha, &res, GFP_KERNEL);
513 if (!ascb)
514 return -ENOMEM;
515 scb = ascb->scb;
516
517 if (tmf == TMF_QUERY_TASK)
518 scb->header.opcode = QUERY_SSP_TASK;
519 else
520 scb->header.opcode = INITIATE_SSP_TMF;
521
522 scb->ssp_tmf.proto_conn_rate = (1 << 4); /* SSP */
523 scb->ssp_tmf.proto_conn_rate |= dev->linkrate;
524 /* SSP frame header */
525 scb->ssp_tmf.ssp_frame.frame_type = SSP_TASK;
526 memcpy(scb->ssp_tmf.ssp_frame.hashed_dest_addr,
527 dev->hashed_sas_addr, HASHED_SAS_ADDR_SIZE);
528 memcpy(scb->ssp_tmf.ssp_frame.hashed_src_addr,
529 dev->port->ha->hashed_sas_addr, HASHED_SAS_ADDR_SIZE);
530 scb->ssp_tmf.ssp_frame.tptt = cpu_to_be16(0xFFFF);
531 /* SSP Task IU */
532 memcpy(scb->ssp_tmf.ssp_task.lun, lun, 8);
533 scb->ssp_tmf.ssp_task.tmf = tmf;
534
535 scb->ssp_tmf.sister_scb = cpu_to_le16(0xFFFF);
536 scb->ssp_tmf.conn_handle= cpu_to_le16((u16)(unsigned long)
537 dev->lldd_dev);
538 scb->ssp_tmf.retry_count = 1;
539 scb->ssp_tmf.itnl_to = cpu_to_le16(ITNL_TIMEOUT_CONST);
540 if (tmf == TMF_QUERY_TASK)
541 scb->ssp_tmf.index = cpu_to_le16(index);
542
543 res = asd_enqueue_internal(ascb, asd_tmf_tasklet_complete,
544 asd_tmf_timedout);
545 if (res)
546 goto out_err;
547 wait_for_completion(&ascb->completion);
548 res = (int) (unsigned long) ascb->uldd_task;
549
550 switch (res) {
551 case TC_NO_ERROR + 0xFF00:
552 res = TMF_RESP_FUNC_COMPLETE;
553 break;
554 case TF_NAK_RECV + 0xFF00:
555 res = TMF_RESP_INVALID_FRAME;
556 break;
557 case TF_TMF_TASK_DONE + 0xFF00:
558 res = TMF_RESP_FUNC_FAILED;
559 break;
560 case TF_TMF_NO_TAG + 0xFF00:
561 case TF_TMF_TAG_FREE + 0xFF00: /* the tag is in the free list */
562 case TF_TMF_NO_CONN_HANDLE + 0xFF00: /* no such device */
563 res = TMF_RESP_FUNC_COMPLETE;
564 break;
565 case TF_TMF_NO_CTX + 0xFF00: /* not in seq, or proto != SSP */
566 res = TMF_RESP_FUNC_ESUPP;
567 break;
568 default:
569 ASD_DPRINTK("%s: converting result 0x%x to TMF_RESP_FUNC_FAILED\n",
570 __FUNCTION__, res);
571 res = TMF_RESP_FUNC_FAILED;
572 break;
573 }
574out_err:
575 asd_ascb_free(ascb);
576 return res;
577}
578
579int asd_abort_task_set(struct domain_device *dev, u8 *lun)
580{
581 int res = asd_initiate_ssp_tmf(dev, lun, TMF_ABORT_TASK_SET, 0);
582
583 if (res == TMF_RESP_FUNC_COMPLETE)
584 asd_clear_nexus_I_T_L(dev, lun);
585 return res;
586}
587
588int asd_clear_aca(struct domain_device *dev, u8 *lun)
589{
590 int res = asd_initiate_ssp_tmf(dev, lun, TMF_CLEAR_ACA, 0);
591
592 if (res == TMF_RESP_FUNC_COMPLETE)
593 asd_clear_nexus_I_T_L(dev, lun);
594 return res;
595}
596
597int asd_clear_task_set(struct domain_device *dev, u8 *lun)
598{
599 int res = asd_initiate_ssp_tmf(dev, lun, TMF_CLEAR_TASK_SET, 0);
600
601 if (res == TMF_RESP_FUNC_COMPLETE)
602 asd_clear_nexus_I_T_L(dev, lun);
603 return res;
604}
605
606int asd_lu_reset(struct domain_device *dev, u8 *lun)
607{
608 int res = asd_initiate_ssp_tmf(dev, lun, TMF_LU_RESET, 0);
609
610 if (res == TMF_RESP_FUNC_COMPLETE)
611 asd_clear_nexus_I_T_L(dev, lun);
612 return res;
613}
614
615/**
616 * asd_query_task -- send a QUERY TASK TMF to an I_T_L_Q nexus
617 * task: pointer to sas_task struct of interest
618 *
619 * Returns: TMF_RESP_FUNC_COMPLETE if the task is not in the task set,
620 * or TMF_RESP_FUNC_SUCC if the task is in the task set.
621 *
622 * Normally the management layer sets the task to aborted state,
623 * and then calls query task and then abort task.
624 */
625int asd_query_task(struct sas_task *task)
626{
627 struct asd_ascb *ascb = task->lldd_task;
628 int index;
629
630 if (ascb) {
631 index = ascb->tc_index;
632 return asd_initiate_ssp_tmf(task->dev, task->ssp_task.LUN,
633 TMF_QUERY_TASK, index);
634 }
635 return TMF_RESP_FUNC_COMPLETE;
636}
diff --git a/drivers/scsi/libsas/Kconfig b/drivers/scsi/libsas/Kconfig
new file mode 100644
index 000000000000..aafdc92f8312
--- /dev/null
+++ b/drivers/scsi/libsas/Kconfig
@@ -0,0 +1,39 @@
1#
2# Kernel configuration file for the SAS Class
3#
4# Copyright (C) 2005 Adaptec, Inc. All rights reserved.
5# Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
6#
7# This file is licensed under GPLv2.
8#
9# This program is free software; you can redistribute it and/or
10# modify it under the terms of the GNU General Public License as
11# published by the Free Software Foundation; version 2 of the
12# License.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17# General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program; if not, write to the Free Software
21# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22# USA
23#
24
25config SCSI_SAS_LIBSAS
26 tristate "SAS Domain Transport Attributes"
27 depends on SCSI
28 select SCSI_SAS_ATTRS
29 help
30 This provides transport specific helpers for SAS drivers which
31 use the domain device construct (like the aic94xxx).
32
33config SCSI_SAS_LIBSAS_DEBUG
34 bool "Compile the SAS Domain Transport Attributes in debug mode"
35 default y
36 depends on SCSI_SAS_LIBSAS
37 help
38 Compiles the SAS Layer in debug mode. In debug mode, the
39 SAS Layer prints diagnostic and debug messages.
diff --git a/drivers/scsi/libsas/Makefile b/drivers/scsi/libsas/Makefile
new file mode 100644
index 000000000000..44d972a3b4bd
--- /dev/null
+++ b/drivers/scsi/libsas/Makefile
@@ -0,0 +1,36 @@
1#
2# Kernel Makefile for the libsas helpers
3#
4# Copyright (C) 2005 Adaptec, Inc. All rights reserved.
5# Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
6#
7# This file is licensed under GPLv2.
8#
9# This program is free software; you can redistribute it and/or
10# modify it under the terms of the GNU General Public License as
11# published by the Free Software Foundation; version 2 of the
12# License.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17# General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program; if not, write to the Free Software
21# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22# USA
23
24ifeq ($(CONFIG_SCSI_SAS_LIBSAS_DEBUG),y)
25 EXTRA_CFLAGS += -DSAS_DEBUG
26endif
27
28obj-$(CONFIG_SCSI_SAS_LIBSAS) += libsas.o
29libsas-y += sas_init.o \
30 sas_phy.o \
31 sas_port.o \
32 sas_event.o \
33 sas_dump.o \
34 sas_discover.o \
35 sas_expander.o \
36 sas_scsi_host.o
diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c
new file mode 100644
index 000000000000..d977bd492d8d
--- /dev/null
+++ b/drivers/scsi/libsas/sas_discover.c
@@ -0,0 +1,749 @@
1/*
2 * Serial Attached SCSI (SAS) Discover process
3 *
4 * Copyright (C) 2005 Adaptec, Inc. All rights reserved.
5 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
6 *
7 * This file is licensed under GPLv2.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 *
23 */
24
25#include <linux/pci.h>
26#include <linux/scatterlist.h>
27#include <scsi/scsi_host.h>
28#include <scsi/scsi_eh.h>
29#include "sas_internal.h"
30
31#include <scsi/scsi_transport.h>
32#include <scsi/scsi_transport_sas.h>
33#include "../scsi_sas_internal.h"
34
35/* ---------- Basic task processing for discovery purposes ---------- */
36
37void sas_init_dev(struct domain_device *dev)
38{
39 INIT_LIST_HEAD(&dev->siblings);
40 INIT_LIST_HEAD(&dev->dev_list_node);
41 switch (dev->dev_type) {
42 case SAS_END_DEV:
43 break;
44 case EDGE_DEV:
45 case FANOUT_DEV:
46 INIT_LIST_HEAD(&dev->ex_dev.children);
47 break;
48 case SATA_DEV:
49 case SATA_PM:
50 case SATA_PM_PORT:
51 INIT_LIST_HEAD(&dev->sata_dev.children);
52 break;
53 default:
54 break;
55 }
56}
57
58static void sas_task_timedout(unsigned long _task)
59{
60 struct sas_task *task = (void *) _task;
61 unsigned long flags;
62
63 spin_lock_irqsave(&task->task_state_lock, flags);
64 if (!(task->task_state_flags & SAS_TASK_STATE_DONE))
65 task->task_state_flags |= SAS_TASK_STATE_ABORTED;
66 spin_unlock_irqrestore(&task->task_state_lock, flags);
67
68 complete(&task->completion);
69}
70
71static void sas_disc_task_done(struct sas_task *task)
72{
73 if (!del_timer(&task->timer))
74 return;
75 complete(&task->completion);
76}
77
78#define SAS_DEV_TIMEOUT 10
79
80/**
81 * sas_execute_task -- Basic task processing for discovery
82 * @task: the task to be executed
83 * @buffer: pointer to buffer to do I/O
84 * @size: size of @buffer
85 * @pci_dma_dir: PCI_DMA_...
86 */
87static int sas_execute_task(struct sas_task *task, void *buffer, int size,
88 int pci_dma_dir)
89{
90 int res = 0;
91 struct scatterlist *scatter = NULL;
92 struct task_status_struct *ts = &task->task_status;
93 int num_scatter = 0;
94 int retries = 0;
95 struct sas_internal *i =
96 to_sas_internal(task->dev->port->ha->core.shost->transportt);
97
98 if (pci_dma_dir != PCI_DMA_NONE) {
99 scatter = kzalloc(sizeof(*scatter), GFP_KERNEL);
100 if (!scatter)
101 goto out;
102
103 sg_init_one(scatter, buffer, size);
104 num_scatter = 1;
105 }
106
107 task->task_proto = task->dev->tproto;
108 task->scatter = scatter;
109 task->num_scatter = num_scatter;
110 task->total_xfer_len = size;
111 task->data_dir = pci_dma_dir;
112 task->task_done = sas_disc_task_done;
113
114 for (retries = 0; retries < 5; retries++) {
115 task->task_state_flags = SAS_TASK_STATE_PENDING;
116 init_completion(&task->completion);
117
118 task->timer.data = (unsigned long) task;
119 task->timer.function = sas_task_timedout;
120 task->timer.expires = jiffies + SAS_DEV_TIMEOUT*HZ;
121 add_timer(&task->timer);
122
123 res = i->dft->lldd_execute_task(task, 1, GFP_KERNEL);
124 if (res) {
125 del_timer(&task->timer);
126 SAS_DPRINTK("executing SAS discovery task failed:%d\n",
127 res);
128 goto ex_err;
129 }
130 wait_for_completion(&task->completion);
131 res = -ETASK;
132 if (task->task_state_flags & SAS_TASK_STATE_ABORTED) {
133 int res2;
134 SAS_DPRINTK("task aborted, flags:0x%x\n",
135 task->task_state_flags);
136 res2 = i->dft->lldd_abort_task(task);
137 SAS_DPRINTK("came back from abort task\n");
138 if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
139 if (res2 == TMF_RESP_FUNC_COMPLETE)
140 continue; /* Retry the task */
141 else
142 goto ex_err;
143 }
144 }
145 if (task->task_status.stat == SAM_BUSY ||
146 task->task_status.stat == SAM_TASK_SET_FULL ||
147 task->task_status.stat == SAS_QUEUE_FULL) {
148 SAS_DPRINTK("task: q busy, sleeping...\n");
149 schedule_timeout_interruptible(HZ);
150 } else if (task->task_status.stat == SAM_CHECK_COND) {
151 struct scsi_sense_hdr shdr;
152
153 if (!scsi_normalize_sense(ts->buf, ts->buf_valid_size,
154 &shdr)) {
155 SAS_DPRINTK("couldn't normalize sense\n");
156 continue;
157 }
158 if ((shdr.sense_key == 6 && shdr.asc == 0x29) ||
159 (shdr.sense_key == 2 && shdr.asc == 4 &&
160 shdr.ascq == 1)) {
161 SAS_DPRINTK("device %016llx LUN: %016llx "
162 "powering up or not ready yet, "
163 "sleeping...\n",
164 SAS_ADDR(task->dev->sas_addr),
165 SAS_ADDR(task->ssp_task.LUN));
166
167 schedule_timeout_interruptible(5*HZ);
168 } else if (shdr.sense_key == 1) {
169 res = 0;
170 break;
171 } else if (shdr.sense_key == 5) {
172 break;
173 } else {
174 SAS_DPRINTK("dev %016llx LUN: %016llx "
175 "sense key:0x%x ASC:0x%x ASCQ:0x%x"
176 "\n",
177 SAS_ADDR(task->dev->sas_addr),
178 SAS_ADDR(task->ssp_task.LUN),
179 shdr.sense_key,
180 shdr.asc, shdr.ascq);
181 }
182 } else if (task->task_status.resp != SAS_TASK_COMPLETE ||
183 task->task_status.stat != SAM_GOOD) {
184 SAS_DPRINTK("task finished with resp:0x%x, "
185 "stat:0x%x\n",
186 task->task_status.resp,
187 task->task_status.stat);
188 goto ex_err;
189 } else {
190 res = 0;
191 break;
192 }
193 }
194ex_err:
195 if (pci_dma_dir != PCI_DMA_NONE)
196 kfree(scatter);
197out:
198 return res;
199}
200
201/* ---------- Domain device discovery ---------- */
202
203/**
204 * sas_get_port_device -- Discover devices which caused port creation
205 * @port: pointer to struct sas_port of interest
206 *
207 * Devices directly attached to a HA port, have no parent. This is
208 * how we know they are (domain) "root" devices. All other devices
209 * do, and should have their "parent" pointer set appropriately as
210 * soon as a child device is discovered.
211 */
212static int sas_get_port_device(struct asd_sas_port *port)
213{
214 unsigned long flags;
215 struct asd_sas_phy *phy;
216 struct sas_rphy *rphy;
217 struct domain_device *dev;
218
219 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
220 if (!dev)
221 return -ENOMEM;
222
223 spin_lock_irqsave(&port->phy_list_lock, flags);
224 if (list_empty(&port->phy_list)) {
225 spin_unlock_irqrestore(&port->phy_list_lock, flags);
226 kfree(dev);
227 return -ENODEV;
228 }
229 phy = container_of(port->phy_list.next, struct asd_sas_phy, port_phy_el);
230 spin_lock(&phy->frame_rcvd_lock);
231 memcpy(dev->frame_rcvd, phy->frame_rcvd, min(sizeof(dev->frame_rcvd),
232 (size_t)phy->frame_rcvd_size));
233 spin_unlock(&phy->frame_rcvd_lock);
234 spin_unlock_irqrestore(&port->phy_list_lock, flags);
235
236 if (dev->frame_rcvd[0] == 0x34 && port->oob_mode == SATA_OOB_MODE) {
237 struct dev_to_host_fis *fis =
238 (struct dev_to_host_fis *) dev->frame_rcvd;
239 if (fis->interrupt_reason == 1 && fis->lbal == 1 &&
240 fis->byte_count_low==0x69 && fis->byte_count_high == 0x96
241 && (fis->device & ~0x10) == 0)
242 dev->dev_type = SATA_PM;
243 else
244 dev->dev_type = SATA_DEV;
245 dev->tproto = SATA_PROTO;
246 } else {
247 struct sas_identify_frame *id =
248 (struct sas_identify_frame *) dev->frame_rcvd;
249 dev->dev_type = id->dev_type;
250 dev->iproto = id->initiator_bits;
251 dev->tproto = id->target_bits;
252 }
253
254 sas_init_dev(dev);
255
256 switch (dev->dev_type) {
257 case SAS_END_DEV:
258 rphy = sas_end_device_alloc(port->port);
259 break;
260 case EDGE_DEV:
261 rphy = sas_expander_alloc(port->port,
262 SAS_EDGE_EXPANDER_DEVICE);
263 break;
264 case FANOUT_DEV:
265 rphy = sas_expander_alloc(port->port,
266 SAS_FANOUT_EXPANDER_DEVICE);
267 break;
268 case SATA_DEV:
269 default:
270 printk("ERROR: Unidentified device type %d\n", dev->dev_type);
271 rphy = NULL;
272 break;
273 }
274
275 if (!rphy) {
276 kfree(dev);
277 return -ENODEV;
278 }
279 rphy->identify.phy_identifier = phy->phy->identify.phy_identifier;
280 memcpy(dev->sas_addr, port->attached_sas_addr, SAS_ADDR_SIZE);
281 sas_fill_in_rphy(dev, rphy);
282 sas_hash_addr(dev->hashed_sas_addr, dev->sas_addr);
283 port->port_dev = dev;
284 dev->port = port;
285 dev->linkrate = port->linkrate;
286 dev->min_linkrate = port->linkrate;
287 dev->max_linkrate = port->linkrate;
288 dev->pathways = port->num_phys;
289 memset(port->disc.fanout_sas_addr, 0, SAS_ADDR_SIZE);
290 memset(port->disc.eeds_a, 0, SAS_ADDR_SIZE);
291 memset(port->disc.eeds_b, 0, SAS_ADDR_SIZE);
292 port->disc.max_level = 0;
293
294 dev->rphy = rphy;
295 spin_lock(&port->dev_list_lock);
296 list_add_tail(&dev->dev_list_node, &port->dev_list);
297 spin_unlock(&port->dev_list_lock);
298
299 return 0;
300}
301
302/* ---------- Discover and Revalidate ---------- */
303
304/* ---------- SATA ---------- */
305
306static void sas_get_ata_command_set(struct domain_device *dev)
307{
308 struct dev_to_host_fis *fis =
309 (struct dev_to_host_fis *) dev->frame_rcvd;
310
311 if ((fis->sector_count == 1 && /* ATA */
312 fis->lbal == 1 &&
313 fis->lbam == 0 &&
314 fis->lbah == 0 &&
315 fis->device == 0)
316 ||
317 (fis->sector_count == 0 && /* CE-ATA (mATA) */
318 fis->lbal == 0 &&
319 fis->lbam == 0xCE &&
320 fis->lbah == 0xAA &&
321 (fis->device & ~0x10) == 0))
322
323 dev->sata_dev.command_set = ATA_COMMAND_SET;
324
325 else if ((fis->interrupt_reason == 1 && /* ATAPI */
326 fis->lbal == 1 &&
327 fis->byte_count_low == 0x14 &&
328 fis->byte_count_high == 0xEB &&
329 (fis->device & ~0x10) == 0))
330
331 dev->sata_dev.command_set = ATAPI_COMMAND_SET;
332
333 else if ((fis->sector_count == 1 && /* SEMB */
334 fis->lbal == 1 &&
335 fis->lbam == 0x3C &&
336 fis->lbah == 0xC3 &&
337 fis->device == 0)
338 ||
339 (fis->interrupt_reason == 1 && /* SATA PM */
340 fis->lbal == 1 &&
341 fis->byte_count_low == 0x69 &&
342 fis->byte_count_high == 0x96 &&
343 (fis->device & ~0x10) == 0))
344
345 /* Treat it as a superset? */
346 dev->sata_dev.command_set = ATAPI_COMMAND_SET;
347}
348
349/**
350 * sas_issue_ata_cmd -- Basic SATA command processing for discovery
351 * @dev: the device to send the command to
352 * @command: the command register
353 * @features: the features register
354 * @buffer: pointer to buffer to do I/O
355 * @size: size of @buffer
356 * @pci_dma_dir: PCI_DMA_...
357 */
358static int sas_issue_ata_cmd(struct domain_device *dev, u8 command,
359 u8 features, void *buffer, int size,
360 int pci_dma_dir)
361{
362 int res = 0;
363 struct sas_task *task;
364 struct dev_to_host_fis *d2h_fis = (struct dev_to_host_fis *)
365 &dev->frame_rcvd[0];
366
367 res = -ENOMEM;
368 task = sas_alloc_task(GFP_KERNEL);
369 if (!task)
370 goto out;
371
372 task->dev = dev;
373
374 task->ata_task.fis.command = command;
375 task->ata_task.fis.features = features;
376 task->ata_task.fis.device = d2h_fis->device;
377 task->ata_task.retry_count = 1;
378
379 res = sas_execute_task(task, buffer, size, pci_dma_dir);
380
381 sas_free_task(task);
382out:
383 return res;
384}
385
386static void sas_sata_propagate_sas_addr(struct domain_device *dev)
387{
388 unsigned long flags;
389 struct asd_sas_port *port = dev->port;
390 struct asd_sas_phy *phy;
391
392 BUG_ON(dev->parent);
393
394 memcpy(port->attached_sas_addr, dev->sas_addr, SAS_ADDR_SIZE);
395 spin_lock_irqsave(&port->phy_list_lock, flags);
396 list_for_each_entry(phy, &port->phy_list, port_phy_el)
397 memcpy(phy->attached_sas_addr, dev->sas_addr, SAS_ADDR_SIZE);
398 spin_unlock_irqrestore(&port->phy_list_lock, flags);
399}
400
401#define ATA_IDENTIFY_DEV 0xEC
402#define ATA_IDENTIFY_PACKET_DEV 0xA1
403#define ATA_SET_FEATURES 0xEF
404#define ATA_FEATURE_PUP_STBY_SPIN_UP 0x07
405
406/**
407 * sas_discover_sata_dev -- discover a STP/SATA device (SATA_DEV)
408 * @dev: STP/SATA device of interest (ATA/ATAPI)
409 *
410 * The LLDD has already been notified of this device, so that we can
411 * send FISes to it. Here we try to get IDENTIFY DEVICE or IDENTIFY
412 * PACKET DEVICE, if ATAPI device, so that the LLDD can fine-tune its
413 * performance for this device.
414 */
415static int sas_discover_sata_dev(struct domain_device *dev)
416{
417 int res;
418 __le16 *identify_x;
419 u8 command;
420
421 identify_x = kzalloc(512, GFP_KERNEL);
422 if (!identify_x)
423 return -ENOMEM;
424
425 if (dev->sata_dev.command_set == ATA_COMMAND_SET) {
426 dev->sata_dev.identify_device = identify_x;
427 command = ATA_IDENTIFY_DEV;
428 } else {
429 dev->sata_dev.identify_packet_device = identify_x;
430 command = ATA_IDENTIFY_PACKET_DEV;
431 }
432
433 res = sas_issue_ata_cmd(dev, command, 0, identify_x, 512,
434 PCI_DMA_FROMDEVICE);
435 if (res)
436 goto out_err;
437
438 /* lives on the media? */
439 if (le16_to_cpu(identify_x[0]) & 4) {
440 /* incomplete response */
441 SAS_DPRINTK("sending SET FEATURE/PUP_STBY_SPIN_UP to "
442 "dev %llx\n", SAS_ADDR(dev->sas_addr));
443 if (!le16_to_cpu(identify_x[83] & (1<<6)))
444 goto cont1;
445 res = sas_issue_ata_cmd(dev, ATA_SET_FEATURES,
446 ATA_FEATURE_PUP_STBY_SPIN_UP,
447 NULL, 0, PCI_DMA_NONE);
448 if (res)
449 goto cont1;
450
451 schedule_timeout_interruptible(5*HZ); /* More time? */
452 res = sas_issue_ata_cmd(dev, command, 0, identify_x, 512,
453 PCI_DMA_FROMDEVICE);
454 if (res)
455 goto out_err;
456 }
457cont1:
458 /* Get WWN */
459 if (dev->port->oob_mode != SATA_OOB_MODE) {
460 memcpy(dev->sas_addr, dev->sata_dev.rps_resp.rps.stp_sas_addr,
461 SAS_ADDR_SIZE);
462 } else if (dev->sata_dev.command_set == ATA_COMMAND_SET &&
463 (le16_to_cpu(dev->sata_dev.identify_device[108]) & 0xF000)
464 == 0x5000) {
465 int i;
466
467 for (i = 0; i < 4; i++) {
468 dev->sas_addr[2*i] =
469 (le16_to_cpu(dev->sata_dev.identify_device[108+i]) & 0xFF00) >> 8;
470 dev->sas_addr[2*i+1] =
471 le16_to_cpu(dev->sata_dev.identify_device[108+i]) & 0x00FF;
472 }
473 }
474 sas_hash_addr(dev->hashed_sas_addr, dev->sas_addr);
475 if (!dev->parent)
476 sas_sata_propagate_sas_addr(dev);
477
478 /* XXX Hint: register this SATA device with SATL.
479 When this returns, dev->sata_dev->lu is alive and
480 present.
481 sas_satl_register_dev(dev);
482 */
483 return 0;
484out_err:
485 dev->sata_dev.identify_packet_device = NULL;
486 dev->sata_dev.identify_device = NULL;
487 kfree(identify_x);
488 return res;
489}
490
491static int sas_discover_sata_pm(struct domain_device *dev)
492{
493 return -ENODEV;
494}
495
496int sas_notify_lldd_dev_found(struct domain_device *dev)
497{
498 int res = 0;
499 struct sas_ha_struct *sas_ha = dev->port->ha;
500 struct Scsi_Host *shost = sas_ha->core.shost;
501 struct sas_internal *i = to_sas_internal(shost->transportt);
502
503 if (i->dft->lldd_dev_found) {
504 res = i->dft->lldd_dev_found(dev);
505 if (res) {
506 printk("sas: driver on pcidev %s cannot handle "
507 "device %llx, error:%d\n",
508 pci_name(sas_ha->pcidev),
509 SAS_ADDR(dev->sas_addr), res);
510 }
511 }
512 return res;
513}
514
515
516void sas_notify_lldd_dev_gone(struct domain_device *dev)
517{
518 struct sas_ha_struct *sas_ha = dev->port->ha;
519 struct Scsi_Host *shost = sas_ha->core.shost;
520 struct sas_internal *i = to_sas_internal(shost->transportt);
521
522 if (i->dft->lldd_dev_gone)
523 i->dft->lldd_dev_gone(dev);
524}
525
526/* ---------- Common/dispatchers ---------- */
527
528/**
529 * sas_discover_sata -- discover an STP/SATA domain device
530 * @dev: pointer to struct domain_device of interest
531 *
532 * First we notify the LLDD of this device, so we can send frames to
533 * it. Then depending on the type of device we call the appropriate
534 * discover functions. Once device discover is done, we notify the
535 * LLDD so that it can fine-tune its parameters for the device, by
536 * removing it and then adding it. That is, the second time around,
537 * the driver would have certain fields, that it is looking at, set.
538 * Finally we initialize the kobj so that the device can be added to
539 * the system at registration time. Devices directly attached to a HA
540 * port, have no parents. All other devices do, and should have their
541 * "parent" pointer set appropriately before calling this function.
542 */
543int sas_discover_sata(struct domain_device *dev)
544{
545 int res;
546
547 sas_get_ata_command_set(dev);
548
549 res = sas_notify_lldd_dev_found(dev);
550 if (res)
551 return res;
552
553 switch (dev->dev_type) {
554 case SATA_DEV:
555 res = sas_discover_sata_dev(dev);
556 break;
557 case SATA_PM:
558 res = sas_discover_sata_pm(dev);
559 break;
560 default:
561 break;
562 }
563
564 sas_notify_lldd_dev_gone(dev);
565 if (!res) {
566 sas_notify_lldd_dev_found(dev);
567 }
568 return res;
569}
570
571/**
572 * sas_discover_end_dev -- discover an end device (SSP, etc)
573 * @end: pointer to domain device of interest
574 *
575 * See comment in sas_discover_sata().
576 */
577int sas_discover_end_dev(struct domain_device *dev)
578{
579 int res;
580
581 res = sas_notify_lldd_dev_found(dev);
582 if (res)
583 return res;
584
585 res = sas_rphy_add(dev->rphy);
586 if (res)
587 goto out_err;
588
589 /* do this to get the end device port attributes which will have
590 * been scanned in sas_rphy_add */
591 sas_notify_lldd_dev_gone(dev);
592 sas_notify_lldd_dev_found(dev);
593
594 return 0;
595
596out_err:
597 sas_notify_lldd_dev_gone(dev);
598 return res;
599}
600
601/* ---------- Device registration and unregistration ---------- */
602
603static inline void sas_unregister_common_dev(struct domain_device *dev)
604{
605 sas_notify_lldd_dev_gone(dev);
606 if (!dev->parent)
607 dev->port->port_dev = NULL;
608 else
609 list_del_init(&dev->siblings);
610 list_del_init(&dev->dev_list_node);
611}
612
613void sas_unregister_dev(struct domain_device *dev)
614{
615 if (dev->rphy) {
616 sas_remove_children(&dev->rphy->dev);
617 sas_rphy_delete(dev->rphy);
618 dev->rphy = NULL;
619 }
620 if (dev->dev_type == EDGE_DEV || dev->dev_type == FANOUT_DEV) {
621 /* remove the phys and ports, everything else should be gone */
622 kfree(dev->ex_dev.ex_phy);
623 dev->ex_dev.ex_phy = NULL;
624 }
625 sas_unregister_common_dev(dev);
626}
627
628void sas_unregister_domain_devices(struct asd_sas_port *port)
629{
630 struct domain_device *dev, *n;
631
632 list_for_each_entry_safe_reverse(dev,n,&port->dev_list,dev_list_node)
633 sas_unregister_dev(dev);
634
635 port->port->rphy = NULL;
636
637}
638
639/* ---------- Discovery and Revalidation ---------- */
640
641/**
642 * sas_discover_domain -- discover the domain
643 * @port: port to the domain of interest
644 *
645 * NOTE: this process _must_ quit (return) as soon as any connection
646 * errors are encountered. Connection recovery is done elsewhere.
647 * Discover process only interrogates devices in order to discover the
648 * domain.
649 */
650static void sas_discover_domain(void *data)
651{
652 int error = 0;
653 struct asd_sas_port *port = data;
654
655 sas_begin_event(DISCE_DISCOVER_DOMAIN, &port->disc.disc_event_lock,
656 &port->disc.pending);
657
658 if (port->port_dev)
659 return ;
660 else {
661 error = sas_get_port_device(port);
662 if (error)
663 return;
664 }
665
666 SAS_DPRINTK("DOING DISCOVERY on port %d, pid:%d\n", port->id,
667 current->pid);
668
669 switch (port->port_dev->dev_type) {
670 case SAS_END_DEV:
671 error = sas_discover_end_dev(port->port_dev);
672 break;
673 case EDGE_DEV:
674 case FANOUT_DEV:
675 error = sas_discover_root_expander(port->port_dev);
676 break;
677 case SATA_DEV:
678 case SATA_PM:
679 error = sas_discover_sata(port->port_dev);
680 break;
681 default:
682 SAS_DPRINTK("unhandled device %d\n", port->port_dev->dev_type);
683 break;
684 }
685
686 if (error) {
687 kfree(port->port_dev); /* not kobject_register-ed yet */
688 port->port_dev = NULL;
689 }
690
691 SAS_DPRINTK("DONE DISCOVERY on port %d, pid:%d, result:%d\n", port->id,
692 current->pid, error);
693}
694
695static void sas_revalidate_domain(void *data)
696{
697 int res = 0;
698 struct asd_sas_port *port = data;
699
700 sas_begin_event(DISCE_REVALIDATE_DOMAIN, &port->disc.disc_event_lock,
701 &port->disc.pending);
702
703 SAS_DPRINTK("REVALIDATING DOMAIN on port %d, pid:%d\n", port->id,
704 current->pid);
705 if (port->port_dev)
706 res = sas_ex_revalidate_domain(port->port_dev);
707
708 SAS_DPRINTK("done REVALIDATING DOMAIN on port %d, pid:%d, res 0x%x\n",
709 port->id, current->pid, res);
710}
711
712/* ---------- Events ---------- */
713
714int sas_discover_event(struct asd_sas_port *port, enum discover_event ev)
715{
716 struct sas_discovery *disc;
717
718 if (!port)
719 return 0;
720 disc = &port->disc;
721
722 BUG_ON(ev >= DISC_NUM_EVENTS);
723
724 sas_queue_event(ev, &disc->disc_event_lock, &disc->pending,
725 &disc->disc_work[ev], port->ha->core.shost);
726
727 return 0;
728}
729
730/**
731 * sas_init_disc -- initialize the discovery struct in the port
732 * @port: pointer to struct port
733 *
734 * Called when the ports are being initialized.
735 */
736void sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *port)
737{
738 int i;
739
740 static void (*sas_event_fns[DISC_NUM_EVENTS])(void *) = {
741 [DISCE_DISCOVER_DOMAIN] = sas_discover_domain,
742 [DISCE_REVALIDATE_DOMAIN] = sas_revalidate_domain,
743 };
744
745 spin_lock_init(&disc->disc_event_lock);
746 disc->pending = 0;
747 for (i = 0; i < DISC_NUM_EVENTS; i++)
748 INIT_WORK(&disc->disc_work[i], sas_event_fns[i], port);
749}
diff --git a/drivers/scsi/libsas/sas_dump.c b/drivers/scsi/libsas/sas_dump.c
new file mode 100644
index 000000000000..f1246d2c9bef
--- /dev/null
+++ b/drivers/scsi/libsas/sas_dump.c
@@ -0,0 +1,76 @@
1/*
2 * Serial Attached SCSI (SAS) Dump/Debugging routines
3 *
4 * Copyright (C) 2005 Adaptec, Inc. All rights reserved.
5 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
6 *
7 * This file is licensed under GPLv2.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 *
23 */
24
25#include "sas_dump.h"
26
27#ifdef SAS_DEBUG
28
29static const char *sas_hae_str[] = {
30 [0] = "HAE_RESET",
31};
32
33static const char *sas_porte_str[] = {
34 [0] = "PORTE_BYTES_DMAED",
35 [1] = "PORTE_BROADCAST_RCVD",
36 [2] = "PORTE_LINK_RESET_ERR",
37 [3] = "PORTE_TIMER_EVENT",
38 [4] = "PORTE_HARD_RESET",
39};
40
41static const char *sas_phye_str[] = {
42 [0] = "PHYE_LOSS_OF_SIGNAL",
43 [1] = "PHYE_OOB_DONE",
44 [2] = "PHYE_OOB_ERROR",
45 [3] = "PHYE_SPINUP_HOLD",
46};
47
48void sas_dprint_porte(int phyid, enum port_event pe)
49{
50 SAS_DPRINTK("phy%d: port event: %s\n", phyid, sas_porte_str[pe]);
51}
52void sas_dprint_phye(int phyid, enum phy_event pe)
53{
54 SAS_DPRINTK("phy%d: phy event: %s\n", phyid, sas_phye_str[pe]);
55}
56
57void sas_dprint_hae(struct sas_ha_struct *sas_ha, enum ha_event he)
58{
59 SAS_DPRINTK("ha %s: %s event\n", pci_name(sas_ha->pcidev),
60 sas_hae_str[he]);
61}
62
63void sas_dump_port(struct asd_sas_port *port)
64{
65 SAS_DPRINTK("port%d: class:0x%x\n", port->id, port->class);
66 SAS_DPRINTK("port%d: sas_addr:%llx\n", port->id,
67 SAS_ADDR(port->sas_addr));
68 SAS_DPRINTK("port%d: attached_sas_addr:%llx\n", port->id,
69 SAS_ADDR(port->attached_sas_addr));
70 SAS_DPRINTK("port%d: iproto:0x%x\n", port->id, port->iproto);
71 SAS_DPRINTK("port%d: tproto:0x%x\n", port->id, port->tproto);
72 SAS_DPRINTK("port%d: oob_mode:0x%x\n", port->id, port->oob_mode);
73 SAS_DPRINTK("port%d: num_phys:%d\n", port->id, port->num_phys);
74}
75
76#endif /* SAS_DEBUG */
diff --git a/drivers/scsi/libsas/sas_dump.h b/drivers/scsi/libsas/sas_dump.h
new file mode 100644
index 000000000000..47b45d4f5258
--- /dev/null
+++ b/drivers/scsi/libsas/sas_dump.h
@@ -0,0 +1,42 @@
1/*
2 * Serial Attached SCSI (SAS) Dump/Debugging routines header file
3 *
4 * Copyright (C) 2005 Adaptec, Inc. All rights reserved.
5 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
6 *
7 * This file is licensed under GPLv2.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 *
23 */
24
25#include "sas_internal.h"
26
27#ifdef SAS_DEBUG
28
29void sas_dprint_porte(int phyid, enum port_event pe);
30void sas_dprint_phye(int phyid, enum phy_event pe);
31void sas_dprint_hae(struct sas_ha_struct *sas_ha, enum ha_event he);
32void sas_dump_port(struct asd_sas_port *port);
33
34#else /* SAS_DEBUG */
35
36static inline void sas_dprint_porte(int phyid, enum port_event pe) { }
37static inline void sas_dprint_phye(int phyid, enum phy_event pe) { }
38static inline void sas_dprint_hae(struct sas_ha_struct *sas_ha,
39 enum ha_event he) { }
40static inline void sas_dump_port(struct asd_sas_port *port) { }
41
42#endif /* SAS_DEBUG */
diff --git a/drivers/scsi/libsas/sas_event.c b/drivers/scsi/libsas/sas_event.c
new file mode 100644
index 000000000000..19110ed1c89c
--- /dev/null
+++ b/drivers/scsi/libsas/sas_event.c
@@ -0,0 +1,75 @@
1/*
2 * Serial Attached SCSI (SAS) Event processing
3 *
4 * Copyright (C) 2005 Adaptec, Inc. All rights reserved.
5 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
6 *
7 * This file is licensed under GPLv2.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 *
23 */
24
25#include <scsi/scsi_host.h>
26#include "sas_internal.h"
27#include "sas_dump.h"
28
29static void notify_ha_event(struct sas_ha_struct *sas_ha, enum ha_event event)
30{
31 BUG_ON(event >= HA_NUM_EVENTS);
32
33 sas_queue_event(event, &sas_ha->event_lock, &sas_ha->pending,
34 &sas_ha->ha_events[event], sas_ha->core.shost);
35}
36
37static void notify_port_event(struct asd_sas_phy *phy, enum port_event event)
38{
39 struct sas_ha_struct *ha = phy->ha;
40
41 BUG_ON(event >= PORT_NUM_EVENTS);
42
43 sas_queue_event(event, &ha->event_lock, &phy->port_events_pending,
44 &phy->port_events[event], ha->core.shost);
45}
46
47static void notify_phy_event(struct asd_sas_phy *phy, enum phy_event event)
48{
49 struct sas_ha_struct *ha = phy->ha;
50
51 BUG_ON(event >= PHY_NUM_EVENTS);
52
53 sas_queue_event(event, &ha->event_lock, &phy->phy_events_pending,
54 &phy->phy_events[event], ha->core.shost);
55}
56
57int sas_init_events(struct sas_ha_struct *sas_ha)
58{
59 static void (*sas_ha_event_fns[HA_NUM_EVENTS])(void *) = {
60 [HAE_RESET] = sas_hae_reset,
61 };
62
63 int i;
64
65 spin_lock_init(&sas_ha->event_lock);
66
67 for (i = 0; i < HA_NUM_EVENTS; i++)
68 INIT_WORK(&sas_ha->ha_events[i], sas_ha_event_fns[i], sas_ha);
69
70 sas_ha->notify_ha_event = notify_ha_event;
71 sas_ha->notify_port_event = notify_port_event;
72 sas_ha->notify_phy_event = notify_phy_event;
73
74 return 0;
75}
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
new file mode 100644
index 000000000000..b653a263f76a
--- /dev/null
+++ b/drivers/scsi/libsas/sas_expander.c
@@ -0,0 +1,1862 @@
1/*
2 * Serial Attached SCSI (SAS) Expander discovery and configuration
3 *
4 * Copyright (C) 2005 Adaptec, Inc. All rights reserved.
5 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
6 *
7 * This file is licensed under GPLv2.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 *
23 */
24
25#include <linux/pci.h>
26#include <linux/scatterlist.h>
27
28#include "sas_internal.h"
29
30#include <scsi/scsi_transport.h>
31#include <scsi/scsi_transport_sas.h>
32#include "../scsi_sas_internal.h"
33
34static int sas_discover_expander(struct domain_device *dev);
35static int sas_configure_routing(struct domain_device *dev, u8 *sas_addr);
36static int sas_configure_phy(struct domain_device *dev, int phy_id,
37 u8 *sas_addr, int include);
38static int sas_disable_routing(struct domain_device *dev, u8 *sas_addr);
39
40#if 0
41/* FIXME: smp needs to migrate into the sas class */
42static ssize_t smp_portal_read(struct kobject *, char *, loff_t, size_t);
43static ssize_t smp_portal_write(struct kobject *, char *, loff_t, size_t);
44#endif
45
46/* ---------- SMP task management ---------- */
47
48static void smp_task_timedout(unsigned long _task)
49{
50 struct sas_task *task = (void *) _task;
51 unsigned long flags;
52
53 spin_lock_irqsave(&task->task_state_lock, flags);
54 if (!(task->task_state_flags & SAS_TASK_STATE_DONE))
55 task->task_state_flags |= SAS_TASK_STATE_ABORTED;
56 spin_unlock_irqrestore(&task->task_state_lock, flags);
57
58 complete(&task->completion);
59}
60
61static void smp_task_done(struct sas_task *task)
62{
63 if (!del_timer(&task->timer))
64 return;
65 complete(&task->completion);
66}
67
68/* Give it some long enough timeout. In seconds. */
69#define SMP_TIMEOUT 10
70
71static int smp_execute_task(struct domain_device *dev, void *req, int req_size,
72 void *resp, int resp_size)
73{
74 int res;
75 struct sas_task *task = sas_alloc_task(GFP_KERNEL);
76 struct sas_internal *i =
77 to_sas_internal(dev->port->ha->core.shost->transportt);
78
79 if (!task)
80 return -ENOMEM;
81
82 task->dev = dev;
83 task->task_proto = dev->tproto;
84 sg_init_one(&task->smp_task.smp_req, req, req_size);
85 sg_init_one(&task->smp_task.smp_resp, resp, resp_size);
86
87 task->task_done = smp_task_done;
88
89 task->timer.data = (unsigned long) task;
90 task->timer.function = smp_task_timedout;
91 task->timer.expires = jiffies + SMP_TIMEOUT*HZ;
92 add_timer(&task->timer);
93
94 res = i->dft->lldd_execute_task(task, 1, GFP_KERNEL);
95
96 if (res) {
97 del_timer(&task->timer);
98 SAS_DPRINTK("executing SMP task failed:%d\n", res);
99 goto ex_err;
100 }
101
102 wait_for_completion(&task->completion);
103 res = -ETASK;
104 if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
105 SAS_DPRINTK("smp task timed out or aborted\n");
106 i->dft->lldd_abort_task(task);
107 if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
108 SAS_DPRINTK("SMP task aborted and not done\n");
109 goto ex_err;
110 }
111 }
112 if (task->task_status.resp == SAS_TASK_COMPLETE &&
113 task->task_status.stat == SAM_GOOD)
114 res = 0;
115 else
116 SAS_DPRINTK("%s: task to dev %016llx response: 0x%x "
117 "status 0x%x\n", __FUNCTION__,
118 SAS_ADDR(dev->sas_addr),
119 task->task_status.resp,
120 task->task_status.stat);
121ex_err:
122 sas_free_task(task);
123 return res;
124}
125
126/* ---------- Allocations ---------- */
127
128static inline void *alloc_smp_req(int size)
129{
130 u8 *p = kzalloc(size, GFP_KERNEL);
131 if (p)
132 p[0] = SMP_REQUEST;
133 return p;
134}
135
136static inline void *alloc_smp_resp(int size)
137{
138 return kzalloc(size, GFP_KERNEL);
139}
140
141/* ---------- Expander configuration ---------- */
142
143static void sas_set_ex_phy(struct domain_device *dev, int phy_id,
144 void *disc_resp)
145{
146 struct expander_device *ex = &dev->ex_dev;
147 struct ex_phy *phy = &ex->ex_phy[phy_id];
148 struct smp_resp *resp = disc_resp;
149 struct discover_resp *dr = &resp->disc;
150 struct sas_rphy *rphy = dev->rphy;
151 int rediscover = (phy->phy != NULL);
152
153 if (!rediscover) {
154 phy->phy = sas_phy_alloc(&rphy->dev, phy_id);
155
156 /* FIXME: error_handling */
157 BUG_ON(!phy->phy);
158 }
159
160 switch (resp->result) {
161 case SMP_RESP_PHY_VACANT:
162 phy->phy_state = PHY_VACANT;
163 return;
164 default:
165 phy->phy_state = PHY_NOT_PRESENT;
166 return;
167 case SMP_RESP_FUNC_ACC:
168 phy->phy_state = PHY_EMPTY; /* do not know yet */
169 break;
170 }
171
172 phy->phy_id = phy_id;
173 phy->attached_dev_type = dr->attached_dev_type;
174 phy->linkrate = dr->linkrate;
175 phy->attached_sata_host = dr->attached_sata_host;
176 phy->attached_sata_dev = dr->attached_sata_dev;
177 phy->attached_sata_ps = dr->attached_sata_ps;
178 phy->attached_iproto = dr->iproto << 1;
179 phy->attached_tproto = dr->tproto << 1;
180 memcpy(phy->attached_sas_addr, dr->attached_sas_addr, SAS_ADDR_SIZE);
181 phy->attached_phy_id = dr->attached_phy_id;
182 phy->phy_change_count = dr->change_count;
183 phy->routing_attr = dr->routing_attr;
184 phy->virtual = dr->virtual;
185 phy->last_da_index = -1;
186
187 phy->phy->identify.initiator_port_protocols = phy->attached_iproto;
188 phy->phy->identify.target_port_protocols = phy->attached_tproto;
189 phy->phy->identify.phy_identifier = phy_id;
190 phy->phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
191 phy->phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
192 phy->phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
193 phy->phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
194 switch (phy->linkrate) {
195 case PHY_LINKRATE_1_5:
196 phy->phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
197 break;
198 case PHY_LINKRATE_3:
199 phy->phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
200 break;
201 case PHY_LINKRATE_6:
202 phy->phy->negotiated_linkrate = SAS_LINK_RATE_6_0_GBPS;
203 break;
204 default:
205 phy->phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
206 break;
207 }
208
209 if (!rediscover)
210 sas_phy_add(phy->phy);
211
212 SAS_DPRINTK("ex %016llx phy%02d:%c attached: %016llx\n",
213 SAS_ADDR(dev->sas_addr), phy->phy_id,
214 phy->routing_attr == TABLE_ROUTING ? 'T' :
215 phy->routing_attr == DIRECT_ROUTING ? 'D' :
216 phy->routing_attr == SUBTRACTIVE_ROUTING ? 'S' : '?',
217 SAS_ADDR(phy->attached_sas_addr));
218
219 return;
220}
221
222#define DISCOVER_REQ_SIZE 16
223#define DISCOVER_RESP_SIZE 56
224
225static int sas_ex_phy_discover(struct domain_device *dev, int single)
226{
227 struct expander_device *ex = &dev->ex_dev;
228 int res = 0;
229 u8 *disc_req;
230 u8 *disc_resp;
231
232 disc_req = alloc_smp_req(DISCOVER_REQ_SIZE);
233 if (!disc_req)
234 return -ENOMEM;
235
236 disc_resp = alloc_smp_req(DISCOVER_RESP_SIZE);
237 if (!disc_resp) {
238 kfree(disc_req);
239 return -ENOMEM;
240 }
241
242 disc_req[1] = SMP_DISCOVER;
243
244 if (0 <= single && single < ex->num_phys) {
245 disc_req[9] = single;
246 res = smp_execute_task(dev, disc_req, DISCOVER_REQ_SIZE,
247 disc_resp, DISCOVER_RESP_SIZE);
248 if (res)
249 goto out_err;
250 sas_set_ex_phy(dev, single, disc_resp);
251 } else {
252 int i;
253
254 for (i = 0; i < ex->num_phys; i++) {
255 disc_req[9] = i;
256 res = smp_execute_task(dev, disc_req,
257 DISCOVER_REQ_SIZE, disc_resp,
258 DISCOVER_RESP_SIZE);
259 if (res)
260 goto out_err;
261 sas_set_ex_phy(dev, i, disc_resp);
262 }
263 }
264out_err:
265 kfree(disc_resp);
266 kfree(disc_req);
267 return res;
268}
269
270static int sas_expander_discover(struct domain_device *dev)
271{
272 struct expander_device *ex = &dev->ex_dev;
273 int res = -ENOMEM;
274
275 ex->ex_phy = kzalloc(sizeof(*ex->ex_phy)*ex->num_phys, GFP_KERNEL);
276 if (!ex->ex_phy)
277 return -ENOMEM;
278
279 res = sas_ex_phy_discover(dev, -1);
280 if (res)
281 goto out_err;
282
283 return 0;
284 out_err:
285 kfree(ex->ex_phy);
286 ex->ex_phy = NULL;
287 return res;
288}
289
290#define MAX_EXPANDER_PHYS 128
291
292static void ex_assign_report_general(struct domain_device *dev,
293 struct smp_resp *resp)
294{
295 struct report_general_resp *rg = &resp->rg;
296
297 dev->ex_dev.ex_change_count = be16_to_cpu(rg->change_count);
298 dev->ex_dev.max_route_indexes = be16_to_cpu(rg->route_indexes);
299 dev->ex_dev.num_phys = min(rg->num_phys, (u8)MAX_EXPANDER_PHYS);
300 dev->ex_dev.conf_route_table = rg->conf_route_table;
301 dev->ex_dev.configuring = rg->configuring;
302 memcpy(dev->ex_dev.enclosure_logical_id, rg->enclosure_logical_id, 8);
303}
304
305#define RG_REQ_SIZE 8
306#define RG_RESP_SIZE 32
307
308static int sas_ex_general(struct domain_device *dev)
309{
310 u8 *rg_req;
311 struct smp_resp *rg_resp;
312 int res;
313 int i;
314
315 rg_req = alloc_smp_req(RG_REQ_SIZE);
316 if (!rg_req)
317 return -ENOMEM;
318
319 rg_resp = alloc_smp_resp(RG_RESP_SIZE);
320 if (!rg_resp) {
321 kfree(rg_req);
322 return -ENOMEM;
323 }
324
325 rg_req[1] = SMP_REPORT_GENERAL;
326
327 for (i = 0; i < 5; i++) {
328 res = smp_execute_task(dev, rg_req, RG_REQ_SIZE, rg_resp,
329 RG_RESP_SIZE);
330
331 if (res) {
332 SAS_DPRINTK("RG to ex %016llx failed:0x%x\n",
333 SAS_ADDR(dev->sas_addr), res);
334 goto out;
335 } else if (rg_resp->result != SMP_RESP_FUNC_ACC) {
336 SAS_DPRINTK("RG:ex %016llx returned SMP result:0x%x\n",
337 SAS_ADDR(dev->sas_addr), rg_resp->result);
338 res = rg_resp->result;
339 goto out;
340 }
341
342 ex_assign_report_general(dev, rg_resp);
343
344 if (dev->ex_dev.configuring) {
345 SAS_DPRINTK("RG: ex %llx self-configuring...\n",
346 SAS_ADDR(dev->sas_addr));
347 schedule_timeout_interruptible(5*HZ);
348 } else
349 break;
350 }
351out:
352 kfree(rg_req);
353 kfree(rg_resp);
354 return res;
355}
356
357static void ex_assign_manuf_info(struct domain_device *dev, void
358 *_mi_resp)
359{
360 u8 *mi_resp = _mi_resp;
361 struct sas_rphy *rphy = dev->rphy;
362 struct sas_expander_device *edev = rphy_to_expander_device(rphy);
363
364 memcpy(edev->vendor_id, mi_resp + 12, SAS_EXPANDER_VENDOR_ID_LEN);
365 memcpy(edev->product_id, mi_resp + 20, SAS_EXPANDER_PRODUCT_ID_LEN);
366 memcpy(edev->product_rev, mi_resp + 36,
367 SAS_EXPANDER_PRODUCT_REV_LEN);
368
369 if (mi_resp[8] & 1) {
370 memcpy(edev->component_vendor_id, mi_resp + 40,
371 SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN);
372 edev->component_id = mi_resp[48] << 8 | mi_resp[49];
373 edev->component_revision_id = mi_resp[50];
374 }
375}
376
377#define MI_REQ_SIZE 8
378#define MI_RESP_SIZE 64
379
380static int sas_ex_manuf_info(struct domain_device *dev)
381{
382 u8 *mi_req;
383 u8 *mi_resp;
384 int res;
385
386 mi_req = alloc_smp_req(MI_REQ_SIZE);
387 if (!mi_req)
388 return -ENOMEM;
389
390 mi_resp = alloc_smp_resp(MI_RESP_SIZE);
391 if (!mi_resp) {
392 kfree(mi_req);
393 return -ENOMEM;
394 }
395
396 mi_req[1] = SMP_REPORT_MANUF_INFO;
397
398 res = smp_execute_task(dev, mi_req, MI_REQ_SIZE, mi_resp,MI_RESP_SIZE);
399 if (res) {
400 SAS_DPRINTK("MI: ex %016llx failed:0x%x\n",
401 SAS_ADDR(dev->sas_addr), res);
402 goto out;
403 } else if (mi_resp[2] != SMP_RESP_FUNC_ACC) {
404 SAS_DPRINTK("MI ex %016llx returned SMP result:0x%x\n",
405 SAS_ADDR(dev->sas_addr), mi_resp[2]);
406 goto out;
407 }
408
409 ex_assign_manuf_info(dev, mi_resp);
410out:
411 kfree(mi_req);
412 kfree(mi_resp);
413 return res;
414}
415
416#define PC_REQ_SIZE 44
417#define PC_RESP_SIZE 8
418
419int sas_smp_phy_control(struct domain_device *dev, int phy_id,
420 enum phy_func phy_func)
421{
422 u8 *pc_req;
423 u8 *pc_resp;
424 int res;
425
426 pc_req = alloc_smp_req(PC_REQ_SIZE);
427 if (!pc_req)
428 return -ENOMEM;
429
430 pc_resp = alloc_smp_resp(PC_RESP_SIZE);
431 if (!pc_resp) {
432 kfree(pc_req);
433 return -ENOMEM;
434 }
435
436 pc_req[1] = SMP_PHY_CONTROL;
437 pc_req[9] = phy_id;
438 pc_req[10]= phy_func;
439
440 res = smp_execute_task(dev, pc_req, PC_REQ_SIZE, pc_resp,PC_RESP_SIZE);
441
442 kfree(pc_resp);
443 kfree(pc_req);
444 return res;
445}
446
447static void sas_ex_disable_phy(struct domain_device *dev, int phy_id)
448{
449 struct expander_device *ex = &dev->ex_dev;
450 struct ex_phy *phy = &ex->ex_phy[phy_id];
451
452 sas_smp_phy_control(dev, phy_id, PHY_FUNC_DISABLE);
453 phy->linkrate = PHY_DISABLED;
454}
455
456static void sas_ex_disable_port(struct domain_device *dev, u8 *sas_addr)
457{
458 struct expander_device *ex = &dev->ex_dev;
459 int i;
460
461 for (i = 0; i < ex->num_phys; i++) {
462 struct ex_phy *phy = &ex->ex_phy[i];
463
464 if (phy->phy_state == PHY_VACANT ||
465 phy->phy_state == PHY_NOT_PRESENT)
466 continue;
467
468 if (SAS_ADDR(phy->attached_sas_addr) == SAS_ADDR(sas_addr))
469 sas_ex_disable_phy(dev, i);
470 }
471}
472
473static int sas_dev_present_in_domain(struct asd_sas_port *port,
474 u8 *sas_addr)
475{
476 struct domain_device *dev;
477
478 if (SAS_ADDR(port->sas_addr) == SAS_ADDR(sas_addr))
479 return 1;
480 list_for_each_entry(dev, &port->dev_list, dev_list_node) {
481 if (SAS_ADDR(dev->sas_addr) == SAS_ADDR(sas_addr))
482 return 1;
483 }
484 return 0;
485}
486
487#define RPEL_REQ_SIZE 16
488#define RPEL_RESP_SIZE 32
489int sas_smp_get_phy_events(struct sas_phy *phy)
490{
491 int res;
492 struct sas_rphy *rphy = dev_to_rphy(phy->dev.parent);
493 struct domain_device *dev = sas_find_dev_by_rphy(rphy);
494 u8 *req = alloc_smp_req(RPEL_REQ_SIZE);
495 u8 *resp = kzalloc(RPEL_RESP_SIZE, GFP_KERNEL);
496
497 if (!resp)
498 return -ENOMEM;
499
500 req[1] = SMP_REPORT_PHY_ERR_LOG;
501 req[9] = phy->number;
502
503 res = smp_execute_task(dev, req, RPEL_REQ_SIZE,
504 resp, RPEL_RESP_SIZE);
505
506 if (!res)
507 goto out;
508
509 phy->invalid_dword_count = scsi_to_u32(&resp[12]);
510 phy->running_disparity_error_count = scsi_to_u32(&resp[16]);
511 phy->loss_of_dword_sync_count = scsi_to_u32(&resp[20]);
512 phy->phy_reset_problem_count = scsi_to_u32(&resp[24]);
513
514 out:
515 kfree(resp);
516 return res;
517
518}
519
520#define RPS_REQ_SIZE 16
521#define RPS_RESP_SIZE 60
522
523static int sas_get_report_phy_sata(struct domain_device *dev,
524 int phy_id,
525 struct smp_resp *rps_resp)
526{
527 int res;
528 u8 *rps_req = alloc_smp_req(RPS_REQ_SIZE);
529
530 if (!rps_req)
531 return -ENOMEM;
532
533 rps_req[1] = SMP_REPORT_PHY_SATA;
534 rps_req[9] = phy_id;
535
536 res = smp_execute_task(dev, rps_req, RPS_REQ_SIZE,
537 rps_resp, RPS_RESP_SIZE);
538
539 kfree(rps_req);
540 return 0;
541}
542
543static void sas_ex_get_linkrate(struct domain_device *parent,
544 struct domain_device *child,
545 struct ex_phy *parent_phy)
546{
547 struct expander_device *parent_ex = &parent->ex_dev;
548 struct sas_port *port;
549 int i;
550
551 child->pathways = 0;
552
553 port = parent_phy->port;
554
555 for (i = 0; i < parent_ex->num_phys; i++) {
556 struct ex_phy *phy = &parent_ex->ex_phy[i];
557
558 if (phy->phy_state == PHY_VACANT ||
559 phy->phy_state == PHY_NOT_PRESENT)
560 continue;
561
562 if (SAS_ADDR(phy->attached_sas_addr) ==
563 SAS_ADDR(child->sas_addr)) {
564
565 child->min_linkrate = min(parent->min_linkrate,
566 phy->linkrate);
567 child->max_linkrate = max(parent->max_linkrate,
568 phy->linkrate);
569 child->pathways++;
570 sas_port_add_phy(port, phy->phy);
571 }
572 }
573 child->linkrate = min(parent_phy->linkrate, child->max_linkrate);
574 child->pathways = min(child->pathways, parent->pathways);
575}
576
577static struct domain_device *sas_ex_discover_end_dev(
578 struct domain_device *parent, int phy_id)
579{
580 struct expander_device *parent_ex = &parent->ex_dev;
581 struct ex_phy *phy = &parent_ex->ex_phy[phy_id];
582 struct domain_device *child = NULL;
583 struct sas_rphy *rphy;
584 int res;
585
586 if (phy->attached_sata_host || phy->attached_sata_ps)
587 return NULL;
588
589 child = kzalloc(sizeof(*child), GFP_KERNEL);
590 if (!child)
591 return NULL;
592
593 child->parent = parent;
594 child->port = parent->port;
595 child->iproto = phy->attached_iproto;
596 memcpy(child->sas_addr, phy->attached_sas_addr, SAS_ADDR_SIZE);
597 sas_hash_addr(child->hashed_sas_addr, child->sas_addr);
598 phy->port = sas_port_alloc(&parent->rphy->dev, phy_id);
599 BUG_ON(!phy->port);
600 /* FIXME: better error handling*/
601 BUG_ON(sas_port_add(phy->port) != 0);
602 sas_ex_get_linkrate(parent, child, phy);
603
604 if ((phy->attached_tproto & SAS_PROTO_STP) || phy->attached_sata_dev) {
605 child->dev_type = SATA_DEV;
606 if (phy->attached_tproto & SAS_PROTO_STP)
607 child->tproto = phy->attached_tproto;
608 if (phy->attached_sata_dev)
609 child->tproto |= SATA_DEV;
610 res = sas_get_report_phy_sata(parent, phy_id,
611 &child->sata_dev.rps_resp);
612 if (res) {
613 SAS_DPRINTK("report phy sata to %016llx:0x%x returned "
614 "0x%x\n", SAS_ADDR(parent->sas_addr),
615 phy_id, res);
616 kfree(child);
617 return NULL;
618 }
619 memcpy(child->frame_rcvd, &child->sata_dev.rps_resp.rps.fis,
620 sizeof(struct dev_to_host_fis));
621 sas_init_dev(child);
622 res = sas_discover_sata(child);
623 if (res) {
624 SAS_DPRINTK("sas_discover_sata() for device %16llx at "
625 "%016llx:0x%x returned 0x%x\n",
626 SAS_ADDR(child->sas_addr),
627 SAS_ADDR(parent->sas_addr), phy_id, res);
628 kfree(child);
629 return NULL;
630 }
631 } else if (phy->attached_tproto & SAS_PROTO_SSP) {
632 child->dev_type = SAS_END_DEV;
633 rphy = sas_end_device_alloc(phy->port);
634 /* FIXME: error handling */
635 BUG_ON(!rphy);
636 child->tproto = phy->attached_tproto;
637 sas_init_dev(child);
638
639 child->rphy = rphy;
640 sas_fill_in_rphy(child, rphy);
641
642 spin_lock(&parent->port->dev_list_lock);
643 list_add_tail(&child->dev_list_node, &parent->port->dev_list);
644 spin_unlock(&parent->port->dev_list_lock);
645
646 res = sas_discover_end_dev(child);
647 if (res) {
648 SAS_DPRINTK("sas_discover_end_dev() for device %16llx "
649 "at %016llx:0x%x returned 0x%x\n",
650 SAS_ADDR(child->sas_addr),
651 SAS_ADDR(parent->sas_addr), phy_id, res);
652 /* FIXME: this kfrees list elements without removing them */
653 //kfree(child);
654 return NULL;
655 }
656 } else {
657 SAS_DPRINTK("target proto 0x%x at %016llx:0x%x not handled\n",
658 phy->attached_tproto, SAS_ADDR(parent->sas_addr),
659 phy_id);
660 }
661
662 list_add_tail(&child->siblings, &parent_ex->children);
663 return child;
664}
665
666static struct domain_device *sas_ex_discover_expander(
667 struct domain_device *parent, int phy_id)
668{
669 struct sas_expander_device *parent_ex = rphy_to_expander_device(parent->rphy);
670 struct ex_phy *phy = &parent->ex_dev.ex_phy[phy_id];
671 struct domain_device *child = NULL;
672 struct sas_rphy *rphy;
673 struct sas_expander_device *edev;
674 struct asd_sas_port *port;
675 int res;
676
677 if (phy->routing_attr == DIRECT_ROUTING) {
678 SAS_DPRINTK("ex %016llx:0x%x:D <--> ex %016llx:0x%x is not "
679 "allowed\n",
680 SAS_ADDR(parent->sas_addr), phy_id,
681 SAS_ADDR(phy->attached_sas_addr),
682 phy->attached_phy_id);
683 return NULL;
684 }
685 child = kzalloc(sizeof(*child), GFP_KERNEL);
686 if (!child)
687 return NULL;
688
689 phy->port = sas_port_alloc(&parent->rphy->dev, phy_id);
690 /* FIXME: better error handling */
691 BUG_ON(sas_port_add(phy->port) != 0);
692
693
694 switch (phy->attached_dev_type) {
695 case EDGE_DEV:
696 rphy = sas_expander_alloc(phy->port,
697 SAS_EDGE_EXPANDER_DEVICE);
698 break;
699 case FANOUT_DEV:
700 rphy = sas_expander_alloc(phy->port,
701 SAS_FANOUT_EXPANDER_DEVICE);
702 break;
703 default:
704 rphy = NULL; /* shut gcc up */
705 BUG();
706 }
707 port = parent->port;
708 child->rphy = rphy;
709 edev = rphy_to_expander_device(rphy);
710 child->dev_type = phy->attached_dev_type;
711 child->parent = parent;
712 child->port = port;
713 child->iproto = phy->attached_iproto;
714 child->tproto = phy->attached_tproto;
715 memcpy(child->sas_addr, phy->attached_sas_addr, SAS_ADDR_SIZE);
716 sas_hash_addr(child->hashed_sas_addr, child->sas_addr);
717 sas_ex_get_linkrate(parent, child, phy);
718 edev->level = parent_ex->level + 1;
719 parent->port->disc.max_level = max(parent->port->disc.max_level,
720 edev->level);
721 sas_init_dev(child);
722 sas_fill_in_rphy(child, rphy);
723 sas_rphy_add(rphy);
724
725 spin_lock(&parent->port->dev_list_lock);
726 list_add_tail(&child->dev_list_node, &parent->port->dev_list);
727 spin_unlock(&parent->port->dev_list_lock);
728
729 res = sas_discover_expander(child);
730 if (res) {
731 kfree(child);
732 return NULL;
733 }
734 list_add_tail(&child->siblings, &parent->ex_dev.children);
735 return child;
736}
737
738static int sas_ex_discover_dev(struct domain_device *dev, int phy_id)
739{
740 struct expander_device *ex = &dev->ex_dev;
741 struct ex_phy *ex_phy = &ex->ex_phy[phy_id];
742 struct domain_device *child = NULL;
743 int res = 0;
744
745 /* Phy state */
746 if (ex_phy->linkrate == PHY_SPINUP_HOLD) {
747 if (!sas_smp_phy_control(dev, phy_id, PHY_FUNC_LINK_RESET))
748 res = sas_ex_phy_discover(dev, phy_id);
749 if (res)
750 return res;
751 }
752
753 /* Parent and domain coherency */
754 if (!dev->parent && (SAS_ADDR(ex_phy->attached_sas_addr) ==
755 SAS_ADDR(dev->port->sas_addr))) {
756 sas_add_parent_port(dev, phy_id);
757 return 0;
758 }
759 if (dev->parent && (SAS_ADDR(ex_phy->attached_sas_addr) ==
760 SAS_ADDR(dev->parent->sas_addr))) {
761 sas_add_parent_port(dev, phy_id);
762 if (ex_phy->routing_attr == TABLE_ROUTING)
763 sas_configure_phy(dev, phy_id, dev->port->sas_addr, 1);
764 return 0;
765 }
766
767 if (sas_dev_present_in_domain(dev->port, ex_phy->attached_sas_addr))
768 sas_ex_disable_port(dev, ex_phy->attached_sas_addr);
769
770 if (ex_phy->attached_dev_type == NO_DEVICE) {
771 if (ex_phy->routing_attr == DIRECT_ROUTING) {
772 memset(ex_phy->attached_sas_addr, 0, SAS_ADDR_SIZE);
773 sas_configure_routing(dev, ex_phy->attached_sas_addr);
774 }
775 return 0;
776 } else if (ex_phy->linkrate == PHY_LINKRATE_UNKNOWN)
777 return 0;
778
779 if (ex_phy->attached_dev_type != SAS_END_DEV &&
780 ex_phy->attached_dev_type != FANOUT_DEV &&
781 ex_phy->attached_dev_type != EDGE_DEV) {
782 SAS_DPRINTK("unknown device type(0x%x) attached to ex %016llx "
783 "phy 0x%x\n", ex_phy->attached_dev_type,
784 SAS_ADDR(dev->sas_addr),
785 phy_id);
786 return 0;
787 }
788
789 res = sas_configure_routing(dev, ex_phy->attached_sas_addr);
790 if (res) {
791 SAS_DPRINTK("configure routing for dev %016llx "
792 "reported 0x%x. Forgotten\n",
793 SAS_ADDR(ex_phy->attached_sas_addr), res);
794 sas_disable_routing(dev, ex_phy->attached_sas_addr);
795 return res;
796 }
797
798 switch (ex_phy->attached_dev_type) {
799 case SAS_END_DEV:
800 child = sas_ex_discover_end_dev(dev, phy_id);
801 break;
802 case FANOUT_DEV:
803 if (SAS_ADDR(dev->port->disc.fanout_sas_addr)) {
804 SAS_DPRINTK("second fanout expander %016llx phy 0x%x "
805 "attached to ex %016llx phy 0x%x\n",
806 SAS_ADDR(ex_phy->attached_sas_addr),
807 ex_phy->attached_phy_id,
808 SAS_ADDR(dev->sas_addr),
809 phy_id);
810 sas_ex_disable_phy(dev, phy_id);
811 break;
812 } else
813 memcpy(dev->port->disc.fanout_sas_addr,
814 ex_phy->attached_sas_addr, SAS_ADDR_SIZE);
815 /* fallthrough */
816 case EDGE_DEV:
817 child = sas_ex_discover_expander(dev, phy_id);
818 break;
819 default:
820 break;
821 }
822
823 if (child) {
824 int i;
825
826 for (i = 0; i < ex->num_phys; i++) {
827 if (ex->ex_phy[i].phy_state == PHY_VACANT ||
828 ex->ex_phy[i].phy_state == PHY_NOT_PRESENT)
829 continue;
830
831 if (SAS_ADDR(ex->ex_phy[i].attached_sas_addr) ==
832 SAS_ADDR(child->sas_addr))
833 ex->ex_phy[i].phy_state= PHY_DEVICE_DISCOVERED;
834 }
835 }
836
837 return res;
838}
839
840static int sas_find_sub_addr(struct domain_device *dev, u8 *sub_addr)
841{
842 struct expander_device *ex = &dev->ex_dev;
843 int i;
844
845 for (i = 0; i < ex->num_phys; i++) {
846 struct ex_phy *phy = &ex->ex_phy[i];
847
848 if (phy->phy_state == PHY_VACANT ||
849 phy->phy_state == PHY_NOT_PRESENT)
850 continue;
851
852 if ((phy->attached_dev_type == EDGE_DEV ||
853 phy->attached_dev_type == FANOUT_DEV) &&
854 phy->routing_attr == SUBTRACTIVE_ROUTING) {
855
856 memcpy(sub_addr, phy->attached_sas_addr,SAS_ADDR_SIZE);
857
858 return 1;
859 }
860 }
861 return 0;
862}
863
864static int sas_check_level_subtractive_boundary(struct domain_device *dev)
865{
866 struct expander_device *ex = &dev->ex_dev;
867 struct domain_device *child;
868 u8 sub_addr[8] = {0, };
869
870 list_for_each_entry(child, &ex->children, siblings) {
871 if (child->dev_type != EDGE_DEV &&
872 child->dev_type != FANOUT_DEV)
873 continue;
874 if (sub_addr[0] == 0) {
875 sas_find_sub_addr(child, sub_addr);
876 continue;
877 } else {
878 u8 s2[8];
879
880 if (sas_find_sub_addr(child, s2) &&
881 (SAS_ADDR(sub_addr) != SAS_ADDR(s2))) {
882
883 SAS_DPRINTK("ex %016llx->%016llx-?->%016llx "
884 "diverges from subtractive "
885 "boundary %016llx\n",
886 SAS_ADDR(dev->sas_addr),
887 SAS_ADDR(child->sas_addr),
888 SAS_ADDR(s2),
889 SAS_ADDR(sub_addr));
890
891 sas_ex_disable_port(child, s2);
892 }
893 }
894 }
895 return 0;
896}
897/**
898 * sas_ex_discover_devices -- discover devices attached to this expander
899 * dev: pointer to the expander domain device
900 * single: if you want to do a single phy, else set to -1;
901 *
902 * Configure this expander for use with its devices and register the
903 * devices of this expander.
904 */
905static int sas_ex_discover_devices(struct domain_device *dev, int single)
906{
907 struct expander_device *ex = &dev->ex_dev;
908 int i = 0, end = ex->num_phys;
909 int res = 0;
910
911 if (0 <= single && single < end) {
912 i = single;
913 end = i+1;
914 }
915
916 for ( ; i < end; i++) {
917 struct ex_phy *ex_phy = &ex->ex_phy[i];
918
919 if (ex_phy->phy_state == PHY_VACANT ||
920 ex_phy->phy_state == PHY_NOT_PRESENT ||
921 ex_phy->phy_state == PHY_DEVICE_DISCOVERED)
922 continue;
923
924 switch (ex_phy->linkrate) {
925 case PHY_DISABLED:
926 case PHY_RESET_PROBLEM:
927 case PHY_PORT_SELECTOR:
928 continue;
929 default:
930 res = sas_ex_discover_dev(dev, i);
931 if (res)
932 break;
933 continue;
934 }
935 }
936
937 if (!res)
938 sas_check_level_subtractive_boundary(dev);
939
940 return res;
941}
942
943static int sas_check_ex_subtractive_boundary(struct domain_device *dev)
944{
945 struct expander_device *ex = &dev->ex_dev;
946 int i;
947 u8 *sub_sas_addr = NULL;
948
949 if (dev->dev_type != EDGE_DEV)
950 return 0;
951
952 for (i = 0; i < ex->num_phys; i++) {
953 struct ex_phy *phy = &ex->ex_phy[i];
954
955 if (phy->phy_state == PHY_VACANT ||
956 phy->phy_state == PHY_NOT_PRESENT)
957 continue;
958
959 if ((phy->attached_dev_type == FANOUT_DEV ||
960 phy->attached_dev_type == EDGE_DEV) &&
961 phy->routing_attr == SUBTRACTIVE_ROUTING) {
962
963 if (!sub_sas_addr)
964 sub_sas_addr = &phy->attached_sas_addr[0];
965 else if (SAS_ADDR(sub_sas_addr) !=
966 SAS_ADDR(phy->attached_sas_addr)) {
967
968 SAS_DPRINTK("ex %016llx phy 0x%x "
969 "diverges(%016llx) on subtractive "
970 "boundary(%016llx). Disabled\n",
971 SAS_ADDR(dev->sas_addr), i,
972 SAS_ADDR(phy->attached_sas_addr),
973 SAS_ADDR(sub_sas_addr));
974 sas_ex_disable_phy(dev, i);
975 }
976 }
977 }
978 return 0;
979}
980
981static void sas_print_parent_topology_bug(struct domain_device *child,
982 struct ex_phy *parent_phy,
983 struct ex_phy *child_phy)
984{
985 static const char ra_char[] = {
986 [DIRECT_ROUTING] = 'D',
987 [SUBTRACTIVE_ROUTING] = 'S',
988 [TABLE_ROUTING] = 'T',
989 };
990 static const char *ex_type[] = {
991 [EDGE_DEV] = "edge",
992 [FANOUT_DEV] = "fanout",
993 };
994 struct domain_device *parent = child->parent;
995
996 sas_printk("%s ex %016llx phy 0x%x <--> %s ex %016llx phy 0x%x "
997 "has %c:%c routing link!\n",
998
999 ex_type[parent->dev_type],
1000 SAS_ADDR(parent->sas_addr),
1001 parent_phy->phy_id,
1002
1003 ex_type[child->dev_type],
1004 SAS_ADDR(child->sas_addr),
1005 child_phy->phy_id,
1006
1007 ra_char[parent_phy->routing_attr],
1008 ra_char[child_phy->routing_attr]);
1009}
1010
1011static int sas_check_eeds(struct domain_device *child,
1012 struct ex_phy *parent_phy,
1013 struct ex_phy *child_phy)
1014{
1015 int res = 0;
1016 struct domain_device *parent = child->parent;
1017
1018 if (SAS_ADDR(parent->port->disc.fanout_sas_addr) != 0) {
1019 res = -ENODEV;
1020 SAS_DPRINTK("edge ex %016llx phy S:0x%x <--> edge ex %016llx "
1021 "phy S:0x%x, while there is a fanout ex %016llx\n",
1022 SAS_ADDR(parent->sas_addr),
1023 parent_phy->phy_id,
1024 SAS_ADDR(child->sas_addr),
1025 child_phy->phy_id,
1026 SAS_ADDR(parent->port->disc.fanout_sas_addr));
1027 } else if (SAS_ADDR(parent->port->disc.eeds_a) == 0) {
1028 memcpy(parent->port->disc.eeds_a, parent->sas_addr,
1029 SAS_ADDR_SIZE);
1030 memcpy(parent->port->disc.eeds_b, child->sas_addr,
1031 SAS_ADDR_SIZE);
1032 } else if (((SAS_ADDR(parent->port->disc.eeds_a) ==
1033 SAS_ADDR(parent->sas_addr)) ||
1034 (SAS_ADDR(parent->port->disc.eeds_a) ==
1035 SAS_ADDR(child->sas_addr)))
1036 &&
1037 ((SAS_ADDR(parent->port->disc.eeds_b) ==
1038 SAS_ADDR(parent->sas_addr)) ||
1039 (SAS_ADDR(parent->port->disc.eeds_b) ==
1040 SAS_ADDR(child->sas_addr))))
1041 ;
1042 else {
1043 res = -ENODEV;
1044 SAS_DPRINTK("edge ex %016llx phy 0x%x <--> edge ex %016llx "
1045 "phy 0x%x link forms a third EEDS!\n",
1046 SAS_ADDR(parent->sas_addr),
1047 parent_phy->phy_id,
1048 SAS_ADDR(child->sas_addr),
1049 child_phy->phy_id);
1050 }
1051
1052 return res;
1053}
1054
1055/* Here we spill over 80 columns. It is intentional.
1056 */
1057static int sas_check_parent_topology(struct domain_device *child)
1058{
1059 struct expander_device *child_ex = &child->ex_dev;
1060 struct expander_device *parent_ex;
1061 int i;
1062 int res = 0;
1063
1064 if (!child->parent)
1065 return 0;
1066
1067 if (child->parent->dev_type != EDGE_DEV &&
1068 child->parent->dev_type != FANOUT_DEV)
1069 return 0;
1070
1071 parent_ex = &child->parent->ex_dev;
1072
1073 for (i = 0; i < parent_ex->num_phys; i++) {
1074 struct ex_phy *parent_phy = &parent_ex->ex_phy[i];
1075 struct ex_phy *child_phy;
1076
1077 if (parent_phy->phy_state == PHY_VACANT ||
1078 parent_phy->phy_state == PHY_NOT_PRESENT)
1079 continue;
1080
1081 if (SAS_ADDR(parent_phy->attached_sas_addr) != SAS_ADDR(child->sas_addr))
1082 continue;
1083
1084 child_phy = &child_ex->ex_phy[parent_phy->attached_phy_id];
1085
1086 switch (child->parent->dev_type) {
1087 case EDGE_DEV:
1088 if (child->dev_type == FANOUT_DEV) {
1089 if (parent_phy->routing_attr != SUBTRACTIVE_ROUTING ||
1090 child_phy->routing_attr != TABLE_ROUTING) {
1091 sas_print_parent_topology_bug(child, parent_phy, child_phy);
1092 res = -ENODEV;
1093 }
1094 } else if (parent_phy->routing_attr == SUBTRACTIVE_ROUTING) {
1095 if (child_phy->routing_attr == SUBTRACTIVE_ROUTING) {
1096 res = sas_check_eeds(child, parent_phy, child_phy);
1097 } else if (child_phy->routing_attr != TABLE_ROUTING) {
1098 sas_print_parent_topology_bug(child, parent_phy, child_phy);
1099 res = -ENODEV;
1100 }
1101 } else if (parent_phy->routing_attr == TABLE_ROUTING &&
1102 child_phy->routing_attr != SUBTRACTIVE_ROUTING) {
1103 sas_print_parent_topology_bug(child, parent_phy, child_phy);
1104 res = -ENODEV;
1105 }
1106 break;
1107 case FANOUT_DEV:
1108 if (parent_phy->routing_attr != TABLE_ROUTING ||
1109 child_phy->routing_attr != SUBTRACTIVE_ROUTING) {
1110 sas_print_parent_topology_bug(child, parent_phy, child_phy);
1111 res = -ENODEV;
1112 }
1113 break;
1114 default:
1115 break;
1116 }
1117 }
1118
1119 return res;
1120}
1121
1122#define RRI_REQ_SIZE 16
1123#define RRI_RESP_SIZE 44
1124
1125static int sas_configure_present(struct domain_device *dev, int phy_id,
1126 u8 *sas_addr, int *index, int *present)
1127{
1128 int i, res = 0;
1129 struct expander_device *ex = &dev->ex_dev;
1130 struct ex_phy *phy = &ex->ex_phy[phy_id];
1131 u8 *rri_req;
1132 u8 *rri_resp;
1133
1134 *present = 0;
1135 *index = 0;
1136
1137 rri_req = alloc_smp_req(RRI_REQ_SIZE);
1138 if (!rri_req)
1139 return -ENOMEM;
1140
1141 rri_resp = alloc_smp_resp(RRI_RESP_SIZE);
1142 if (!rri_resp) {
1143 kfree(rri_req);
1144 return -ENOMEM;
1145 }
1146
1147 rri_req[1] = SMP_REPORT_ROUTE_INFO;
1148 rri_req[9] = phy_id;
1149
1150 for (i = 0; i < ex->max_route_indexes ; i++) {
1151 *(__be16 *)(rri_req+6) = cpu_to_be16(i);
1152 res = smp_execute_task(dev, rri_req, RRI_REQ_SIZE, rri_resp,
1153 RRI_RESP_SIZE);
1154 if (res)
1155 goto out;
1156 res = rri_resp[2];
1157 if (res == SMP_RESP_NO_INDEX) {
1158 SAS_DPRINTK("overflow of indexes: dev %016llx "
1159 "phy 0x%x index 0x%x\n",
1160 SAS_ADDR(dev->sas_addr), phy_id, i);
1161 goto out;
1162 } else if (res != SMP_RESP_FUNC_ACC) {
1163 SAS_DPRINTK("%s: dev %016llx phy 0x%x index 0x%x "
1164 "result 0x%x\n", __FUNCTION__,
1165 SAS_ADDR(dev->sas_addr), phy_id, i, res);
1166 goto out;
1167 }
1168 if (SAS_ADDR(sas_addr) != 0) {
1169 if (SAS_ADDR(rri_resp+16) == SAS_ADDR(sas_addr)) {
1170 *index = i;
1171 if ((rri_resp[12] & 0x80) == 0x80)
1172 *present = 0;
1173 else
1174 *present = 1;
1175 goto out;
1176 } else if (SAS_ADDR(rri_resp+16) == 0) {
1177 *index = i;
1178 *present = 0;
1179 goto out;
1180 }
1181 } else if (SAS_ADDR(rri_resp+16) == 0 &&
1182 phy->last_da_index < i) {
1183 phy->last_da_index = i;
1184 *index = i;
1185 *present = 0;
1186 goto out;
1187 }
1188 }
1189 res = -1;
1190out:
1191 kfree(rri_req);
1192 kfree(rri_resp);
1193 return res;
1194}
1195
1196#define CRI_REQ_SIZE 44
1197#define CRI_RESP_SIZE 8
1198
1199static int sas_configure_set(struct domain_device *dev, int phy_id,
1200 u8 *sas_addr, int index, int include)
1201{
1202 int res;
1203 u8 *cri_req;
1204 u8 *cri_resp;
1205
1206 cri_req = alloc_smp_req(CRI_REQ_SIZE);
1207 if (!cri_req)
1208 return -ENOMEM;
1209
1210 cri_resp = alloc_smp_resp(CRI_RESP_SIZE);
1211 if (!cri_resp) {
1212 kfree(cri_req);
1213 return -ENOMEM;
1214 }
1215
1216 cri_req[1] = SMP_CONF_ROUTE_INFO;
1217 *(__be16 *)(cri_req+6) = cpu_to_be16(index);
1218 cri_req[9] = phy_id;
1219 if (SAS_ADDR(sas_addr) == 0 || !include)
1220 cri_req[12] |= 0x80;
1221 memcpy(cri_req+16, sas_addr, SAS_ADDR_SIZE);
1222
1223 res = smp_execute_task(dev, cri_req, CRI_REQ_SIZE, cri_resp,
1224 CRI_RESP_SIZE);
1225 if (res)
1226 goto out;
1227 res = cri_resp[2];
1228 if (res == SMP_RESP_NO_INDEX) {
1229 SAS_DPRINTK("overflow of indexes: dev %016llx phy 0x%x "
1230 "index 0x%x\n",
1231 SAS_ADDR(dev->sas_addr), phy_id, index);
1232 }
1233out:
1234 kfree(cri_req);
1235 kfree(cri_resp);
1236 return res;
1237}
1238
1239static int sas_configure_phy(struct domain_device *dev, int phy_id,
1240 u8 *sas_addr, int include)
1241{
1242 int index;
1243 int present;
1244 int res;
1245
1246 res = sas_configure_present(dev, phy_id, sas_addr, &index, &present);
1247 if (res)
1248 return res;
1249 if (include ^ present)
1250 return sas_configure_set(dev, phy_id, sas_addr, index,include);
1251
1252 return res;
1253}
1254
1255/**
1256 * sas_configure_parent -- configure routing table of parent
1257 * parent: parent expander
1258 * child: child expander
1259 * sas_addr: SAS port identifier of device directly attached to child
1260 */
1261static int sas_configure_parent(struct domain_device *parent,
1262 struct domain_device *child,
1263 u8 *sas_addr, int include)
1264{
1265 struct expander_device *ex_parent = &parent->ex_dev;
1266 int res = 0;
1267 int i;
1268
1269 if (parent->parent) {
1270 res = sas_configure_parent(parent->parent, parent, sas_addr,
1271 include);
1272 if (res)
1273 return res;
1274 }
1275
1276 if (ex_parent->conf_route_table == 0) {
1277 SAS_DPRINTK("ex %016llx has self-configuring routing table\n",
1278 SAS_ADDR(parent->sas_addr));
1279 return 0;
1280 }
1281
1282 for (i = 0; i < ex_parent->num_phys; i++) {
1283 struct ex_phy *phy = &ex_parent->ex_phy[i];
1284
1285 if ((phy->routing_attr == TABLE_ROUTING) &&
1286 (SAS_ADDR(phy->attached_sas_addr) ==
1287 SAS_ADDR(child->sas_addr))) {
1288 res = sas_configure_phy(parent, i, sas_addr, include);
1289 if (res)
1290 return res;
1291 }
1292 }
1293
1294 return res;
1295}
1296
1297/**
1298 * sas_configure_routing -- configure routing
1299 * dev: expander device
1300 * sas_addr: port identifier of device directly attached to the expander device
1301 */
1302static int sas_configure_routing(struct domain_device *dev, u8 *sas_addr)
1303{
1304 if (dev->parent)
1305 return sas_configure_parent(dev->parent, dev, sas_addr, 1);
1306 return 0;
1307}
1308
1309static int sas_disable_routing(struct domain_device *dev, u8 *sas_addr)
1310{
1311 if (dev->parent)
1312 return sas_configure_parent(dev->parent, dev, sas_addr, 0);
1313 return 0;
1314}
1315
1316#if 0
1317#define SMP_BIN_ATTR_NAME "smp_portal"
1318
1319static void sas_ex_smp_hook(struct domain_device *dev)
1320{
1321 struct expander_device *ex_dev = &dev->ex_dev;
1322 struct bin_attribute *bin_attr = &ex_dev->smp_bin_attr;
1323
1324 memset(bin_attr, 0, sizeof(*bin_attr));
1325
1326 bin_attr->attr.name = SMP_BIN_ATTR_NAME;
1327 bin_attr->attr.owner = THIS_MODULE;
1328 bin_attr->attr.mode = 0600;
1329
1330 bin_attr->size = 0;
1331 bin_attr->private = NULL;
1332 bin_attr->read = smp_portal_read;
1333 bin_attr->write= smp_portal_write;
1334 bin_attr->mmap = NULL;
1335
1336 ex_dev->smp_portal_pid = -1;
1337 init_MUTEX(&ex_dev->smp_sema);
1338}
1339#endif
1340
1341/**
1342 * sas_discover_expander -- expander discovery
1343 * @ex: pointer to expander domain device
1344 *
1345 * See comment in sas_discover_sata().
1346 */
1347static int sas_discover_expander(struct domain_device *dev)
1348{
1349 int res;
1350
1351 res = sas_notify_lldd_dev_found(dev);
1352 if (res)
1353 return res;
1354
1355 res = sas_ex_general(dev);
1356 if (res)
1357 goto out_err;
1358 res = sas_ex_manuf_info(dev);
1359 if (res)
1360 goto out_err;
1361
1362 res = sas_expander_discover(dev);
1363 if (res) {
1364 SAS_DPRINTK("expander %016llx discovery failed(0x%x)\n",
1365 SAS_ADDR(dev->sas_addr), res);
1366 goto out_err;
1367 }
1368
1369 sas_check_ex_subtractive_boundary(dev);
1370 res = sas_check_parent_topology(dev);
1371 if (res)
1372 goto out_err;
1373 return 0;
1374out_err:
1375 sas_notify_lldd_dev_gone(dev);
1376 return res;
1377}
1378
1379static int sas_ex_level_discovery(struct asd_sas_port *port, const int level)
1380{
1381 int res = 0;
1382 struct domain_device *dev;
1383
1384 list_for_each_entry(dev, &port->dev_list, dev_list_node) {
1385 if (dev->dev_type == EDGE_DEV ||
1386 dev->dev_type == FANOUT_DEV) {
1387 struct sas_expander_device *ex =
1388 rphy_to_expander_device(dev->rphy);
1389
1390 if (level == ex->level)
1391 res = sas_ex_discover_devices(dev, -1);
1392 else if (level > 0)
1393 res = sas_ex_discover_devices(port->port_dev, -1);
1394
1395 }
1396 }
1397
1398 return res;
1399}
1400
1401static int sas_ex_bfs_disc(struct asd_sas_port *port)
1402{
1403 int res;
1404 int level;
1405
1406 do {
1407 level = port->disc.max_level;
1408 res = sas_ex_level_discovery(port, level);
1409 mb();
1410 } while (level < port->disc.max_level);
1411
1412 return res;
1413}
1414
1415int sas_discover_root_expander(struct domain_device *dev)
1416{
1417 int res;
1418 struct sas_expander_device *ex = rphy_to_expander_device(dev->rphy);
1419
1420 sas_rphy_add(dev->rphy);
1421
1422 ex->level = dev->port->disc.max_level; /* 0 */
1423 res = sas_discover_expander(dev);
1424 if (!res)
1425 sas_ex_bfs_disc(dev->port);
1426
1427 return res;
1428}
1429
1430/* ---------- Domain revalidation ---------- */
1431
1432static int sas_get_phy_discover(struct domain_device *dev,
1433 int phy_id, struct smp_resp *disc_resp)
1434{
1435 int res;
1436 u8 *disc_req;
1437
1438 disc_req = alloc_smp_req(DISCOVER_REQ_SIZE);
1439 if (!disc_req)
1440 return -ENOMEM;
1441
1442 disc_req[1] = SMP_DISCOVER;
1443 disc_req[9] = phy_id;
1444
1445 res = smp_execute_task(dev, disc_req, DISCOVER_REQ_SIZE,
1446 disc_resp, DISCOVER_RESP_SIZE);
1447 if (res)
1448 goto out;
1449 else if (disc_resp->result != SMP_RESP_FUNC_ACC) {
1450 res = disc_resp->result;
1451 goto out;
1452 }
1453out:
1454 kfree(disc_req);
1455 return res;
1456}
1457
1458static int sas_get_phy_change_count(struct domain_device *dev,
1459 int phy_id, int *pcc)
1460{
1461 int res;
1462 struct smp_resp *disc_resp;
1463
1464 disc_resp = alloc_smp_resp(DISCOVER_RESP_SIZE);
1465 if (!disc_resp)
1466 return -ENOMEM;
1467
1468 res = sas_get_phy_discover(dev, phy_id, disc_resp);
1469 if (!res)
1470 *pcc = disc_resp->disc.change_count;
1471
1472 kfree(disc_resp);
1473 return res;
1474}
1475
1476static int sas_get_phy_attached_sas_addr(struct domain_device *dev,
1477 int phy_id, u8 *attached_sas_addr)
1478{
1479 int res;
1480 struct smp_resp *disc_resp;
1481 struct discover_resp *dr;
1482
1483 disc_resp = alloc_smp_resp(DISCOVER_RESP_SIZE);
1484 if (!disc_resp)
1485 return -ENOMEM;
1486 dr = &disc_resp->disc;
1487
1488 res = sas_get_phy_discover(dev, phy_id, disc_resp);
1489 if (!res) {
1490 memcpy(attached_sas_addr,disc_resp->disc.attached_sas_addr,8);
1491 if (dr->attached_dev_type == 0)
1492 memset(attached_sas_addr, 0, 8);
1493 }
1494 kfree(disc_resp);
1495 return res;
1496}
1497
1498static int sas_find_bcast_phy(struct domain_device *dev, int *phy_id,
1499 int from_phy)
1500{
1501 struct expander_device *ex = &dev->ex_dev;
1502 int res = 0;
1503 int i;
1504
1505 for (i = from_phy; i < ex->num_phys; i++) {
1506 int phy_change_count = 0;
1507
1508 res = sas_get_phy_change_count(dev, i, &phy_change_count);
1509 if (res)
1510 goto out;
1511 else if (phy_change_count != ex->ex_phy[i].phy_change_count) {
1512 ex->ex_phy[i].phy_change_count = phy_change_count;
1513 *phy_id = i;
1514 return 0;
1515 }
1516 }
1517out:
1518 return res;
1519}
1520
1521static int sas_get_ex_change_count(struct domain_device *dev, int *ecc)
1522{
1523 int res;
1524 u8 *rg_req;
1525 struct smp_resp *rg_resp;
1526
1527 rg_req = alloc_smp_req(RG_REQ_SIZE);
1528 if (!rg_req)
1529 return -ENOMEM;
1530
1531 rg_resp = alloc_smp_resp(RG_RESP_SIZE);
1532 if (!rg_resp) {
1533 kfree(rg_req);
1534 return -ENOMEM;
1535 }
1536
1537 rg_req[1] = SMP_REPORT_GENERAL;
1538
1539 res = smp_execute_task(dev, rg_req, RG_REQ_SIZE, rg_resp,
1540 RG_RESP_SIZE);
1541 if (res)
1542 goto out;
1543 if (rg_resp->result != SMP_RESP_FUNC_ACC) {
1544 res = rg_resp->result;
1545 goto out;
1546 }
1547
1548 *ecc = be16_to_cpu(rg_resp->rg.change_count);
1549out:
1550 kfree(rg_resp);
1551 kfree(rg_req);
1552 return res;
1553}
1554
1555static int sas_find_bcast_dev(struct domain_device *dev,
1556 struct domain_device **src_dev)
1557{
1558 struct expander_device *ex = &dev->ex_dev;
1559 int ex_change_count = -1;
1560 int res;
1561
1562 res = sas_get_ex_change_count(dev, &ex_change_count);
1563 if (res)
1564 goto out;
1565 if (ex_change_count != -1 &&
1566 ex_change_count != ex->ex_change_count) {
1567 *src_dev = dev;
1568 ex->ex_change_count = ex_change_count;
1569 } else {
1570 struct domain_device *ch;
1571
1572 list_for_each_entry(ch, &ex->children, siblings) {
1573 if (ch->dev_type == EDGE_DEV ||
1574 ch->dev_type == FANOUT_DEV) {
1575 res = sas_find_bcast_dev(ch, src_dev);
1576 if (src_dev)
1577 return res;
1578 }
1579 }
1580 }
1581out:
1582 return res;
1583}
1584
1585static void sas_unregister_ex_tree(struct domain_device *dev)
1586{
1587 struct expander_device *ex = &dev->ex_dev;
1588 struct domain_device *child, *n;
1589
1590 list_for_each_entry_safe(child, n, &ex->children, siblings) {
1591 if (child->dev_type == EDGE_DEV ||
1592 child->dev_type == FANOUT_DEV)
1593 sas_unregister_ex_tree(child);
1594 else
1595 sas_unregister_dev(child);
1596 }
1597 sas_unregister_dev(dev);
1598}
1599
1600static void sas_unregister_devs_sas_addr(struct domain_device *parent,
1601 int phy_id)
1602{
1603 struct expander_device *ex_dev = &parent->ex_dev;
1604 struct ex_phy *phy = &ex_dev->ex_phy[phy_id];
1605 struct domain_device *child, *n;
1606
1607 list_for_each_entry_safe(child, n, &ex_dev->children, siblings) {
1608 if (SAS_ADDR(child->sas_addr) ==
1609 SAS_ADDR(phy->attached_sas_addr)) {
1610 if (child->dev_type == EDGE_DEV ||
1611 child->dev_type == FANOUT_DEV)
1612 sas_unregister_ex_tree(child);
1613 else
1614 sas_unregister_dev(child);
1615 break;
1616 }
1617 }
1618 sas_disable_routing(parent, phy->attached_sas_addr);
1619 memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE);
1620 sas_port_delete_phy(phy->port, phy->phy);
1621 if (phy->port->num_phys == 0)
1622 sas_port_delete(phy->port);
1623 phy->port = NULL;
1624}
1625
1626static int sas_discover_bfs_by_root_level(struct domain_device *root,
1627 const int level)
1628{
1629 struct expander_device *ex_root = &root->ex_dev;
1630 struct domain_device *child;
1631 int res = 0;
1632
1633 list_for_each_entry(child, &ex_root->children, siblings) {
1634 if (child->dev_type == EDGE_DEV ||
1635 child->dev_type == FANOUT_DEV) {
1636 struct sas_expander_device *ex =
1637 rphy_to_expander_device(child->rphy);
1638
1639 if (level > ex->level)
1640 res = sas_discover_bfs_by_root_level(child,
1641 level);
1642 else if (level == ex->level)
1643 res = sas_ex_discover_devices(child, -1);
1644 }
1645 }
1646 return res;
1647}
1648
1649static int sas_discover_bfs_by_root(struct domain_device *dev)
1650{
1651 int res;
1652 struct sas_expander_device *ex = rphy_to_expander_device(dev->rphy);
1653 int level = ex->level+1;
1654
1655 res = sas_ex_discover_devices(dev, -1);
1656 if (res)
1657 goto out;
1658 do {
1659 res = sas_discover_bfs_by_root_level(dev, level);
1660 mb();
1661 level += 1;
1662 } while (level <= dev->port->disc.max_level);
1663out:
1664 return res;
1665}
1666
1667static int sas_discover_new(struct domain_device *dev, int phy_id)
1668{
1669 struct ex_phy *ex_phy = &dev->ex_dev.ex_phy[phy_id];
1670 struct domain_device *child;
1671 int res;
1672
1673 SAS_DPRINTK("ex %016llx phy%d new device attached\n",
1674 SAS_ADDR(dev->sas_addr), phy_id);
1675 res = sas_ex_phy_discover(dev, phy_id);
1676 if (res)
1677 goto out;
1678 res = sas_ex_discover_devices(dev, phy_id);
1679 if (res)
1680 goto out;
1681 list_for_each_entry(child, &dev->ex_dev.children, siblings) {
1682 if (SAS_ADDR(child->sas_addr) ==
1683 SAS_ADDR(ex_phy->attached_sas_addr)) {
1684 if (child->dev_type == EDGE_DEV ||
1685 child->dev_type == FANOUT_DEV)
1686 res = sas_discover_bfs_by_root(child);
1687 break;
1688 }
1689 }
1690out:
1691 return res;
1692}
1693
1694static int sas_rediscover_dev(struct domain_device *dev, int phy_id)
1695{
1696 struct expander_device *ex = &dev->ex_dev;
1697 struct ex_phy *phy = &ex->ex_phy[phy_id];
1698 u8 attached_sas_addr[8];
1699 int res;
1700
1701 res = sas_get_phy_attached_sas_addr(dev, phy_id, attached_sas_addr);
1702 switch (res) {
1703 case SMP_RESP_NO_PHY:
1704 phy->phy_state = PHY_NOT_PRESENT;
1705 sas_unregister_devs_sas_addr(dev, phy_id);
1706 goto out; break;
1707 case SMP_RESP_PHY_VACANT:
1708 phy->phy_state = PHY_VACANT;
1709 sas_unregister_devs_sas_addr(dev, phy_id);
1710 goto out; break;
1711 case SMP_RESP_FUNC_ACC:
1712 break;
1713 }
1714
1715 if (SAS_ADDR(attached_sas_addr) == 0) {
1716 phy->phy_state = PHY_EMPTY;
1717 sas_unregister_devs_sas_addr(dev, phy_id);
1718 } else if (SAS_ADDR(attached_sas_addr) ==
1719 SAS_ADDR(phy->attached_sas_addr)) {
1720 SAS_DPRINTK("ex %016llx phy 0x%x broadcast flutter\n",
1721 SAS_ADDR(dev->sas_addr), phy_id);
1722 } else
1723 res = sas_discover_new(dev, phy_id);
1724out:
1725 return res;
1726}
1727
1728static int sas_rediscover(struct domain_device *dev, const int phy_id)
1729{
1730 struct expander_device *ex = &dev->ex_dev;
1731 struct ex_phy *changed_phy = &ex->ex_phy[phy_id];
1732 int res = 0;
1733 int i;
1734
1735 SAS_DPRINTK("ex %016llx phy%d originated BROADCAST(CHANGE)\n",
1736 SAS_ADDR(dev->sas_addr), phy_id);
1737
1738 if (SAS_ADDR(changed_phy->attached_sas_addr) != 0) {
1739 for (i = 0; i < ex->num_phys; i++) {
1740 struct ex_phy *phy = &ex->ex_phy[i];
1741
1742 if (i == phy_id)
1743 continue;
1744 if (SAS_ADDR(phy->attached_sas_addr) ==
1745 SAS_ADDR(changed_phy->attached_sas_addr)) {
1746 SAS_DPRINTK("phy%d part of wide port with "
1747 "phy%d\n", phy_id, i);
1748 goto out;
1749 }
1750 }
1751 res = sas_rediscover_dev(dev, phy_id);
1752 } else
1753 res = sas_discover_new(dev, phy_id);
1754out:
1755 return res;
1756}
1757
1758/**
1759 * sas_revalidate_domain -- revalidate the domain
1760 * @port: port to the domain of interest
1761 *
1762 * NOTE: this process _must_ quit (return) as soon as any connection
1763 * errors are encountered. Connection recovery is done elsewhere.
1764 * Discover process only interrogates devices in order to discover the
1765 * domain.
1766 */
1767int sas_ex_revalidate_domain(struct domain_device *port_dev)
1768{
1769 int res;
1770 struct domain_device *dev = NULL;
1771
1772 res = sas_find_bcast_dev(port_dev, &dev);
1773 if (res)
1774 goto out;
1775 if (dev) {
1776 struct expander_device *ex = &dev->ex_dev;
1777 int i = 0, phy_id;
1778
1779 do {
1780 phy_id = -1;
1781 res = sas_find_bcast_phy(dev, &phy_id, i);
1782 if (phy_id == -1)
1783 break;
1784 res = sas_rediscover(dev, phy_id);
1785 i = phy_id + 1;
1786 } while (i < ex->num_phys);
1787 }
1788out:
1789 return res;
1790}
1791
1792#if 0
1793/* ---------- SMP portal ---------- */
1794
1795static ssize_t smp_portal_write(struct kobject *kobj, char *buf, loff_t offs,
1796 size_t size)
1797{
1798 struct domain_device *dev = to_dom_device(kobj);
1799 struct expander_device *ex = &dev->ex_dev;
1800
1801 if (offs != 0)
1802 return -EFBIG;
1803 else if (size == 0)
1804 return 0;
1805
1806 down_interruptible(&ex->smp_sema);
1807 if (ex->smp_req)
1808 kfree(ex->smp_req);
1809 ex->smp_req = kzalloc(size, GFP_USER);
1810 if (!ex->smp_req) {
1811 up(&ex->smp_sema);
1812 return -ENOMEM;
1813 }
1814 memcpy(ex->smp_req, buf, size);
1815 ex->smp_req_size = size;
1816 ex->smp_portal_pid = current->pid;
1817 up(&ex->smp_sema);
1818
1819 return size;
1820}
1821
1822static ssize_t smp_portal_read(struct kobject *kobj, char *buf, loff_t offs,
1823 size_t size)
1824{
1825 struct domain_device *dev = to_dom_device(kobj);
1826 struct expander_device *ex = &dev->ex_dev;
1827 u8 *smp_resp;
1828 int res = -EINVAL;
1829
1830 /* XXX: sysfs gives us an offset of 0x10 or 0x8 while in fact
1831 * it should be 0.
1832 */
1833
1834 down_interruptible(&ex->smp_sema);
1835 if (!ex->smp_req || ex->smp_portal_pid != current->pid)
1836 goto out;
1837
1838 res = 0;
1839 if (size == 0)
1840 goto out;
1841
1842 res = -ENOMEM;
1843 smp_resp = alloc_smp_resp(size);
1844 if (!smp_resp)
1845 goto out;
1846 res = smp_execute_task(dev, ex->smp_req, ex->smp_req_size,
1847 smp_resp, size);
1848 if (!res) {
1849 memcpy(buf, smp_resp, size);
1850 res = size;
1851 }
1852
1853 kfree(smp_resp);
1854out:
1855 kfree(ex->smp_req);
1856 ex->smp_req = NULL;
1857 ex->smp_req_size = 0;
1858 ex->smp_portal_pid = -1;
1859 up(&ex->smp_sema);
1860 return res;
1861}
1862#endif
diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c
new file mode 100644
index 000000000000..b961664b8106
--- /dev/null
+++ b/drivers/scsi/libsas/sas_init.c
@@ -0,0 +1,227 @@
1/*
2 * Serial Attached SCSI (SAS) Transport Layer initialization
3 *
4 * Copyright (C) 2005 Adaptec, Inc. All rights reserved.
5 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
6 *
7 * This file is licensed under GPLv2.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22 * USA
23 *
24 */
25
26#include <linux/module.h>
27#include <linux/init.h>
28#include <linux/device.h>
29#include <linux/spinlock.h>
30#include <scsi/scsi_host.h>
31#include <scsi/scsi_device.h>
32#include <scsi/scsi_transport.h>
33#include <scsi/scsi_transport_sas.h>
34
35#include "sas_internal.h"
36
37#include "../scsi_sas_internal.h"
38
39kmem_cache_t *sas_task_cache;
40
41/*------------ SAS addr hash -----------*/
42void sas_hash_addr(u8 *hashed, const u8 *sas_addr)
43{
44 const u32 poly = 0x00DB2777;
45 u32 r = 0;
46 int i;
47
48 for (i = 0; i < 8; i++) {
49 int b;
50 for (b = 7; b >= 0; b--) {
51 r <<= 1;
52 if ((1 << b) & sas_addr[i]) {
53 if (!(r & 0x01000000))
54 r ^= poly;
55 } else if (r & 0x01000000)
56 r ^= poly;
57 }
58 }
59
60 hashed[0] = (r >> 16) & 0xFF;
61 hashed[1] = (r >> 8) & 0xFF ;
62 hashed[2] = r & 0xFF;
63}
64
65
66/* ---------- HA events ---------- */
67
68void sas_hae_reset(void *data)
69{
70 struct sas_ha_struct *ha = data;
71
72 sas_begin_event(HAE_RESET, &ha->event_lock,
73 &ha->pending);
74}
75
76int sas_register_ha(struct sas_ha_struct *sas_ha)
77{
78 int error = 0;
79
80 spin_lock_init(&sas_ha->phy_port_lock);
81 sas_hash_addr(sas_ha->hashed_sas_addr, sas_ha->sas_addr);
82
83 if (sas_ha->lldd_queue_size == 0)
84 sas_ha->lldd_queue_size = 1;
85 else if (sas_ha->lldd_queue_size == -1)
86 sas_ha->lldd_queue_size = 128; /* Sanity */
87
88 error = sas_register_phys(sas_ha);
89 if (error) {
90 printk(KERN_NOTICE "couldn't register sas phys:%d\n", error);
91 return error;
92 }
93
94 error = sas_register_ports(sas_ha);
95 if (error) {
96 printk(KERN_NOTICE "couldn't register sas ports:%d\n", error);
97 goto Undo_phys;
98 }
99
100 error = sas_init_events(sas_ha);
101 if (error) {
102 printk(KERN_NOTICE "couldn't start event thread:%d\n", error);
103 goto Undo_ports;
104 }
105
106 if (sas_ha->lldd_max_execute_num > 1) {
107 error = sas_init_queue(sas_ha);
108 if (error) {
109 printk(KERN_NOTICE "couldn't start queue thread:%d, "
110 "running in direct mode\n", error);
111 sas_ha->lldd_max_execute_num = 1;
112 }
113 }
114
115 return 0;
116
117Undo_ports:
118 sas_unregister_ports(sas_ha);
119Undo_phys:
120
121 return error;
122}
123
124int sas_unregister_ha(struct sas_ha_struct *sas_ha)
125{
126 if (sas_ha->lldd_max_execute_num > 1) {
127 sas_shutdown_queue(sas_ha);
128 }
129
130 sas_unregister_ports(sas_ha);
131
132 return 0;
133}
134
135static int sas_get_linkerrors(struct sas_phy *phy)
136{
137 if (scsi_is_sas_phy_local(phy))
138 /* FIXME: we have no local phy stats
139 * gathering at this time */
140 return -EINVAL;
141
142 return sas_smp_get_phy_events(phy);
143}
144
145static int sas_phy_reset(struct sas_phy *phy, int hard_reset)
146{
147 int ret;
148 enum phy_func reset_type;
149
150 if (hard_reset)
151 reset_type = PHY_FUNC_HARD_RESET;
152 else
153 reset_type = PHY_FUNC_LINK_RESET;
154
155 if (scsi_is_sas_phy_local(phy)) {
156 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
157 struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost);
158 struct asd_sas_phy *asd_phy = sas_ha->sas_phy[phy->number];
159 struct sas_internal *i =
160 to_sas_internal(sas_ha->core.shost->transportt);
161
162 ret = i->dft->lldd_control_phy(asd_phy, reset_type);
163 } else {
164 struct sas_rphy *rphy = dev_to_rphy(phy->dev.parent);
165 struct domain_device *ddev = sas_find_dev_by_rphy(rphy);
166 ret = sas_smp_phy_control(ddev, phy->number, reset_type);
167 }
168 return ret;
169}
170
171static struct sas_function_template sft = {
172 .phy_reset = sas_phy_reset,
173 .get_linkerrors = sas_get_linkerrors,
174};
175
176struct scsi_transport_template *
177sas_domain_attach_transport(struct sas_domain_function_template *dft)
178{
179 struct scsi_transport_template *stt = sas_attach_transport(&sft);
180 struct sas_internal *i;
181
182 if (!stt)
183 return stt;
184
185 i = to_sas_internal(stt);
186 i->dft = dft;
187 stt->create_work_queue = 1;
188 stt->eh_timed_out = sas_scsi_timed_out;
189 stt->eh_strategy_handler = sas_scsi_recover_host;
190
191 return stt;
192}
193EXPORT_SYMBOL_GPL(sas_domain_attach_transport);
194
195
196void sas_domain_release_transport(struct scsi_transport_template *stt)
197{
198 sas_release_transport(stt);
199}
200EXPORT_SYMBOL_GPL(sas_domain_release_transport);
201
202/* ---------- SAS Class register/unregister ---------- */
203
204static int __init sas_class_init(void)
205{
206 sas_task_cache = kmem_cache_create("sas_task", sizeof(struct sas_task),
207 0, SLAB_HWCACHE_ALIGN, NULL, NULL);
208 if (!sas_task_cache)
209 return -ENOMEM;
210
211 return 0;
212}
213
214static void __exit sas_class_exit(void)
215{
216 kmem_cache_destroy(sas_task_cache);
217}
218
219MODULE_AUTHOR("Luben Tuikov <luben_tuikov@adaptec.com>");
220MODULE_DESCRIPTION("SAS Transport Layer");
221MODULE_LICENSE("GPL v2");
222
223module_init(sas_class_init);
224module_exit(sas_class_exit);
225
226EXPORT_SYMBOL_GPL(sas_register_ha);
227EXPORT_SYMBOL_GPL(sas_unregister_ha);
diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h
new file mode 100644
index 000000000000..89c397680846
--- /dev/null
+++ b/drivers/scsi/libsas/sas_internal.h
@@ -0,0 +1,146 @@
1/*
2 * Serial Attached SCSI (SAS) class internal header file
3 *
4 * Copyright (C) 2005 Adaptec, Inc. All rights reserved.
5 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
6 *
7 * This file is licensed under GPLv2.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22 * USA
23 *
24 */
25
26#ifndef _SAS_INTERNAL_H_
27#define _SAS_INTERNAL_H_
28
29#include <scsi/scsi.h>
30#include <scsi/scsi_host.h>
31#include <scsi/scsi_transport_sas.h>
32#include <scsi/libsas.h>
33
34#define sas_printk(fmt, ...) printk(KERN_NOTICE "sas: " fmt, ## __VA_ARGS__)
35
36#ifdef SAS_DEBUG
37#define SAS_DPRINTK(fmt, ...) printk(KERN_NOTICE "sas: " fmt, ## __VA_ARGS__)
38#else
39#define SAS_DPRINTK(fmt, ...)
40#endif
41
42void sas_scsi_recover_host(struct Scsi_Host *shost);
43
44int sas_show_class(enum sas_class class, char *buf);
45int sas_show_proto(enum sas_proto proto, char *buf);
46int sas_show_linkrate(enum sas_phy_linkrate linkrate, char *buf);
47int sas_show_oob_mode(enum sas_oob_mode oob_mode, char *buf);
48
49int sas_register_phys(struct sas_ha_struct *sas_ha);
50void sas_unregister_phys(struct sas_ha_struct *sas_ha);
51
52int sas_register_ports(struct sas_ha_struct *sas_ha);
53void sas_unregister_ports(struct sas_ha_struct *sas_ha);
54
55enum scsi_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *);
56
57int sas_init_queue(struct sas_ha_struct *sas_ha);
58int sas_init_events(struct sas_ha_struct *sas_ha);
59void sas_shutdown_queue(struct sas_ha_struct *sas_ha);
60
61void sas_deform_port(struct asd_sas_phy *phy);
62
63void sas_porte_bytes_dmaed(void *);
64void sas_porte_broadcast_rcvd(void *);
65void sas_porte_link_reset_err(void *);
66void sas_porte_timer_event(void *);
67void sas_porte_hard_reset(void *);
68
69int sas_notify_lldd_dev_found(struct domain_device *);
70void sas_notify_lldd_dev_gone(struct domain_device *);
71
72int sas_smp_phy_control(struct domain_device *dev, int phy_id,
73 enum phy_func phy_func);
74int sas_smp_get_phy_events(struct sas_phy *phy);
75
76struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy);
77
78void sas_hae_reset(void *);
79
80static inline void sas_queue_event(int event, spinlock_t *lock,
81 unsigned long *pending,
82 struct work_struct *work,
83 struct Scsi_Host *shost)
84{
85 unsigned long flags;
86
87 spin_lock_irqsave(lock, flags);
88 if (test_bit(event, pending)) {
89 spin_unlock_irqrestore(lock, flags);
90 return;
91 }
92 __set_bit(event, pending);
93 spin_unlock_irqrestore(lock, flags);
94 scsi_queue_work(shost, work);
95}
96
97static inline void sas_begin_event(int event, spinlock_t *lock,
98 unsigned long *pending)
99{
100 unsigned long flags;
101
102 spin_lock_irqsave(lock, flags);
103 __clear_bit(event, pending);
104 spin_unlock_irqrestore(lock, flags);
105}
106
107static inline void sas_fill_in_rphy(struct domain_device *dev,
108 struct sas_rphy *rphy)
109{
110 rphy->identify.sas_address = SAS_ADDR(dev->sas_addr);
111 rphy->identify.initiator_port_protocols = dev->iproto;
112 rphy->identify.target_port_protocols = dev->tproto;
113 switch (dev->dev_type) {
114 case SATA_DEV:
115 /* FIXME: need sata device type */
116 case SAS_END_DEV:
117 rphy->identify.device_type = SAS_END_DEVICE;
118 break;
119 case EDGE_DEV:
120 rphy->identify.device_type = SAS_EDGE_EXPANDER_DEVICE;
121 break;
122 case FANOUT_DEV:
123 rphy->identify.device_type = SAS_FANOUT_EXPANDER_DEVICE;
124 break;
125 default:
126 rphy->identify.device_type = SAS_PHY_UNUSED;
127 break;
128 }
129}
130
131static inline void sas_add_parent_port(struct domain_device *dev, int phy_id)
132{
133 struct expander_device *ex = &dev->ex_dev;
134 struct ex_phy *ex_phy = &ex->ex_phy[phy_id];
135
136 if (!ex->parent_port) {
137 ex->parent_port = sas_port_alloc(&dev->rphy->dev, phy_id);
138 /* FIXME: error handling */
139 BUG_ON(!ex->parent_port);
140 BUG_ON(sas_port_add(ex->parent_port));
141 sas_port_mark_backlink(ex->parent_port);
142 }
143 sas_port_add_phy(ex->parent_port, ex_phy->phy);
144}
145
146#endif /* _SAS_INTERNAL_H_ */
diff --git a/drivers/scsi/libsas/sas_phy.c b/drivers/scsi/libsas/sas_phy.c
new file mode 100644
index 000000000000..024ab00e70d2
--- /dev/null
+++ b/drivers/scsi/libsas/sas_phy.c
@@ -0,0 +1,157 @@
1/*
2 * Serial Attached SCSI (SAS) Phy class
3 *
4 * Copyright (C) 2005 Adaptec, Inc. All rights reserved.
5 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
6 *
7 * This file is licensed under GPLv2.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 *
23 */
24
25#include "sas_internal.h"
26#include <scsi/scsi_host.h>
27#include <scsi/scsi_transport.h>
28#include <scsi/scsi_transport_sas.h>
29#include "../scsi_sas_internal.h"
30
31/* ---------- Phy events ---------- */
32
33static void sas_phye_loss_of_signal(void *data)
34{
35 struct asd_sas_phy *phy = data;
36
37 sas_begin_event(PHYE_LOSS_OF_SIGNAL, &phy->ha->event_lock,
38 &phy->phy_events_pending);
39 phy->error = 0;
40 sas_deform_port(phy);
41}
42
43static void sas_phye_oob_done(void *data)
44{
45 struct asd_sas_phy *phy = data;
46
47 sas_begin_event(PHYE_OOB_DONE, &phy->ha->event_lock,
48 &phy->phy_events_pending);
49 phy->error = 0;
50}
51
52static void sas_phye_oob_error(void *data)
53{
54 struct asd_sas_phy *phy = data;
55 struct sas_ha_struct *sas_ha = phy->ha;
56 struct asd_sas_port *port = phy->port;
57 struct sas_internal *i =
58 to_sas_internal(sas_ha->core.shost->transportt);
59
60 sas_begin_event(PHYE_OOB_ERROR, &phy->ha->event_lock,
61 &phy->phy_events_pending);
62
63 sas_deform_port(phy);
64
65 if (!port && phy->enabled && i->dft->lldd_control_phy) {
66 phy->error++;
67 switch (phy->error) {
68 case 1:
69 case 2:
70 i->dft->lldd_control_phy(phy, PHY_FUNC_HARD_RESET);
71 break;
72 case 3:
73 default:
74 phy->error = 0;
75 phy->enabled = 0;
76 i->dft->lldd_control_phy(phy, PHY_FUNC_DISABLE);
77 break;
78 }
79 }
80}
81
82static void sas_phye_spinup_hold(void *data)
83{
84 struct asd_sas_phy *phy = data;
85 struct sas_ha_struct *sas_ha = phy->ha;
86 struct sas_internal *i =
87 to_sas_internal(sas_ha->core.shost->transportt);
88
89 sas_begin_event(PHYE_SPINUP_HOLD, &phy->ha->event_lock,
90 &phy->phy_events_pending);
91
92 phy->error = 0;
93 i->dft->lldd_control_phy(phy, PHY_FUNC_RELEASE_SPINUP_HOLD);
94}
95
96/* ---------- Phy class registration ---------- */
97
98int sas_register_phys(struct sas_ha_struct *sas_ha)
99{
100 int i;
101
102 static void (*sas_phy_event_fns[PHY_NUM_EVENTS])(void *) = {
103 [PHYE_LOSS_OF_SIGNAL] = sas_phye_loss_of_signal,
104 [PHYE_OOB_DONE] = sas_phye_oob_done,
105 [PHYE_OOB_ERROR] = sas_phye_oob_error,
106 [PHYE_SPINUP_HOLD] = sas_phye_spinup_hold,
107 };
108
109 static void (*sas_port_event_fns[PORT_NUM_EVENTS])(void *) = {
110 [PORTE_BYTES_DMAED] = sas_porte_bytes_dmaed,
111 [PORTE_BROADCAST_RCVD] = sas_porte_broadcast_rcvd,
112 [PORTE_LINK_RESET_ERR] = sas_porte_link_reset_err,
113 [PORTE_TIMER_EVENT] = sas_porte_timer_event,
114 [PORTE_HARD_RESET] = sas_porte_hard_reset,
115 };
116
117 /* Now register the phys. */
118 for (i = 0; i < sas_ha->num_phys; i++) {
119 int k;
120 struct asd_sas_phy *phy = sas_ha->sas_phy[i];
121
122 phy->error = 0;
123 INIT_LIST_HEAD(&phy->port_phy_el);
124 for (k = 0; k < PORT_NUM_EVENTS; k++)
125 INIT_WORK(&phy->port_events[k], sas_port_event_fns[k],
126 phy);
127
128 for (k = 0; k < PHY_NUM_EVENTS; k++)
129 INIT_WORK(&phy->phy_events[k], sas_phy_event_fns[k],
130 phy);
131 phy->port = NULL;
132 phy->ha = sas_ha;
133 spin_lock_init(&phy->frame_rcvd_lock);
134 spin_lock_init(&phy->sas_prim_lock);
135 phy->frame_rcvd_size = 0;
136
137 phy->phy = sas_phy_alloc(&sas_ha->core.shost->shost_gendev,
138 i);
139 if (!phy->phy)
140 return -ENOMEM;
141
142 phy->phy->identify.initiator_port_protocols =
143 phy->iproto;
144 phy->phy->identify.target_port_protocols = phy->tproto;
145 phy->phy->identify.sas_address = SAS_ADDR(sas_ha->sas_addr);
146 phy->phy->identify.phy_identifier = i;
147 phy->phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
148 phy->phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
149 phy->phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
150 phy->phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
151 phy->phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
152
153 sas_phy_add(phy->phy);
154 }
155
156 return 0;
157}
diff --git a/drivers/scsi/libsas/sas_port.c b/drivers/scsi/libsas/sas_port.c
new file mode 100644
index 000000000000..253cdcf306a2
--- /dev/null
+++ b/drivers/scsi/libsas/sas_port.c
@@ -0,0 +1,279 @@
1/*
2 * Serial Attached SCSI (SAS) Port class
3 *
4 * Copyright (C) 2005 Adaptec, Inc. All rights reserved.
5 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
6 *
7 * This file is licensed under GPLv2.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 *
23 */
24
25#include "sas_internal.h"
26
27#include <scsi/scsi_transport.h>
28#include <scsi/scsi_transport_sas.h>
29#include "../scsi_sas_internal.h"
30
31/**
32 * sas_form_port -- add this phy to a port
33 * @phy: the phy of interest
34 *
35 * This function adds this phy to an existing port, thus creating a wide
36 * port, or it creates a port and adds the phy to the port.
37 */
38static void sas_form_port(struct asd_sas_phy *phy)
39{
40 int i;
41 struct sas_ha_struct *sas_ha = phy->ha;
42 struct asd_sas_port *port = phy->port;
43 struct sas_internal *si =
44 to_sas_internal(sas_ha->core.shost->transportt);
45
46 if (port) {
47 if (memcmp(port->attached_sas_addr, phy->attached_sas_addr,
48 SAS_ADDR_SIZE) == 0)
49 sas_deform_port(phy);
50 else {
51 SAS_DPRINTK("%s: phy%d belongs to port%d already(%d)!\n",
52 __FUNCTION__, phy->id, phy->port->id,
53 phy->port->num_phys);
54 return;
55 }
56 }
57
58 /* find a port */
59 spin_lock(&sas_ha->phy_port_lock);
60 for (i = 0; i < sas_ha->num_phys; i++) {
61 port = sas_ha->sas_port[i];
62 spin_lock(&port->phy_list_lock);
63 if (*(u64 *) port->sas_addr &&
64 memcmp(port->attached_sas_addr,
65 phy->attached_sas_addr, SAS_ADDR_SIZE) == 0 &&
66 port->num_phys > 0) {
67 /* wide port */
68 SAS_DPRINTK("phy%d matched wide port%d\n", phy->id,
69 port->id);
70 break;
71 } else if (*(u64 *) port->sas_addr == 0 && port->num_phys==0) {
72 memcpy(port->sas_addr, phy->sas_addr, SAS_ADDR_SIZE);
73 break;
74 }
75 spin_unlock(&port->phy_list_lock);
76 }
77
78 if (i >= sas_ha->num_phys) {
79 printk(KERN_NOTICE "%s: couldn't find a free port, bug?\n",
80 __FUNCTION__);
81 spin_unlock(&sas_ha->phy_port_lock);
82 return;
83 }
84
85 /* add the phy to the port */
86 list_add_tail(&phy->port_phy_el, &port->phy_list);
87 phy->port = port;
88 port->num_phys++;
89 port->phy_mask |= (1U << phy->id);
90
91 if (!port->phy)
92 port->phy = phy->phy;
93
94 SAS_DPRINTK("phy%d added to port%d, phy_mask:0x%x\n", phy->id,
95 port->id, port->phy_mask);
96
97 if (*(u64 *)port->attached_sas_addr == 0) {
98 port->class = phy->class;
99 memcpy(port->attached_sas_addr, phy->attached_sas_addr,
100 SAS_ADDR_SIZE);
101 port->iproto = phy->iproto;
102 port->tproto = phy->tproto;
103 port->oob_mode = phy->oob_mode;
104 port->linkrate = phy->linkrate;
105 } else
106 port->linkrate = max(port->linkrate, phy->linkrate);
107 spin_unlock(&port->phy_list_lock);
108 spin_unlock(&sas_ha->phy_port_lock);
109
110 if (!port->port) {
111 port->port = sas_port_alloc(phy->phy->dev.parent, port->id);
112 BUG_ON(!port->port);
113 sas_port_add(port->port);
114 }
115 sas_port_add_phy(port->port, phy->phy);
116
117 if (port->port_dev)
118 port->port_dev->pathways = port->num_phys;
119
120 /* Tell the LLDD about this port formation. */
121 if (si->dft->lldd_port_formed)
122 si->dft->lldd_port_formed(phy);
123
124 sas_discover_event(phy->port, DISCE_DISCOVER_DOMAIN);
125}
126
127/**
128 * sas_deform_port -- remove this phy from the port it belongs to
129 * @phy: the phy of interest
130 *
131 * This is called when the physical link to the other phy has been
132 * lost (on this phy), in Event thread context. We cannot delay here.
133 */
134void sas_deform_port(struct asd_sas_phy *phy)
135{
136 struct sas_ha_struct *sas_ha = phy->ha;
137 struct asd_sas_port *port = phy->port;
138 struct sas_internal *si =
139 to_sas_internal(sas_ha->core.shost->transportt);
140
141 if (!port)
142 return; /* done by a phy event */
143
144 if (port->port_dev)
145 port->port_dev->pathways--;
146
147 if (port->num_phys == 1) {
148 sas_unregister_domain_devices(port);
149 sas_port_delete(port->port);
150 port->port = NULL;
151 } else
152 sas_port_delete_phy(port->port, phy->phy);
153
154
155 if (si->dft->lldd_port_deformed)
156 si->dft->lldd_port_deformed(phy);
157
158 spin_lock(&sas_ha->phy_port_lock);
159 spin_lock(&port->phy_list_lock);
160
161 list_del_init(&phy->port_phy_el);
162 phy->port = NULL;
163 port->num_phys--;
164 port->phy_mask &= ~(1U << phy->id);
165
166 if (port->num_phys == 0) {
167 INIT_LIST_HEAD(&port->phy_list);
168 memset(port->sas_addr, 0, SAS_ADDR_SIZE);
169 memset(port->attached_sas_addr, 0, SAS_ADDR_SIZE);
170 port->class = 0;
171 port->iproto = 0;
172 port->tproto = 0;
173 port->oob_mode = 0;
174 port->phy_mask = 0;
175 }
176 spin_unlock(&port->phy_list_lock);
177 spin_unlock(&sas_ha->phy_port_lock);
178
179 return;
180}
181
182/* ---------- SAS port events ---------- */
183
184void sas_porte_bytes_dmaed(void *data)
185{
186 struct asd_sas_phy *phy = data;
187
188 sas_begin_event(PORTE_BYTES_DMAED, &phy->ha->event_lock,
189 &phy->port_events_pending);
190
191 sas_form_port(phy);
192}
193
194void sas_porte_broadcast_rcvd(void *data)
195{
196 unsigned long flags;
197 u32 prim;
198 struct asd_sas_phy *phy = data;
199
200 sas_begin_event(PORTE_BROADCAST_RCVD, &phy->ha->event_lock,
201 &phy->port_events_pending);
202
203 spin_lock_irqsave(&phy->sas_prim_lock, flags);
204 prim = phy->sas_prim;
205 spin_unlock_irqrestore(&phy->sas_prim_lock, flags);
206
207 SAS_DPRINTK("broadcast received: %d\n", prim);
208 sas_discover_event(phy->port, DISCE_REVALIDATE_DOMAIN);
209}
210
211void sas_porte_link_reset_err(void *data)
212{
213 struct asd_sas_phy *phy = data;
214
215 sas_begin_event(PORTE_LINK_RESET_ERR, &phy->ha->event_lock,
216 &phy->port_events_pending);
217
218 sas_deform_port(phy);
219}
220
221void sas_porte_timer_event(void *data)
222{
223 struct asd_sas_phy *phy = data;
224
225 sas_begin_event(PORTE_TIMER_EVENT, &phy->ha->event_lock,
226 &phy->port_events_pending);
227
228 sas_deform_port(phy);
229}
230
231void sas_porte_hard_reset(void *data)
232{
233 struct asd_sas_phy *phy = data;
234
235 sas_begin_event(PORTE_HARD_RESET, &phy->ha->event_lock,
236 &phy->port_events_pending);
237
238 sas_deform_port(phy);
239}
240
241/* ---------- SAS port registration ---------- */
242
243static void sas_init_port(struct asd_sas_port *port,
244 struct sas_ha_struct *sas_ha, int i)
245{
246 port->id = i;
247 INIT_LIST_HEAD(&port->dev_list);
248 spin_lock_init(&port->phy_list_lock);
249 INIT_LIST_HEAD(&port->phy_list);
250 port->num_phys = 0;
251 port->phy_mask = 0;
252 port->ha = sas_ha;
253
254 spin_lock_init(&port->dev_list_lock);
255}
256
257int sas_register_ports(struct sas_ha_struct *sas_ha)
258{
259 int i;
260
261 /* initialize the ports and discovery */
262 for (i = 0; i < sas_ha->num_phys; i++) {
263 struct asd_sas_port *port = sas_ha->sas_port[i];
264
265 sas_init_port(port, sas_ha, i);
266 sas_init_disc(&port->disc, port);
267 }
268 return 0;
269}
270
271void sas_unregister_ports(struct sas_ha_struct *sas_ha)
272{
273 int i;
274
275 for (i = 0; i < sas_ha->num_phys; i++)
276 if (sas_ha->sas_phy[i]->port)
277 sas_deform_port(sas_ha->sas_phy[i]);
278
279}
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c
new file mode 100644
index 000000000000..43e0e4e36934
--- /dev/null
+++ b/drivers/scsi/libsas/sas_scsi_host.c
@@ -0,0 +1,786 @@
1/*
2 * Serial Attached SCSI (SAS) class SCSI Host glue.
3 *
4 * Copyright (C) 2005 Adaptec, Inc. All rights reserved.
5 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
6 *
7 * This file is licensed under GPLv2.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22 * USA
23 *
24 */
25
26#include "sas_internal.h"
27
28#include <scsi/scsi_host.h>
29#include <scsi/scsi_device.h>
30#include <scsi/scsi_tcq.h>
31#include <scsi/scsi.h>
32#include <scsi/scsi_transport.h>
33#include <scsi/scsi_transport_sas.h>
34#include "../scsi_sas_internal.h"
35
36#include <linux/err.h>
37#include <linux/blkdev.h>
38#include <linux/scatterlist.h>
39
40/* ---------- SCSI Host glue ---------- */
41
42#define TO_SAS_TASK(_scsi_cmd) ((void *)(_scsi_cmd)->host_scribble)
43#define ASSIGN_SAS_TASK(_sc, _t) do { (_sc)->host_scribble = (void *) _t; } while (0)
44
45static void sas_scsi_task_done(struct sas_task *task)
46{
47 struct task_status_struct *ts = &task->task_status;
48 struct scsi_cmnd *sc = task->uldd_task;
49 unsigned ts_flags = task->task_state_flags;
50 int hs = 0, stat = 0;
51
52 if (unlikely(!sc)) {
53 SAS_DPRINTK("task_done called with non existing SCSI cmnd!\n");
54 list_del_init(&task->list);
55 sas_free_task(task);
56 return;
57 }
58
59 if (ts->resp == SAS_TASK_UNDELIVERED) {
60 /* transport error */
61 hs = DID_NO_CONNECT;
62 } else { /* ts->resp == SAS_TASK_COMPLETE */
63 /* task delivered, what happened afterwards? */
64 switch (ts->stat) {
65 case SAS_DEV_NO_RESPONSE:
66 case SAS_INTERRUPTED:
67 case SAS_PHY_DOWN:
68 case SAS_NAK_R_ERR:
69 case SAS_OPEN_TO:
70 hs = DID_NO_CONNECT;
71 break;
72 case SAS_DATA_UNDERRUN:
73 sc->resid = ts->residual;
74 if (sc->request_bufflen - sc->resid < sc->underflow)
75 hs = DID_ERROR;
76 break;
77 case SAS_DATA_OVERRUN:
78 hs = DID_ERROR;
79 break;
80 case SAS_QUEUE_FULL:
81 hs = DID_SOFT_ERROR; /* retry */
82 break;
83 case SAS_DEVICE_UNKNOWN:
84 hs = DID_BAD_TARGET;
85 break;
86 case SAS_SG_ERR:
87 hs = DID_PARITY;
88 break;
89 case SAS_OPEN_REJECT:
90 if (ts->open_rej_reason == SAS_OREJ_RSVD_RETRY)
91 hs = DID_SOFT_ERROR; /* retry */
92 else
93 hs = DID_ERROR;
94 break;
95 case SAS_PROTO_RESPONSE:
96 SAS_DPRINTK("LLDD:%s sent SAS_PROTO_RESP for an SSP "
97 "task; please report this\n",
98 task->dev->port->ha->sas_ha_name);
99 break;
100 case SAS_ABORTED_TASK:
101 hs = DID_ABORT;
102 break;
103 case SAM_CHECK_COND:
104 memcpy(sc->sense_buffer, ts->buf,
105 max(SCSI_SENSE_BUFFERSIZE, ts->buf_valid_size));
106 stat = SAM_CHECK_COND;
107 break;
108 default:
109 stat = ts->stat;
110 break;
111 }
112 }
113 ASSIGN_SAS_TASK(sc, NULL);
114 sc->result = (hs << 16) | stat;
115 list_del_init(&task->list);
116 sas_free_task(task);
117 /* This is very ugly but this is how SCSI Core works. */
118 if (ts_flags & SAS_TASK_STATE_ABORTED)
119 scsi_finish_command(sc);
120 else
121 sc->scsi_done(sc);
122}
123
124static enum task_attribute sas_scsi_get_task_attr(struct scsi_cmnd *cmd)
125{
126 enum task_attribute ta = TASK_ATTR_SIMPLE;
127 if (cmd->request && blk_rq_tagged(cmd->request)) {
128 if (cmd->device->ordered_tags &&
129 (cmd->request->flags & REQ_HARDBARRIER))
130 ta = TASK_ATTR_HOQ;
131 }
132 return ta;
133}
134
135static struct sas_task *sas_create_task(struct scsi_cmnd *cmd,
136 struct domain_device *dev,
137 unsigned long gfp_flags)
138{
139 struct sas_task *task = sas_alloc_task(gfp_flags);
140 struct scsi_lun lun;
141
142 if (!task)
143 return NULL;
144
145 *(u32 *)cmd->sense_buffer = 0;
146 task->uldd_task = cmd;
147 ASSIGN_SAS_TASK(cmd, task);
148
149 task->dev = dev;
150 task->task_proto = task->dev->tproto; /* BUG_ON(!SSP) */
151
152 task->ssp_task.retry_count = 1;
153 int_to_scsilun(cmd->device->lun, &lun);
154 memcpy(task->ssp_task.LUN, &lun.scsi_lun, 8);
155 task->ssp_task.task_attr = sas_scsi_get_task_attr(cmd);
156 memcpy(task->ssp_task.cdb, cmd->cmnd, 16);
157
158 task->scatter = cmd->request_buffer;
159 task->num_scatter = cmd->use_sg;
160 task->total_xfer_len = cmd->request_bufflen;
161 task->data_dir = cmd->sc_data_direction;
162
163 task->task_done = sas_scsi_task_done;
164
165 return task;
166}
167
168static int sas_queue_up(struct sas_task *task)
169{
170 struct sas_ha_struct *sas_ha = task->dev->port->ha;
171 struct scsi_core *core = &sas_ha->core;
172 unsigned long flags;
173 LIST_HEAD(list);
174
175 spin_lock_irqsave(&core->task_queue_lock, flags);
176 if (sas_ha->lldd_queue_size < core->task_queue_size + 1) {
177 spin_unlock_irqrestore(&core->task_queue_lock, flags);
178 return -SAS_QUEUE_FULL;
179 }
180 list_add_tail(&task->list, &core->task_queue);
181 core->task_queue_size += 1;
182 spin_unlock_irqrestore(&core->task_queue_lock, flags);
183 up(&core->queue_thread_sema);
184
185 return 0;
186}
187
188/**
189 * sas_queuecommand -- Enqueue a command for processing
190 * @parameters: See SCSI Core documentation
191 *
192 * Note: XXX: Remove the host unlock/lock pair when SCSI Core can
193 * call us without holding an IRQ spinlock...
194 */
195int sas_queuecommand(struct scsi_cmnd *cmd,
196 void (*scsi_done)(struct scsi_cmnd *))
197{
198 int res = 0;
199 struct domain_device *dev = cmd_to_domain_dev(cmd);
200 struct Scsi_Host *host = cmd->device->host;
201 struct sas_internal *i = to_sas_internal(host->transportt);
202
203 spin_unlock_irq(host->host_lock);
204
205 {
206 struct sas_ha_struct *sas_ha = dev->port->ha;
207 struct sas_task *task;
208
209 res = -ENOMEM;
210 task = sas_create_task(cmd, dev, GFP_ATOMIC);
211 if (!task)
212 goto out;
213
214 cmd->scsi_done = scsi_done;
215 /* Queue up, Direct Mode or Task Collector Mode. */
216 if (sas_ha->lldd_max_execute_num < 2)
217 res = i->dft->lldd_execute_task(task, 1, GFP_ATOMIC);
218 else
219 res = sas_queue_up(task);
220
221 /* Examine */
222 if (res) {
223 SAS_DPRINTK("lldd_execute_task returned: %d\n", res);
224 ASSIGN_SAS_TASK(cmd, NULL);
225 sas_free_task(task);
226 if (res == -SAS_QUEUE_FULL) {
227 cmd->result = DID_SOFT_ERROR << 16; /* retry */
228 res = 0;
229 scsi_done(cmd);
230 }
231 goto out;
232 }
233 }
234out:
235 spin_lock_irq(host->host_lock);
236 return res;
237}
238
239static void sas_scsi_clear_queue_lu(struct list_head *error_q, struct scsi_cmnd *my_cmd)
240{
241 struct scsi_cmnd *cmd, *n;
242
243 list_for_each_entry_safe(cmd, n, error_q, eh_entry) {
244 if (cmd == my_cmd)
245 list_del_init(&cmd->eh_entry);
246 }
247}
248
249static void sas_scsi_clear_queue_I_T(struct list_head *error_q,
250 struct domain_device *dev)
251{
252 struct scsi_cmnd *cmd, *n;
253
254 list_for_each_entry_safe(cmd, n, error_q, eh_entry) {
255 struct domain_device *x = cmd_to_domain_dev(cmd);
256
257 if (x == dev)
258 list_del_init(&cmd->eh_entry);
259 }
260}
261
262static void sas_scsi_clear_queue_port(struct list_head *error_q,
263 struct asd_sas_port *port)
264{
265 struct scsi_cmnd *cmd, *n;
266
267 list_for_each_entry_safe(cmd, n, error_q, eh_entry) {
268 struct domain_device *dev = cmd_to_domain_dev(cmd);
269 struct asd_sas_port *x = dev->port;
270
271 if (x == port)
272 list_del_init(&cmd->eh_entry);
273 }
274}
275
276enum task_disposition {
277 TASK_IS_DONE,
278 TASK_IS_ABORTED,
279 TASK_IS_AT_LU,
280 TASK_IS_NOT_AT_LU,
281};
282
283static enum task_disposition sas_scsi_find_task(struct sas_task *task)
284{
285 struct sas_ha_struct *ha = task->dev->port->ha;
286 unsigned long flags;
287 int i, res;
288 struct sas_internal *si =
289 to_sas_internal(task->dev->port->ha->core.shost->transportt);
290
291 if (ha->lldd_max_execute_num > 1) {
292 struct scsi_core *core = &ha->core;
293 struct sas_task *t, *n;
294
295 spin_lock_irqsave(&core->task_queue_lock, flags);
296 list_for_each_entry_safe(t, n, &core->task_queue, list) {
297 if (task == t) {
298 list_del_init(&t->list);
299 spin_unlock_irqrestore(&core->task_queue_lock,
300 flags);
301 SAS_DPRINTK("%s: task 0x%p aborted from "
302 "task_queue\n",
303 __FUNCTION__, task);
304 return TASK_IS_ABORTED;
305 }
306 }
307 spin_unlock_irqrestore(&core->task_queue_lock, flags);
308 }
309
310 for (i = 0; i < 5; i++) {
311 SAS_DPRINTK("%s: aborting task 0x%p\n", __FUNCTION__, task);
312 res = si->dft->lldd_abort_task(task);
313
314 spin_lock_irqsave(&task->task_state_lock, flags);
315 if (task->task_state_flags & SAS_TASK_STATE_DONE) {
316 spin_unlock_irqrestore(&task->task_state_lock, flags);
317 SAS_DPRINTK("%s: task 0x%p is done\n", __FUNCTION__,
318 task);
319 return TASK_IS_DONE;
320 }
321 spin_unlock_irqrestore(&task->task_state_lock, flags);
322
323 if (res == TMF_RESP_FUNC_COMPLETE) {
324 SAS_DPRINTK("%s: task 0x%p is aborted\n",
325 __FUNCTION__, task);
326 return TASK_IS_ABORTED;
327 } else if (si->dft->lldd_query_task) {
328 SAS_DPRINTK("%s: querying task 0x%p\n",
329 __FUNCTION__, task);
330 res = si->dft->lldd_query_task(task);
331 if (res == TMF_RESP_FUNC_SUCC) {
332 SAS_DPRINTK("%s: task 0x%p at LU\n",
333 __FUNCTION__, task);
334 return TASK_IS_AT_LU;
335 } else if (res == TMF_RESP_FUNC_COMPLETE) {
336 SAS_DPRINTK("%s: task 0x%p not at LU\n",
337 __FUNCTION__, task);
338 return TASK_IS_NOT_AT_LU;
339 }
340 }
341 }
342 return res;
343}
344
345static int sas_recover_lu(struct domain_device *dev, struct scsi_cmnd *cmd)
346{
347 int res = TMF_RESP_FUNC_FAILED;
348 struct scsi_lun lun;
349 struct sas_internal *i =
350 to_sas_internal(dev->port->ha->core.shost->transportt);
351
352 int_to_scsilun(cmd->device->lun, &lun);
353
354 SAS_DPRINTK("eh: device %llx LUN %x has the task\n",
355 SAS_ADDR(dev->sas_addr),
356 cmd->device->lun);
357
358 if (i->dft->lldd_abort_task_set)
359 res = i->dft->lldd_abort_task_set(dev, lun.scsi_lun);
360
361 if (res == TMF_RESP_FUNC_FAILED) {
362 if (i->dft->lldd_clear_task_set)
363 res = i->dft->lldd_clear_task_set(dev, lun.scsi_lun);
364 }
365
366 if (res == TMF_RESP_FUNC_FAILED) {
367 if (i->dft->lldd_lu_reset)
368 res = i->dft->lldd_lu_reset(dev, lun.scsi_lun);
369 }
370
371 return res;
372}
373
374static int sas_recover_I_T(struct domain_device *dev)
375{
376 int res = TMF_RESP_FUNC_FAILED;
377 struct sas_internal *i =
378 to_sas_internal(dev->port->ha->core.shost->transportt);
379
380 SAS_DPRINTK("I_T nexus reset for dev %016llx\n",
381 SAS_ADDR(dev->sas_addr));
382
383 if (i->dft->lldd_I_T_nexus_reset)
384 res = i->dft->lldd_I_T_nexus_reset(dev);
385
386 return res;
387}
388
389void sas_scsi_recover_host(struct Scsi_Host *shost)
390{
391 struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost);
392 unsigned long flags;
393 LIST_HEAD(error_q);
394 struct scsi_cmnd *cmd, *n;
395 enum task_disposition res = TASK_IS_DONE;
396 int tmf_resp;
397 struct sas_internal *i = to_sas_internal(shost->transportt);
398
399 spin_lock_irqsave(shost->host_lock, flags);
400 list_splice_init(&shost->eh_cmd_q, &error_q);
401 spin_unlock_irqrestore(shost->host_lock, flags);
402
403 SAS_DPRINTK("Enter %s\n", __FUNCTION__);
404
405 /* All tasks on this list were marked SAS_TASK_STATE_ABORTED
406 * by sas_scsi_timed_out() callback.
407 */
408Again:
409 SAS_DPRINTK("going over list...\n");
410 list_for_each_entry_safe(cmd, n, &error_q, eh_entry) {
411 struct sas_task *task = TO_SAS_TASK(cmd);
412
413 SAS_DPRINTK("trying to find task 0x%p\n", task);
414 list_del_init(&cmd->eh_entry);
415 res = sas_scsi_find_task(task);
416
417 cmd->eh_eflags = 0;
418 shost->host_failed--;
419
420 switch (res) {
421 case TASK_IS_DONE:
422 SAS_DPRINTK("%s: task 0x%p is done\n", __FUNCTION__,
423 task);
424 task->task_done(task);
425 continue;
426 case TASK_IS_ABORTED:
427 SAS_DPRINTK("%s: task 0x%p is aborted\n",
428 __FUNCTION__, task);
429 task->task_done(task);
430 continue;
431 case TASK_IS_AT_LU:
432 SAS_DPRINTK("task 0x%p is at LU: lu recover\n", task);
433 tmf_resp = sas_recover_lu(task->dev, cmd);
434 if (tmf_resp == TMF_RESP_FUNC_COMPLETE) {
435 SAS_DPRINTK("dev %016llx LU %x is "
436 "recovered\n",
437 SAS_ADDR(task->dev),
438 cmd->device->lun);
439 task->task_done(task);
440 sas_scsi_clear_queue_lu(&error_q, cmd);
441 goto Again;
442 }
443 /* fallthrough */
444 case TASK_IS_NOT_AT_LU:
445 SAS_DPRINTK("task 0x%p is not at LU: I_T recover\n",
446 task);
447 tmf_resp = sas_recover_I_T(task->dev);
448 if (tmf_resp == TMF_RESP_FUNC_COMPLETE) {
449 SAS_DPRINTK("I_T %016llx recovered\n",
450 SAS_ADDR(task->dev->sas_addr));
451 task->task_done(task);
452 sas_scsi_clear_queue_I_T(&error_q, task->dev);
453 goto Again;
454 }
455 /* Hammer time :-) */
456 if (i->dft->lldd_clear_nexus_port) {
457 struct asd_sas_port *port = task->dev->port;
458 SAS_DPRINTK("clearing nexus for port:%d\n",
459 port->id);
460 res = i->dft->lldd_clear_nexus_port(port);
461 if (res == TMF_RESP_FUNC_COMPLETE) {
462 SAS_DPRINTK("clear nexus port:%d "
463 "succeeded\n", port->id);
464 task->task_done(task);
465 sas_scsi_clear_queue_port(&error_q,
466 port);
467 goto Again;
468 }
469 }
470 if (i->dft->lldd_clear_nexus_ha) {
471 SAS_DPRINTK("clear nexus ha\n");
472 res = i->dft->lldd_clear_nexus_ha(ha);
473 if (res == TMF_RESP_FUNC_COMPLETE) {
474 SAS_DPRINTK("clear nexus ha "
475 "succeeded\n");
476 task->task_done(task);
477 goto out;
478 }
479 }
480 /* If we are here -- this means that no amount
481 * of effort could recover from errors. Quite
482 * possibly the HA just disappeared.
483 */
484 SAS_DPRINTK("error from device %llx, LUN %x "
485 "couldn't be recovered in any way\n",
486 SAS_ADDR(task->dev->sas_addr),
487 cmd->device->lun);
488
489 task->task_done(task);
490 goto clear_q;
491 }
492 }
493out:
494 SAS_DPRINTK("--- Exit %s\n", __FUNCTION__);
495 return;
496clear_q:
497 SAS_DPRINTK("--- Exit %s -- clear_q\n", __FUNCTION__);
498 list_for_each_entry_safe(cmd, n, &error_q, eh_entry) {
499 struct sas_task *task = TO_SAS_TASK(cmd);
500 list_del_init(&cmd->eh_entry);
501 task->task_done(task);
502 }
503}
504
505enum scsi_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *cmd)
506{
507 struct sas_task *task = TO_SAS_TASK(cmd);
508 unsigned long flags;
509
510 if (!task) {
511 SAS_DPRINTK("command 0x%p, task 0x%p, timed out: EH_HANDLED\n",
512 cmd, task);
513 return EH_HANDLED;
514 }
515
516 spin_lock_irqsave(&task->task_state_lock, flags);
517 if (task->task_state_flags & SAS_TASK_STATE_DONE) {
518 spin_unlock_irqrestore(&task->task_state_lock, flags);
519 SAS_DPRINTK("command 0x%p, task 0x%p, timed out: EH_HANDLED\n",
520 cmd, task);
521 return EH_HANDLED;
522 }
523 task->task_state_flags |= SAS_TASK_STATE_ABORTED;
524 spin_unlock_irqrestore(&task->task_state_lock, flags);
525
526 SAS_DPRINTK("command 0x%p, task 0x%p, timed out: EH_NOT_HANDLED\n",
527 cmd, task);
528
529 return EH_NOT_HANDLED;
530}
531
532struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy)
533{
534 struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent);
535 struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost);
536 struct domain_device *found_dev = NULL;
537 int i;
538
539 spin_lock(&ha->phy_port_lock);
540 for (i = 0; i < ha->num_phys; i++) {
541 struct asd_sas_port *port = ha->sas_port[i];
542 struct domain_device *dev;
543
544 spin_lock(&port->dev_list_lock);
545 list_for_each_entry(dev, &port->dev_list, dev_list_node) {
546 if (rphy == dev->rphy) {
547 found_dev = dev;
548 spin_unlock(&port->dev_list_lock);
549 goto found;
550 }
551 }
552 spin_unlock(&port->dev_list_lock);
553 }
554 found:
555 spin_unlock(&ha->phy_port_lock);
556
557 return found_dev;
558}
559
560static inline struct domain_device *sas_find_target(struct scsi_target *starget)
561{
562 struct sas_rphy *rphy = dev_to_rphy(starget->dev.parent);
563
564 return sas_find_dev_by_rphy(rphy);
565}
566
567int sas_target_alloc(struct scsi_target *starget)
568{
569 struct domain_device *found_dev = sas_find_target(starget);
570
571 if (!found_dev)
572 return -ENODEV;
573
574 starget->hostdata = found_dev;
575 return 0;
576}
577
578#define SAS_DEF_QD 32
579#define SAS_MAX_QD 64
580
581int sas_slave_configure(struct scsi_device *scsi_dev)
582{
583 struct domain_device *dev = sdev_to_domain_dev(scsi_dev);
584 struct sas_ha_struct *sas_ha;
585
586 BUG_ON(dev->rphy->identify.device_type != SAS_END_DEVICE);
587
588 sas_ha = dev->port->ha;
589
590 sas_read_port_mode_page(scsi_dev);
591
592 if (scsi_dev->tagged_supported) {
593 scsi_set_tag_type(scsi_dev, MSG_SIMPLE_TAG);
594 scsi_activate_tcq(scsi_dev, SAS_DEF_QD);
595 } else {
596 SAS_DPRINTK("device %llx, LUN %x doesn't support "
597 "TCQ\n", SAS_ADDR(dev->sas_addr),
598 scsi_dev->lun);
599 scsi_dev->tagged_supported = 0;
600 scsi_set_tag_type(scsi_dev, 0);
601 scsi_deactivate_tcq(scsi_dev, 1);
602 }
603
604 return 0;
605}
606
607void sas_slave_destroy(struct scsi_device *scsi_dev)
608{
609}
610
611int sas_change_queue_depth(struct scsi_device *scsi_dev, int new_depth)
612{
613 int res = min(new_depth, SAS_MAX_QD);
614
615 if (scsi_dev->tagged_supported)
616 scsi_adjust_queue_depth(scsi_dev, scsi_get_tag_type(scsi_dev),
617 res);
618 else {
619 struct domain_device *dev = sdev_to_domain_dev(scsi_dev);
620 sas_printk("device %llx LUN %x queue depth changed to 1\n",
621 SAS_ADDR(dev->sas_addr),
622 scsi_dev->lun);
623 scsi_adjust_queue_depth(scsi_dev, 0, 1);
624 res = 1;
625 }
626
627 return res;
628}
629
630int sas_change_queue_type(struct scsi_device *scsi_dev, int qt)
631{
632 if (!scsi_dev->tagged_supported)
633 return 0;
634
635 scsi_deactivate_tcq(scsi_dev, 1);
636
637 scsi_set_tag_type(scsi_dev, qt);
638 scsi_activate_tcq(scsi_dev, scsi_dev->queue_depth);
639
640 return qt;
641}
642
643int sas_bios_param(struct scsi_device *scsi_dev,
644 struct block_device *bdev,
645 sector_t capacity, int *hsc)
646{
647 hsc[0] = 255;
648 hsc[1] = 63;
649 sector_div(capacity, 255*63);
650 hsc[2] = capacity;
651
652 return 0;
653}
654
655/* ---------- Task Collector Thread implementation ---------- */
656
657static void sas_queue(struct sas_ha_struct *sas_ha)
658{
659 struct scsi_core *core = &sas_ha->core;
660 unsigned long flags;
661 LIST_HEAD(q);
662 int can_queue;
663 int res;
664 struct sas_internal *i = to_sas_internal(core->shost->transportt);
665
666 spin_lock_irqsave(&core->task_queue_lock, flags);
667 while (!core->queue_thread_kill &&
668 !list_empty(&core->task_queue)) {
669
670 can_queue = sas_ha->lldd_queue_size - core->task_queue_size;
671 if (can_queue >= 0) {
672 can_queue = core->task_queue_size;
673 list_splice_init(&core->task_queue, &q);
674 } else {
675 struct list_head *a, *n;
676
677 can_queue = sas_ha->lldd_queue_size;
678 list_for_each_safe(a, n, &core->task_queue) {
679 list_move_tail(a, &q);
680 if (--can_queue == 0)
681 break;
682 }
683 can_queue = sas_ha->lldd_queue_size;
684 }
685 core->task_queue_size -= can_queue;
686 spin_unlock_irqrestore(&core->task_queue_lock, flags);
687 {
688 struct sas_task *task = list_entry(q.next,
689 struct sas_task,
690 list);
691 list_del_init(&q);
692 res = i->dft->lldd_execute_task(task, can_queue,
693 GFP_KERNEL);
694 if (unlikely(res))
695 __list_add(&q, task->list.prev, &task->list);
696 }
697 spin_lock_irqsave(&core->task_queue_lock, flags);
698 if (res) {
699 list_splice_init(&q, &core->task_queue); /*at head*/
700 core->task_queue_size += can_queue;
701 }
702 }
703 spin_unlock_irqrestore(&core->task_queue_lock, flags);
704}
705
706static DECLARE_COMPLETION(queue_th_comp);
707
708/**
709 * sas_queue_thread -- The Task Collector thread
710 * @_sas_ha: pointer to struct sas_ha
711 */
712static int sas_queue_thread(void *_sas_ha)
713{
714 struct sas_ha_struct *sas_ha = _sas_ha;
715 struct scsi_core *core = &sas_ha->core;
716
717 daemonize("sas_queue_%d", core->shost->host_no);
718 current->flags |= PF_NOFREEZE;
719
720 complete(&queue_th_comp);
721
722 while (1) {
723 down_interruptible(&core->queue_thread_sema);
724 sas_queue(sas_ha);
725 if (core->queue_thread_kill)
726 break;
727 }
728
729 complete(&queue_th_comp);
730
731 return 0;
732}
733
734int sas_init_queue(struct sas_ha_struct *sas_ha)
735{
736 int res;
737 struct scsi_core *core = &sas_ha->core;
738
739 spin_lock_init(&core->task_queue_lock);
740 core->task_queue_size = 0;
741 INIT_LIST_HEAD(&core->task_queue);
742 init_MUTEX_LOCKED(&core->queue_thread_sema);
743
744 res = kernel_thread(sas_queue_thread, sas_ha, 0);
745 if (res >= 0)
746 wait_for_completion(&queue_th_comp);
747
748 return res < 0 ? res : 0;
749}
750
751void sas_shutdown_queue(struct sas_ha_struct *sas_ha)
752{
753 unsigned long flags;
754 struct scsi_core *core = &sas_ha->core;
755 struct sas_task *task, *n;
756
757 init_completion(&queue_th_comp);
758 core->queue_thread_kill = 1;
759 up(&core->queue_thread_sema);
760 wait_for_completion(&queue_th_comp);
761
762 if (!list_empty(&core->task_queue))
763 SAS_DPRINTK("HA: %llx: scsi core task queue is NOT empty!?\n",
764 SAS_ADDR(sas_ha->sas_addr));
765
766 spin_lock_irqsave(&core->task_queue_lock, flags);
767 list_for_each_entry_safe(task, n, &core->task_queue, list) {
768 struct scsi_cmnd *cmd = task->uldd_task;
769
770 list_del_init(&task->list);
771
772 ASSIGN_SAS_TASK(cmd, NULL);
773 sas_free_task(task);
774 cmd->result = DID_ABORT << 16;
775 cmd->scsi_done(cmd);
776 }
777 spin_unlock_irqrestore(&core->task_queue_lock, flags);
778}
779
780EXPORT_SYMBOL_GPL(sas_queuecommand);
781EXPORT_SYMBOL_GPL(sas_target_alloc);
782EXPORT_SYMBOL_GPL(sas_slave_configure);
783EXPORT_SYMBOL_GPL(sas_slave_destroy);
784EXPORT_SYMBOL_GPL(sas_change_queue_depth);
785EXPORT_SYMBOL_GPL(sas_change_queue_type);
786EXPORT_SYMBOL_GPL(sas_bios_param);