brintos

brintos / linux-shallow public Read only

0
0
Text · 153.9 KiB · dec1e2d Raw
4782 lines · c
1/*2 * PMC-Sierra SPC 8001 SAS/SATA based host adapters driver3 *4 * Copyright (c) 2008-2009 USI Co., Ltd.5 * All rights reserved.6 *7 * Redistribution and use in source and binary forms, with or without8 * modification, are permitted provided that the following conditions9 * are met:10 * 1. Redistributions of source code must retain the above copyright11 *    notice, this list of conditions, and the following disclaimer,12 *    without modification.13 * 2. Redistributions in binary form must reproduce at minimum a disclaimer14 *    substantially similar to the "NO WARRANTY" disclaimer below15 *    ("Disclaimer") and any redistribution must be conditioned upon16 *    including a substantially similar Disclaimer requirement for further17 *    binary redistribution.18 * 3. Neither the names of the above-listed copyright holders nor the names19 *    of any contributors may be used to endorse or promote products derived20 *    from this software without specific prior written permission.21 *22 * Alternatively, this software may be distributed under the terms of the23 * GNU General Public License ("GPL") version 2 as published by the Free24 * Software Foundation.25 *26 * NO WARRANTY27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR30 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT31 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,35 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING36 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE37 * POSSIBILITY OF SUCH DAMAGES.38 *39 */40 #include <linux/slab.h>41 #include "pm8001_sas.h"42 #include "pm8001_hwi.h"43 #include "pm8001_chips.h"44 #include "pm8001_ctl.h"45 #include "pm80xx_tracepoints.h"46 47/**48 * read_main_config_table - read the configure table and save it.49 * @pm8001_ha: our hba card information50 */51static void read_main_config_table(struct pm8001_hba_info *pm8001_ha)52{53	void __iomem *address = pm8001_ha->main_cfg_tbl_addr;54	pm8001_ha->main_cfg_tbl.pm8001_tbl.signature	=55				pm8001_mr32(address, 0x00);56	pm8001_ha->main_cfg_tbl.pm8001_tbl.interface_rev =57				pm8001_mr32(address, 0x04);58	pm8001_ha->main_cfg_tbl.pm8001_tbl.firmware_rev	=59				pm8001_mr32(address, 0x08);60	pm8001_ha->main_cfg_tbl.pm8001_tbl.max_out_io	=61				pm8001_mr32(address, 0x0C);62	pm8001_ha->main_cfg_tbl.pm8001_tbl.max_sgl	=63				pm8001_mr32(address, 0x10);64	pm8001_ha->main_cfg_tbl.pm8001_tbl.ctrl_cap_flag =65				pm8001_mr32(address, 0x14);66	pm8001_ha->main_cfg_tbl.pm8001_tbl.gst_offset	=67				pm8001_mr32(address, 0x18);68	pm8001_ha->main_cfg_tbl.pm8001_tbl.inbound_queue_offset =69		pm8001_mr32(address, MAIN_IBQ_OFFSET);70	pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_queue_offset =71		pm8001_mr32(address, MAIN_OBQ_OFFSET);72	pm8001_ha->main_cfg_tbl.pm8001_tbl.hda_mode_flag	=73		pm8001_mr32(address, MAIN_HDA_FLAGS_OFFSET);74 75	/* read analog Setting offset from the configuration table */76	pm8001_ha->main_cfg_tbl.pm8001_tbl.anolog_setup_table_offset =77		pm8001_mr32(address, MAIN_ANALOG_SETUP_OFFSET);78 79	/* read Error Dump Offset and Length */80	pm8001_ha->main_cfg_tbl.pm8001_tbl.fatal_err_dump_offset0 =81		pm8001_mr32(address, MAIN_FATAL_ERROR_RDUMP0_OFFSET);82	pm8001_ha->main_cfg_tbl.pm8001_tbl.fatal_err_dump_length0 =83		pm8001_mr32(address, MAIN_FATAL_ERROR_RDUMP0_LENGTH);84	pm8001_ha->main_cfg_tbl.pm8001_tbl.fatal_err_dump_offset1 =85		pm8001_mr32(address, MAIN_FATAL_ERROR_RDUMP1_OFFSET);86	pm8001_ha->main_cfg_tbl.pm8001_tbl.fatal_err_dump_length1 =87		pm8001_mr32(address, MAIN_FATAL_ERROR_RDUMP1_LENGTH);88}89 90/**91 * read_general_status_table - read the general status table and save it.92 * @pm8001_ha: our hba card information93 */94static void read_general_status_table(struct pm8001_hba_info *pm8001_ha)95{96	void __iomem *address = pm8001_ha->general_stat_tbl_addr;97	pm8001_ha->gs_tbl.pm8001_tbl.gst_len_mpistate	=98				pm8001_mr32(address, 0x00);99	pm8001_ha->gs_tbl.pm8001_tbl.iq_freeze_state0	=100				pm8001_mr32(address, 0x04);101	pm8001_ha->gs_tbl.pm8001_tbl.iq_freeze_state1	=102				pm8001_mr32(address, 0x08);103	pm8001_ha->gs_tbl.pm8001_tbl.msgu_tcnt		=104				pm8001_mr32(address, 0x0C);105	pm8001_ha->gs_tbl.pm8001_tbl.iop_tcnt		=106				pm8001_mr32(address, 0x10);107	pm8001_ha->gs_tbl.pm8001_tbl.rsvd		=108				pm8001_mr32(address, 0x14);109	pm8001_ha->gs_tbl.pm8001_tbl.phy_state[0]	=110				pm8001_mr32(address, 0x18);111	pm8001_ha->gs_tbl.pm8001_tbl.phy_state[1]	=112				pm8001_mr32(address, 0x1C);113	pm8001_ha->gs_tbl.pm8001_tbl.phy_state[2]	=114				pm8001_mr32(address, 0x20);115	pm8001_ha->gs_tbl.pm8001_tbl.phy_state[3]	=116				pm8001_mr32(address, 0x24);117	pm8001_ha->gs_tbl.pm8001_tbl.phy_state[4]	=118				pm8001_mr32(address, 0x28);119	pm8001_ha->gs_tbl.pm8001_tbl.phy_state[5]	=120				pm8001_mr32(address, 0x2C);121	pm8001_ha->gs_tbl.pm8001_tbl.phy_state[6]	=122				pm8001_mr32(address, 0x30);123	pm8001_ha->gs_tbl.pm8001_tbl.phy_state[7]	=124				pm8001_mr32(address, 0x34);125	pm8001_ha->gs_tbl.pm8001_tbl.gpio_input_val	=126				pm8001_mr32(address, 0x38);127	pm8001_ha->gs_tbl.pm8001_tbl.rsvd1[0]		=128				pm8001_mr32(address, 0x3C);129	pm8001_ha->gs_tbl.pm8001_tbl.rsvd1[1]		=130				pm8001_mr32(address, 0x40);131	pm8001_ha->gs_tbl.pm8001_tbl.recover_err_info[0]	=132				pm8001_mr32(address, 0x44);133	pm8001_ha->gs_tbl.pm8001_tbl.recover_err_info[1]	=134				pm8001_mr32(address, 0x48);135	pm8001_ha->gs_tbl.pm8001_tbl.recover_err_info[2]	=136				pm8001_mr32(address, 0x4C);137	pm8001_ha->gs_tbl.pm8001_tbl.recover_err_info[3]	=138				pm8001_mr32(address, 0x50);139	pm8001_ha->gs_tbl.pm8001_tbl.recover_err_info[4]	=140				pm8001_mr32(address, 0x54);141	pm8001_ha->gs_tbl.pm8001_tbl.recover_err_info[5]	=142				pm8001_mr32(address, 0x58);143	pm8001_ha->gs_tbl.pm8001_tbl.recover_err_info[6]	=144				pm8001_mr32(address, 0x5C);145	pm8001_ha->gs_tbl.pm8001_tbl.recover_err_info[7]	=146				pm8001_mr32(address, 0x60);147}148 149/**150 * read_inbnd_queue_table - read the inbound queue table and save it.151 * @pm8001_ha: our hba card information152 */153static void read_inbnd_queue_table(struct pm8001_hba_info *pm8001_ha)154{155	int i;156	void __iomem *address = pm8001_ha->inbnd_q_tbl_addr;157	for (i = 0; i < PM8001_MAX_INB_NUM; i++) {158		u32 offset = i * 0x20;159		pm8001_ha->inbnd_q_tbl[i].pi_pci_bar =160		      get_pci_bar_index(pm8001_mr32(address, (offset + 0x14)));161		pm8001_ha->inbnd_q_tbl[i].pi_offset =162			pm8001_mr32(address, (offset + 0x18));163	}164}165 166/**167 * read_outbnd_queue_table - read the outbound queue table and save it.168 * @pm8001_ha: our hba card information169 */170static void read_outbnd_queue_table(struct pm8001_hba_info *pm8001_ha)171{172	int i;173	void __iomem *address = pm8001_ha->outbnd_q_tbl_addr;174	for (i = 0; i < PM8001_MAX_OUTB_NUM; i++) {175		u32 offset = i * 0x24;176		pm8001_ha->outbnd_q_tbl[i].ci_pci_bar =177		      get_pci_bar_index(pm8001_mr32(address, (offset + 0x14)));178		pm8001_ha->outbnd_q_tbl[i].ci_offset =179			pm8001_mr32(address, (offset + 0x18));180	}181}182 183/**184 * init_default_table_values - init the default table.185 * @pm8001_ha: our hba card information186 */187static void init_default_table_values(struct pm8001_hba_info *pm8001_ha)188{189	int i;190	u32 offsetib, offsetob;191	void __iomem *addressib = pm8001_ha->inbnd_q_tbl_addr;192	void __iomem *addressob = pm8001_ha->outbnd_q_tbl_addr;193	u32 ib_offset = pm8001_ha->ib_offset;194	u32 ob_offset = pm8001_ha->ob_offset;195	u32 ci_offset = pm8001_ha->ci_offset;196	u32 pi_offset = pm8001_ha->pi_offset;197 198	pm8001_ha->main_cfg_tbl.pm8001_tbl.inbound_q_nppd_hppd		= 0;199	pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_hw_event_pid0_3	= 0;200	pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_hw_event_pid4_7	= 0;201	pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_ncq_event_pid0_3	= 0;202	pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_ncq_event_pid4_7	= 0;203	pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_tgt_ITNexus_event_pid0_3 =204									 0;205	pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_tgt_ITNexus_event_pid4_7 =206									 0;207	pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_tgt_ssp_event_pid0_3 = 0;208	pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_tgt_ssp_event_pid4_7 = 0;209	pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_tgt_smp_event_pid0_3 = 0;210	pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_tgt_smp_event_pid4_7 = 0;211 212	pm8001_ha->main_cfg_tbl.pm8001_tbl.upper_event_log_addr		=213		pm8001_ha->memoryMap.region[AAP1].phys_addr_hi;214	pm8001_ha->main_cfg_tbl.pm8001_tbl.lower_event_log_addr		=215		pm8001_ha->memoryMap.region[AAP1].phys_addr_lo;216	pm8001_ha->main_cfg_tbl.pm8001_tbl.event_log_size		=217		PM8001_EVENT_LOG_SIZE;218	pm8001_ha->main_cfg_tbl.pm8001_tbl.event_log_option		= 0x01;219	pm8001_ha->main_cfg_tbl.pm8001_tbl.upper_iop_event_log_addr	=220		pm8001_ha->memoryMap.region[IOP].phys_addr_hi;221	pm8001_ha->main_cfg_tbl.pm8001_tbl.lower_iop_event_log_addr	=222		pm8001_ha->memoryMap.region[IOP].phys_addr_lo;223	pm8001_ha->main_cfg_tbl.pm8001_tbl.iop_event_log_size		=224		PM8001_EVENT_LOG_SIZE;225	pm8001_ha->main_cfg_tbl.pm8001_tbl.iop_event_log_option		= 0x01;226	pm8001_ha->main_cfg_tbl.pm8001_tbl.fatal_err_interrupt		= 0x01;227	for (i = 0; i < pm8001_ha->max_q_num; i++) {228		pm8001_ha->inbnd_q_tbl[i].element_pri_size_cnt	=229			PM8001_MPI_QUEUE | (pm8001_ha->iomb_size << 16) | (0x00<<30);230		pm8001_ha->inbnd_q_tbl[i].upper_base_addr	=231			pm8001_ha->memoryMap.region[ib_offset + i].phys_addr_hi;232		pm8001_ha->inbnd_q_tbl[i].lower_base_addr	=233		pm8001_ha->memoryMap.region[ib_offset + i].phys_addr_lo;234		pm8001_ha->inbnd_q_tbl[i].base_virt		=235		  (u8 *)pm8001_ha->memoryMap.region[ib_offset + i].virt_ptr;236		pm8001_ha->inbnd_q_tbl[i].total_length		=237			pm8001_ha->memoryMap.region[ib_offset + i].total_len;238		pm8001_ha->inbnd_q_tbl[i].ci_upper_base_addr	=239			pm8001_ha->memoryMap.region[ci_offset + i].phys_addr_hi;240		pm8001_ha->inbnd_q_tbl[i].ci_lower_base_addr	=241			pm8001_ha->memoryMap.region[ci_offset + i].phys_addr_lo;242		pm8001_ha->inbnd_q_tbl[i].ci_virt		=243			pm8001_ha->memoryMap.region[ci_offset + i].virt_ptr;244		pm8001_write_32(pm8001_ha->inbnd_q_tbl[i].ci_virt, 0, 0);245		offsetib = i * 0x20;246		pm8001_ha->inbnd_q_tbl[i].pi_pci_bar		=247			get_pci_bar_index(pm8001_mr32(addressib,248				(offsetib + 0x14)));249		pm8001_ha->inbnd_q_tbl[i].pi_offset		=250			pm8001_mr32(addressib, (offsetib + 0x18));251		pm8001_ha->inbnd_q_tbl[i].producer_idx		= 0;252		pm8001_ha->inbnd_q_tbl[i].consumer_index	= 0;253	}254	for (i = 0; i < pm8001_ha->max_q_num; i++) {255		pm8001_ha->outbnd_q_tbl[i].element_size_cnt	=256			PM8001_MPI_QUEUE | (pm8001_ha->iomb_size << 16) | (0x01<<30);257		pm8001_ha->outbnd_q_tbl[i].upper_base_addr	=258			pm8001_ha->memoryMap.region[ob_offset + i].phys_addr_hi;259		pm8001_ha->outbnd_q_tbl[i].lower_base_addr	=260			pm8001_ha->memoryMap.region[ob_offset + i].phys_addr_lo;261		pm8001_ha->outbnd_q_tbl[i].base_virt		=262		  (u8 *)pm8001_ha->memoryMap.region[ob_offset + i].virt_ptr;263		pm8001_ha->outbnd_q_tbl[i].total_length		=264			pm8001_ha->memoryMap.region[ob_offset + i].total_len;265		pm8001_ha->outbnd_q_tbl[i].pi_upper_base_addr	=266			pm8001_ha->memoryMap.region[pi_offset + i].phys_addr_hi;267		pm8001_ha->outbnd_q_tbl[i].pi_lower_base_addr	=268			pm8001_ha->memoryMap.region[pi_offset + i].phys_addr_lo;269		pm8001_ha->outbnd_q_tbl[i].interrup_vec_cnt_delay	=270			0 | (10 << 16) | (i << 24);271		pm8001_ha->outbnd_q_tbl[i].pi_virt		=272			pm8001_ha->memoryMap.region[pi_offset + i].virt_ptr;273		pm8001_write_32(pm8001_ha->outbnd_q_tbl[i].pi_virt, 0, 0);274		offsetob = i * 0x24;275		pm8001_ha->outbnd_q_tbl[i].ci_pci_bar		=276			get_pci_bar_index(pm8001_mr32(addressob,277			offsetob + 0x14));278		pm8001_ha->outbnd_q_tbl[i].ci_offset		=279			pm8001_mr32(addressob, (offsetob + 0x18));280		pm8001_ha->outbnd_q_tbl[i].consumer_idx		= 0;281		pm8001_ha->outbnd_q_tbl[i].producer_index	= 0;282	}283}284 285/**286 * update_main_config_table - update the main default table to the HBA.287 * @pm8001_ha: our hba card information288 */289static void update_main_config_table(struct pm8001_hba_info *pm8001_ha)290{291	void __iomem *address = pm8001_ha->main_cfg_tbl_addr;292	pm8001_mw32(address, 0x24,293		pm8001_ha->main_cfg_tbl.pm8001_tbl.inbound_q_nppd_hppd);294	pm8001_mw32(address, 0x28,295		pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_hw_event_pid0_3);296	pm8001_mw32(address, 0x2C,297		pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_hw_event_pid4_7);298	pm8001_mw32(address, 0x30,299		pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_ncq_event_pid0_3);300	pm8001_mw32(address, 0x34,301		pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_ncq_event_pid4_7);302	pm8001_mw32(address, 0x38,303		pm8001_ha->main_cfg_tbl.pm8001_tbl.304					outbound_tgt_ITNexus_event_pid0_3);305	pm8001_mw32(address, 0x3C,306		pm8001_ha->main_cfg_tbl.pm8001_tbl.307					outbound_tgt_ITNexus_event_pid4_7);308	pm8001_mw32(address, 0x40,309		pm8001_ha->main_cfg_tbl.pm8001_tbl.310					outbound_tgt_ssp_event_pid0_3);311	pm8001_mw32(address, 0x44,312		pm8001_ha->main_cfg_tbl.pm8001_tbl.313					outbound_tgt_ssp_event_pid4_7);314	pm8001_mw32(address, 0x48,315		pm8001_ha->main_cfg_tbl.pm8001_tbl.316					outbound_tgt_smp_event_pid0_3);317	pm8001_mw32(address, 0x4C,318		pm8001_ha->main_cfg_tbl.pm8001_tbl.319					outbound_tgt_smp_event_pid4_7);320	pm8001_mw32(address, 0x50,321		pm8001_ha->main_cfg_tbl.pm8001_tbl.upper_event_log_addr);322	pm8001_mw32(address, 0x54,323		pm8001_ha->main_cfg_tbl.pm8001_tbl.lower_event_log_addr);324	pm8001_mw32(address, 0x58,325		pm8001_ha->main_cfg_tbl.pm8001_tbl.event_log_size);326	pm8001_mw32(address, 0x5C,327		pm8001_ha->main_cfg_tbl.pm8001_tbl.event_log_option);328	pm8001_mw32(address, 0x60,329		pm8001_ha->main_cfg_tbl.pm8001_tbl.upper_iop_event_log_addr);330	pm8001_mw32(address, 0x64,331		pm8001_ha->main_cfg_tbl.pm8001_tbl.lower_iop_event_log_addr);332	pm8001_mw32(address, 0x68,333		pm8001_ha->main_cfg_tbl.pm8001_tbl.iop_event_log_size);334	pm8001_mw32(address, 0x6C,335		pm8001_ha->main_cfg_tbl.pm8001_tbl.iop_event_log_option);336	pm8001_mw32(address, 0x70,337		pm8001_ha->main_cfg_tbl.pm8001_tbl.fatal_err_interrupt);338}339 340/**341 * update_inbnd_queue_table - update the inbound queue table to the HBA.342 * @pm8001_ha: our hba card information343 * @number: entry in the queue344 */345static void update_inbnd_queue_table(struct pm8001_hba_info *pm8001_ha,346				     int number)347{348	void __iomem *address = pm8001_ha->inbnd_q_tbl_addr;349	u16 offset = number * 0x20;350	pm8001_mw32(address, offset + 0x00,351		pm8001_ha->inbnd_q_tbl[number].element_pri_size_cnt);352	pm8001_mw32(address, offset + 0x04,353		pm8001_ha->inbnd_q_tbl[number].upper_base_addr);354	pm8001_mw32(address, offset + 0x08,355		pm8001_ha->inbnd_q_tbl[number].lower_base_addr);356	pm8001_mw32(address, offset + 0x0C,357		pm8001_ha->inbnd_q_tbl[number].ci_upper_base_addr);358	pm8001_mw32(address, offset + 0x10,359		pm8001_ha->inbnd_q_tbl[number].ci_lower_base_addr);360}361 362/**363 * update_outbnd_queue_table - update the outbound queue table to the HBA.364 * @pm8001_ha: our hba card information365 * @number: entry in the queue366 */367static void update_outbnd_queue_table(struct pm8001_hba_info *pm8001_ha,368				      int number)369{370	void __iomem *address = pm8001_ha->outbnd_q_tbl_addr;371	u16 offset = number * 0x24;372	pm8001_mw32(address, offset + 0x00,373		pm8001_ha->outbnd_q_tbl[number].element_size_cnt);374	pm8001_mw32(address, offset + 0x04,375		pm8001_ha->outbnd_q_tbl[number].upper_base_addr);376	pm8001_mw32(address, offset + 0x08,377		pm8001_ha->outbnd_q_tbl[number].lower_base_addr);378	pm8001_mw32(address, offset + 0x0C,379		pm8001_ha->outbnd_q_tbl[number].pi_upper_base_addr);380	pm8001_mw32(address, offset + 0x10,381		pm8001_ha->outbnd_q_tbl[number].pi_lower_base_addr);382	pm8001_mw32(address, offset + 0x1C,383		pm8001_ha->outbnd_q_tbl[number].interrup_vec_cnt_delay);384}385 386/**387 * pm8001_bar4_shift - function is called to shift BAR base address388 * @pm8001_ha : our hba card information389 * @shiftValue : shifting value in memory bar.390 */391int pm8001_bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shiftValue)392{393	u32 regVal;394	unsigned long start;395 396	/* program the inbound AXI translation Lower Address */397	pm8001_cw32(pm8001_ha, 1, SPC_IBW_AXI_TRANSLATION_LOW, shiftValue);398 399	/* confirm the setting is written */400	start = jiffies + HZ; /* 1 sec */401	do {402		regVal = pm8001_cr32(pm8001_ha, 1, SPC_IBW_AXI_TRANSLATION_LOW);403	} while ((regVal != shiftValue) && time_before(jiffies, start));404 405	if (regVal != shiftValue) {406		pm8001_dbg(pm8001_ha, INIT,407			   "TIMEOUT:SPC_IBW_AXI_TRANSLATION_LOW = 0x%x\n",408			   regVal);409		return -1;410	}411	return 0;412}413 414/**415 * mpi_set_phys_g3_with_ssc416 * @pm8001_ha: our hba card information417 * @SSCbit: set SSCbit to 0 to disable all phys ssc; 1 to enable all phys ssc.418 */419static void mpi_set_phys_g3_with_ssc(struct pm8001_hba_info *pm8001_ha,420				     u32 SSCbit)421{422	u32 offset, i;423	unsigned long flags;424 425#define SAS2_SETTINGS_LOCAL_PHY_0_3_SHIFT_ADDR 0x00030000426#define SAS2_SETTINGS_LOCAL_PHY_4_7_SHIFT_ADDR 0x00040000427#define SAS2_SETTINGS_LOCAL_PHY_0_3_OFFSET 0x1074428#define SAS2_SETTINGS_LOCAL_PHY_4_7_OFFSET 0x1074429#define PHY_G3_WITHOUT_SSC_BIT_SHIFT 12430#define PHY_G3_WITH_SSC_BIT_SHIFT 13431#define SNW3_PHY_CAPABILITIES_PARITY 31432 433   /*434    * Using shifted destination address 0x3_0000:0x1074 + 0x4000*N (N=0:3)435    * Using shifted destination address 0x4_0000:0x1074 + 0x4000*(N-4) (N=4:7)436    */437	spin_lock_irqsave(&pm8001_ha->lock, flags);438	if (-1 == pm8001_bar4_shift(pm8001_ha,439				SAS2_SETTINGS_LOCAL_PHY_0_3_SHIFT_ADDR)) {440		spin_unlock_irqrestore(&pm8001_ha->lock, flags);441		return;442	}443 444	for (i = 0; i < 4; i++) {445		offset = SAS2_SETTINGS_LOCAL_PHY_0_3_OFFSET + 0x4000 * i;446		pm8001_cw32(pm8001_ha, 2, offset, 0x80001501);447	}448	/* shift membase 3 for SAS2_SETTINGS_LOCAL_PHY 4 - 7 */449	if (-1 == pm8001_bar4_shift(pm8001_ha,450				SAS2_SETTINGS_LOCAL_PHY_4_7_SHIFT_ADDR)) {451		spin_unlock_irqrestore(&pm8001_ha->lock, flags);452		return;453	}454	for (i = 4; i < 8; i++) {455		offset = SAS2_SETTINGS_LOCAL_PHY_4_7_OFFSET + 0x4000 * (i-4);456		pm8001_cw32(pm8001_ha, 2, offset, 0x80001501);457	}458	/*************************************************************459	Change the SSC upspreading value to 0x0 so that upspreading is disabled.460	Device MABC SMOD0 Controls461	Address: (via MEMBASE-III):462	Using shifted destination address 0x0_0000: with Offset 0xD8463 464	31:28 R/W Reserved Do not change465	27:24 R/W SAS_SMOD_SPRDUP 0000466	23:20 R/W SAS_SMOD_SPRDDN 0000467	19:0  R/W  Reserved Do not change468	Upon power-up this register will read as 0x8990c016,469	and I would like you to change the SAS_SMOD_SPRDUP bits to 0b0000470	so that the written value will be 0x8090c016.471	This will ensure only down-spreading SSC is enabled on the SPC.472	*************************************************************/473	pm8001_cr32(pm8001_ha, 2, 0xd8);474	pm8001_cw32(pm8001_ha, 2, 0xd8, 0x8000C016);475 476	/*set the shifted destination address to 0x0 to avoid error operation */477	pm8001_bar4_shift(pm8001_ha, 0x0);478	spin_unlock_irqrestore(&pm8001_ha->lock, flags);479	return;480}481 482/**483 * mpi_set_open_retry_interval_reg484 * @pm8001_ha: our hba card information485 * @interval: interval time for each OPEN_REJECT (RETRY). The units are in 1us.486 */487static void mpi_set_open_retry_interval_reg(struct pm8001_hba_info *pm8001_ha,488					    u32 interval)489{490	u32 offset;491	u32 value;492	u32 i;493	unsigned long flags;494 495#define OPEN_RETRY_INTERVAL_PHY_0_3_SHIFT_ADDR 0x00030000496#define OPEN_RETRY_INTERVAL_PHY_4_7_SHIFT_ADDR 0x00040000497#define OPEN_RETRY_INTERVAL_PHY_0_3_OFFSET 0x30B4498#define OPEN_RETRY_INTERVAL_PHY_4_7_OFFSET 0x30B4499#define OPEN_RETRY_INTERVAL_REG_MASK 0x0000FFFF500 501	value = interval & OPEN_RETRY_INTERVAL_REG_MASK;502	spin_lock_irqsave(&pm8001_ha->lock, flags);503	/* shift bar and set the OPEN_REJECT(RETRY) interval time of PHY 0 -3.*/504	if (-1 == pm8001_bar4_shift(pm8001_ha,505			     OPEN_RETRY_INTERVAL_PHY_0_3_SHIFT_ADDR)) {506		spin_unlock_irqrestore(&pm8001_ha->lock, flags);507		return;508	}509	for (i = 0; i < 4; i++) {510		offset = OPEN_RETRY_INTERVAL_PHY_0_3_OFFSET + 0x4000 * i;511		pm8001_cw32(pm8001_ha, 2, offset, value);512	}513 514	if (-1 == pm8001_bar4_shift(pm8001_ha,515			     OPEN_RETRY_INTERVAL_PHY_4_7_SHIFT_ADDR)) {516		spin_unlock_irqrestore(&pm8001_ha->lock, flags);517		return;518	}519	for (i = 4; i < 8; i++) {520		offset = OPEN_RETRY_INTERVAL_PHY_4_7_OFFSET + 0x4000 * (i-4);521		pm8001_cw32(pm8001_ha, 2, offset, value);522	}523	/*set the shifted destination address to 0x0 to avoid error operation */524	pm8001_bar4_shift(pm8001_ha, 0x0);525	spin_unlock_irqrestore(&pm8001_ha->lock, flags);526	return;527}528 529/**530 * mpi_init_check - check firmware initialization status.531 * @pm8001_ha: our hba card information532 */533static int mpi_init_check(struct pm8001_hba_info *pm8001_ha)534{535	u32 max_wait_count;536	u32 value;537	u32 gst_len_mpistate;538	/* Write bit0=1 to Inbound DoorBell Register to tell the SPC FW the539	table is updated */540	pm8001_cw32(pm8001_ha, 0, MSGU_IBDB_SET, SPC_MSGU_CFG_TABLE_UPDATE);541	/* wait until Inbound DoorBell Clear Register toggled */542	max_wait_count = 1 * 1000 * 1000;/* 1 sec */543	do {544		udelay(1);545		value = pm8001_cr32(pm8001_ha, 0, MSGU_IBDB_SET);546		value &= SPC_MSGU_CFG_TABLE_UPDATE;547	} while ((value != 0) && (--max_wait_count));548 549	if (!max_wait_count)550		return -1;551	/* check the MPI-State for initialization */552	gst_len_mpistate =553		pm8001_mr32(pm8001_ha->general_stat_tbl_addr,554		GST_GSTLEN_MPIS_OFFSET);555	if (GST_MPI_STATE_INIT != (gst_len_mpistate & GST_MPI_STATE_MASK))556		return -1;557	/* check MPI Initialization error */558	gst_len_mpistate = gst_len_mpistate >> 16;559	if (0x0000 != gst_len_mpistate)560		return -1;561	return 0;562}563 564/**565 * check_fw_ready - The LLDD check if the FW is ready, if not, return error.566 * @pm8001_ha: our hba card information567 */568static int check_fw_ready(struct pm8001_hba_info *pm8001_ha)569{570	u32 value, value1;571	u32 max_wait_count;572	/* check error state */573	value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1);574	value1 = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_2);575	/* check AAP error */576	if (SCRATCH_PAD1_ERR == (value & SCRATCH_PAD_STATE_MASK)) {577		/* error state */578		value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_0);579		return -1;580	}581 582	/* check IOP error */583	if (SCRATCH_PAD2_ERR == (value1 & SCRATCH_PAD_STATE_MASK)) {584		/* error state */585		value1 = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_3);586		return -1;587	}588 589	/* bit 4-31 of scratch pad1 should be zeros if it is not590	in error state*/591	if (value & SCRATCH_PAD1_STATE_MASK) {592		/* error case */593		pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_0);594		return -1;595	}596 597	/* bit 2, 4-31 of scratch pad2 should be zeros if it is not598	in error state */599	if (value1 & SCRATCH_PAD2_STATE_MASK) {600		/* error case */601		return -1;602	}603 604	max_wait_count = 1 * 1000 * 1000;/* 1 sec timeout */605 606	/* wait until scratch pad 1 and 2 registers in ready state  */607	do {608		udelay(1);609		value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1)610			& SCRATCH_PAD1_RDY;611		value1 = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_2)612			& SCRATCH_PAD2_RDY;613		if ((--max_wait_count) == 0)614			return -1;615	} while ((value != SCRATCH_PAD1_RDY) || (value1 != SCRATCH_PAD2_RDY));616	return 0;617}618 619static void init_pci_device_addresses(struct pm8001_hba_info *pm8001_ha)620{621	void __iomem *base_addr;622	u32	value;623	u32	offset;624	u32	pcibar;625	u32	pcilogic;626 627	value = pm8001_cr32(pm8001_ha, 0, 0x44);628	offset = value & 0x03FFFFFF;629	pm8001_dbg(pm8001_ha, INIT, "Scratchpad 0 Offset: %x\n", offset);630	pcilogic = (value & 0xFC000000) >> 26;631	pcibar = get_pci_bar_index(pcilogic);632	pm8001_dbg(pm8001_ha, INIT, "Scratchpad 0 PCI BAR: %d\n", pcibar);633	pm8001_ha->main_cfg_tbl_addr = base_addr =634		pm8001_ha->io_mem[pcibar].memvirtaddr + offset;635	pm8001_ha->general_stat_tbl_addr =636		base_addr + pm8001_cr32(pm8001_ha, pcibar, offset + 0x18);637	pm8001_ha->inbnd_q_tbl_addr =638		base_addr + pm8001_cr32(pm8001_ha, pcibar, offset + 0x1C);639	pm8001_ha->outbnd_q_tbl_addr =640		base_addr + pm8001_cr32(pm8001_ha, pcibar, offset + 0x20);641}642 643/**644 * pm8001_chip_init - the main init function that initialize whole PM8001 chip.645 * @pm8001_ha: our hba card information646 */647static int pm8001_chip_init(struct pm8001_hba_info *pm8001_ha)648{649	u32 i = 0;650	u16 deviceid;651	pci_read_config_word(pm8001_ha->pdev, PCI_DEVICE_ID, &deviceid);652	/* 8081 controllers need BAR shift to access MPI space653	* as this is shared with BIOS data */654	if (deviceid == 0x8081 || deviceid == 0x0042) {655		if (-1 == pm8001_bar4_shift(pm8001_ha, GSM_SM_BASE)) {656			pm8001_dbg(pm8001_ha, FAIL,657				   "Shift Bar4 to 0x%x failed\n",658				   GSM_SM_BASE);659			return -1;660		}661	}662	/* check the firmware status */663	if (-1 == check_fw_ready(pm8001_ha)) {664		pm8001_dbg(pm8001_ha, FAIL, "Firmware is not ready!\n");665		return -EBUSY;666	}667 668	/* Initialize pci space address eg: mpi offset */669	init_pci_device_addresses(pm8001_ha);670	init_default_table_values(pm8001_ha);671	read_main_config_table(pm8001_ha);672	read_general_status_table(pm8001_ha);673	read_inbnd_queue_table(pm8001_ha);674	read_outbnd_queue_table(pm8001_ha);675	/* update main config table ,inbound table and outbound table */676	update_main_config_table(pm8001_ha);677	for (i = 0; i < pm8001_ha->max_q_num; i++)678		update_inbnd_queue_table(pm8001_ha, i);679	for (i = 0; i < pm8001_ha->max_q_num; i++)680		update_outbnd_queue_table(pm8001_ha, i);681	/* 8081 controller donot require these operations */682	if (deviceid != 0x8081 && deviceid != 0x0042) {683		mpi_set_phys_g3_with_ssc(pm8001_ha, 0);684		/* 7->130ms, 34->500ms, 119->1.5s */685		mpi_set_open_retry_interval_reg(pm8001_ha, 119);686	}687	/* notify firmware update finished and check initialization status */688	if (0 == mpi_init_check(pm8001_ha)) {689		pm8001_dbg(pm8001_ha, INIT, "MPI initialize successful!\n");690	} else691		return -EBUSY;692	/*This register is a 16-bit timer with a resolution of 1us. This is the693	timer used for interrupt delay/coalescing in the PCIe Application Layer.694	Zero is not a valid value. A value of 1 in the register will cause the695	interrupts to be normal. A value greater than 1 will cause coalescing696	delays.*/697	pm8001_cw32(pm8001_ha, 1, 0x0033c0, 0x1);698	pm8001_cw32(pm8001_ha, 1, 0x0033c4, 0x0);699	return 0;700}701 702static void pm8001_chip_post_init(struct pm8001_hba_info *pm8001_ha)703{704}705 706static int mpi_uninit_check(struct pm8001_hba_info *pm8001_ha)707{708	u32 max_wait_count;709	u32 value;710	u32 gst_len_mpistate;711	u16 deviceid;712	pci_read_config_word(pm8001_ha->pdev, PCI_DEVICE_ID, &deviceid);713	if (deviceid == 0x8081 || deviceid == 0x0042) {714		if (-1 == pm8001_bar4_shift(pm8001_ha, GSM_SM_BASE)) {715			pm8001_dbg(pm8001_ha, FAIL,716				   "Shift Bar4 to 0x%x failed\n",717				   GSM_SM_BASE);718			return -1;719		}720	}721	init_pci_device_addresses(pm8001_ha);722	/* Write bit1=1 to Inbound DoorBell Register to tell the SPC FW the723	table is stop */724	pm8001_cw32(pm8001_ha, 0, MSGU_IBDB_SET, SPC_MSGU_CFG_TABLE_RESET);725 726	/* wait until Inbound DoorBell Clear Register toggled */727	max_wait_count = 1 * 1000 * 1000;/* 1 sec */728	do {729		udelay(1);730		value = pm8001_cr32(pm8001_ha, 0, MSGU_IBDB_SET);731		value &= SPC_MSGU_CFG_TABLE_RESET;732	} while ((value != 0) && (--max_wait_count));733 734	if (!max_wait_count) {735		pm8001_dbg(pm8001_ha, FAIL, "TIMEOUT:IBDB value/=0x%x\n",736			   value);737		return -1;738	}739 740	/* check the MPI-State for termination in progress */741	/* wait until Inbound DoorBell Clear Register toggled */742	max_wait_count = 1 * 1000 * 1000;  /* 1 sec */743	do {744		udelay(1);745		gst_len_mpistate =746			pm8001_mr32(pm8001_ha->general_stat_tbl_addr,747			GST_GSTLEN_MPIS_OFFSET);748		if (GST_MPI_STATE_UNINIT ==749			(gst_len_mpistate & GST_MPI_STATE_MASK))750			break;751	} while (--max_wait_count);752	if (!max_wait_count) {753		pm8001_dbg(pm8001_ha, FAIL, " TIME OUT MPI State = 0x%x\n",754			   gst_len_mpistate & GST_MPI_STATE_MASK);755		return -1;756	}757	return 0;758}759 760/**761 * soft_reset_ready_check - Function to check FW is ready for soft reset.762 * @pm8001_ha: our hba card information763 */764static u32 soft_reset_ready_check(struct pm8001_hba_info *pm8001_ha)765{766	u32 regVal, regVal1, regVal2;767	if (mpi_uninit_check(pm8001_ha) != 0) {768		pm8001_dbg(pm8001_ha, FAIL, "MPI state is not ready\n");769		return -1;770	}771	/* read the scratch pad 2 register bit 2 */772	regVal = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_2)773		& SCRATCH_PAD2_FWRDY_RST;774	if (regVal == SCRATCH_PAD2_FWRDY_RST) {775		pm8001_dbg(pm8001_ha, INIT, "Firmware is ready for reset.\n");776	} else {777		unsigned long flags;778		/* Trigger NMI twice via RB6 */779		spin_lock_irqsave(&pm8001_ha->lock, flags);780		if (-1 == pm8001_bar4_shift(pm8001_ha, RB6_ACCESS_REG)) {781			spin_unlock_irqrestore(&pm8001_ha->lock, flags);782			pm8001_dbg(pm8001_ha, FAIL,783				   "Shift Bar4 to 0x%x failed\n",784				   RB6_ACCESS_REG);785			return -1;786		}787		pm8001_cw32(pm8001_ha, 2, SPC_RB6_OFFSET,788			RB6_MAGIC_NUMBER_RST);789		pm8001_cw32(pm8001_ha, 2, SPC_RB6_OFFSET, RB6_MAGIC_NUMBER_RST);790		/* wait for 100 ms */791		mdelay(100);792		regVal = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_2) &793			SCRATCH_PAD2_FWRDY_RST;794		if (regVal != SCRATCH_PAD2_FWRDY_RST) {795			regVal1 = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1);796			regVal2 = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_2);797			pm8001_dbg(pm8001_ha, FAIL, "TIMEOUT:MSGU_SCRATCH_PAD1=0x%x, MSGU_SCRATCH_PAD2=0x%x\n",798				   regVal1, regVal2);799			pm8001_dbg(pm8001_ha, FAIL,800				   "SCRATCH_PAD0 value = 0x%x\n",801				   pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_0));802			pm8001_dbg(pm8001_ha, FAIL,803				   "SCRATCH_PAD3 value = 0x%x\n",804				   pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_3));805			spin_unlock_irqrestore(&pm8001_ha->lock, flags);806			return -1;807		}808		spin_unlock_irqrestore(&pm8001_ha->lock, flags);809	}810	return 0;811}812 813/**814 * pm8001_chip_soft_rst - soft reset the PM8001 chip, so that the clear all815 * the FW register status to the originated status.816 * @pm8001_ha: our hba card information817 */818static int819pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha)820{821	u32	regVal, toggleVal;822	u32	max_wait_count;823	u32	regVal1, regVal2, regVal3;824	u32	signature = 0x252acbcd; /* for host scratch pad0 */825	unsigned long flags;826 827	/* step1: Check FW is ready for soft reset */828	if (soft_reset_ready_check(pm8001_ha) != 0) {829		pm8001_dbg(pm8001_ha, FAIL, "FW is not ready\n");830		return -1;831	}832 833	/* step 2: clear NMI status register on AAP1 and IOP, write the same834	value to clear */835	/* map 0x60000 to BAR4(0x20), BAR2(win) */836	spin_lock_irqsave(&pm8001_ha->lock, flags);837	if (-1 == pm8001_bar4_shift(pm8001_ha, MBIC_AAP1_ADDR_BASE)) {838		spin_unlock_irqrestore(&pm8001_ha->lock, flags);839		pm8001_dbg(pm8001_ha, FAIL, "Shift Bar4 to 0x%x failed\n",840			   MBIC_AAP1_ADDR_BASE);841		return -1;842	}843	regVal = pm8001_cr32(pm8001_ha, 2, MBIC_NMI_ENABLE_VPE0_IOP);844	pm8001_dbg(pm8001_ha, INIT, "MBIC - NMI Enable VPE0 (IOP)= 0x%x\n",845		   regVal);846	pm8001_cw32(pm8001_ha, 2, MBIC_NMI_ENABLE_VPE0_IOP, 0x0);847	/* map 0x70000 to BAR4(0x20), BAR2(win) */848	if (-1 == pm8001_bar4_shift(pm8001_ha, MBIC_IOP_ADDR_BASE)) {849		spin_unlock_irqrestore(&pm8001_ha->lock, flags);850		pm8001_dbg(pm8001_ha, FAIL, "Shift Bar4 to 0x%x failed\n",851			   MBIC_IOP_ADDR_BASE);852		return -1;853	}854	regVal = pm8001_cr32(pm8001_ha, 2, MBIC_NMI_ENABLE_VPE0_AAP1);855	pm8001_dbg(pm8001_ha, INIT, "MBIC - NMI Enable VPE0 (AAP1)= 0x%x\n",856		   regVal);857	pm8001_cw32(pm8001_ha, 2, MBIC_NMI_ENABLE_VPE0_AAP1, 0x0);858 859	regVal = pm8001_cr32(pm8001_ha, 1, PCIE_EVENT_INTERRUPT_ENABLE);860	pm8001_dbg(pm8001_ha, INIT, "PCIE -Event Interrupt Enable = 0x%x\n",861		   regVal);862	pm8001_cw32(pm8001_ha, 1, PCIE_EVENT_INTERRUPT_ENABLE, 0x0);863 864	regVal = pm8001_cr32(pm8001_ha, 1, PCIE_EVENT_INTERRUPT);865	pm8001_dbg(pm8001_ha, INIT, "PCIE - Event Interrupt  = 0x%x\n",866		   regVal);867	pm8001_cw32(pm8001_ha, 1, PCIE_EVENT_INTERRUPT, regVal);868 869	regVal = pm8001_cr32(pm8001_ha, 1, PCIE_ERROR_INTERRUPT_ENABLE);870	pm8001_dbg(pm8001_ha, INIT, "PCIE -Error Interrupt Enable = 0x%x\n",871		   regVal);872	pm8001_cw32(pm8001_ha, 1, PCIE_ERROR_INTERRUPT_ENABLE, 0x0);873 874	regVal = pm8001_cr32(pm8001_ha, 1, PCIE_ERROR_INTERRUPT);875	pm8001_dbg(pm8001_ha, INIT, "PCIE - Error Interrupt = 0x%x\n", regVal);876	pm8001_cw32(pm8001_ha, 1, PCIE_ERROR_INTERRUPT, regVal);877 878	/* read the scratch pad 1 register bit 2 */879	regVal = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1)880		& SCRATCH_PAD1_RST;881	toggleVal = regVal ^ SCRATCH_PAD1_RST;882 883	/* set signature in host scratch pad0 register to tell SPC that the884	host performs the soft reset */885	pm8001_cw32(pm8001_ha, 0, MSGU_HOST_SCRATCH_PAD_0, signature);886 887	/* read required registers for confirmming */888	/* map 0x0700000 to BAR4(0x20), BAR2(win) */889	if (-1 == pm8001_bar4_shift(pm8001_ha, GSM_ADDR_BASE)) {890		spin_unlock_irqrestore(&pm8001_ha->lock, flags);891		pm8001_dbg(pm8001_ha, FAIL, "Shift Bar4 to 0x%x failed\n",892			   GSM_ADDR_BASE);893		return -1;894	}895	pm8001_dbg(pm8001_ha, INIT,896		   "GSM 0x0(0x00007b88)-GSM Configuration and Reset = 0x%x\n",897		   pm8001_cr32(pm8001_ha, 2, GSM_CONFIG_RESET));898 899	/* step 3: host read GSM Configuration and Reset register */900	regVal = pm8001_cr32(pm8001_ha, 2, GSM_CONFIG_RESET);901	/* Put those bits to low */902	/* GSM XCBI offset = 0x70 0000903	0x00 Bit 13 COM_SLV_SW_RSTB 1904	0x00 Bit 12 QSSP_SW_RSTB 1905	0x00 Bit 11 RAAE_SW_RSTB 1906	0x00 Bit 9 RB_1_SW_RSTB 1907	0x00 Bit 8 SM_SW_RSTB 1908	*/909	regVal &= ~(0x00003b00);910	/* host write GSM Configuration and Reset register */911	pm8001_cw32(pm8001_ha, 2, GSM_CONFIG_RESET, regVal);912	pm8001_dbg(pm8001_ha, INIT,913		   "GSM 0x0 (0x00007b88 ==> 0x00004088) - GSM Configuration and Reset is set to = 0x%x\n",914		   pm8001_cr32(pm8001_ha, 2, GSM_CONFIG_RESET));915 916	/* step 4: */917	/* disable GSM - Read Address Parity Check */918	regVal1 = pm8001_cr32(pm8001_ha, 2, GSM_READ_ADDR_PARITY_CHECK);919	pm8001_dbg(pm8001_ha, INIT,920		   "GSM 0x700038 - Read Address Parity Check Enable = 0x%x\n",921		   regVal1);922	pm8001_cw32(pm8001_ha, 2, GSM_READ_ADDR_PARITY_CHECK, 0x0);923	pm8001_dbg(pm8001_ha, INIT,924		   "GSM 0x700038 - Read Address Parity Check Enable is set to = 0x%x\n",925		   pm8001_cr32(pm8001_ha, 2, GSM_READ_ADDR_PARITY_CHECK));926 927	/* disable GSM - Write Address Parity Check */928	regVal2 = pm8001_cr32(pm8001_ha, 2, GSM_WRITE_ADDR_PARITY_CHECK);929	pm8001_dbg(pm8001_ha, INIT,930		   "GSM 0x700040 - Write Address Parity Check Enable = 0x%x\n",931		   regVal2);932	pm8001_cw32(pm8001_ha, 2, GSM_WRITE_ADDR_PARITY_CHECK, 0x0);933	pm8001_dbg(pm8001_ha, INIT,934		   "GSM 0x700040 - Write Address Parity Check Enable is set to = 0x%x\n",935		   pm8001_cr32(pm8001_ha, 2, GSM_WRITE_ADDR_PARITY_CHECK));936 937	/* disable GSM - Write Data Parity Check */938	regVal3 = pm8001_cr32(pm8001_ha, 2, GSM_WRITE_DATA_PARITY_CHECK);939	pm8001_dbg(pm8001_ha, INIT, "GSM 0x300048 - Write Data Parity Check Enable = 0x%x\n",940		   regVal3);941	pm8001_cw32(pm8001_ha, 2, GSM_WRITE_DATA_PARITY_CHECK, 0x0);942	pm8001_dbg(pm8001_ha, INIT,943		   "GSM 0x300048 - Write Data Parity Check Enable is set to = 0x%x\n",944		   pm8001_cr32(pm8001_ha, 2, GSM_WRITE_DATA_PARITY_CHECK));945 946	/* step 5: delay 10 usec */947	udelay(10);948	/* step 5-b: set GPIO-0 output control to tristate anyway */949	if (-1 == pm8001_bar4_shift(pm8001_ha, GPIO_ADDR_BASE)) {950		spin_unlock_irqrestore(&pm8001_ha->lock, flags);951		pm8001_dbg(pm8001_ha, INIT, "Shift Bar4 to 0x%x failed\n",952			   GPIO_ADDR_BASE);953		return -1;954	}955	regVal = pm8001_cr32(pm8001_ha, 2, GPIO_GPIO_0_0UTPUT_CTL_OFFSET);956	pm8001_dbg(pm8001_ha, INIT, "GPIO Output Control Register: = 0x%x\n",957		   regVal);958	/* set GPIO-0 output control to tri-state */959	regVal &= 0xFFFFFFFC;960	pm8001_cw32(pm8001_ha, 2, GPIO_GPIO_0_0UTPUT_CTL_OFFSET, regVal);961 962	/* Step 6: Reset the IOP and AAP1 */963	/* map 0x00000 to BAR4(0x20), BAR2(win) */964	if (-1 == pm8001_bar4_shift(pm8001_ha, SPC_TOP_LEVEL_ADDR_BASE)) {965		spin_unlock_irqrestore(&pm8001_ha->lock, flags);966		pm8001_dbg(pm8001_ha, FAIL, "SPC Shift Bar4 to 0x%x failed\n",967			   SPC_TOP_LEVEL_ADDR_BASE);968		return -1;969	}970	regVal = pm8001_cr32(pm8001_ha, 2, SPC_REG_RESET);971	pm8001_dbg(pm8001_ha, INIT, "Top Register before resetting IOP/AAP1:= 0x%x\n",972		   regVal);973	regVal &= ~(SPC_REG_RESET_PCS_IOP_SS | SPC_REG_RESET_PCS_AAP1_SS);974	pm8001_cw32(pm8001_ha, 2, SPC_REG_RESET, regVal);975 976	/* step 7: Reset the BDMA/OSSP */977	regVal = pm8001_cr32(pm8001_ha, 2, SPC_REG_RESET);978	pm8001_dbg(pm8001_ha, INIT, "Top Register before resetting BDMA/OSSP: = 0x%x\n",979		   regVal);980	regVal &= ~(SPC_REG_RESET_BDMA_CORE | SPC_REG_RESET_OSSP);981	pm8001_cw32(pm8001_ha, 2, SPC_REG_RESET, regVal);982 983	/* step 8: delay 10 usec */984	udelay(10);985 986	/* step 9: bring the BDMA and OSSP out of reset */987	regVal = pm8001_cr32(pm8001_ha, 2, SPC_REG_RESET);988	pm8001_dbg(pm8001_ha, INIT,989		   "Top Register before bringing up BDMA/OSSP:= 0x%x\n",990		   regVal);991	regVal |= (SPC_REG_RESET_BDMA_CORE | SPC_REG_RESET_OSSP);992	pm8001_cw32(pm8001_ha, 2, SPC_REG_RESET, regVal);993 994	/* step 10: delay 10 usec */995	udelay(10);996 997	/* step 11: reads and sets the GSM Configuration and Reset Register */998	/* map 0x0700000 to BAR4(0x20), BAR2(win) */999	if (-1 == pm8001_bar4_shift(pm8001_ha, GSM_ADDR_BASE)) {1000		spin_unlock_irqrestore(&pm8001_ha->lock, flags);1001		pm8001_dbg(pm8001_ha, FAIL, "SPC Shift Bar4 to 0x%x failed\n",1002			   GSM_ADDR_BASE);1003		return -1;1004	}1005	pm8001_dbg(pm8001_ha, INIT,1006		   "GSM 0x0 (0x00007b88)-GSM Configuration and Reset = 0x%x\n",1007		   pm8001_cr32(pm8001_ha, 2, GSM_CONFIG_RESET));1008	regVal = pm8001_cr32(pm8001_ha, 2, GSM_CONFIG_RESET);1009	/* Put those bits to high */1010	/* GSM XCBI offset = 0x70 00001011	0x00 Bit 13 COM_SLV_SW_RSTB 11012	0x00 Bit 12 QSSP_SW_RSTB 11013	0x00 Bit 11 RAAE_SW_RSTB 11014	0x00 Bit 9   RB_1_SW_RSTB 11015	0x00 Bit 8   SM_SW_RSTB 11016	*/1017	regVal |= (GSM_CONFIG_RESET_VALUE);1018	pm8001_cw32(pm8001_ha, 2, GSM_CONFIG_RESET, regVal);1019	pm8001_dbg(pm8001_ha, INIT, "GSM (0x00004088 ==> 0x00007b88) - GSM Configuration and Reset is set to = 0x%x\n",1020		   pm8001_cr32(pm8001_ha, 2, GSM_CONFIG_RESET));1021 1022	/* step 12: Restore GSM - Read Address Parity Check */1023	regVal = pm8001_cr32(pm8001_ha, 2, GSM_READ_ADDR_PARITY_CHECK);1024	/* just for debugging */1025	pm8001_dbg(pm8001_ha, INIT,1026		   "GSM 0x700038 - Read Address Parity Check Enable = 0x%x\n",1027		   regVal);1028	pm8001_cw32(pm8001_ha, 2, GSM_READ_ADDR_PARITY_CHECK, regVal1);1029	pm8001_dbg(pm8001_ha, INIT, "GSM 0x700038 - Read Address Parity Check Enable is set to = 0x%x\n",1030		   pm8001_cr32(pm8001_ha, 2, GSM_READ_ADDR_PARITY_CHECK));1031	/* Restore GSM - Write Address Parity Check */1032	regVal = pm8001_cr32(pm8001_ha, 2, GSM_WRITE_ADDR_PARITY_CHECK);1033	pm8001_cw32(pm8001_ha, 2, GSM_WRITE_ADDR_PARITY_CHECK, regVal2);1034	pm8001_dbg(pm8001_ha, INIT,1035		   "GSM 0x700040 - Write Address Parity Check Enable is set to = 0x%x\n",1036		   pm8001_cr32(pm8001_ha, 2, GSM_WRITE_ADDR_PARITY_CHECK));1037	/* Restore GSM - Write Data Parity Check */1038	regVal = pm8001_cr32(pm8001_ha, 2, GSM_WRITE_DATA_PARITY_CHECK);1039	pm8001_cw32(pm8001_ha, 2, GSM_WRITE_DATA_PARITY_CHECK, regVal3);1040	pm8001_dbg(pm8001_ha, INIT,1041		   "GSM 0x700048 - Write Data Parity Check Enable is set to = 0x%x\n",1042		   pm8001_cr32(pm8001_ha, 2, GSM_WRITE_DATA_PARITY_CHECK));1043 1044	/* step 13: bring the IOP and AAP1 out of reset */1045	/* map 0x00000 to BAR4(0x20), BAR2(win) */1046	if (-1 == pm8001_bar4_shift(pm8001_ha, SPC_TOP_LEVEL_ADDR_BASE)) {1047		spin_unlock_irqrestore(&pm8001_ha->lock, flags);1048		pm8001_dbg(pm8001_ha, FAIL, "Shift Bar4 to 0x%x failed\n",1049			   SPC_TOP_LEVEL_ADDR_BASE);1050		return -1;1051	}1052	regVal = pm8001_cr32(pm8001_ha, 2, SPC_REG_RESET);1053	regVal |= (SPC_REG_RESET_PCS_IOP_SS | SPC_REG_RESET_PCS_AAP1_SS);1054	pm8001_cw32(pm8001_ha, 2, SPC_REG_RESET, regVal);1055 1056	/* step 14: delay 10 usec - Normal Mode */1057	udelay(10);1058	/* check Soft Reset Normal mode or Soft Reset HDA mode */1059	if (signature == SPC_SOFT_RESET_SIGNATURE) {1060		/* step 15 (Normal Mode): wait until scratch pad1 register1061		bit 2 toggled */1062		max_wait_count = 2 * 1000 * 1000;/* 2 sec */1063		do {1064			udelay(1);1065			regVal = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1) &1066				SCRATCH_PAD1_RST;1067		} while ((regVal != toggleVal) && (--max_wait_count));1068 1069		if (!max_wait_count) {1070			regVal = pm8001_cr32(pm8001_ha, 0,1071				MSGU_SCRATCH_PAD_1);1072			pm8001_dbg(pm8001_ha, FAIL, "TIMEOUT : ToggleVal 0x%x,MSGU_SCRATCH_PAD1 = 0x%x\n",1073				   toggleVal, regVal);1074			pm8001_dbg(pm8001_ha, FAIL,1075				   "SCRATCH_PAD0 value = 0x%x\n",1076				   pm8001_cr32(pm8001_ha, 0,1077					       MSGU_SCRATCH_PAD_0));1078			pm8001_dbg(pm8001_ha, FAIL,1079				   "SCRATCH_PAD2 value = 0x%x\n",1080				   pm8001_cr32(pm8001_ha, 0,1081					       MSGU_SCRATCH_PAD_2));1082			pm8001_dbg(pm8001_ha, FAIL,1083				   "SCRATCH_PAD3 value = 0x%x\n",1084				   pm8001_cr32(pm8001_ha, 0,1085					       MSGU_SCRATCH_PAD_3));1086			spin_unlock_irqrestore(&pm8001_ha->lock, flags);1087			return -1;1088		}1089 1090		/* step 16 (Normal) - Clear ODMR and ODCR */1091		pm8001_cw32(pm8001_ha, 0, MSGU_ODCR, ODCR_CLEAR_ALL);1092		pm8001_cw32(pm8001_ha, 0, MSGU_ODMR, ODMR_CLEAR_ALL);1093 1094		/* step 17 (Normal Mode): wait for the FW and IOP to get1095		ready - 1 sec timeout */1096		/* Wait for the SPC Configuration Table to be ready */1097		if (check_fw_ready(pm8001_ha) == -1) {1098			regVal = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1);1099			/* return error if MPI Configuration Table not ready */1100			pm8001_dbg(pm8001_ha, INIT,1101				   "FW not ready SCRATCH_PAD1 = 0x%x\n",1102				   regVal);1103			regVal = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_2);1104			/* return error if MPI Configuration Table not ready */1105			pm8001_dbg(pm8001_ha, INIT,1106				   "FW not ready SCRATCH_PAD2 = 0x%x\n",1107				   regVal);1108			pm8001_dbg(pm8001_ha, INIT,1109				   "SCRATCH_PAD0 value = 0x%x\n",1110				   pm8001_cr32(pm8001_ha, 0,1111					       MSGU_SCRATCH_PAD_0));1112			pm8001_dbg(pm8001_ha, INIT,1113				   "SCRATCH_PAD3 value = 0x%x\n",1114				   pm8001_cr32(pm8001_ha, 0,1115					       MSGU_SCRATCH_PAD_3));1116			spin_unlock_irqrestore(&pm8001_ha->lock, flags);1117			return -1;1118		}1119	}1120	pm8001_bar4_shift(pm8001_ha, 0);1121	spin_unlock_irqrestore(&pm8001_ha->lock, flags);1122 1123	pm8001_dbg(pm8001_ha, INIT, "SPC soft reset Complete\n");1124	return 0;1125}1126 1127static void pm8001_hw_chip_rst(struct pm8001_hba_info *pm8001_ha)1128{1129	u32 i;1130	u32 regVal;1131	pm8001_dbg(pm8001_ha, INIT, "chip reset start\n");1132 1133	/* do SPC chip reset. */1134	regVal = pm8001_cr32(pm8001_ha, 1, SPC_REG_RESET);1135	regVal &= ~(SPC_REG_RESET_DEVICE);1136	pm8001_cw32(pm8001_ha, 1, SPC_REG_RESET, regVal);1137 1138	/* delay 10 usec */1139	udelay(10);1140 1141	/* bring chip reset out of reset */1142	regVal = pm8001_cr32(pm8001_ha, 1, SPC_REG_RESET);1143	regVal |= SPC_REG_RESET_DEVICE;1144	pm8001_cw32(pm8001_ha, 1, SPC_REG_RESET, regVal);1145 1146	/* delay 10 usec */1147	udelay(10);1148 1149	/* wait for 20 msec until the firmware gets reloaded */1150	i = 20;1151	do {1152		mdelay(1);1153	} while ((--i) != 0);1154 1155	pm8001_dbg(pm8001_ha, INIT, "chip reset finished\n");1156}1157 1158/**1159 * pm8001_chip_iounmap - which mapped when initialized.1160 * @pm8001_ha: our hba card information1161 */1162void pm8001_chip_iounmap(struct pm8001_hba_info *pm8001_ha)1163{1164	s8 bar, logical = 0;1165	for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {1166		/*1167		** logical BARs for SPC:1168		** bar 0 and 1 - logical BAR01169		** bar 2 and 3 - logical BAR11170		** bar4 - logical BAR21171		** bar5 - logical BAR31172		** Skip the appropriate assignments:1173		*/1174		if ((bar == 1) || (bar == 3))1175			continue;1176		if (pm8001_ha->io_mem[logical].memvirtaddr) {1177			iounmap(pm8001_ha->io_mem[logical].memvirtaddr);1178			logical++;1179		}1180	}1181}1182 1183/**1184 * pm8001_chip_interrupt_enable - enable PM8001 chip interrupt1185 * @pm8001_ha: our hba card information1186 * @vec: unused1187 */1188static void1189pm8001_chip_interrupt_enable(struct pm8001_hba_info *pm8001_ha, u8 vec)1190{1191	if (pm8001_ha->use_msix) {1192		pm8001_cw32(pm8001_ha, 0, MSIX_TABLE_BASE,1193			    MSIX_INTERRUPT_ENABLE);1194		pm8001_cw32(pm8001_ha, 0,  MSGU_ODCR, 1);1195	} else {1196		pm8001_cw32(pm8001_ha, 0, MSGU_ODMR, ODMR_CLEAR_ALL);1197		pm8001_cw32(pm8001_ha, 0, MSGU_ODCR, ODCR_CLEAR_ALL);1198	}1199}1200 1201/**1202 * pm8001_chip_interrupt_disable - disable PM8001 chip interrupt1203 * @pm8001_ha: our hba card information1204 * @vec: unused1205 */1206static void1207pm8001_chip_interrupt_disable(struct pm8001_hba_info *pm8001_ha, u8 vec)1208{1209	if (pm8001_ha->use_msix)1210		pm8001_cw32(pm8001_ha, 0, MSIX_TABLE_BASE,1211			    MSIX_INTERRUPT_DISABLE);1212	else1213		pm8001_cw32(pm8001_ha, 0, MSGU_ODMR, ODMR_MASK_ALL);1214}1215 1216/**1217 * pm8001_mpi_msg_free_get - get the free message buffer for transfer1218 * inbound queue.1219 * @circularQ: the inbound queue  we want to transfer to HBA.1220 * @messageSize: the message size of this transfer, normally it is 64 bytes1221 * @messagePtr: the pointer to message.1222 */1223int pm8001_mpi_msg_free_get(struct inbound_queue_table *circularQ,1224			    u16 messageSize, void **messagePtr)1225{1226	u32 offset, consumer_index;1227	struct mpi_msg_hdr *msgHeader;1228	u8 bcCount = 1; /* only support single buffer */1229 1230	/* Checks is the requested message size can be allocated in this queue*/1231	if (messageSize > IOMB_SIZE_SPCV) {1232		*messagePtr = NULL;1233		return -1;1234	}1235 1236	/* Stores the new consumer index */1237	consumer_index = pm8001_read_32(circularQ->ci_virt);1238	circularQ->consumer_index = cpu_to_le32(consumer_index);1239	if (((circularQ->producer_idx + bcCount) % PM8001_MPI_QUEUE) ==1240		le32_to_cpu(circularQ->consumer_index)) {1241		*messagePtr = NULL;1242		return -1;1243	}1244	/* get memory IOMB buffer address */1245	offset = circularQ->producer_idx * messageSize;1246	/* increment to next bcCount element */1247	circularQ->producer_idx = (circularQ->producer_idx + bcCount)1248				% PM8001_MPI_QUEUE;1249	/* Adds that distance to the base of the region virtual address plus1250	the message header size*/1251	msgHeader = (struct mpi_msg_hdr *)(circularQ->base_virt	+ offset);1252	*messagePtr = ((void *)msgHeader) + sizeof(struct mpi_msg_hdr);1253	return 0;1254}1255 1256/**1257 * pm8001_mpi_build_cmd- build the message queue for transfer, update the PI to1258 * FW to tell the fw to get this message from IOMB.1259 * @pm8001_ha: our hba card information1260 * @q_index: the index in the inbound queue we want to transfer to HBA.1261 * @opCode: the operation code represents commands which LLDD and fw recognized.1262 * @payload: the command payload of each operation command.1263 * @nb: size in bytes of the command payload1264 * @responseQueue: queue to interrupt on w/ command response (if any)1265 */1266int pm8001_mpi_build_cmd(struct pm8001_hba_info *pm8001_ha,1267			 u32 q_index, u32 opCode, void *payload, size_t nb,1268			 u32 responseQueue)1269{1270	u32 Header = 0, hpriority = 0, bc = 1, category = 0x02;1271	void *pMessage;1272	unsigned long flags;1273	struct inbound_queue_table *circularQ = &pm8001_ha->inbnd_q_tbl[q_index];1274	int rv;1275	u32 htag = le32_to_cpu(*(__le32 *)payload);1276 1277	trace_pm80xx_mpi_build_cmd(pm8001_ha->id, opCode, htag, q_index,1278		circularQ->producer_idx, le32_to_cpu(circularQ->consumer_index));1279 1280	if (WARN_ON(q_index >= pm8001_ha->max_q_num))1281		return -EINVAL;1282 1283	spin_lock_irqsave(&circularQ->iq_lock, flags);1284	rv = pm8001_mpi_msg_free_get(circularQ, pm8001_ha->iomb_size,1285			&pMessage);1286	if (rv < 0) {1287		pm8001_dbg(pm8001_ha, IO, "No free mpi buffer\n");1288		rv = -ENOMEM;1289		goto done;1290	}1291 1292	if (nb > (pm8001_ha->iomb_size - sizeof(struct mpi_msg_hdr)))1293		nb = pm8001_ha->iomb_size - sizeof(struct mpi_msg_hdr);1294	memcpy(pMessage, payload, nb);1295	if (nb + sizeof(struct mpi_msg_hdr) < pm8001_ha->iomb_size)1296		memset(pMessage + nb, 0, pm8001_ha->iomb_size -1297				(nb + sizeof(struct mpi_msg_hdr)));1298 1299	/*Build the header*/1300	Header = ((1 << 31) | (hpriority << 30) | ((bc & 0x1f) << 24)1301		| ((responseQueue & 0x3F) << 16)1302		| ((category & 0xF) << 12) | (opCode & 0xFFF));1303 1304	pm8001_write_32((pMessage - 4), 0, cpu_to_le32(Header));1305	/*Update the PI to the firmware*/1306	pm8001_cw32(pm8001_ha, circularQ->pi_pci_bar,1307		circularQ->pi_offset, circularQ->producer_idx);1308	pm8001_dbg(pm8001_ha, DEVIO,1309		   "INB Q %x OPCODE:%x , UPDATED PI=%d CI=%d\n",1310		   responseQueue, opCode, circularQ->producer_idx,1311		   circularQ->consumer_index);1312done:1313	spin_unlock_irqrestore(&circularQ->iq_lock, flags);1314	return rv;1315}1316 1317u32 pm8001_mpi_msg_free_set(struct pm8001_hba_info *pm8001_ha, void *pMsg,1318			    struct outbound_queue_table *circularQ, u8 bc)1319{1320	u32 producer_index;1321	struct mpi_msg_hdr *msgHeader;1322	struct mpi_msg_hdr *pOutBoundMsgHeader;1323 1324	msgHeader = (struct mpi_msg_hdr *)(pMsg - sizeof(struct mpi_msg_hdr));1325	pOutBoundMsgHeader = (struct mpi_msg_hdr *)(circularQ->base_virt +1326				circularQ->consumer_idx * pm8001_ha->iomb_size);1327	if (pOutBoundMsgHeader != msgHeader) {1328		pm8001_dbg(pm8001_ha, FAIL,1329			   "consumer_idx = %d msgHeader = %p\n",1330			   circularQ->consumer_idx, msgHeader);1331 1332		/* Update the producer index from SPC */1333		producer_index = pm8001_read_32(circularQ->pi_virt);1334		circularQ->producer_index = cpu_to_le32(producer_index);1335		pm8001_dbg(pm8001_ha, FAIL,1336			   "consumer_idx = %d producer_index = %dmsgHeader = %p\n",1337			   circularQ->consumer_idx,1338			   circularQ->producer_index, msgHeader);1339		return 0;1340	}1341	/* free the circular queue buffer elements associated with the message*/1342	circularQ->consumer_idx = (circularQ->consumer_idx + bc)1343				% PM8001_MPI_QUEUE;1344	/* update the CI of outbound queue */1345	pm8001_cw32(pm8001_ha, circularQ->ci_pci_bar, circularQ->ci_offset,1346		circularQ->consumer_idx);1347	/* Update the producer index from SPC*/1348	producer_index = pm8001_read_32(circularQ->pi_virt);1349	circularQ->producer_index = cpu_to_le32(producer_index);1350	pm8001_dbg(pm8001_ha, IO, " CI=%d PI=%d\n",1351		   circularQ->consumer_idx, circularQ->producer_index);1352	return 0;1353}1354 1355/**1356 * pm8001_mpi_msg_consume- get the MPI message from outbound queue1357 * message table.1358 * @pm8001_ha: our hba card information1359 * @circularQ: the outbound queue  table.1360 * @messagePtr1: the message contents of this outbound message.1361 * @pBC: the message size.1362 */1363u32 pm8001_mpi_msg_consume(struct pm8001_hba_info *pm8001_ha,1364			   struct outbound_queue_table *circularQ,1365			   void **messagePtr1, u8 *pBC)1366{1367	struct mpi_msg_hdr	*msgHeader;1368	__le32	msgHeader_tmp;1369	u32 header_tmp;1370	do {1371		/* If there are not-yet-delivered messages ... */1372		if (le32_to_cpu(circularQ->producer_index)1373			!= circularQ->consumer_idx) {1374			/*Get the pointer to the circular queue buffer element*/1375			msgHeader = (struct mpi_msg_hdr *)1376				(circularQ->base_virt +1377				circularQ->consumer_idx * pm8001_ha->iomb_size);1378			/* read header */1379			header_tmp = pm8001_read_32(msgHeader);1380			msgHeader_tmp = cpu_to_le32(header_tmp);1381			pm8001_dbg(pm8001_ha, DEVIO,1382				   "outbound opcode msgheader:%x ci=%d pi=%d\n",1383				   msgHeader_tmp, circularQ->consumer_idx,1384				   circularQ->producer_index);1385			if (0 != (le32_to_cpu(msgHeader_tmp) & 0x80000000)) {1386				if (OPC_OUB_SKIP_ENTRY !=1387					(le32_to_cpu(msgHeader_tmp) & 0xfff)) {1388					*messagePtr1 =1389						((u8 *)msgHeader) +1390						sizeof(struct mpi_msg_hdr);1391					*pBC = (u8)((le32_to_cpu(msgHeader_tmp)1392						>> 24) & 0x1f);1393					pm8001_dbg(pm8001_ha, IO,1394						   ": CI=%d PI=%d msgHeader=%x\n",1395						   circularQ->consumer_idx,1396						   circularQ->producer_index,1397						   msgHeader_tmp);1398					return MPI_IO_STATUS_SUCCESS;1399				} else {1400					circularQ->consumer_idx =1401						(circularQ->consumer_idx +1402						((le32_to_cpu(msgHeader_tmp)1403						 >> 24) & 0x1f))1404							% PM8001_MPI_QUEUE;1405					msgHeader_tmp = 0;1406					pm8001_write_32(msgHeader, 0, 0);1407					/* update the CI of outbound queue */1408					pm8001_cw32(pm8001_ha,1409						circularQ->ci_pci_bar,1410						circularQ->ci_offset,1411						circularQ->consumer_idx);1412				}1413			} else {1414				circularQ->consumer_idx =1415					(circularQ->consumer_idx +1416					((le32_to_cpu(msgHeader_tmp) >> 24) &1417					0x1f)) % PM8001_MPI_QUEUE;1418				msgHeader_tmp = 0;1419				pm8001_write_32(msgHeader, 0, 0);1420				/* update the CI of outbound queue */1421				pm8001_cw32(pm8001_ha, circularQ->ci_pci_bar,1422					circularQ->ci_offset,1423					circularQ->consumer_idx);1424				return MPI_IO_STATUS_FAIL;1425			}1426		} else {1427			u32 producer_index;1428			void *pi_virt = circularQ->pi_virt;1429			/* spurious interrupt during setup if1430			 * kexec-ing and driver doing a doorbell access1431			 * with the pre-kexec oq interrupt setup1432			 */1433			if (!pi_virt)1434				break;1435			/* Update the producer index from SPC */1436			producer_index = pm8001_read_32(pi_virt);1437			circularQ->producer_index = cpu_to_le32(producer_index);1438		}1439	} while (le32_to_cpu(circularQ->producer_index) !=1440		circularQ->consumer_idx);1441	/* while we don't have any more not-yet-delivered message */1442	/* report empty */1443	return MPI_IO_STATUS_BUSY;1444}1445 1446void pm8001_work_fn(struct work_struct *work)1447{1448	struct pm8001_work *pw = container_of(work, struct pm8001_work, work);1449	struct pm8001_device *pm8001_dev;1450	struct domain_device *dev;1451 1452	/*1453	 * So far, all users of this stash an associated structure here.1454	 * If we get here, and this pointer is null, then the action1455	 * was cancelled. This nullification happens when the device1456	 * goes away.1457	 */1458	if (pw->handler != IO_FATAL_ERROR) {1459		pm8001_dev = pw->data; /* Most stash device structure */1460		if ((pm8001_dev == NULL)1461		 || ((pw->handler != IO_XFER_ERROR_BREAK)1462			 && (pm8001_dev->dev_type == SAS_PHY_UNUSED))) {1463			kfree(pw);1464			return;1465		}1466	}1467 1468	switch (pw->handler) {1469	case IO_XFER_ERROR_BREAK:1470	{	/* This one stashes the sas_task instead */1471		struct sas_task *t = (struct sas_task *)pm8001_dev;1472		struct pm8001_ccb_info *ccb;1473		struct pm8001_hba_info *pm8001_ha = pw->pm8001_ha;1474		unsigned long flags, flags1;1475		struct task_status_struct *ts;1476		int i;1477 1478		if (pm8001_query_task(t) == TMF_RESP_FUNC_SUCC)1479			break; /* Task still on lu */1480		spin_lock_irqsave(&pm8001_ha->lock, flags);1481 1482		spin_lock_irqsave(&t->task_state_lock, flags1);1483		if (unlikely((t->task_state_flags & SAS_TASK_STATE_DONE))) {1484			spin_unlock_irqrestore(&t->task_state_lock, flags1);1485			spin_unlock_irqrestore(&pm8001_ha->lock, flags);1486			break; /* Task got completed by another */1487		}1488		spin_unlock_irqrestore(&t->task_state_lock, flags1);1489 1490		/* Search for a possible ccb that matches the task */1491		for (i = 0; ccb = NULL, i < PM8001_MAX_CCB; i++) {1492			ccb = &pm8001_ha->ccb_info[i];1493			if ((ccb->ccb_tag != PM8001_INVALID_TAG) &&1494			    (ccb->task == t))1495				break;1496		}1497		if (!ccb) {1498			spin_unlock_irqrestore(&pm8001_ha->lock, flags);1499			break; /* Task got freed by another */1500		}1501		ts = &t->task_status;1502		ts->resp = SAS_TASK_COMPLETE;1503		/* Force the midlayer to retry */1504		ts->stat = SAS_QUEUE_FULL;1505		pm8001_dev = ccb->device;1506		if (pm8001_dev)1507			atomic_dec(&pm8001_dev->running_req);1508		spin_lock_irqsave(&t->task_state_lock, flags1);1509		t->task_state_flags &= ~SAS_TASK_STATE_PENDING;1510		t->task_state_flags |= SAS_TASK_STATE_DONE;1511		if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) {1512			spin_unlock_irqrestore(&t->task_state_lock, flags1);1513			pm8001_dbg(pm8001_ha, FAIL, "task 0x%p done with event 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n",1514				   t, pw->handler, ts->resp, ts->stat);1515			pm8001_ccb_task_free(pm8001_ha, ccb);1516			spin_unlock_irqrestore(&pm8001_ha->lock, flags);1517		} else {1518			spin_unlock_irqrestore(&t->task_state_lock, flags1);1519			pm8001_ccb_task_free(pm8001_ha, ccb);1520			mb();/* in order to force CPU ordering */1521			spin_unlock_irqrestore(&pm8001_ha->lock, flags);1522			t->task_done(t);1523		}1524	}	break;1525	case IO_XFER_OPEN_RETRY_TIMEOUT:1526	{	/* This one stashes the sas_task instead */1527		struct sas_task *t = (struct sas_task *)pm8001_dev;1528		struct pm8001_ccb_info *ccb;1529		struct pm8001_hba_info *pm8001_ha = pw->pm8001_ha;1530		unsigned long flags, flags1;1531		int i, ret = 0;1532 1533		pm8001_dbg(pm8001_ha, IO, "IO_XFER_OPEN_RETRY_TIMEOUT\n");1534 1535		ret = pm8001_query_task(t);1536 1537		if (ret == TMF_RESP_FUNC_SUCC)1538			pm8001_dbg(pm8001_ha, IO, "...Task on lu\n");1539		else if (ret == TMF_RESP_FUNC_COMPLETE)1540			pm8001_dbg(pm8001_ha, IO, "...Task NOT on lu\n");1541		else1542			pm8001_dbg(pm8001_ha, DEVIO, "...query task failed!!!\n");1543 1544		spin_lock_irqsave(&pm8001_ha->lock, flags);1545 1546		spin_lock_irqsave(&t->task_state_lock, flags1);1547 1548		if (unlikely((t->task_state_flags & SAS_TASK_STATE_DONE))) {1549			spin_unlock_irqrestore(&t->task_state_lock, flags1);1550			spin_unlock_irqrestore(&pm8001_ha->lock, flags);1551			if (ret == TMF_RESP_FUNC_SUCC) /* task on lu */1552				(void)pm8001_abort_task(t);1553			break; /* Task got completed by another */1554		}1555 1556		spin_unlock_irqrestore(&t->task_state_lock, flags1);1557 1558		/* Search for a possible ccb that matches the task */1559		for (i = 0; ccb = NULL, i < PM8001_MAX_CCB; i++) {1560			ccb = &pm8001_ha->ccb_info[i];1561			if ((ccb->ccb_tag != PM8001_INVALID_TAG) &&1562			    (ccb->task == t))1563				break;1564		}1565		if (!ccb) {1566			spin_unlock_irqrestore(&pm8001_ha->lock, flags);1567			if (ret == TMF_RESP_FUNC_SUCC) /* task on lu */1568				(void)pm8001_abort_task(t);1569			break; /* Task got freed by another */1570		}1571 1572		pm8001_dev = ccb->device;1573		dev = pm8001_dev->sas_device;1574 1575		switch (ret) {1576		case TMF_RESP_FUNC_SUCC: /* task on lu */1577			ccb->open_retry = 1; /* Snub completion */1578			spin_unlock_irqrestore(&pm8001_ha->lock, flags);1579			ret = pm8001_abort_task(t);1580			ccb->open_retry = 0;1581			switch (ret) {1582			case TMF_RESP_FUNC_SUCC:1583			case TMF_RESP_FUNC_COMPLETE:1584				break;1585			default: /* device misbehavior */1586				ret = TMF_RESP_FUNC_FAILED;1587				pm8001_dbg(pm8001_ha, IO, "...Reset phy\n");1588				pm8001_I_T_nexus_reset(dev);1589				break;1590			}1591			break;1592 1593		case TMF_RESP_FUNC_COMPLETE: /* task not on lu */1594			spin_unlock_irqrestore(&pm8001_ha->lock, flags);1595			/* Do we need to abort the task locally? */1596			break;1597 1598		default: /* device misbehavior */1599			spin_unlock_irqrestore(&pm8001_ha->lock, flags);1600			ret = TMF_RESP_FUNC_FAILED;1601			pm8001_dbg(pm8001_ha, IO, "...Reset phy\n");1602			pm8001_I_T_nexus_reset(dev);1603		}1604 1605		if (ret == TMF_RESP_FUNC_FAILED)1606			t = NULL;1607		pm8001_open_reject_retry(pm8001_ha, t, pm8001_dev);1608		pm8001_dbg(pm8001_ha, IO, "...Complete\n");1609	}	break;1610	case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS:1611		dev = pm8001_dev->sas_device;1612		pm8001_I_T_nexus_event_handler(dev);1613		break;1614	case IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY:1615		dev = pm8001_dev->sas_device;1616		pm8001_I_T_nexus_reset(dev);1617		break;1618	case IO_DS_IN_ERROR:1619		dev = pm8001_dev->sas_device;1620		pm8001_I_T_nexus_reset(dev);1621		break;1622	case IO_DS_NON_OPERATIONAL:1623		dev = pm8001_dev->sas_device;1624		pm8001_I_T_nexus_reset(dev);1625		break;1626	case IO_FATAL_ERROR:1627	{1628		struct pm8001_hba_info *pm8001_ha = pw->pm8001_ha;1629		struct pm8001_ccb_info *ccb;1630		struct task_status_struct *ts;1631		struct sas_task *task;1632		int i;1633		u32 device_id;1634 1635		for (i = 0; ccb = NULL, i < PM8001_MAX_CCB; i++) {1636			ccb = &pm8001_ha->ccb_info[i];1637			task = ccb->task;1638			ts = &task->task_status;1639 1640			if (task != NULL) {1641				dev = task->dev;1642				if (!dev) {1643					pm8001_dbg(pm8001_ha, FAIL,1644						"dev is NULL\n");1645					continue;1646				}1647				/*complete sas task and update to top layer */1648				pm8001_ccb_task_free(pm8001_ha, ccb);1649				ts->resp = SAS_TASK_COMPLETE;1650				task->task_done(task);1651			} else if (ccb->ccb_tag != PM8001_INVALID_TAG) {1652				/* complete the internal commands/non-sas task */1653				pm8001_dev = ccb->device;1654				if (pm8001_dev->dcompletion) {1655					complete(pm8001_dev->dcompletion);1656					pm8001_dev->dcompletion = NULL;1657				}1658				complete(pm8001_ha->nvmd_completion);1659				pm8001_ccb_free(pm8001_ha, ccb);1660			}1661		}1662		/* Deregister all the device ids  */1663		for (i = 0; i < PM8001_MAX_DEVICES; i++) {1664			pm8001_dev = &pm8001_ha->devices[i];1665			device_id = pm8001_dev->device_id;1666			if (device_id) {1667				PM8001_CHIP_DISP->dereg_dev_req(pm8001_ha, device_id);1668				pm8001_free_dev(pm8001_dev);1669			}1670		}1671	}1672	break;1673	case IO_XFER_ERROR_ABORTED_NCQ_MODE:1674	{1675		dev = pm8001_dev->sas_device;1676		sas_ata_device_link_abort(dev, false);1677	}1678	break;1679	}1680	kfree(pw);1681}1682 1683int pm8001_handle_event(struct pm8001_hba_info *pm8001_ha, void *data,1684			       int handler)1685{1686	struct pm8001_work *pw;1687	int ret = 0;1688 1689	pw = kmalloc(sizeof(struct pm8001_work), GFP_ATOMIC);1690	if (pw) {1691		pw->pm8001_ha = pm8001_ha;1692		pw->data = data;1693		pw->handler = handler;1694		INIT_WORK(&pw->work, pm8001_work_fn);1695		queue_work(pm8001_wq, &pw->work);1696	} else1697		ret = -ENOMEM;1698 1699	return ret;1700}1701 1702/**1703 * mpi_ssp_completion- process the event that FW response to the SSP request.1704 * @pm8001_ha: our hba card information1705 * @piomb: the message contents of this outbound message.1706 *1707 * When FW has completed a ssp request for example a IO request, after it has1708 * filled the SG data with the data, it will trigger this event representing1709 * that he has finished the job; please check the corresponding buffer.1710 * So we will tell the caller who maybe waiting the result to tell upper layer1711 * that the task has been finished.1712 */1713static void1714mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)1715{1716	struct sas_task *t;1717	struct pm8001_ccb_info *ccb;1718	unsigned long flags;1719	u32 status;1720	u32 param;1721	u32 tag;1722	struct ssp_completion_resp *psspPayload;1723	struct task_status_struct *ts;1724	struct ssp_response_iu *iu;1725	struct pm8001_device *pm8001_dev;1726	psspPayload = (struct ssp_completion_resp *)(piomb + 4);1727	status = le32_to_cpu(psspPayload->status);1728	tag = le32_to_cpu(psspPayload->tag);1729	ccb = &pm8001_ha->ccb_info[tag];1730	if ((status == IO_ABORTED) && ccb->open_retry) {1731		/* Being completed by another */1732		ccb->open_retry = 0;1733		return;1734	}1735	pm8001_dev = ccb->device;1736	param = le32_to_cpu(psspPayload->param);1737 1738	t = ccb->task;1739 1740	if (status && status != IO_UNDERFLOW)1741		pm8001_dbg(pm8001_ha, FAIL, "sas IO status 0x%x\n", status);1742	if (unlikely(!t || !t->lldd_task || !t->dev))1743		return;1744	ts = &t->task_status;1745	/* Print sas address of IO failed device */1746	if ((status != IO_SUCCESS) && (status != IO_OVERFLOW) &&1747		(status != IO_UNDERFLOW))1748		pm8001_dbg(pm8001_ha, FAIL, "SAS Address of IO Failure Drive:%016llx\n",1749			   SAS_ADDR(t->dev->sas_addr));1750 1751	if (status)1752		pm8001_dbg(pm8001_ha, IOERR,1753			   "status:0x%x, tag:0x%x, task:0x%p\n",1754			   status, tag, t);1755 1756	switch (status) {1757	case IO_SUCCESS:1758		pm8001_dbg(pm8001_ha, IO, "IO_SUCCESS,param = %d\n",1759			   param);1760		if (param == 0) {1761			ts->resp = SAS_TASK_COMPLETE;1762			ts->stat = SAS_SAM_STAT_GOOD;1763		} else {1764			ts->resp = SAS_TASK_COMPLETE;1765			ts->stat = SAS_PROTO_RESPONSE;1766			ts->residual = param;1767			iu = &psspPayload->ssp_resp_iu;1768			sas_ssp_task_response(pm8001_ha->dev, t, iu);1769		}1770		if (pm8001_dev)1771			atomic_dec(&pm8001_dev->running_req);1772		break;1773	case IO_ABORTED:1774		pm8001_dbg(pm8001_ha, IO, "IO_ABORTED IOMB Tag\n");1775		ts->resp = SAS_TASK_COMPLETE;1776		ts->stat = SAS_ABORTED_TASK;1777		break;1778	case IO_UNDERFLOW:1779		/* SSP Completion with error */1780		pm8001_dbg(pm8001_ha, IO, "IO_UNDERFLOW,param = %d\n",1781			   param);1782		ts->resp = SAS_TASK_COMPLETE;1783		ts->stat = SAS_DATA_UNDERRUN;1784		ts->residual = param;1785		if (pm8001_dev)1786			atomic_dec(&pm8001_dev->running_req);1787		break;1788	case IO_NO_DEVICE:1789		pm8001_dbg(pm8001_ha, IO, "IO_NO_DEVICE\n");1790		ts->resp = SAS_TASK_UNDELIVERED;1791		ts->stat = SAS_PHY_DOWN;1792		break;1793	case IO_XFER_ERROR_BREAK:1794		pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_BREAK\n");1795		ts->resp = SAS_TASK_COMPLETE;1796		ts->stat = SAS_OPEN_REJECT;1797		/* Force the midlayer to retry */1798		ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;1799		break;1800	case IO_XFER_ERROR_PHY_NOT_READY:1801		pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_PHY_NOT_READY\n");1802		ts->resp = SAS_TASK_COMPLETE;1803		ts->stat = SAS_OPEN_REJECT;1804		ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;1805		break;1806	case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED:1807		pm8001_dbg(pm8001_ha, IO,1808			   "IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED\n");1809		ts->resp = SAS_TASK_COMPLETE;1810		ts->stat = SAS_OPEN_REJECT;1811		ts->open_rej_reason = SAS_OREJ_EPROTO;1812		break;1813	case IO_OPEN_CNX_ERROR_ZONE_VIOLATION:1814		pm8001_dbg(pm8001_ha, IO,1815			   "IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n");1816		ts->resp = SAS_TASK_COMPLETE;1817		ts->stat = SAS_OPEN_REJECT;1818		ts->open_rej_reason = SAS_OREJ_UNKNOWN;1819		break;1820	case IO_OPEN_CNX_ERROR_BREAK:1821		pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_BREAK\n");1822		ts->resp = SAS_TASK_COMPLETE;1823		ts->stat = SAS_OPEN_REJECT;1824		ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;1825		break;1826	case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS:1827		pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n");1828		ts->resp = SAS_TASK_COMPLETE;1829		ts->stat = SAS_OPEN_REJECT;1830		ts->open_rej_reason = SAS_OREJ_UNKNOWN;1831		if (!t->uldd_task)1832			pm8001_handle_event(pm8001_ha,1833				pm8001_dev,1834				IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);1835		break;1836	case IO_OPEN_CNX_ERROR_BAD_DESTINATION:1837		pm8001_dbg(pm8001_ha, IO,1838			   "IO_OPEN_CNX_ERROR_BAD_DESTINATION\n");1839		ts->resp = SAS_TASK_COMPLETE;1840		ts->stat = SAS_OPEN_REJECT;1841		ts->open_rej_reason = SAS_OREJ_BAD_DEST;1842		break;1843	case IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED:1844		pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n");1845		ts->resp = SAS_TASK_COMPLETE;1846		ts->stat = SAS_OPEN_REJECT;1847		ts->open_rej_reason = SAS_OREJ_CONN_RATE;1848		break;1849	case IO_OPEN_CNX_ERROR_WRONG_DESTINATION:1850		pm8001_dbg(pm8001_ha, IO,1851			   "IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n");1852		ts->resp = SAS_TASK_UNDELIVERED;1853		ts->stat = SAS_OPEN_REJECT;1854		ts->open_rej_reason = SAS_OREJ_WRONG_DEST;1855		break;1856	case IO_XFER_ERROR_NAK_RECEIVED:1857		pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_NAK_RECEIVED\n");1858		ts->resp = SAS_TASK_COMPLETE;1859		ts->stat = SAS_OPEN_REJECT;1860		ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;1861		break;1862	case IO_XFER_ERROR_ACK_NAK_TIMEOUT:1863		pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_ACK_NAK_TIMEOUT\n");1864		ts->resp = SAS_TASK_COMPLETE;1865		ts->stat = SAS_NAK_R_ERR;1866		break;1867	case IO_XFER_ERROR_DMA:1868		pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_DMA\n");1869		ts->resp = SAS_TASK_COMPLETE;1870		ts->stat = SAS_OPEN_REJECT;1871		break;1872	case IO_XFER_OPEN_RETRY_TIMEOUT:1873		pm8001_dbg(pm8001_ha, IO, "IO_XFER_OPEN_RETRY_TIMEOUT\n");1874		ts->resp = SAS_TASK_COMPLETE;1875		ts->stat = SAS_OPEN_REJECT;1876		ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;1877		break;1878	case IO_XFER_ERROR_OFFSET_MISMATCH:1879		pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_OFFSET_MISMATCH\n");1880		ts->resp = SAS_TASK_COMPLETE;1881		ts->stat = SAS_OPEN_REJECT;1882		break;1883	case IO_PORT_IN_RESET:1884		pm8001_dbg(pm8001_ha, IO, "IO_PORT_IN_RESET\n");1885		ts->resp = SAS_TASK_COMPLETE;1886		ts->stat = SAS_OPEN_REJECT;1887		break;1888	case IO_DS_NON_OPERATIONAL:1889		pm8001_dbg(pm8001_ha, IO, "IO_DS_NON_OPERATIONAL\n");1890		ts->resp = SAS_TASK_COMPLETE;1891		ts->stat = SAS_OPEN_REJECT;1892		if (!t->uldd_task)1893			pm8001_handle_event(pm8001_ha,1894				pm8001_dev,1895				IO_DS_NON_OPERATIONAL);1896		break;1897	case IO_DS_IN_RECOVERY:1898		pm8001_dbg(pm8001_ha, IO, "IO_DS_IN_RECOVERY\n");1899		ts->resp = SAS_TASK_COMPLETE;1900		ts->stat = SAS_OPEN_REJECT;1901		break;1902	case IO_TM_TAG_NOT_FOUND:1903		pm8001_dbg(pm8001_ha, IO, "IO_TM_TAG_NOT_FOUND\n");1904		ts->resp = SAS_TASK_COMPLETE;1905		ts->stat = SAS_OPEN_REJECT;1906		break;1907	case IO_SSP_EXT_IU_ZERO_LEN_ERROR:1908		pm8001_dbg(pm8001_ha, IO, "IO_SSP_EXT_IU_ZERO_LEN_ERROR\n");1909		ts->resp = SAS_TASK_COMPLETE;1910		ts->stat = SAS_OPEN_REJECT;1911		break;1912	case IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY:1913		pm8001_dbg(pm8001_ha, IO,1914			   "IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY\n");1915		ts->resp = SAS_TASK_COMPLETE;1916		ts->stat = SAS_OPEN_REJECT;1917		ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;1918		break;1919	default:1920		pm8001_dbg(pm8001_ha, DEVIO, "Unknown status 0x%x\n", status);1921		/* not allowed case. Therefore, return failed status */1922		ts->resp = SAS_TASK_COMPLETE;1923		ts->stat = SAS_OPEN_REJECT;1924		break;1925	}1926	pm8001_dbg(pm8001_ha, IO, "scsi_status = %x\n",1927		   psspPayload->ssp_resp_iu.status);1928	spin_lock_irqsave(&t->task_state_lock, flags);1929	t->task_state_flags &= ~SAS_TASK_STATE_PENDING;1930	t->task_state_flags |= SAS_TASK_STATE_DONE;1931	if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) {1932		spin_unlock_irqrestore(&t->task_state_lock, flags);1933		pm8001_dbg(pm8001_ha, FAIL, "task 0x%p done with io_status 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n",1934			   t, status, ts->resp, ts->stat);1935		pm8001_ccb_task_free(pm8001_ha, ccb);1936	} else {1937		spin_unlock_irqrestore(&t->task_state_lock, flags);1938		pm8001_ccb_task_free(pm8001_ha, ccb);1939		mb();/* in order to force CPU ordering */1940		t->task_done(t);1941	}1942}1943 1944/*See the comments for mpi_ssp_completion */1945static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha, void *piomb)1946{1947	struct sas_task *t;1948	unsigned long flags;1949	struct task_status_struct *ts;1950	struct pm8001_ccb_info *ccb;1951	struct pm8001_device *pm8001_dev;1952	struct ssp_event_resp *psspPayload =1953		(struct ssp_event_resp *)(piomb + 4);1954	u32 event = le32_to_cpu(psspPayload->event);1955	u32 tag = le32_to_cpu(psspPayload->tag);1956	u32 port_id = le32_to_cpu(psspPayload->port_id);1957	u32 dev_id = le32_to_cpu(psspPayload->device_id);1958 1959	ccb = &pm8001_ha->ccb_info[tag];1960	t = ccb->task;1961	pm8001_dev = ccb->device;1962	if (event)1963		pm8001_dbg(pm8001_ha, FAIL, "sas IO status 0x%x\n", event);1964	if (unlikely(!t || !t->lldd_task || !t->dev))1965		return;1966	ts = &t->task_status;1967	pm8001_dbg(pm8001_ha, DEVIO, "port_id = %x,device_id = %x\n",1968		   port_id, dev_id);1969	switch (event) {1970	case IO_OVERFLOW:1971		pm8001_dbg(pm8001_ha, IO, "IO_UNDERFLOW\n");1972		ts->resp = SAS_TASK_COMPLETE;1973		ts->stat = SAS_DATA_OVERRUN;1974		ts->residual = 0;1975		if (pm8001_dev)1976			atomic_dec(&pm8001_dev->running_req);1977		break;1978	case IO_XFER_ERROR_BREAK:1979		pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_BREAK\n");1980		pm8001_handle_event(pm8001_ha, t, IO_XFER_ERROR_BREAK);1981		return;1982	case IO_XFER_ERROR_PHY_NOT_READY:1983		pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_PHY_NOT_READY\n");1984		ts->resp = SAS_TASK_COMPLETE;1985		ts->stat = SAS_OPEN_REJECT;1986		ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;1987		break;1988	case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED:1989		pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED\n");1990		ts->resp = SAS_TASK_COMPLETE;1991		ts->stat = SAS_OPEN_REJECT;1992		ts->open_rej_reason = SAS_OREJ_EPROTO;1993		break;1994	case IO_OPEN_CNX_ERROR_ZONE_VIOLATION:1995		pm8001_dbg(pm8001_ha, IO,1996			   "IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n");1997		ts->resp = SAS_TASK_COMPLETE;1998		ts->stat = SAS_OPEN_REJECT;1999		ts->open_rej_reason = SAS_OREJ_UNKNOWN;2000		break;2001	case IO_OPEN_CNX_ERROR_BREAK:2002		pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_BREAK\n");2003		ts->resp = SAS_TASK_COMPLETE;2004		ts->stat = SAS_OPEN_REJECT;2005		ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;2006		break;2007	case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS:2008		pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n");2009		ts->resp = SAS_TASK_COMPLETE;2010		ts->stat = SAS_OPEN_REJECT;2011		ts->open_rej_reason = SAS_OREJ_UNKNOWN;2012		if (!t->uldd_task)2013			pm8001_handle_event(pm8001_ha,2014				pm8001_dev,2015				IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);2016		break;2017	case IO_OPEN_CNX_ERROR_BAD_DESTINATION:2018		pm8001_dbg(pm8001_ha, IO,2019			   "IO_OPEN_CNX_ERROR_BAD_DESTINATION\n");2020		ts->resp = SAS_TASK_COMPLETE;2021		ts->stat = SAS_OPEN_REJECT;2022		ts->open_rej_reason = SAS_OREJ_BAD_DEST;2023		break;2024	case IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED:2025		pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n");2026		ts->resp = SAS_TASK_COMPLETE;2027		ts->stat = SAS_OPEN_REJECT;2028		ts->open_rej_reason = SAS_OREJ_CONN_RATE;2029		break;2030	case IO_OPEN_CNX_ERROR_WRONG_DESTINATION:2031		pm8001_dbg(pm8001_ha, IO,2032			   "IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n");2033		ts->resp = SAS_TASK_COMPLETE;2034		ts->stat = SAS_OPEN_REJECT;2035		ts->open_rej_reason = SAS_OREJ_WRONG_DEST;2036		break;2037	case IO_XFER_ERROR_NAK_RECEIVED:2038		pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_NAK_RECEIVED\n");2039		ts->resp = SAS_TASK_COMPLETE;2040		ts->stat = SAS_OPEN_REJECT;2041		ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;2042		break;2043	case IO_XFER_ERROR_ACK_NAK_TIMEOUT:2044		pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_ACK_NAK_TIMEOUT\n");2045		ts->resp = SAS_TASK_COMPLETE;2046		ts->stat = SAS_NAK_R_ERR;2047		break;2048	case IO_XFER_OPEN_RETRY_TIMEOUT:2049		pm8001_dbg(pm8001_ha, IO, "IO_XFER_OPEN_RETRY_TIMEOUT\n");2050		pm8001_handle_event(pm8001_ha, t, IO_XFER_OPEN_RETRY_TIMEOUT);2051		return;2052	case IO_XFER_ERROR_UNEXPECTED_PHASE:2053		pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_UNEXPECTED_PHASE\n");2054		ts->resp = SAS_TASK_COMPLETE;2055		ts->stat = SAS_DATA_OVERRUN;2056		break;2057	case IO_XFER_ERROR_XFER_RDY_OVERRUN:2058		pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_XFER_RDY_OVERRUN\n");2059		ts->resp = SAS_TASK_COMPLETE;2060		ts->stat = SAS_DATA_OVERRUN;2061		break;2062	case IO_XFER_ERROR_XFER_RDY_NOT_EXPECTED:2063		pm8001_dbg(pm8001_ha, IO,2064			   "IO_XFER_ERROR_XFER_RDY_NOT_EXPECTED\n");2065		ts->resp = SAS_TASK_COMPLETE;2066		ts->stat = SAS_DATA_OVERRUN;2067		break;2068	case IO_XFER_ERROR_CMD_ISSUE_ACK_NAK_TIMEOUT:2069		pm8001_dbg(pm8001_ha, IO,2070			   "IO_XFER_ERROR_CMD_ISSUE_ACK_NAK_TIMEOUT\n");2071		ts->resp = SAS_TASK_COMPLETE;2072		ts->stat = SAS_DATA_OVERRUN;2073		break;2074	case IO_XFER_ERROR_OFFSET_MISMATCH:2075		pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_OFFSET_MISMATCH\n");2076		ts->resp = SAS_TASK_COMPLETE;2077		ts->stat = SAS_DATA_OVERRUN;2078		break;2079	case IO_XFER_ERROR_XFER_ZERO_DATA_LEN:2080		pm8001_dbg(pm8001_ha, IO,2081			   "IO_XFER_ERROR_XFER_ZERO_DATA_LEN\n");2082		ts->resp = SAS_TASK_COMPLETE;2083		ts->stat = SAS_DATA_OVERRUN;2084		break;2085	case IO_XFER_CMD_FRAME_ISSUED:2086		pm8001_dbg(pm8001_ha, IO, "IO_XFER_CMD_FRAME_ISSUED\n");2087		return;2088	default:2089		pm8001_dbg(pm8001_ha, DEVIO, "Unknown status 0x%x\n", event);2090		/* not allowed case. Therefore, return failed status */2091		ts->resp = SAS_TASK_COMPLETE;2092		ts->stat = SAS_DATA_OVERRUN;2093		break;2094	}2095	spin_lock_irqsave(&t->task_state_lock, flags);2096	t->task_state_flags &= ~SAS_TASK_STATE_PENDING;2097	t->task_state_flags |= SAS_TASK_STATE_DONE;2098	if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) {2099		spin_unlock_irqrestore(&t->task_state_lock, flags);2100		pm8001_dbg(pm8001_ha, FAIL, "task 0x%p done with event 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n",2101			   t, event, ts->resp, ts->stat);2102		pm8001_ccb_task_free(pm8001_ha, ccb);2103	} else {2104		spin_unlock_irqrestore(&t->task_state_lock, flags);2105		pm8001_ccb_task_free(pm8001_ha, ccb);2106		mb();/* in order to force CPU ordering */2107		t->task_done(t);2108	}2109}2110 2111/*See the comments for mpi_ssp_completion */2112static void2113mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)2114{2115	struct sas_task *t;2116	struct pm8001_ccb_info *ccb;2117	u32 param;2118	u32 status;2119	u32 tag;2120	int i, j;2121	u8 sata_addr_low[4];2122	u32 temp_sata_addr_low;2123	u8 sata_addr_hi[4];2124	u32 temp_sata_addr_hi;2125	struct sata_completion_resp *psataPayload;2126	struct task_status_struct *ts;2127	struct ata_task_resp *resp ;2128	u32 *sata_resp;2129	struct pm8001_device *pm8001_dev;2130	unsigned long flags;2131 2132	psataPayload = (struct sata_completion_resp *)(piomb + 4);2133	status = le32_to_cpu(psataPayload->status);2134	param = le32_to_cpu(psataPayload->param);2135	tag = le32_to_cpu(psataPayload->tag);2136 2137	ccb = &pm8001_ha->ccb_info[tag];2138	t = ccb->task;2139	pm8001_dev = ccb->device;2140 2141	if (t) {2142		if (t->dev && (t->dev->lldd_dev))2143			pm8001_dev = t->dev->lldd_dev;2144	} else {2145		pm8001_dbg(pm8001_ha, FAIL, "task null, freeing CCB tag %d\n",2146			   ccb->ccb_tag);2147		pm8001_ccb_free(pm8001_ha, ccb);2148		return;2149	}2150 2151	if (pm8001_dev && unlikely(!t || !t->lldd_task || !t->dev)) {2152		pm8001_dbg(pm8001_ha, FAIL, "task or dev null\n");2153		return;2154	}2155 2156	ts = &t->task_status;2157 2158	if (status)2159		pm8001_dbg(pm8001_ha, IOERR,2160			   "status:0x%x, tag:0x%x, task::0x%p\n",2161			   status, tag, t);2162 2163	/* Print sas address of IO failed device */2164	if ((status != IO_SUCCESS) && (status != IO_OVERFLOW) &&2165		(status != IO_UNDERFLOW)) {2166		if (!((t->dev->parent) &&2167			(dev_is_expander(t->dev->parent->dev_type)))) {2168			for (i = 0, j = 4; j <= 7 && i <= 3; i++, j++)2169				sata_addr_low[i] = pm8001_ha->sas_addr[j];2170			for (i = 0, j = 0; j <= 3 && i <= 3; i++, j++)2171				sata_addr_hi[i] = pm8001_ha->sas_addr[j];2172			memcpy(&temp_sata_addr_low, sata_addr_low,2173				sizeof(sata_addr_low));2174			memcpy(&temp_sata_addr_hi, sata_addr_hi,2175				sizeof(sata_addr_hi));2176			temp_sata_addr_hi = (((temp_sata_addr_hi >> 24) & 0xff)2177						|((temp_sata_addr_hi << 8) &2178						0xff0000) |2179						((temp_sata_addr_hi >> 8)2180						& 0xff00) |2181						((temp_sata_addr_hi << 24) &2182						0xff000000));2183			temp_sata_addr_low = ((((temp_sata_addr_low >> 24)2184						& 0xff) |2185						((temp_sata_addr_low << 8)2186						& 0xff0000) |2187						((temp_sata_addr_low >> 8)2188						& 0xff00) |2189						((temp_sata_addr_low << 24)2190						& 0xff000000)) +2191						pm8001_dev->attached_phy +2192						0x10);2193			pm8001_dbg(pm8001_ha, FAIL,2194				   "SAS Address of IO Failure Drive:%08x%08x\n",2195				   temp_sata_addr_hi,2196				   temp_sata_addr_low);2197		} else {2198			pm8001_dbg(pm8001_ha, FAIL,2199				   "SAS Address of IO Failure Drive:%016llx\n",2200				   SAS_ADDR(t->dev->sas_addr));2201		}2202	}2203	switch (status) {2204	case IO_SUCCESS:2205		pm8001_dbg(pm8001_ha, IO, "IO_SUCCESS\n");2206		if (param == 0) {2207			ts->resp = SAS_TASK_COMPLETE;2208			ts->stat = SAS_SAM_STAT_GOOD;2209		} else {2210			u8 len;2211			ts->resp = SAS_TASK_COMPLETE;2212			ts->stat = SAS_PROTO_RESPONSE;2213			ts->residual = param;2214			pm8001_dbg(pm8001_ha, IO,2215				   "SAS_PROTO_RESPONSE len = %d\n",2216				   param);2217			sata_resp = &psataPayload->sata_resp[0];2218			resp = (struct ata_task_resp *)ts->buf;2219			if (t->ata_task.dma_xfer == 0 &&2220			    t->data_dir == DMA_FROM_DEVICE) {2221				len = sizeof(struct pio_setup_fis);2222				pm8001_dbg(pm8001_ha, IO,2223					   "PIO read len = %d\n", len);2224			} else if (t->ata_task.use_ncq &&2225				   t->data_dir != DMA_NONE) {2226				len = sizeof(struct set_dev_bits_fis);2227				pm8001_dbg(pm8001_ha, IO, "FPDMA len = %d\n",2228					   len);2229			} else {2230				len = sizeof(struct dev_to_host_fis);2231				pm8001_dbg(pm8001_ha, IO, "other len = %d\n",2232					   len);2233			}2234			if (SAS_STATUS_BUF_SIZE >= sizeof(*resp)) {2235				resp->frame_len = len;2236				memcpy(&resp->ending_fis[0], sata_resp, len);2237				ts->buf_valid_size = sizeof(*resp);2238			} else2239				pm8001_dbg(pm8001_ha, IO,2240					   "response too large\n");2241		}2242		if (pm8001_dev)2243			atomic_dec(&pm8001_dev->running_req);2244		break;2245	case IO_ABORTED:2246		pm8001_dbg(pm8001_ha, IO, "IO_ABORTED IOMB Tag\n");2247		ts->resp = SAS_TASK_COMPLETE;2248		ts->stat = SAS_ABORTED_TASK;2249		if (pm8001_dev)2250			atomic_dec(&pm8001_dev->running_req);2251		break;2252		/* following cases are to do cases */2253	case IO_UNDERFLOW:2254		/* SATA Completion with error */2255		pm8001_dbg(pm8001_ha, IO, "IO_UNDERFLOW param = %d\n", param);2256		ts->resp = SAS_TASK_COMPLETE;2257		ts->stat = SAS_DATA_UNDERRUN;2258		ts->residual =  param;2259		if (pm8001_dev)2260			atomic_dec(&pm8001_dev->running_req);2261		break;2262	case IO_NO_DEVICE:2263		pm8001_dbg(pm8001_ha, IO, "IO_NO_DEVICE\n");2264		ts->resp = SAS_TASK_UNDELIVERED;2265		ts->stat = SAS_PHY_DOWN;2266		if (pm8001_dev)2267			atomic_dec(&pm8001_dev->running_req);2268		break;2269	case IO_XFER_ERROR_BREAK:2270		pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_BREAK\n");2271		ts->resp = SAS_TASK_COMPLETE;2272		ts->stat = SAS_INTERRUPTED;2273		if (pm8001_dev)2274			atomic_dec(&pm8001_dev->running_req);2275		break;2276	case IO_XFER_ERROR_PHY_NOT_READY:2277		pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_PHY_NOT_READY\n");2278		ts->resp = SAS_TASK_COMPLETE;2279		ts->stat = SAS_OPEN_REJECT;2280		ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;2281		if (pm8001_dev)2282			atomic_dec(&pm8001_dev->running_req);2283		break;2284	case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED:2285		pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED\n");2286		ts->resp = SAS_TASK_COMPLETE;2287		ts->stat = SAS_OPEN_REJECT;2288		ts->open_rej_reason = SAS_OREJ_EPROTO;2289		if (pm8001_dev)2290			atomic_dec(&pm8001_dev->running_req);2291		break;2292	case IO_OPEN_CNX_ERROR_ZONE_VIOLATION:2293		pm8001_dbg(pm8001_ha, IO,2294			   "IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n");2295		ts->resp = SAS_TASK_COMPLETE;2296		ts->stat = SAS_OPEN_REJECT;2297		ts->open_rej_reason = SAS_OREJ_UNKNOWN;2298		if (pm8001_dev)2299			atomic_dec(&pm8001_dev->running_req);2300		break;2301	case IO_OPEN_CNX_ERROR_BREAK:2302		pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_BREAK\n");2303		ts->resp = SAS_TASK_COMPLETE;2304		ts->stat = SAS_OPEN_REJECT;2305		ts->open_rej_reason = SAS_OREJ_RSVD_CONT0;2306		if (pm8001_dev)2307			atomic_dec(&pm8001_dev->running_req);2308		break;2309	case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS:2310		pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n");2311		ts->resp = SAS_TASK_COMPLETE;2312		ts->stat = SAS_DEV_NO_RESPONSE;2313		if (!t->uldd_task) {2314			pm8001_handle_event(pm8001_ha,2315				pm8001_dev,2316				IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);2317			ts->resp = SAS_TASK_UNDELIVERED;2318			ts->stat = SAS_QUEUE_FULL;2319			pm8001_ccb_task_free_done(pm8001_ha, ccb);2320			return;2321		}2322		break;2323	case IO_OPEN_CNX_ERROR_BAD_DESTINATION:2324		pm8001_dbg(pm8001_ha, IO,2325			   "IO_OPEN_CNX_ERROR_BAD_DESTINATION\n");2326		ts->resp = SAS_TASK_UNDELIVERED;2327		ts->stat = SAS_OPEN_REJECT;2328		ts->open_rej_reason = SAS_OREJ_BAD_DEST;2329		if (!t->uldd_task) {2330			pm8001_handle_event(pm8001_ha,2331				pm8001_dev,2332				IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);2333			ts->resp = SAS_TASK_UNDELIVERED;2334			ts->stat = SAS_QUEUE_FULL;2335			pm8001_ccb_task_free_done(pm8001_ha, ccb);2336			return;2337		}2338		break;2339	case IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED:2340		pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n");2341		ts->resp = SAS_TASK_COMPLETE;2342		ts->stat = SAS_OPEN_REJECT;2343		ts->open_rej_reason = SAS_OREJ_CONN_RATE;2344		if (pm8001_dev)2345			atomic_dec(&pm8001_dev->running_req);2346		break;2347	case IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY:2348		pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY\n");2349		ts->resp = SAS_TASK_COMPLETE;2350		ts->stat = SAS_DEV_NO_RESPONSE;2351		if (!t->uldd_task) {2352			pm8001_handle_event(pm8001_ha,2353				pm8001_dev,2354				IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY);2355			ts->resp = SAS_TASK_UNDELIVERED;2356			ts->stat = SAS_QUEUE_FULL;2357			pm8001_ccb_task_free_done(pm8001_ha, ccb);2358			return;2359		}2360		break;2361	case IO_OPEN_CNX_ERROR_WRONG_DESTINATION:2362		pm8001_dbg(pm8001_ha, IO,2363			   "IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n");2364		ts->resp = SAS_TASK_COMPLETE;2365		ts->stat = SAS_OPEN_REJECT;2366		ts->open_rej_reason = SAS_OREJ_WRONG_DEST;2367		if (pm8001_dev)2368			atomic_dec(&pm8001_dev->running_req);2369		break;2370	case IO_XFER_ERROR_NAK_RECEIVED:2371		pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_NAK_RECEIVED\n");2372		ts->resp = SAS_TASK_COMPLETE;2373		ts->stat = SAS_NAK_R_ERR;2374		if (pm8001_dev)2375			atomic_dec(&pm8001_dev->running_req);2376		break;2377	case IO_XFER_ERROR_ACK_NAK_TIMEOUT:2378		pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_ACK_NAK_TIMEOUT\n");2379		ts->resp = SAS_TASK_COMPLETE;2380		ts->stat = SAS_NAK_R_ERR;2381		if (pm8001_dev)2382			atomic_dec(&pm8001_dev->running_req);2383		break;2384	case IO_XFER_ERROR_DMA:2385		pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_DMA\n");2386		ts->resp = SAS_TASK_COMPLETE;2387		ts->stat = SAS_ABORTED_TASK;2388		if (pm8001_dev)2389			atomic_dec(&pm8001_dev->running_req);2390		break;2391	case IO_XFER_ERROR_SATA_LINK_TIMEOUT:2392		pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_SATA_LINK_TIMEOUT\n");2393		ts->resp = SAS_TASK_UNDELIVERED;2394		ts->stat = SAS_DEV_NO_RESPONSE;2395		if (pm8001_dev)2396			atomic_dec(&pm8001_dev->running_req);2397		break;2398	case IO_XFER_ERROR_REJECTED_NCQ_MODE:2399		pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_REJECTED_NCQ_MODE\n");2400		ts->resp = SAS_TASK_COMPLETE;2401		ts->stat = SAS_DATA_UNDERRUN;2402		if (pm8001_dev)2403			atomic_dec(&pm8001_dev->running_req);2404		break;2405	case IO_XFER_OPEN_RETRY_TIMEOUT:2406		pm8001_dbg(pm8001_ha, IO, "IO_XFER_OPEN_RETRY_TIMEOUT\n");2407		ts->resp = SAS_TASK_COMPLETE;2408		ts->stat = SAS_OPEN_TO;2409		if (pm8001_dev)2410			atomic_dec(&pm8001_dev->running_req);2411		break;2412	case IO_PORT_IN_RESET:2413		pm8001_dbg(pm8001_ha, IO, "IO_PORT_IN_RESET\n");2414		ts->resp = SAS_TASK_COMPLETE;2415		ts->stat = SAS_DEV_NO_RESPONSE;2416		if (pm8001_dev)2417			atomic_dec(&pm8001_dev->running_req);2418		break;2419	case IO_DS_NON_OPERATIONAL:2420		pm8001_dbg(pm8001_ha, IO, "IO_DS_NON_OPERATIONAL\n");2421		ts->resp = SAS_TASK_COMPLETE;2422		ts->stat = SAS_DEV_NO_RESPONSE;2423		if (!t->uldd_task) {2424			pm8001_handle_event(pm8001_ha, pm8001_dev,2425				    IO_DS_NON_OPERATIONAL);2426			ts->resp = SAS_TASK_UNDELIVERED;2427			ts->stat = SAS_QUEUE_FULL;2428			pm8001_ccb_task_free_done(pm8001_ha, ccb);2429			return;2430		}2431		break;2432	case IO_DS_IN_RECOVERY:2433		pm8001_dbg(pm8001_ha, IO, "  IO_DS_IN_RECOVERY\n");2434		ts->resp = SAS_TASK_COMPLETE;2435		ts->stat = SAS_DEV_NO_RESPONSE;2436		if (pm8001_dev)2437			atomic_dec(&pm8001_dev->running_req);2438		break;2439	case IO_DS_IN_ERROR:2440		pm8001_dbg(pm8001_ha, IO, "IO_DS_IN_ERROR\n");2441		ts->resp = SAS_TASK_COMPLETE;2442		ts->stat = SAS_DEV_NO_RESPONSE;2443		if (!t->uldd_task) {2444			pm8001_handle_event(pm8001_ha, pm8001_dev,2445				    IO_DS_IN_ERROR);2446			ts->resp = SAS_TASK_UNDELIVERED;2447			ts->stat = SAS_QUEUE_FULL;2448			pm8001_ccb_task_free_done(pm8001_ha, ccb);2449			return;2450		}2451		break;2452	case IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY:2453		pm8001_dbg(pm8001_ha, IO,2454			   "IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY\n");2455		ts->resp = SAS_TASK_COMPLETE;2456		ts->stat = SAS_OPEN_REJECT;2457		ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;2458		if (pm8001_dev)2459			atomic_dec(&pm8001_dev->running_req);2460		break;2461	default:2462		pm8001_dbg(pm8001_ha, DEVIO, "Unknown status 0x%x\n", status);2463		/* not allowed case. Therefore, return failed status */2464		ts->resp = SAS_TASK_COMPLETE;2465		ts->stat = SAS_DEV_NO_RESPONSE;2466		if (pm8001_dev)2467			atomic_dec(&pm8001_dev->running_req);2468		break;2469	}2470	spin_lock_irqsave(&t->task_state_lock, flags);2471	t->task_state_flags &= ~SAS_TASK_STATE_PENDING;2472	t->task_state_flags |= SAS_TASK_STATE_DONE;2473	if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) {2474		spin_unlock_irqrestore(&t->task_state_lock, flags);2475		pm8001_dbg(pm8001_ha, FAIL,2476			   "task 0x%p done with io_status 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n",2477			   t, status, ts->resp, ts->stat);2478		pm8001_ccb_task_free(pm8001_ha, ccb);2479	} else {2480		spin_unlock_irqrestore(&t->task_state_lock, flags);2481		pm8001_ccb_task_free_done(pm8001_ha, ccb);2482	}2483}2484 2485/*See the comments for mpi_ssp_completion */2486static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha, void *piomb)2487{2488	struct sas_task *t;2489	struct task_status_struct *ts;2490	struct pm8001_ccb_info *ccb;2491	struct pm8001_device *pm8001_dev;2492	struct sata_event_resp *psataPayload =2493		(struct sata_event_resp *)(piomb + 4);2494	u32 event = le32_to_cpu(psataPayload->event);2495	u32 tag = le32_to_cpu(psataPayload->tag);2496	u32 port_id = le32_to_cpu(psataPayload->port_id);2497	u32 dev_id = le32_to_cpu(psataPayload->device_id);2498 2499	if (event)2500		pm8001_dbg(pm8001_ha, FAIL, "SATA EVENT 0x%x\n", event);2501 2502	/* Check if this is NCQ error */2503	if (event == IO_XFER_ERROR_ABORTED_NCQ_MODE) {2504		/* find device using device id */2505		pm8001_dev = pm8001_find_dev(pm8001_ha, dev_id);2506		if (pm8001_dev)2507			pm8001_handle_event(pm8001_ha,2508				pm8001_dev,2509				IO_XFER_ERROR_ABORTED_NCQ_MODE);2510		return;2511	}2512 2513	ccb = &pm8001_ha->ccb_info[tag];2514	t = ccb->task;2515	pm8001_dev = ccb->device;2516	if (event)2517		pm8001_dbg(pm8001_ha, FAIL, "sata IO status 0x%x\n", event);2518 2519	if (unlikely(!t)) {2520		pm8001_dbg(pm8001_ha, FAIL, "task null, freeing CCB tag %d\n",2521			   ccb->ccb_tag);2522		pm8001_ccb_free(pm8001_ha, ccb);2523		return;2524	}2525 2526	if (unlikely(!t->lldd_task || !t->dev))2527		return;2528 2529	ts = &t->task_status;2530	pm8001_dbg(pm8001_ha, DEVIO,2531		   "port_id:0x%x, device_id:0x%x, tag:0x%x, event:0x%x\n",2532		   port_id, dev_id, tag, event);2533	switch (event) {2534	case IO_OVERFLOW:2535		pm8001_dbg(pm8001_ha, IO, "IO_UNDERFLOW\n");2536		ts->resp = SAS_TASK_COMPLETE;2537		ts->stat = SAS_DATA_OVERRUN;2538		ts->residual = 0;2539		break;2540	case IO_XFER_ERROR_BREAK:2541		pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_BREAK\n");2542		ts->resp = SAS_TASK_COMPLETE;2543		ts->stat = SAS_INTERRUPTED;2544		break;2545	case IO_XFER_ERROR_PHY_NOT_READY:2546		pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_PHY_NOT_READY\n");2547		ts->resp = SAS_TASK_COMPLETE;2548		ts->stat = SAS_OPEN_REJECT;2549		ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;2550		break;2551	case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED:2552		pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED\n");2553		ts->resp = SAS_TASK_COMPLETE;2554		ts->stat = SAS_OPEN_REJECT;2555		ts->open_rej_reason = SAS_OREJ_EPROTO;2556		break;2557	case IO_OPEN_CNX_ERROR_ZONE_VIOLATION:2558		pm8001_dbg(pm8001_ha, IO,2559			   "IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n");2560		ts->resp = SAS_TASK_COMPLETE;2561		ts->stat = SAS_OPEN_REJECT;2562		ts->open_rej_reason = SAS_OREJ_UNKNOWN;2563		break;2564	case IO_OPEN_CNX_ERROR_BREAK:2565		pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_BREAK\n");2566		ts->resp = SAS_TASK_COMPLETE;2567		ts->stat = SAS_OPEN_REJECT;2568		ts->open_rej_reason = SAS_OREJ_RSVD_CONT0;2569		break;2570	case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS:2571		pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n");2572		ts->resp = SAS_TASK_UNDELIVERED;2573		ts->stat = SAS_DEV_NO_RESPONSE;2574		if (!t->uldd_task) {2575			pm8001_handle_event(pm8001_ha,2576				pm8001_dev,2577				IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);2578			ts->resp = SAS_TASK_COMPLETE;2579			ts->stat = SAS_QUEUE_FULL;2580			return;2581		}2582		break;2583	case IO_OPEN_CNX_ERROR_BAD_DESTINATION:2584		pm8001_dbg(pm8001_ha, IO,2585			   "IO_OPEN_CNX_ERROR_BAD_DESTINATION\n");2586		ts->resp = SAS_TASK_UNDELIVERED;2587		ts->stat = SAS_OPEN_REJECT;2588		ts->open_rej_reason = SAS_OREJ_BAD_DEST;2589		break;2590	case IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED:2591		pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n");2592		ts->resp = SAS_TASK_COMPLETE;2593		ts->stat = SAS_OPEN_REJECT;2594		ts->open_rej_reason = SAS_OREJ_CONN_RATE;2595		break;2596	case IO_OPEN_CNX_ERROR_WRONG_DESTINATION:2597		pm8001_dbg(pm8001_ha, IO,2598			   "IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n");2599		ts->resp = SAS_TASK_COMPLETE;2600		ts->stat = SAS_OPEN_REJECT;2601		ts->open_rej_reason = SAS_OREJ_WRONG_DEST;2602		break;2603	case IO_XFER_ERROR_NAK_RECEIVED:2604		pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_NAK_RECEIVED\n");2605		ts->resp = SAS_TASK_COMPLETE;2606		ts->stat = SAS_NAK_R_ERR;2607		break;2608	case IO_XFER_ERROR_PEER_ABORTED:2609		pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_PEER_ABORTED\n");2610		ts->resp = SAS_TASK_COMPLETE;2611		ts->stat = SAS_NAK_R_ERR;2612		break;2613	case IO_XFER_ERROR_REJECTED_NCQ_MODE:2614		pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_REJECTED_NCQ_MODE\n");2615		ts->resp = SAS_TASK_COMPLETE;2616		ts->stat = SAS_DATA_UNDERRUN;2617		break;2618	case IO_XFER_OPEN_RETRY_TIMEOUT:2619		pm8001_dbg(pm8001_ha, IO, "IO_XFER_OPEN_RETRY_TIMEOUT\n");2620		ts->resp = SAS_TASK_COMPLETE;2621		ts->stat = SAS_OPEN_TO;2622		break;2623	case IO_XFER_ERROR_UNEXPECTED_PHASE:2624		pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_UNEXPECTED_PHASE\n");2625		ts->resp = SAS_TASK_COMPLETE;2626		ts->stat = SAS_OPEN_TO;2627		break;2628	case IO_XFER_ERROR_XFER_RDY_OVERRUN:2629		pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_XFER_RDY_OVERRUN\n");2630		ts->resp = SAS_TASK_COMPLETE;2631		ts->stat = SAS_OPEN_TO;2632		break;2633	case IO_XFER_ERROR_XFER_RDY_NOT_EXPECTED:2634		pm8001_dbg(pm8001_ha, IO,2635			   "IO_XFER_ERROR_XFER_RDY_NOT_EXPECTED\n");2636		ts->resp = SAS_TASK_COMPLETE;2637		ts->stat = SAS_OPEN_TO;2638		break;2639	case IO_XFER_ERROR_OFFSET_MISMATCH:2640		pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_OFFSET_MISMATCH\n");2641		ts->resp = SAS_TASK_COMPLETE;2642		ts->stat = SAS_OPEN_TO;2643		break;2644	case IO_XFER_ERROR_XFER_ZERO_DATA_LEN:2645		pm8001_dbg(pm8001_ha, IO,2646			   "IO_XFER_ERROR_XFER_ZERO_DATA_LEN\n");2647		ts->resp = SAS_TASK_COMPLETE;2648		ts->stat = SAS_OPEN_TO;2649		break;2650	case IO_XFER_CMD_FRAME_ISSUED:2651		pm8001_dbg(pm8001_ha, IO, "IO_XFER_CMD_FRAME_ISSUED\n");2652		break;2653	case IO_XFER_PIO_SETUP_ERROR:2654		pm8001_dbg(pm8001_ha, IO, "IO_XFER_PIO_SETUP_ERROR\n");2655		ts->resp = SAS_TASK_COMPLETE;2656		ts->stat = SAS_OPEN_TO;2657		break;2658	default:2659		pm8001_dbg(pm8001_ha, DEVIO, "Unknown status 0x%x\n", event);2660		/* not allowed case. Therefore, return failed status */2661		ts->resp = SAS_TASK_COMPLETE;2662		ts->stat = SAS_OPEN_TO;2663		break;2664	}2665}2666 2667/*See the comments for mpi_ssp_completion */2668static void2669mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)2670{2671	struct sas_task *t;2672	struct pm8001_ccb_info *ccb;2673	unsigned long flags;2674	u32 status;2675	u32 tag;2676	struct smp_completion_resp *psmpPayload;2677	struct task_status_struct *ts;2678	struct pm8001_device *pm8001_dev;2679 2680	psmpPayload = (struct smp_completion_resp *)(piomb + 4);2681	status = le32_to_cpu(psmpPayload->status);2682	tag = le32_to_cpu(psmpPayload->tag);2683 2684	ccb = &pm8001_ha->ccb_info[tag];2685	t = ccb->task;2686	ts = &t->task_status;2687	pm8001_dev = ccb->device;2688	if (status) {2689		pm8001_dbg(pm8001_ha, FAIL, "smp IO status 0x%x\n", status);2690		pm8001_dbg(pm8001_ha, IOERR,2691			   "status:0x%x, tag:0x%x, task:0x%p\n",2692			   status, tag, t);2693	}2694	if (unlikely(!t || !t->lldd_task || !t->dev))2695		return;2696 2697	switch (status) {2698	case IO_SUCCESS:2699		pm8001_dbg(pm8001_ha, IO, "IO_SUCCESS\n");2700		ts->resp = SAS_TASK_COMPLETE;2701		ts->stat = SAS_SAM_STAT_GOOD;2702		if (pm8001_dev)2703			atomic_dec(&pm8001_dev->running_req);2704		break;2705	case IO_ABORTED:2706		pm8001_dbg(pm8001_ha, IO, "IO_ABORTED IOMB\n");2707		ts->resp = SAS_TASK_COMPLETE;2708		ts->stat = SAS_ABORTED_TASK;2709		if (pm8001_dev)2710			atomic_dec(&pm8001_dev->running_req);2711		break;2712	case IO_OVERFLOW:2713		pm8001_dbg(pm8001_ha, IO, "IO_UNDERFLOW\n");2714		ts->resp = SAS_TASK_COMPLETE;2715		ts->stat = SAS_DATA_OVERRUN;2716		ts->residual = 0;2717		if (pm8001_dev)2718			atomic_dec(&pm8001_dev->running_req);2719		break;2720	case IO_NO_DEVICE:2721		pm8001_dbg(pm8001_ha, IO, "IO_NO_DEVICE\n");2722		ts->resp = SAS_TASK_COMPLETE;2723		ts->stat = SAS_PHY_DOWN;2724		break;2725	case IO_ERROR_HW_TIMEOUT:2726		pm8001_dbg(pm8001_ha, IO, "IO_ERROR_HW_TIMEOUT\n");2727		ts->resp = SAS_TASK_COMPLETE;2728		ts->stat = SAS_SAM_STAT_BUSY;2729		break;2730	case IO_XFER_ERROR_BREAK:2731		pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_BREAK\n");2732		ts->resp = SAS_TASK_COMPLETE;2733		ts->stat = SAS_SAM_STAT_BUSY;2734		break;2735	case IO_XFER_ERROR_PHY_NOT_READY:2736		pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_PHY_NOT_READY\n");2737		ts->resp = SAS_TASK_COMPLETE;2738		ts->stat = SAS_SAM_STAT_BUSY;2739		break;2740	case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED:2741		pm8001_dbg(pm8001_ha, IO,2742			   "IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED\n");2743		ts->resp = SAS_TASK_COMPLETE;2744		ts->stat = SAS_OPEN_REJECT;2745		ts->open_rej_reason = SAS_OREJ_UNKNOWN;2746		break;2747	case IO_OPEN_CNX_ERROR_ZONE_VIOLATION:2748		pm8001_dbg(pm8001_ha, IO,2749			   "IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n");2750		ts->resp = SAS_TASK_COMPLETE;2751		ts->stat = SAS_OPEN_REJECT;2752		ts->open_rej_reason = SAS_OREJ_UNKNOWN;2753		break;2754	case IO_OPEN_CNX_ERROR_BREAK:2755		pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_BREAK\n");2756		ts->resp = SAS_TASK_COMPLETE;2757		ts->stat = SAS_OPEN_REJECT;2758		ts->open_rej_reason = SAS_OREJ_RSVD_CONT0;2759		break;2760	case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS:2761		pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n");2762		ts->resp = SAS_TASK_COMPLETE;2763		ts->stat = SAS_OPEN_REJECT;2764		ts->open_rej_reason = SAS_OREJ_UNKNOWN;2765		pm8001_handle_event(pm8001_ha,2766				pm8001_dev,2767				IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);2768		break;2769	case IO_OPEN_CNX_ERROR_BAD_DESTINATION:2770		pm8001_dbg(pm8001_ha, IO,2771			   "IO_OPEN_CNX_ERROR_BAD_DESTINATION\n");2772		ts->resp = SAS_TASK_COMPLETE;2773		ts->stat = SAS_OPEN_REJECT;2774		ts->open_rej_reason = SAS_OREJ_BAD_DEST;2775		break;2776	case IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED:2777		pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n");2778		ts->resp = SAS_TASK_COMPLETE;2779		ts->stat = SAS_OPEN_REJECT;2780		ts->open_rej_reason = SAS_OREJ_CONN_RATE;2781		break;2782	case IO_OPEN_CNX_ERROR_WRONG_DESTINATION:2783		pm8001_dbg(pm8001_ha, IO,2784			   "IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n");2785		ts->resp = SAS_TASK_COMPLETE;2786		ts->stat = SAS_OPEN_REJECT;2787		ts->open_rej_reason = SAS_OREJ_WRONG_DEST;2788		break;2789	case IO_XFER_ERROR_RX_FRAME:2790		pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_RX_FRAME\n");2791		ts->resp = SAS_TASK_COMPLETE;2792		ts->stat = SAS_DEV_NO_RESPONSE;2793		break;2794	case IO_XFER_OPEN_RETRY_TIMEOUT:2795		pm8001_dbg(pm8001_ha, IO, "IO_XFER_OPEN_RETRY_TIMEOUT\n");2796		ts->resp = SAS_TASK_COMPLETE;2797		ts->stat = SAS_OPEN_REJECT;2798		ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;2799		break;2800	case IO_ERROR_INTERNAL_SMP_RESOURCE:2801		pm8001_dbg(pm8001_ha, IO, "IO_ERROR_INTERNAL_SMP_RESOURCE\n");2802		ts->resp = SAS_TASK_COMPLETE;2803		ts->stat = SAS_QUEUE_FULL;2804		break;2805	case IO_PORT_IN_RESET:2806		pm8001_dbg(pm8001_ha, IO, "IO_PORT_IN_RESET\n");2807		ts->resp = SAS_TASK_COMPLETE;2808		ts->stat = SAS_OPEN_REJECT;2809		ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;2810		break;2811	case IO_DS_NON_OPERATIONAL:2812		pm8001_dbg(pm8001_ha, IO, "IO_DS_NON_OPERATIONAL\n");2813		ts->resp = SAS_TASK_COMPLETE;2814		ts->stat = SAS_DEV_NO_RESPONSE;2815		break;2816	case IO_DS_IN_RECOVERY:2817		pm8001_dbg(pm8001_ha, IO, "IO_DS_IN_RECOVERY\n");2818		ts->resp = SAS_TASK_COMPLETE;2819		ts->stat = SAS_OPEN_REJECT;2820		ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;2821		break;2822	case IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY:2823		pm8001_dbg(pm8001_ha, IO,2824			   "IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY\n");2825		ts->resp = SAS_TASK_COMPLETE;2826		ts->stat = SAS_OPEN_REJECT;2827		ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;2828		break;2829	default:2830		pm8001_dbg(pm8001_ha, DEVIO, "Unknown status 0x%x\n", status);2831		ts->resp = SAS_TASK_COMPLETE;2832		ts->stat = SAS_DEV_NO_RESPONSE;2833		/* not allowed case. Therefore, return failed status */2834		break;2835	}2836	spin_lock_irqsave(&t->task_state_lock, flags);2837	t->task_state_flags &= ~SAS_TASK_STATE_PENDING;2838	t->task_state_flags |= SAS_TASK_STATE_DONE;2839	if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) {2840		spin_unlock_irqrestore(&t->task_state_lock, flags);2841		pm8001_dbg(pm8001_ha, FAIL, "task 0x%p done with io_status 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n",2842			   t, status, ts->resp, ts->stat);2843		pm8001_ccb_task_free(pm8001_ha, ccb);2844	} else {2845		spin_unlock_irqrestore(&t->task_state_lock, flags);2846		pm8001_ccb_task_free_done(pm8001_ha, ccb);2847	}2848}2849 2850void pm8001_mpi_set_dev_state_resp(struct pm8001_hba_info *pm8001_ha,2851		void *piomb)2852{2853	struct set_dev_state_resp *pPayload =2854		(struct set_dev_state_resp *)(piomb + 4);2855	u32 tag = le32_to_cpu(pPayload->tag);2856	struct pm8001_ccb_info *ccb = &pm8001_ha->ccb_info[tag];2857	struct pm8001_device *pm8001_dev = ccb->device;2858	u32 status = le32_to_cpu(pPayload->status);2859	u32 device_id = le32_to_cpu(pPayload->device_id);2860	u8 pds = le32_to_cpu(pPayload->pds_nds) & PDS_BITS;2861	u8 nds = le32_to_cpu(pPayload->pds_nds) & NDS_BITS;2862 2863	pm8001_dbg(pm8001_ha, MSG,2864		   "Set device id = 0x%x state from 0x%x to 0x%x status = 0x%x!\n",2865		   device_id, pds, nds, status);2866	complete(pm8001_dev->setds_completion);2867	pm8001_ccb_free(pm8001_ha, ccb);2868}2869 2870void pm8001_mpi_set_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)2871{2872	struct get_nvm_data_resp *pPayload =2873		(struct get_nvm_data_resp *)(piomb + 4);2874	u32 tag = le32_to_cpu(pPayload->tag);2875	struct pm8001_ccb_info *ccb = &pm8001_ha->ccb_info[tag];2876	u32 dlen_status = le32_to_cpu(pPayload->dlen_status);2877 2878	complete(pm8001_ha->nvmd_completion);2879	pm8001_dbg(pm8001_ha, MSG, "Set nvm data complete!\n");2880	if ((dlen_status & NVMD_STAT) != 0) {2881		pm8001_dbg(pm8001_ha, FAIL, "Set nvm data error %x\n",2882				dlen_status);2883	}2884	pm8001_ccb_free(pm8001_ha, ccb);2885}2886 2887void2888pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)2889{2890	struct fw_control_ex    *fw_control_context;2891	struct get_nvm_data_resp *pPayload =2892		(struct get_nvm_data_resp *)(piomb + 4);2893	u32 tag = le32_to_cpu(pPayload->tag);2894	struct pm8001_ccb_info *ccb = &pm8001_ha->ccb_info[tag];2895	u32 dlen_status = le32_to_cpu(pPayload->dlen_status);2896	u32 ir_tds_bn_dps_das_nvm =2897		le32_to_cpu(pPayload->ir_tda_bn_dps_das_nvm);2898	void *virt_addr = pm8001_ha->memoryMap.region[NVMD].virt_ptr;2899	fw_control_context = ccb->fw_control_context;2900 2901	pm8001_dbg(pm8001_ha, MSG, "Get nvm data complete!\n");2902	if ((dlen_status & NVMD_STAT) != 0) {2903		pm8001_dbg(pm8001_ha, FAIL, "Get nvm data error %x\n",2904				dlen_status);2905		complete(pm8001_ha->nvmd_completion);2906		/* We should free tag during failure also, the tag is not being2907		 * freed by requesting path anywhere.2908		 */2909		pm8001_ccb_free(pm8001_ha, ccb);2910		return;2911	}2912	if (ir_tds_bn_dps_das_nvm & IPMode) {2913		/* indirect mode - IR bit set */2914		pm8001_dbg(pm8001_ha, MSG, "Get NVMD success, IR=1\n");2915		if ((ir_tds_bn_dps_das_nvm & NVMD_TYPE) == TWI_DEVICE) {2916			if (ir_tds_bn_dps_das_nvm == 0x80a80200) {2917				memcpy(pm8001_ha->sas_addr,2918				      ((u8 *)virt_addr + 4),2919				       SAS_ADDR_SIZE);2920				pm8001_dbg(pm8001_ha, MSG, "Get SAS address from VPD successfully!\n");2921			}2922		} else if (((ir_tds_bn_dps_das_nvm & NVMD_TYPE) == C_SEEPROM)2923			|| ((ir_tds_bn_dps_das_nvm & NVMD_TYPE) == VPD_FLASH) ||2924			((ir_tds_bn_dps_das_nvm & NVMD_TYPE) == EXPAN_ROM)) {2925				;2926		} else if (((ir_tds_bn_dps_das_nvm & NVMD_TYPE) == AAP1_RDUMP)2927			|| ((ir_tds_bn_dps_das_nvm & NVMD_TYPE) == IOP_RDUMP)) {2928			;2929		} else {2930			/* Should not be happened*/2931			pm8001_dbg(pm8001_ha, MSG,2932				   "(IR=1)Wrong Device type 0x%x\n",2933				   ir_tds_bn_dps_das_nvm);2934		}2935	} else /* direct mode */{2936		pm8001_dbg(pm8001_ha, MSG,2937			   "Get NVMD success, IR=0, dataLen=%d\n",2938			   (dlen_status & NVMD_LEN) >> 24);2939	}2940	/* Though fw_control_context is freed below, usrAddr still needs2941	 * to be updated as this holds the response to the request function2942	 */2943	memcpy(fw_control_context->usrAddr,2944		pm8001_ha->memoryMap.region[NVMD].virt_ptr,2945		fw_control_context->len);2946	kfree(ccb->fw_control_context);2947	/* To avoid race condition, complete should be2948	 * called after the message is copied to2949	 * fw_control_context->usrAddr2950	 */2951	complete(pm8001_ha->nvmd_completion);2952	pm8001_dbg(pm8001_ha, MSG, "Get nvmd data complete!\n");2953	pm8001_ccb_free(pm8001_ha, ccb);2954}2955 2956int pm8001_mpi_local_phy_ctl(struct pm8001_hba_info *pm8001_ha, void *piomb)2957{2958	u32 tag;2959	struct local_phy_ctl_resp *pPayload =2960		(struct local_phy_ctl_resp *)(piomb + 4);2961	u32 status = le32_to_cpu(pPayload->status);2962	u32 phy_id = le32_to_cpu(pPayload->phyop_phyid) & ID_BITS;2963	u32 phy_op = le32_to_cpu(pPayload->phyop_phyid) & OP_BITS;2964	tag = le32_to_cpu(pPayload->tag);2965	if (status != 0) {2966		pm8001_dbg(pm8001_ha, MSG,2967			   "%x phy execute %x phy op failed!\n",2968			   phy_id, phy_op);2969	} else {2970		pm8001_dbg(pm8001_ha, MSG,2971			   "%x phy execute %x phy op success!\n",2972			   phy_id, phy_op);2973		pm8001_ha->phy[phy_id].reset_success = true;2974	}2975	if (pm8001_ha->phy[phy_id].enable_completion) {2976		complete(pm8001_ha->phy[phy_id].enable_completion);2977		pm8001_ha->phy[phy_id].enable_completion = NULL;2978	}2979	pm8001_tag_free(pm8001_ha, tag);2980	return 0;2981}2982 2983/**2984 * pm8001_bytes_dmaed - one of the interface function communication with libsas2985 * @pm8001_ha: our hba card information2986 * @i: which phy that received the event.2987 *2988 * when HBA driver received the identify done event or initiate FIS received2989 * event(for SATA), it will invoke this function to notify the sas layer that2990 * the sas toplogy has formed, please discover the whole sas domain,2991 * while receive a broadcast(change) primitive just tell the sas2992 * layer to discover the changed domain rather than the whole domain.2993 */2994void pm8001_bytes_dmaed(struct pm8001_hba_info *pm8001_ha, int i)2995{2996	struct pm8001_phy *phy = &pm8001_ha->phy[i];2997	struct asd_sas_phy *sas_phy = &phy->sas_phy;2998	if (!phy->phy_attached)2999		return;3000 3001	if (phy->phy_type & PORT_TYPE_SAS) {3002		struct sas_identify_frame *id;3003		id = (struct sas_identify_frame *)phy->frame_rcvd;3004		id->dev_type = phy->identify.device_type;3005		id->initiator_bits = SAS_PROTOCOL_ALL;3006		id->target_bits = phy->identify.target_port_protocols;3007	} else if (phy->phy_type & PORT_TYPE_SATA) {3008		/*Nothing*/3009	}3010	pm8001_dbg(pm8001_ha, MSG, "phy %d byte dmaded.\n", i);3011 3012	sas_phy->frame_rcvd_size = phy->frame_rcvd_size;3013	sas_notify_port_event(sas_phy, PORTE_BYTES_DMAED, GFP_ATOMIC);3014}3015 3016/* Get the link rate speed  */3017void pm8001_get_lrate_mode(struct pm8001_phy *phy, u8 link_rate)3018{3019	struct sas_phy *sas_phy = phy->sas_phy.phy;3020 3021	switch (link_rate) {3022	case PHY_SPEED_120:3023		phy->sas_phy.linkrate = SAS_LINK_RATE_12_0_GBPS;3024		break;3025	case PHY_SPEED_60:3026		phy->sas_phy.linkrate = SAS_LINK_RATE_6_0_GBPS;3027		break;3028	case PHY_SPEED_30:3029		phy->sas_phy.linkrate = SAS_LINK_RATE_3_0_GBPS;3030		break;3031	case PHY_SPEED_15:3032		phy->sas_phy.linkrate = SAS_LINK_RATE_1_5_GBPS;3033		break;3034	}3035	sas_phy->negotiated_linkrate = phy->sas_phy.linkrate;3036	sas_phy->maximum_linkrate_hw = phy->maximum_linkrate;3037	sas_phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;3038	sas_phy->maximum_linkrate = phy->maximum_linkrate;3039	sas_phy->minimum_linkrate = phy->minimum_linkrate;3040}3041 3042/**3043 * pm8001_get_attached_sas_addr - extract/generate attached SAS address3044 * @phy: pointer to asd_phy3045 * @sas_addr: pointer to buffer where the SAS address is to be written3046 *3047 * This function extracts the SAS address from an IDENTIFY frame3048 * received.  If OOB is SATA, then a SAS address is generated from the3049 * HA tables.3050 *3051 * LOCKING: the frame_rcvd_lock needs to be held since this parses the frame3052 * buffer.3053 */3054void pm8001_get_attached_sas_addr(struct pm8001_phy *phy,3055	u8 *sas_addr)3056{3057	if (phy->sas_phy.frame_rcvd[0] == 0x343058		&& phy->sas_phy.oob_mode == SATA_OOB_MODE) {3059		struct pm8001_hba_info *pm8001_ha = phy->sas_phy.ha->lldd_ha;3060		/* FIS device-to-host */3061		u64 addr = be64_to_cpu(*(__be64 *)pm8001_ha->sas_addr);3062		addr += phy->sas_phy.id;3063		*(__be64 *)sas_addr = cpu_to_be64(addr);3064	} else {3065		struct sas_identify_frame *idframe =3066			(void *) phy->sas_phy.frame_rcvd;3067		memcpy(sas_addr, idframe->sas_addr, SAS_ADDR_SIZE);3068	}3069}3070 3071/**3072 * pm8001_hw_event_ack_req- For PM8001,some events need to acknowage to FW.3073 * @pm8001_ha: our hba card information3074 * @Qnum: the outbound queue message number.3075 * @SEA: source of event to ack3076 * @port_id: port id.3077 * @phyId: phy id.3078 * @param0: parameter 0.3079 * @param1: parameter 1.3080 */3081static void pm8001_hw_event_ack_req(struct pm8001_hba_info *pm8001_ha,3082	u32 Qnum, u32 SEA, u32 port_id, u32 phyId, u32 param0, u32 param1)3083{3084	struct hw_event_ack_req	 payload;3085	u32 opc = OPC_INB_SAS_HW_EVENT_ACK;3086 3087	memset((u8 *)&payload, 0, sizeof(payload));3088	payload.tag = cpu_to_le32(1);3089	payload.sea_phyid_portid = cpu_to_le32(((SEA & 0xFFFF) << 8) |3090		((phyId & 0x0F) << 4) | (port_id & 0x0F));3091	payload.param0 = cpu_to_le32(param0);3092	payload.param1 = cpu_to_le32(param1);3093 3094	pm8001_mpi_build_cmd(pm8001_ha, Qnum, opc, &payload, sizeof(payload), 0);3095}3096 3097static int pm8001_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha,3098	u32 phyId, u32 phy_op);3099 3100/**3101 * hw_event_sas_phy_up -FW tells me a SAS phy up event.3102 * @pm8001_ha: our hba card information3103 * @piomb: IO message buffer3104 */3105static void3106hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb)3107{3108	struct hw_event_resp *pPayload =3109		(struct hw_event_resp *)(piomb + 4);3110	u32 lr_evt_status_phyid_portid =3111		le32_to_cpu(pPayload->lr_evt_status_phyid_portid);3112	u8 link_rate =3113		(u8)((lr_evt_status_phyid_portid & 0xF0000000) >> 28);3114	u8 port_id = (u8)(lr_evt_status_phyid_portid & 0x0000000F);3115	u8 phy_id =3116		(u8)((lr_evt_status_phyid_portid & 0x000000F0) >> 4);3117	u32 npip_portstate = le32_to_cpu(pPayload->npip_portstate);3118	u8 portstate = (u8)(npip_portstate & 0x0000000F);3119	struct pm8001_port *port = &pm8001_ha->port[port_id];3120	struct pm8001_phy *phy = &pm8001_ha->phy[phy_id];3121	unsigned long flags;3122	u8 deviceType = pPayload->sas_identify.dev_type;3123	phy->port = port;3124	port->port_id = port_id;3125	port->port_state =  portstate;3126	phy->phy_state = PHY_STATE_LINK_UP_SPC;3127	pm8001_dbg(pm8001_ha, MSG,3128		   "HW_EVENT_SAS_PHY_UP port id = %d, phy id = %d\n",3129		   port_id, phy_id);3130 3131	switch (deviceType) {3132	case SAS_PHY_UNUSED:3133		pm8001_dbg(pm8001_ha, MSG, "device type no device.\n");3134		break;3135	case SAS_END_DEVICE:3136		pm8001_dbg(pm8001_ha, MSG, "end device.\n");3137		pm8001_chip_phy_ctl_req(pm8001_ha, phy_id,3138			PHY_NOTIFY_ENABLE_SPINUP);3139		port->port_attached = 1;3140		pm8001_get_lrate_mode(phy, link_rate);3141		break;3142	case SAS_EDGE_EXPANDER_DEVICE:3143		pm8001_dbg(pm8001_ha, MSG, "expander device.\n");3144		port->port_attached = 1;3145		pm8001_get_lrate_mode(phy, link_rate);3146		break;3147	case SAS_FANOUT_EXPANDER_DEVICE:3148		pm8001_dbg(pm8001_ha, MSG, "fanout expander device.\n");3149		port->port_attached = 1;3150		pm8001_get_lrate_mode(phy, link_rate);3151		break;3152	default:3153		pm8001_dbg(pm8001_ha, DEVIO, "unknown device type(%x)\n",3154			   deviceType);3155		break;3156	}3157	phy->phy_type |= PORT_TYPE_SAS;3158	phy->identify.device_type = deviceType;3159	phy->phy_attached = 1;3160	if (phy->identify.device_type == SAS_END_DEVICE)3161		phy->identify.target_port_protocols = SAS_PROTOCOL_SSP;3162	else if (phy->identify.device_type != SAS_PHY_UNUSED)3163		phy->identify.target_port_protocols = SAS_PROTOCOL_SMP;3164	phy->sas_phy.oob_mode = SAS_OOB_MODE;3165	sas_notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE, GFP_ATOMIC);3166	spin_lock_irqsave(&phy->sas_phy.frame_rcvd_lock, flags);3167	memcpy(phy->frame_rcvd, &pPayload->sas_identify,3168		sizeof(struct sas_identify_frame)-4);3169	phy->frame_rcvd_size = sizeof(struct sas_identify_frame) - 4;3170	pm8001_get_attached_sas_addr(phy, phy->sas_phy.attached_sas_addr);3171	spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags);3172	if (pm8001_ha->flags == PM8001F_RUN_TIME)3173		mdelay(200);/*delay a moment to wait disk to spinup*/3174	pm8001_bytes_dmaed(pm8001_ha, phy_id);3175}3176 3177/**3178 * hw_event_sata_phy_up -FW tells me a SATA phy up event.3179 * @pm8001_ha: our hba card information3180 * @piomb: IO message buffer3181 */3182static void3183hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb)3184{3185	struct hw_event_resp *pPayload =3186		(struct hw_event_resp *)(piomb + 4);3187	u32 lr_evt_status_phyid_portid =3188		le32_to_cpu(pPayload->lr_evt_status_phyid_portid);3189	u8 link_rate =3190		(u8)((lr_evt_status_phyid_portid & 0xF0000000) >> 28);3191	u8 port_id = (u8)(lr_evt_status_phyid_portid & 0x0000000F);3192	u8 phy_id =3193		(u8)((lr_evt_status_phyid_portid & 0x000000F0) >> 4);3194	u32 npip_portstate = le32_to_cpu(pPayload->npip_portstate);3195	u8 portstate = (u8)(npip_portstate & 0x0000000F);3196	struct pm8001_port *port = &pm8001_ha->port[port_id];3197	struct pm8001_phy *phy = &pm8001_ha->phy[phy_id];3198	unsigned long flags;3199	pm8001_dbg(pm8001_ha, DEVIO, "HW_EVENT_SATA_PHY_UP port id = %d, phy id = %d\n",3200		   port_id, phy_id);3201	phy->port = port;3202	port->port_id = port_id;3203	port->port_state =  portstate;3204	phy->phy_state = PHY_STATE_LINK_UP_SPC;3205	port->port_attached = 1;3206	pm8001_get_lrate_mode(phy, link_rate);3207	phy->phy_type |= PORT_TYPE_SATA;3208	phy->phy_attached = 1;3209	phy->sas_phy.oob_mode = SATA_OOB_MODE;3210	sas_notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE, GFP_ATOMIC);3211	spin_lock_irqsave(&phy->sas_phy.frame_rcvd_lock, flags);3212	memcpy(phy->frame_rcvd, ((u8 *)&pPayload->sata_fis - 4),3213		sizeof(struct dev_to_host_fis));3214	phy->frame_rcvd_size = sizeof(struct dev_to_host_fis);3215	phy->identify.target_port_protocols = SAS_PROTOCOL_SATA;3216	phy->identify.device_type = SAS_SATA_DEV;3217	pm8001_get_attached_sas_addr(phy, phy->sas_phy.attached_sas_addr);3218	spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags);3219	pm8001_bytes_dmaed(pm8001_ha, phy_id);3220}3221 3222/**3223 * hw_event_phy_down -we should notify the libsas the phy is down.3224 * @pm8001_ha: our hba card information3225 * @piomb: IO message buffer3226 */3227static void3228hw_event_phy_down(struct pm8001_hba_info *pm8001_ha, void *piomb)3229{3230	struct hw_event_resp *pPayload =3231		(struct hw_event_resp *)(piomb + 4);3232	u32 lr_evt_status_phyid_portid =3233		le32_to_cpu(pPayload->lr_evt_status_phyid_portid);3234	u8 port_id = (u8)(lr_evt_status_phyid_portid & 0x0000000F);3235	u8 phy_id =3236		(u8)((lr_evt_status_phyid_portid & 0x000000F0) >> 4);3237	u32 npip_portstate = le32_to_cpu(pPayload->npip_portstate);3238	u8 portstate = (u8)(npip_portstate & 0x0000000F);3239	struct pm8001_port *port = &pm8001_ha->port[port_id];3240	struct pm8001_phy *phy = &pm8001_ha->phy[phy_id];3241	port->port_state =  portstate;3242	phy->phy_type = 0;3243	phy->identify.device_type = 0;3244	phy->phy_attached = 0;3245	memset(&phy->dev_sas_addr, 0, SAS_ADDR_SIZE);3246	switch (portstate) {3247	case PORT_VALID:3248		break;3249	case PORT_INVALID:3250		pm8001_dbg(pm8001_ha, MSG, " PortInvalid portID %d\n",3251			   port_id);3252		pm8001_dbg(pm8001_ha, MSG,3253			   " Last phy Down and port invalid\n");3254		port->port_attached = 0;3255		pm8001_hw_event_ack_req(pm8001_ha, 0, HW_EVENT_PHY_DOWN,3256			port_id, phy_id, 0, 0);3257		break;3258	case PORT_IN_RESET:3259		pm8001_dbg(pm8001_ha, MSG, " Port In Reset portID %d\n",3260			   port_id);3261		break;3262	case PORT_NOT_ESTABLISHED:3263		pm8001_dbg(pm8001_ha, MSG,3264			   " phy Down and PORT_NOT_ESTABLISHED\n");3265		port->port_attached = 0;3266		break;3267	case PORT_LOSTCOMM:3268		pm8001_dbg(pm8001_ha, MSG, " phy Down and PORT_LOSTCOMM\n");3269		pm8001_dbg(pm8001_ha, MSG,3270			   " Last phy Down and port invalid\n");3271		port->port_attached = 0;3272		pm8001_hw_event_ack_req(pm8001_ha, 0, HW_EVENT_PHY_DOWN,3273			port_id, phy_id, 0, 0);3274		break;3275	default:3276		port->port_attached = 0;3277		pm8001_dbg(pm8001_ha, DEVIO, " phy Down and(default) = %x\n",3278			   portstate);3279		break;3280 3281	}3282}3283 3284/**3285 * pm8001_mpi_reg_resp -process register device ID response.3286 * @pm8001_ha: our hba card information3287 * @piomb: IO message buffer3288 *3289 * when sas layer find a device it will notify LLDD, then the driver register3290 * the domain device to FW, this event is the return device ID which the FW3291 * has assigned, from now, inter-communication with FW is no longer using the3292 * SAS address, use device ID which FW assigned.3293 */3294int pm8001_mpi_reg_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)3295{3296	u32 status;3297	u32 device_id;3298	u32 htag;3299	struct pm8001_ccb_info *ccb;3300	struct pm8001_device *pm8001_dev;3301	struct dev_reg_resp *registerRespPayload =3302		(struct dev_reg_resp *)(piomb + 4);3303 3304	htag = le32_to_cpu(registerRespPayload->tag);3305	ccb = &pm8001_ha->ccb_info[htag];3306	pm8001_dev = ccb->device;3307	status = le32_to_cpu(registerRespPayload->status);3308	device_id = le32_to_cpu(registerRespPayload->device_id);3309	pm8001_dbg(pm8001_ha, INIT,3310		   "register device status %d phy_id 0x%x device_id %d\n",3311		   status, pm8001_dev->attached_phy, device_id);3312	switch (status) {3313	case DEVREG_SUCCESS:3314		pm8001_dbg(pm8001_ha, MSG, "DEVREG_SUCCESS\n");3315		pm8001_dev->device_id = device_id;3316		break;3317	case DEVREG_FAILURE_OUT_OF_RESOURCE:3318		pm8001_dbg(pm8001_ha, MSG, "DEVREG_FAILURE_OUT_OF_RESOURCE\n");3319		break;3320	case DEVREG_FAILURE_DEVICE_ALREADY_REGISTERED:3321		pm8001_dbg(pm8001_ha, MSG,3322			   "DEVREG_FAILURE_DEVICE_ALREADY_REGISTERED\n");3323		break;3324	case DEVREG_FAILURE_INVALID_PHY_ID:3325		pm8001_dbg(pm8001_ha, MSG, "DEVREG_FAILURE_INVALID_PHY_ID\n");3326		break;3327	case DEVREG_FAILURE_PHY_ID_ALREADY_REGISTERED:3328		pm8001_dbg(pm8001_ha, MSG,3329			   "DEVREG_FAILURE_PHY_ID_ALREADY_REGISTERED\n");3330		break;3331	case DEVREG_FAILURE_PORT_ID_OUT_OF_RANGE:3332		pm8001_dbg(pm8001_ha, MSG,3333			   "DEVREG_FAILURE_PORT_ID_OUT_OF_RANGE\n");3334		break;3335	case DEVREG_FAILURE_PORT_NOT_VALID_STATE:3336		pm8001_dbg(pm8001_ha, MSG,3337			   "DEVREG_FAILURE_PORT_NOT_VALID_STATE\n");3338		break;3339	case DEVREG_FAILURE_DEVICE_TYPE_NOT_VALID:3340		pm8001_dbg(pm8001_ha, MSG,3341			   "DEVREG_FAILURE_DEVICE_TYPE_NOT_VALID\n");3342		break;3343	default:3344		pm8001_dbg(pm8001_ha, MSG,3345			   "DEVREG_FAILURE_DEVICE_TYPE_NOT_SUPPORTED\n");3346		break;3347	}3348	complete(pm8001_dev->dcompletion);3349	pm8001_ccb_free(pm8001_ha, ccb);3350	return 0;3351}3352 3353int pm8001_mpi_dereg_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)3354{3355	u32 status;3356	u32 device_id;3357	struct dev_reg_resp *registerRespPayload =3358		(struct dev_reg_resp *)(piomb + 4);3359 3360	status = le32_to_cpu(registerRespPayload->status);3361	device_id = le32_to_cpu(registerRespPayload->device_id);3362	if (status != 0)3363		pm8001_dbg(pm8001_ha, MSG,3364			   " deregister device failed ,status = %x, device_id = %x\n",3365			   status, device_id);3366	return 0;3367}3368 3369/**3370 * pm8001_mpi_fw_flash_update_resp - Response from FW for flash update command.3371 * @pm8001_ha: our hba card information3372 * @piomb: IO message buffer3373 */3374int pm8001_mpi_fw_flash_update_resp(struct pm8001_hba_info *pm8001_ha,3375		void *piomb)3376{3377	u32 status;3378	struct fw_flash_Update_resp *ppayload =3379		(struct fw_flash_Update_resp *)(piomb + 4);3380	u32 tag = le32_to_cpu(ppayload->tag);3381	struct pm8001_ccb_info *ccb = &pm8001_ha->ccb_info[tag];3382 3383	status = le32_to_cpu(ppayload->status);3384	switch (status) {3385	case FLASH_UPDATE_COMPLETE_PENDING_REBOOT:3386		pm8001_dbg(pm8001_ha, MSG,3387			   ": FLASH_UPDATE_COMPLETE_PENDING_REBOOT\n");3388		break;3389	case FLASH_UPDATE_IN_PROGRESS:3390		pm8001_dbg(pm8001_ha, MSG, ": FLASH_UPDATE_IN_PROGRESS\n");3391		break;3392	case FLASH_UPDATE_HDR_ERR:3393		pm8001_dbg(pm8001_ha, MSG, ": FLASH_UPDATE_HDR_ERR\n");3394		break;3395	case FLASH_UPDATE_OFFSET_ERR:3396		pm8001_dbg(pm8001_ha, MSG, ": FLASH_UPDATE_OFFSET_ERR\n");3397		break;3398	case FLASH_UPDATE_CRC_ERR:3399		pm8001_dbg(pm8001_ha, MSG, ": FLASH_UPDATE_CRC_ERR\n");3400		break;3401	case FLASH_UPDATE_LENGTH_ERR:3402		pm8001_dbg(pm8001_ha, MSG, ": FLASH_UPDATE_LENGTH_ERR\n");3403		break;3404	case FLASH_UPDATE_HW_ERR:3405		pm8001_dbg(pm8001_ha, MSG, ": FLASH_UPDATE_HW_ERR\n");3406		break;3407	case FLASH_UPDATE_DNLD_NOT_SUPPORTED:3408		pm8001_dbg(pm8001_ha, MSG,3409			   ": FLASH_UPDATE_DNLD_NOT_SUPPORTED\n");3410		break;3411	case FLASH_UPDATE_DISABLED:3412		pm8001_dbg(pm8001_ha, MSG, ": FLASH_UPDATE_DISABLED\n");3413		break;3414	default:3415		pm8001_dbg(pm8001_ha, DEVIO, "No matched status = %d\n",3416			   status);3417		break;3418	}3419	kfree(ccb->fw_control_context);3420	pm8001_ccb_free(pm8001_ha, ccb);3421	complete(pm8001_ha->nvmd_completion);3422	return 0;3423}3424 3425int pm8001_mpi_general_event(struct pm8001_hba_info *pm8001_ha, void *piomb)3426{3427	u32 status;3428	int i;3429	struct general_event_resp *pPayload =3430		(struct general_event_resp *)(piomb + 4);3431	status = le32_to_cpu(pPayload->status);3432	pm8001_dbg(pm8001_ha, MSG, " status = 0x%x\n", status);3433	for (i = 0; i < GENERAL_EVENT_PAYLOAD; i++)3434		pm8001_dbg(pm8001_ha, MSG, "inb_IOMB_payload[0x%x] 0x%x,\n",3435			   i,3436			   pPayload->inb_IOMB_payload[i]);3437	return 0;3438}3439 3440int pm8001_mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)3441{3442	struct sas_task *t;3443	struct pm8001_ccb_info *ccb;3444	unsigned long flags;3445	u32 status ;3446	u32 tag, scp;3447	struct task_status_struct *ts;3448	struct pm8001_device *pm8001_dev;3449 3450	struct task_abort_resp *pPayload =3451		(struct task_abort_resp *)(piomb + 4);3452 3453	status = le32_to_cpu(pPayload->status);3454	tag = le32_to_cpu(pPayload->tag);3455 3456	scp = le32_to_cpu(pPayload->scp);3457	ccb = &pm8001_ha->ccb_info[tag];3458	t = ccb->task;3459	pm8001_dev = ccb->device; /* retrieve device */3460 3461	if (!t)	{3462		pm8001_dbg(pm8001_ha, FAIL, " TASK NULL. RETURNING !!!\n");3463		return -1;3464	}3465 3466	if (t->task_proto == SAS_PROTOCOL_INTERNAL_ABORT)3467		atomic_dec(&pm8001_dev->running_req);3468 3469	ts = &t->task_status;3470	if (status != 0)3471		pm8001_dbg(pm8001_ha, FAIL, "task abort failed status 0x%x ,tag = 0x%x, scp= 0x%x\n",3472			   status, tag, scp);3473	switch (status) {3474	case IO_SUCCESS:3475		pm8001_dbg(pm8001_ha, EH, "IO_SUCCESS\n");3476		ts->resp = SAS_TASK_COMPLETE;3477		ts->stat = SAS_SAM_STAT_GOOD;3478		break;3479	case IO_NOT_VALID:3480		pm8001_dbg(pm8001_ha, EH, "IO_NOT_VALID\n");3481		ts->resp = TMF_RESP_FUNC_FAILED;3482		break;3483	}3484	spin_lock_irqsave(&t->task_state_lock, flags);3485	t->task_state_flags &= ~SAS_TASK_STATE_PENDING;3486	t->task_state_flags |= SAS_TASK_STATE_DONE;3487	spin_unlock_irqrestore(&t->task_state_lock, flags);3488	pm8001_ccb_task_free(pm8001_ha, ccb);3489	mb();3490 3491	t->task_done(t);3492 3493	return 0;3494}3495 3496/**3497 * mpi_hw_event -The hw event has come.3498 * @pm8001_ha: our hba card information3499 * @piomb: IO message buffer3500 */3501static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb)3502{3503	unsigned long flags;3504	struct hw_event_resp *pPayload =3505		(struct hw_event_resp *)(piomb + 4);3506	u32 lr_evt_status_phyid_portid =3507		le32_to_cpu(pPayload->lr_evt_status_phyid_portid);3508	u8 port_id = (u8)(lr_evt_status_phyid_portid & 0x0000000F);3509	u8 phy_id =3510		(u8)((lr_evt_status_phyid_portid & 0x000000F0) >> 4);3511	u16 eventType =3512		(u16)((lr_evt_status_phyid_portid & 0x00FFFF00) >> 8);3513	u8 status =3514		(u8)((lr_evt_status_phyid_portid & 0x0F000000) >> 24);3515	struct sas_ha_struct *sas_ha = pm8001_ha->sas;3516	struct pm8001_phy *phy = &pm8001_ha->phy[phy_id];3517	struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id];3518	pm8001_dbg(pm8001_ha, DEVIO,3519		   "SPC HW event for portid:%d, phyid:%d, event:%x, status:%x\n",3520		   port_id, phy_id, eventType, status);3521	switch (eventType) {3522	case HW_EVENT_PHY_START_STATUS:3523		pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PHY_START_STATUS status = %x\n",3524			   status);3525		if (status == 0)3526			phy->phy_state = 1;3527 3528		if (pm8001_ha->flags == PM8001F_RUN_TIME &&3529				phy->enable_completion != NULL) {3530			complete(phy->enable_completion);3531			phy->enable_completion = NULL;3532		}3533		break;3534	case HW_EVENT_SAS_PHY_UP:3535		pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PHY_START_STATUS\n");3536		hw_event_sas_phy_up(pm8001_ha, piomb);3537		break;3538	case HW_EVENT_SATA_PHY_UP:3539		pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_SATA_PHY_UP\n");3540		hw_event_sata_phy_up(pm8001_ha, piomb);3541		break;3542	case HW_EVENT_PHY_STOP_STATUS:3543		pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PHY_STOP_STATUS status = %x\n",3544			   status);3545		if (status == 0)3546			phy->phy_state = 0;3547		break;3548	case HW_EVENT_SATA_SPINUP_HOLD:3549		pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_SATA_SPINUP_HOLD\n");3550		sas_notify_phy_event(&phy->sas_phy, PHYE_SPINUP_HOLD,3551			GFP_ATOMIC);3552		break;3553	case HW_EVENT_PHY_DOWN:3554		pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PHY_DOWN\n");3555		sas_notify_phy_event(&phy->sas_phy, PHYE_LOSS_OF_SIGNAL,3556			GFP_ATOMIC);3557		phy->phy_attached = 0;3558		phy->phy_state = 0;3559		hw_event_phy_down(pm8001_ha, piomb);3560		break;3561	case HW_EVENT_PORT_INVALID:3562		pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PORT_INVALID\n");3563		sas_phy_disconnected(sas_phy);3564		phy->phy_attached = 0;3565		sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR,3566			GFP_ATOMIC);3567		break;3568	/* the broadcast change primitive received, tell the LIBSAS this event3569	to revalidate the sas domain*/3570	case HW_EVENT_BROADCAST_CHANGE:3571		pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_BROADCAST_CHANGE\n");3572		pm8001_hw_event_ack_req(pm8001_ha, 0, HW_EVENT_BROADCAST_CHANGE,3573			port_id, phy_id, 1, 0);3574		spin_lock_irqsave(&sas_phy->sas_prim_lock, flags);3575		sas_phy->sas_prim = HW_EVENT_BROADCAST_CHANGE;3576		spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags);3577		sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD,3578			GFP_ATOMIC);3579		break;3580	case HW_EVENT_PHY_ERROR:3581		pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PHY_ERROR\n");3582		sas_phy_disconnected(&phy->sas_phy);3583		phy->phy_attached = 0;3584		sas_notify_phy_event(&phy->sas_phy, PHYE_OOB_ERROR, GFP_ATOMIC);3585		break;3586	case HW_EVENT_BROADCAST_EXP:3587		pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_BROADCAST_EXP\n");3588		spin_lock_irqsave(&sas_phy->sas_prim_lock, flags);3589		sas_phy->sas_prim = HW_EVENT_BROADCAST_EXP;3590		spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags);3591		sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD,3592			GFP_ATOMIC);3593		break;3594	case HW_EVENT_LINK_ERR_INVALID_DWORD:3595		pm8001_dbg(pm8001_ha, MSG,3596			   "HW_EVENT_LINK_ERR_INVALID_DWORD\n");3597		pm8001_hw_event_ack_req(pm8001_ha, 0,3598			HW_EVENT_LINK_ERR_INVALID_DWORD, port_id, phy_id, 0, 0);3599		sas_phy_disconnected(sas_phy);3600		phy->phy_attached = 0;3601		sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR,3602			GFP_ATOMIC);3603		break;3604	case HW_EVENT_LINK_ERR_DISPARITY_ERROR:3605		pm8001_dbg(pm8001_ha, MSG,3606			   "HW_EVENT_LINK_ERR_DISPARITY_ERROR\n");3607		pm8001_hw_event_ack_req(pm8001_ha, 0,3608			HW_EVENT_LINK_ERR_DISPARITY_ERROR,3609			port_id, phy_id, 0, 0);3610		sas_phy_disconnected(sas_phy);3611		phy->phy_attached = 0;3612		sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR,3613			GFP_ATOMIC);3614		break;3615	case HW_EVENT_LINK_ERR_CODE_VIOLATION:3616		pm8001_dbg(pm8001_ha, MSG,3617			   "HW_EVENT_LINK_ERR_CODE_VIOLATION\n");3618		pm8001_hw_event_ack_req(pm8001_ha, 0,3619			HW_EVENT_LINK_ERR_CODE_VIOLATION,3620			port_id, phy_id, 0, 0);3621		sas_phy_disconnected(sas_phy);3622		phy->phy_attached = 0;3623		sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR,3624			GFP_ATOMIC);3625		break;3626	case HW_EVENT_LINK_ERR_LOSS_OF_DWORD_SYNCH:3627		pm8001_dbg(pm8001_ha, MSG,3628			   "HW_EVENT_LINK_ERR_LOSS_OF_DWORD_SYNCH\n");3629		pm8001_hw_event_ack_req(pm8001_ha, 0,3630			HW_EVENT_LINK_ERR_LOSS_OF_DWORD_SYNCH,3631			port_id, phy_id, 0, 0);3632		sas_phy_disconnected(sas_phy);3633		phy->phy_attached = 0;3634		sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR,3635			GFP_ATOMIC);3636		break;3637	case HW_EVENT_MALFUNCTION:3638		pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_MALFUNCTION\n");3639		break;3640	case HW_EVENT_BROADCAST_SES:3641		pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_BROADCAST_SES\n");3642		spin_lock_irqsave(&sas_phy->sas_prim_lock, flags);3643		sas_phy->sas_prim = HW_EVENT_BROADCAST_SES;3644		spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags);3645		sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD,3646			GFP_ATOMIC);3647		break;3648	case HW_EVENT_INBOUND_CRC_ERROR:3649		pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_INBOUND_CRC_ERROR\n");3650		pm8001_hw_event_ack_req(pm8001_ha, 0,3651			HW_EVENT_INBOUND_CRC_ERROR,3652			port_id, phy_id, 0, 0);3653		break;3654	case HW_EVENT_HARD_RESET_RECEIVED:3655		pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_HARD_RESET_RECEIVED\n");3656		sas_notify_port_event(sas_phy, PORTE_HARD_RESET, GFP_ATOMIC);3657		break;3658	case HW_EVENT_ID_FRAME_TIMEOUT:3659		pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_ID_FRAME_TIMEOUT\n");3660		sas_phy_disconnected(sas_phy);3661		phy->phy_attached = 0;3662		sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR,3663			GFP_ATOMIC);3664		break;3665	case HW_EVENT_LINK_ERR_PHY_RESET_FAILED:3666		pm8001_dbg(pm8001_ha, MSG,3667			   "HW_EVENT_LINK_ERR_PHY_RESET_FAILED\n");3668		pm8001_hw_event_ack_req(pm8001_ha, 0,3669			HW_EVENT_LINK_ERR_PHY_RESET_FAILED,3670			port_id, phy_id, 0, 0);3671		sas_phy_disconnected(sas_phy);3672		phy->phy_attached = 0;3673		sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR,3674			GFP_ATOMIC);3675		break;3676	case HW_EVENT_PORT_RESET_TIMER_TMO:3677		pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PORT_RESET_TIMER_TMO\n");3678		sas_phy_disconnected(sas_phy);3679		phy->phy_attached = 0;3680		sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR,3681			GFP_ATOMIC);3682		break;3683	case HW_EVENT_PORT_RECOVERY_TIMER_TMO:3684		pm8001_dbg(pm8001_ha, MSG,3685			   "HW_EVENT_PORT_RECOVERY_TIMER_TMO\n");3686		sas_phy_disconnected(sas_phy);3687		phy->phy_attached = 0;3688		sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR,3689			GFP_ATOMIC);3690		break;3691	case HW_EVENT_PORT_RECOVER:3692		pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PORT_RECOVER\n");3693		break;3694	case HW_EVENT_PORT_RESET_COMPLETE:3695		pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PORT_RESET_COMPLETE\n");3696		break;3697	case EVENT_BROADCAST_ASYNCH_EVENT:3698		pm8001_dbg(pm8001_ha, MSG, "EVENT_BROADCAST_ASYNCH_EVENT\n");3699		break;3700	default:3701		pm8001_dbg(pm8001_ha, DEVIO, "Unknown event type = %x\n",3702			   eventType);3703		break;3704	}3705	return 0;3706}3707 3708/**3709 * process_one_iomb - process one outbound Queue memory block3710 * @pm8001_ha: our hba card information3711 * @piomb: IO message buffer3712 */3713static void process_one_iomb(struct pm8001_hba_info *pm8001_ha, void *piomb)3714{3715	__le32 pHeader = *(__le32 *)piomb;3716	u8 opc = (u8)((le32_to_cpu(pHeader)) & 0xFFF);3717 3718	pm8001_dbg(pm8001_ha, MSG, "process_one_iomb:\n");3719 3720	switch (opc) {3721	case OPC_OUB_ECHO:3722		pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_ECHO\n");3723		break;3724	case OPC_OUB_HW_EVENT:3725		pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_HW_EVENT\n");3726		mpi_hw_event(pm8001_ha, piomb);3727		break;3728	case OPC_OUB_SSP_COMP:3729		pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SSP_COMP\n");3730		mpi_ssp_completion(pm8001_ha, piomb);3731		break;3732	case OPC_OUB_SMP_COMP:3733		pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SMP_COMP\n");3734		mpi_smp_completion(pm8001_ha, piomb);3735		break;3736	case OPC_OUB_LOCAL_PHY_CNTRL:3737		pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_LOCAL_PHY_CNTRL\n");3738		pm8001_mpi_local_phy_ctl(pm8001_ha, piomb);3739		break;3740	case OPC_OUB_DEV_REGIST:3741		pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_DEV_REGIST\n");3742		pm8001_mpi_reg_resp(pm8001_ha, piomb);3743		break;3744	case OPC_OUB_DEREG_DEV:3745		pm8001_dbg(pm8001_ha, MSG, "unregister the device\n");3746		pm8001_mpi_dereg_resp(pm8001_ha, piomb);3747		break;3748	case OPC_OUB_GET_DEV_HANDLE:3749		pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_GET_DEV_HANDLE\n");3750		break;3751	case OPC_OUB_SATA_COMP:3752		pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SATA_COMP\n");3753		mpi_sata_completion(pm8001_ha, piomb);3754		break;3755	case OPC_OUB_SATA_EVENT:3756		pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SATA_EVENT\n");3757		mpi_sata_event(pm8001_ha, piomb);3758		break;3759	case OPC_OUB_SSP_EVENT:3760		pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SSP_EVENT\n");3761		mpi_ssp_event(pm8001_ha, piomb);3762		break;3763	case OPC_OUB_DEV_HANDLE_ARRIV:3764		pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_DEV_HANDLE_ARRIV\n");3765		/*This is for target*/3766		break;3767	case OPC_OUB_SSP_RECV_EVENT:3768		pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SSP_RECV_EVENT\n");3769		/*This is for target*/3770		break;3771	case OPC_OUB_DEV_INFO:3772		pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_DEV_INFO\n");3773		break;3774	case OPC_OUB_FW_FLASH_UPDATE:3775		pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_FW_FLASH_UPDATE\n");3776		pm8001_mpi_fw_flash_update_resp(pm8001_ha, piomb);3777		break;3778	case OPC_OUB_GPIO_RESPONSE:3779		pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_GPIO_RESPONSE\n");3780		break;3781	case OPC_OUB_GPIO_EVENT:3782		pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_GPIO_EVENT\n");3783		break;3784	case OPC_OUB_GENERAL_EVENT:3785		pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_GENERAL_EVENT\n");3786		pm8001_mpi_general_event(pm8001_ha, piomb);3787		break;3788	case OPC_OUB_SSP_ABORT_RSP:3789		pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SSP_ABORT_RSP\n");3790		pm8001_mpi_task_abort_resp(pm8001_ha, piomb);3791		break;3792	case OPC_OUB_SATA_ABORT_RSP:3793		pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SATA_ABORT_RSP\n");3794		pm8001_mpi_task_abort_resp(pm8001_ha, piomb);3795		break;3796	case OPC_OUB_SAS_DIAG_MODE_START_END:3797		pm8001_dbg(pm8001_ha, MSG,3798			   "OPC_OUB_SAS_DIAG_MODE_START_END\n");3799		break;3800	case OPC_OUB_SAS_DIAG_EXECUTE:3801		pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SAS_DIAG_EXECUTE\n");3802		break;3803	case OPC_OUB_GET_TIME_STAMP:3804		pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_GET_TIME_STAMP\n");3805		break;3806	case OPC_OUB_SAS_HW_EVENT_ACK:3807		pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SAS_HW_EVENT_ACK\n");3808		break;3809	case OPC_OUB_PORT_CONTROL:3810		pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_PORT_CONTROL\n");3811		break;3812	case OPC_OUB_SMP_ABORT_RSP:3813		pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SMP_ABORT_RSP\n");3814		pm8001_mpi_task_abort_resp(pm8001_ha, piomb);3815		break;3816	case OPC_OUB_GET_NVMD_DATA:3817		pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_GET_NVMD_DATA\n");3818		pm8001_mpi_get_nvmd_resp(pm8001_ha, piomb);3819		break;3820	case OPC_OUB_SET_NVMD_DATA:3821		pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SET_NVMD_DATA\n");3822		pm8001_mpi_set_nvmd_resp(pm8001_ha, piomb);3823		break;3824	case OPC_OUB_DEVICE_HANDLE_REMOVAL:3825		pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_DEVICE_HANDLE_REMOVAL\n");3826		break;3827	case OPC_OUB_SET_DEVICE_STATE:3828		pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SET_DEVICE_STATE\n");3829		pm8001_mpi_set_dev_state_resp(pm8001_ha, piomb);3830		break;3831	case OPC_OUB_GET_DEVICE_STATE:3832		pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_GET_DEVICE_STATE\n");3833		break;3834	case OPC_OUB_SET_DEV_INFO:3835		pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SET_DEV_INFO\n");3836		break;3837	case OPC_OUB_SAS_RE_INITIALIZE:3838		pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SAS_RE_INITIALIZE\n");3839		break;3840	default:3841		pm8001_dbg(pm8001_ha, DEVIO,3842			   "Unknown outbound Queue IOMB OPC = %x\n",3843			   opc);3844		break;3845	}3846}3847 3848static int process_oq(struct pm8001_hba_info *pm8001_ha, u8 vec)3849{3850	struct outbound_queue_table *circularQ;3851	void *pMsg1 = NULL;3852	u8 bc;3853	u32 ret = MPI_IO_STATUS_FAIL;3854	unsigned long flags;3855 3856	spin_lock_irqsave(&pm8001_ha->lock, flags);3857	circularQ = &pm8001_ha->outbnd_q_tbl[vec];3858	do {3859		ret = pm8001_mpi_msg_consume(pm8001_ha, circularQ, &pMsg1, &bc);3860		if (MPI_IO_STATUS_SUCCESS == ret) {3861			/* process the outbound message */3862			process_one_iomb(pm8001_ha, (void *)(pMsg1 - 4));3863			/* free the message from the outbound circular buffer */3864			pm8001_mpi_msg_free_set(pm8001_ha, pMsg1,3865							circularQ, bc);3866		}3867		if (MPI_IO_STATUS_BUSY == ret) {3868			/* Update the producer index from SPC */3869			circularQ->producer_index =3870				cpu_to_le32(pm8001_read_32(circularQ->pi_virt));3871			if (le32_to_cpu(circularQ->producer_index) ==3872				circularQ->consumer_idx)3873				/* OQ is empty */3874				break;3875		}3876	} while (1);3877	spin_unlock_irqrestore(&pm8001_ha->lock, flags);3878	return ret;3879}3880 3881/* DMA_... to our direction translation. */3882static const u8 data_dir_flags[] = {3883	[DMA_BIDIRECTIONAL]	= DATA_DIR_BYRECIPIENT,	/* UNSPECIFIED */3884	[DMA_TO_DEVICE]		= DATA_DIR_OUT,		/* OUTBOUND */3885	[DMA_FROM_DEVICE]	= DATA_DIR_IN,		/* INBOUND */3886	[DMA_NONE]		= DATA_DIR_NONE,	/* NO TRANSFER */3887};3888void3889pm8001_chip_make_sg(struct scatterlist *scatter, int nr, void *prd)3890{3891	int i;3892	struct scatterlist *sg;3893	struct pm8001_prd *buf_prd = prd;3894 3895	for_each_sg(scatter, sg, nr, i) {3896		buf_prd->addr = cpu_to_le64(sg_dma_address(sg));3897		buf_prd->im_len.len = cpu_to_le32(sg_dma_len(sg));3898		buf_prd->im_len.e = 0;3899		buf_prd++;3900	}3901}3902 3903static void build_smp_cmd(u32 deviceID, __le32 hTag, struct smp_req *psmp_cmd)3904{3905	psmp_cmd->tag = hTag;3906	psmp_cmd->device_id = cpu_to_le32(deviceID);3907	psmp_cmd->len_ip_ir = cpu_to_le32(1|(1 << 1));3908}3909 3910/**3911 * pm8001_chip_smp_req - send a SMP task to FW3912 * @pm8001_ha: our hba card information.3913 * @ccb: the ccb information this request used.3914 */3915static int pm8001_chip_smp_req(struct pm8001_hba_info *pm8001_ha,3916	struct pm8001_ccb_info *ccb)3917{3918	int elem, rc;3919	struct sas_task *task = ccb->task;3920	struct domain_device *dev = task->dev;3921	struct pm8001_device *pm8001_dev = dev->lldd_dev;3922	struct scatterlist *sg_req, *sg_resp;3923	u32 req_len, resp_len;3924	struct smp_req smp_cmd;3925	u32 opc;3926 3927	memset(&smp_cmd, 0, sizeof(smp_cmd));3928	/*3929	 * DMA-map SMP request, response buffers3930	 */3931	sg_req = &task->smp_task.smp_req;3932	elem = dma_map_sg(pm8001_ha->dev, sg_req, 1, DMA_TO_DEVICE);3933	if (!elem)3934		return -ENOMEM;3935	req_len = sg_dma_len(sg_req);3936 3937	sg_resp = &task->smp_task.smp_resp;3938	elem = dma_map_sg(pm8001_ha->dev, sg_resp, 1, DMA_FROM_DEVICE);3939	if (!elem) {3940		rc = -ENOMEM;3941		goto err_out;3942	}3943	resp_len = sg_dma_len(sg_resp);3944	/* must be in dwords */3945	if ((req_len & 0x3) || (resp_len & 0x3)) {3946		rc = -EINVAL;3947		goto err_out_2;3948	}3949 3950	opc = OPC_INB_SMP_REQUEST;3951	smp_cmd.tag = cpu_to_le32(ccb->ccb_tag);3952	smp_cmd.long_smp_req.long_req_addr =3953		cpu_to_le64((u64)sg_dma_address(&task->smp_task.smp_req));3954	smp_cmd.long_smp_req.long_req_size =3955		cpu_to_le32((u32)sg_dma_len(&task->smp_task.smp_req)-4);3956	smp_cmd.long_smp_req.long_resp_addr =3957		cpu_to_le64((u64)sg_dma_address(&task->smp_task.smp_resp));3958	smp_cmd.long_smp_req.long_resp_size =3959		cpu_to_le32((u32)sg_dma_len(&task->smp_task.smp_resp)-4);3960	build_smp_cmd(pm8001_dev->device_id, smp_cmd.tag, &smp_cmd);3961	rc = pm8001_mpi_build_cmd(pm8001_ha, 0, opc,3962				  &smp_cmd, sizeof(smp_cmd), 0);3963	if (rc)3964		goto err_out_2;3965 3966	return 0;3967 3968err_out_2:3969	dma_unmap_sg(pm8001_ha->dev, &ccb->task->smp_task.smp_resp, 1,3970			DMA_FROM_DEVICE);3971err_out:3972	dma_unmap_sg(pm8001_ha->dev, &ccb->task->smp_task.smp_req, 1,3973			DMA_TO_DEVICE);3974	return rc;3975}3976 3977/**3978 * pm8001_chip_ssp_io_req - send a SSP task to FW3979 * @pm8001_ha: our hba card information.3980 * @ccb: the ccb information this request used.3981 */3982static int pm8001_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,3983	struct pm8001_ccb_info *ccb)3984{3985	struct sas_task *task = ccb->task;3986	struct domain_device *dev = task->dev;3987	struct pm8001_device *pm8001_dev = dev->lldd_dev;3988	struct ssp_ini_io_start_req ssp_cmd;3989	u32 tag = ccb->ccb_tag;3990	u64 phys_addr;3991	u32 opc = OPC_INB_SSPINIIOSTART;3992	memset(&ssp_cmd, 0, sizeof(ssp_cmd));3993	memcpy(ssp_cmd.ssp_iu.lun, task->ssp_task.LUN, 8);3994	ssp_cmd.dir_m_tlr =3995		cpu_to_le32(data_dir_flags[task->data_dir] << 8 | 0x0);/*0 for3996	SAS 1.1 compatible TLR*/3997	ssp_cmd.data_len = cpu_to_le32(task->total_xfer_len);3998	ssp_cmd.device_id = cpu_to_le32(pm8001_dev->device_id);3999	ssp_cmd.tag = cpu_to_le32(tag);4000	ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_attr & 7);4001	memcpy(ssp_cmd.ssp_iu.cdb, task->ssp_task.cmd->cmnd,4002	       task->ssp_task.cmd->cmd_len);4003 4004	/* fill in PRD (scatter/gather) table, if any */4005	if (task->num_scatter > 1) {4006		pm8001_chip_make_sg(task->scatter, ccb->n_elem, ccb->buf_prd);4007		phys_addr = ccb->ccb_dma_handle;4008		ssp_cmd.addr_low = cpu_to_le32(lower_32_bits(phys_addr));4009		ssp_cmd.addr_high = cpu_to_le32(upper_32_bits(phys_addr));4010		ssp_cmd.esgl = cpu_to_le32(1<<31);4011	} else if (task->num_scatter == 1) {4012		u64 dma_addr = sg_dma_address(task->scatter);4013		ssp_cmd.addr_low = cpu_to_le32(lower_32_bits(dma_addr));4014		ssp_cmd.addr_high = cpu_to_le32(upper_32_bits(dma_addr));4015		ssp_cmd.len = cpu_to_le32(task->total_xfer_len);4016		ssp_cmd.esgl = 0;4017	} else if (task->num_scatter == 0) {4018		ssp_cmd.addr_low = 0;4019		ssp_cmd.addr_high = 0;4020		ssp_cmd.len = cpu_to_le32(task->total_xfer_len);4021		ssp_cmd.esgl = 0;4022	}4023 4024	return pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &ssp_cmd,4025				    sizeof(ssp_cmd), 0);4026}4027 4028static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha,4029	struct pm8001_ccb_info *ccb)4030{4031	struct sas_task *task = ccb->task;4032	struct domain_device *dev = task->dev;4033	struct pm8001_device *pm8001_ha_dev = dev->lldd_dev;4034	u32 tag = ccb->ccb_tag;4035	struct sata_start_req sata_cmd;4036	u32 hdr_tag, ncg_tag = 0;4037	u64 phys_addr;4038	u32 ATAP = 0x0;4039	u32 dir, retfis = 0;4040	u32  opc = OPC_INB_SATA_HOST_OPSTART;4041 4042	memset(&sata_cmd, 0, sizeof(sata_cmd));4043 4044	if (task->data_dir == DMA_NONE && !task->ata_task.use_ncq) {4045		ATAP = 0x04;  /* no data*/4046		pm8001_dbg(pm8001_ha, IO, "no data\n");4047	} else if (likely(!task->ata_task.device_control_reg_update)) {4048		if (task->ata_task.use_ncq &&4049		    dev->sata_dev.class != ATA_DEV_ATAPI) {4050			ATAP = 0x07; /* FPDMA */4051			pm8001_dbg(pm8001_ha, IO, "FPDMA\n");4052		} else if (task->ata_task.dma_xfer) {4053			ATAP = 0x06; /* DMA */4054			pm8001_dbg(pm8001_ha, IO, "DMA\n");4055		} else {4056			ATAP = 0x05; /* PIO*/4057			pm8001_dbg(pm8001_ha, IO, "PIO\n");4058		}4059	}4060	if (task->ata_task.use_ncq && pm8001_get_ncq_tag(task, &hdr_tag)) {4061		task->ata_task.fis.sector_count |= (u8) (hdr_tag << 3);4062		ncg_tag = hdr_tag;4063	}4064	dir = data_dir_flags[task->data_dir] << 8;4065	sata_cmd.tag = cpu_to_le32(tag);4066	sata_cmd.device_id = cpu_to_le32(pm8001_ha_dev->device_id);4067	sata_cmd.data_len = cpu_to_le32(task->total_xfer_len);4068	if (task->ata_task.return_fis_on_success)4069		retfis = 1;4070	sata_cmd.retfis_ncqtag_atap_dir_m =4071		cpu_to_le32((retfis << 24) | ((ncg_tag & 0xff) << 16) |4072			    ((ATAP & 0x3f) << 10) | dir);4073	sata_cmd.sata_fis = task->ata_task.fis;4074	if (likely(!task->ata_task.device_control_reg_update))4075		sata_cmd.sata_fis.flags |= 0x80;/* C=1: update ATA cmd reg */4076	sata_cmd.sata_fis.flags &= 0xF0;/* PM_PORT field shall be 0 */4077	/* fill in PRD (scatter/gather) table, if any */4078	if (task->num_scatter > 1) {4079		pm8001_chip_make_sg(task->scatter, ccb->n_elem, ccb->buf_prd);4080		phys_addr = ccb->ccb_dma_handle;4081		sata_cmd.addr_low = lower_32_bits(phys_addr);4082		sata_cmd.addr_high = upper_32_bits(phys_addr);4083		sata_cmd.esgl = cpu_to_le32(1 << 31);4084	} else if (task->num_scatter == 1) {4085		u64 dma_addr = sg_dma_address(task->scatter);4086		sata_cmd.addr_low = lower_32_bits(dma_addr);4087		sata_cmd.addr_high = upper_32_bits(dma_addr);4088		sata_cmd.len = cpu_to_le32(task->total_xfer_len);4089		sata_cmd.esgl = 0;4090	} else if (task->num_scatter == 0) {4091		sata_cmd.addr_low = 0;4092		sata_cmd.addr_high = 0;4093		sata_cmd.len = cpu_to_le32(task->total_xfer_len);4094		sata_cmd.esgl = 0;4095	}4096 4097	return pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &sata_cmd,4098				    sizeof(sata_cmd), 0);4099}4100 4101/**4102 * pm8001_chip_phy_start_req - start phy via PHY_START COMMAND4103 * @pm8001_ha: our hba card information.4104 * @phy_id: the phy id which we wanted to start up.4105 */4106static int4107pm8001_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id)4108{4109	struct phy_start_req payload;4110	u32 tag = 0x01;4111	u32 opcode = OPC_INB_PHYSTART;4112 4113	memset(&payload, 0, sizeof(payload));4114	payload.tag = cpu_to_le32(tag);4115	/*4116	 ** [0:7]   PHY Identifier4117	 ** [8:11]  link rate 1.5G, 3G, 6G4118	 ** [12:13] link mode 01b SAS mode; 10b SATA mode; 11b both4119	 ** [14]    0b disable spin up hold; 1b enable spin up hold4120	 */4121	payload.ase_sh_lm_slr_phyid = cpu_to_le32(SPINHOLD_DISABLE |4122		LINKMODE_AUTO |	LINKRATE_15 |4123		LINKRATE_30 | LINKRATE_60 | phy_id);4124	payload.sas_identify.dev_type = SAS_END_DEVICE;4125	payload.sas_identify.initiator_bits = SAS_PROTOCOL_ALL;4126	memcpy(payload.sas_identify.sas_addr,4127		&pm8001_ha->phy[phy_id].dev_sas_addr, SAS_ADDR_SIZE);4128	payload.sas_identify.phy_id = phy_id;4129 4130	return pm8001_mpi_build_cmd(pm8001_ha, 0, opcode, &payload,4131				    sizeof(payload), 0);4132}4133 4134/**4135 * pm8001_chip_phy_stop_req - start phy via PHY_STOP COMMAND4136 * @pm8001_ha: our hba card information.4137 * @phy_id: the phy id which we wanted to start up.4138 */4139static int pm8001_chip_phy_stop_req(struct pm8001_hba_info *pm8001_ha,4140				    u8 phy_id)4141{4142	struct phy_stop_req payload;4143	u32 tag = 0x01;4144	u32 opcode = OPC_INB_PHYSTOP;4145 4146	memset(&payload, 0, sizeof(payload));4147	payload.tag = cpu_to_le32(tag);4148	payload.phy_id = cpu_to_le32(phy_id);4149 4150	return pm8001_mpi_build_cmd(pm8001_ha, 0, opcode, &payload,4151				    sizeof(payload), 0);4152}4153 4154/*4155 * see comments on pm8001_mpi_reg_resp.4156 */4157static int pm8001_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,4158	struct pm8001_device *pm8001_dev, u32 flag)4159{4160	struct reg_dev_req payload;4161	u32	opc;4162	u32 stp_sspsmp_sata = 0x4;4163	u32 linkrate, phy_id;4164	int rc;4165	struct pm8001_ccb_info *ccb;4166	u8 retryFlag = 0x1;4167	u16 firstBurstSize = 0;4168	u16 ITNT = 2000;4169	struct domain_device *dev = pm8001_dev->sas_device;4170	struct domain_device *parent_dev = dev->parent;4171	struct pm8001_port *port = dev->port->lldd_port;4172 4173	memset(&payload, 0, sizeof(payload));4174	ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_dev, NULL);4175	if (!ccb)4176		return -SAS_QUEUE_FULL;4177 4178	payload.tag = cpu_to_le32(ccb->ccb_tag);4179	if (flag == 1)4180		stp_sspsmp_sata = 0x02; /*direct attached sata */4181	else {4182		if (pm8001_dev->dev_type == SAS_SATA_DEV)4183			stp_sspsmp_sata = 0x00; /* stp*/4184		else if (pm8001_dev->dev_type == SAS_END_DEVICE ||4185			dev_is_expander(pm8001_dev->dev_type))4186			stp_sspsmp_sata = 0x01; /*ssp or smp*/4187	}4188	if (parent_dev && dev_is_expander(parent_dev->dev_type))4189		phy_id = parent_dev->ex_dev.ex_phy->phy_id;4190	else4191		phy_id = pm8001_dev->attached_phy;4192	opc = OPC_INB_REG_DEV;4193	linkrate = (pm8001_dev->sas_device->linkrate < dev->port->linkrate) ?4194			pm8001_dev->sas_device->linkrate : dev->port->linkrate;4195	payload.phyid_portid =4196		cpu_to_le32(((port->port_id) & 0x0F) |4197		((phy_id & 0x0F) << 4));4198	payload.dtype_dlr_retry = cpu_to_le32((retryFlag & 0x01) |4199		((linkrate & 0x0F) * 0x1000000) |4200		((stp_sspsmp_sata & 0x03) * 0x10000000));4201	payload.firstburstsize_ITNexustimeout =4202		cpu_to_le32(ITNT | (firstBurstSize * 0x10000));4203	memcpy(payload.sas_addr, pm8001_dev->sas_device->sas_addr,4204		SAS_ADDR_SIZE);4205 4206	rc = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &payload,4207				  sizeof(payload), 0);4208	if (rc)4209		pm8001_ccb_free(pm8001_ha, ccb);4210 4211	return rc;4212}4213 4214/*4215 * see comments on pm8001_mpi_reg_resp.4216 */4217int pm8001_chip_dereg_dev_req(struct pm8001_hba_info *pm8001_ha,4218	u32 device_id)4219{4220	struct dereg_dev_req payload;4221	u32 opc = OPC_INB_DEREG_DEV_HANDLE;4222 4223	memset(&payload, 0, sizeof(payload));4224	payload.tag = cpu_to_le32(1);4225	payload.device_id = cpu_to_le32(device_id);4226	pm8001_dbg(pm8001_ha, INIT, "unregister device device_id %d\n",4227		   device_id);4228 4229	return pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &payload,4230				    sizeof(payload), 0);4231}4232 4233/**4234 * pm8001_chip_phy_ctl_req - support the local phy operation4235 * @pm8001_ha: our hba card information.4236 * @phyId: the phy id which we wanted to operate4237 * @phy_op: the phy operation to request4238 */4239static int pm8001_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha,4240	u32 phyId, u32 phy_op)4241{4242	struct local_phy_ctl_req payload;4243	u32 opc = OPC_INB_LOCAL_PHY_CONTROL;4244 4245	memset(&payload, 0, sizeof(payload));4246	payload.tag = cpu_to_le32(1);4247	payload.phyop_phyid =4248		cpu_to_le32(((phy_op & 0xff) << 8) | (phyId & 0x0F));4249 4250	return pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &payload,4251				    sizeof(payload), 0);4252}4253 4254static u32 pm8001_chip_is_our_interrupt(struct pm8001_hba_info *pm8001_ha)4255{4256	u32 value;4257 4258	if (pm8001_ha->use_msix)4259		return 1;4260 4261	value = pm8001_cr32(pm8001_ha, 0, MSGU_ODR);4262	if (value)4263		return 1;4264	return 0;4265}4266 4267/**4268 * pm8001_chip_isr - PM8001 isr handler.4269 * @pm8001_ha: our hba card information.4270 * @vec: IRQ number4271 */4272static irqreturn_t4273pm8001_chip_isr(struct pm8001_hba_info *pm8001_ha, u8 vec)4274{4275	pm8001_chip_interrupt_disable(pm8001_ha, vec);4276	pm8001_dbg(pm8001_ha, DEVIO,4277		   "irq vec %d, ODMR:0x%x\n",4278		   vec, pm8001_cr32(pm8001_ha, 0, 0x30));4279	process_oq(pm8001_ha, vec);4280	pm8001_chip_interrupt_enable(pm8001_ha, vec);4281	return IRQ_HANDLED;4282}4283 4284static int send_task_abort(struct pm8001_hba_info *pm8001_ha, u32 opc,4285	u32 dev_id, enum sas_internal_abort type, u32 task_tag, u32 cmd_tag)4286{4287	struct task_abort_req task_abort;4288 4289	memset(&task_abort, 0, sizeof(task_abort));4290	if (type == SAS_INTERNAL_ABORT_SINGLE) {4291		task_abort.abort_all = 0;4292		task_abort.device_id = cpu_to_le32(dev_id);4293		task_abort.tag_to_abort = cpu_to_le32(task_tag);4294	} else if (type == SAS_INTERNAL_ABORT_DEV) {4295		task_abort.abort_all = cpu_to_le32(1);4296		task_abort.device_id = cpu_to_le32(dev_id);4297	} else {4298		pm8001_dbg(pm8001_ha, EH, "unknown type (%d)\n", type);4299		return -EIO;4300	}4301 4302	task_abort.tag = cpu_to_le32(cmd_tag);4303 4304	return pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &task_abort,4305				    sizeof(task_abort), 0);4306}4307 4308/*4309 * pm8001_chip_abort_task - SAS abort task when error or exception happened.4310 */4311int pm8001_chip_abort_task(struct pm8001_hba_info *pm8001_ha,4312	struct pm8001_ccb_info *ccb)4313{4314	struct sas_task *task = ccb->task;4315	struct sas_internal_abort_task *abort = &task->abort_task;4316	struct pm8001_device *pm8001_dev = ccb->device;4317	int rc = TMF_RESP_FUNC_FAILED;4318	u32 opc, device_id;4319 4320	pm8001_dbg(pm8001_ha, EH, "cmd_tag = %x, abort task tag = 0x%x\n",4321		   ccb->ccb_tag, abort->tag);4322	if (pm8001_dev->dev_type == SAS_END_DEVICE)4323		opc = OPC_INB_SSP_ABORT;4324	else if (pm8001_dev->dev_type == SAS_SATA_DEV)4325		opc = OPC_INB_SATA_ABORT;4326	else4327		opc = OPC_INB_SMP_ABORT;/* SMP */4328	device_id = pm8001_dev->device_id;4329	rc = send_task_abort(pm8001_ha, opc, device_id, abort->type,4330			     abort->tag, ccb->ccb_tag);4331	if (rc != TMF_RESP_FUNC_COMPLETE)4332		pm8001_dbg(pm8001_ha, EH, "rc= %d\n", rc);4333	return rc;4334}4335 4336/**4337 * pm8001_chip_ssp_tm_req - built the task management command.4338 * @pm8001_ha: our hba card information.4339 * @ccb: the ccb information.4340 * @tmf: task management function.4341 */4342int pm8001_chip_ssp_tm_req(struct pm8001_hba_info *pm8001_ha,4343	struct pm8001_ccb_info *ccb, struct sas_tmf_task *tmf)4344{4345	struct sas_task *task = ccb->task;4346	struct domain_device *dev = task->dev;4347	struct pm8001_device *pm8001_dev = dev->lldd_dev;4348	u32 opc = OPC_INB_SSPINITMSTART;4349	struct ssp_ini_tm_start_req sspTMCmd;4350 4351	memset(&sspTMCmd, 0, sizeof(sspTMCmd));4352	sspTMCmd.device_id = cpu_to_le32(pm8001_dev->device_id);4353	sspTMCmd.relate_tag = cpu_to_le32((u32)tmf->tag_of_task_to_be_managed);4354	sspTMCmd.tmf = cpu_to_le32(tmf->tmf);4355	memcpy(sspTMCmd.lun, task->ssp_task.LUN, 8);4356	sspTMCmd.tag = cpu_to_le32(ccb->ccb_tag);4357	if (pm8001_ha->chip_id != chip_8001)4358		sspTMCmd.ds_ads_m = cpu_to_le32(0x08);4359 4360	return pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &sspTMCmd,4361				    sizeof(sspTMCmd), 0);4362}4363 4364int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha,4365	void *payload)4366{4367	u32 opc = OPC_INB_GET_NVMD_DATA;4368	u32 nvmd_type;4369	int rc;4370	struct pm8001_ccb_info *ccb;4371	struct get_nvm_data_req nvmd_req;4372	struct fw_control_ex *fw_control_context;4373	struct pm8001_ioctl_payload *ioctl_payload = payload;4374 4375	nvmd_type = ioctl_payload->minor_function;4376	fw_control_context = kzalloc(sizeof(struct fw_control_ex), GFP_KERNEL);4377	if (!fw_control_context)4378		return -ENOMEM;4379	fw_control_context->usrAddr = (u8 *)ioctl_payload->func_specific;4380	fw_control_context->len = ioctl_payload->rd_length;4381	memset(&nvmd_req, 0, sizeof(nvmd_req));4382 4383	ccb = pm8001_ccb_alloc(pm8001_ha, NULL, NULL);4384	if (!ccb) {4385		kfree(fw_control_context);4386		return -SAS_QUEUE_FULL;4387	}4388	ccb->fw_control_context = fw_control_context;4389 4390	nvmd_req.tag = cpu_to_le32(ccb->ccb_tag);4391 4392	switch (nvmd_type) {4393	case TWI_DEVICE: {4394		u32 twi_addr, twi_page_size;4395		twi_addr = 0xa8;4396		twi_page_size = 2;4397 4398		nvmd_req.len_ir_vpdd = cpu_to_le32(IPMode | twi_addr << 16 |4399			twi_page_size << 8 | TWI_DEVICE);4400		nvmd_req.resp_len = cpu_to_le32(ioctl_payload->rd_length);4401		nvmd_req.resp_addr_hi =4402		    cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_hi);4403		nvmd_req.resp_addr_lo =4404		    cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_lo);4405		break;4406	}4407	case C_SEEPROM: {4408		nvmd_req.len_ir_vpdd = cpu_to_le32(IPMode | C_SEEPROM);4409		nvmd_req.resp_len = cpu_to_le32(ioctl_payload->rd_length);4410		nvmd_req.resp_addr_hi =4411		    cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_hi);4412		nvmd_req.resp_addr_lo =4413		    cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_lo);4414		break;4415	}4416	case VPD_FLASH: {4417		nvmd_req.len_ir_vpdd = cpu_to_le32(IPMode | VPD_FLASH);4418		nvmd_req.resp_len = cpu_to_le32(ioctl_payload->rd_length);4419		nvmd_req.resp_addr_hi =4420		    cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_hi);4421		nvmd_req.resp_addr_lo =4422		    cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_lo);4423		break;4424	}4425	case EXPAN_ROM: {4426		nvmd_req.len_ir_vpdd = cpu_to_le32(IPMode | EXPAN_ROM);4427		nvmd_req.resp_len = cpu_to_le32(ioctl_payload->rd_length);4428		nvmd_req.resp_addr_hi =4429		    cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_hi);4430		nvmd_req.resp_addr_lo =4431		    cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_lo);4432		break;4433	}4434	case IOP_RDUMP: {4435		nvmd_req.len_ir_vpdd = cpu_to_le32(IPMode | IOP_RDUMP);4436		nvmd_req.resp_len = cpu_to_le32(ioctl_payload->rd_length);4437		nvmd_req.vpd_offset = cpu_to_le32(ioctl_payload->offset);4438		nvmd_req.resp_addr_hi =4439		cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_hi);4440		nvmd_req.resp_addr_lo =4441		cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_lo);4442		break;4443	}4444	default:4445		break;4446	}4447 4448	rc = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &nvmd_req,4449				  sizeof(nvmd_req), 0);4450	if (rc) {4451		kfree(fw_control_context);4452		pm8001_ccb_free(pm8001_ha, ccb);4453	}4454	return rc;4455}4456 4457int pm8001_chip_set_nvmd_req(struct pm8001_hba_info *pm8001_ha,4458	void *payload)4459{4460	u32 opc = OPC_INB_SET_NVMD_DATA;4461	u32 nvmd_type;4462	int rc;4463	struct pm8001_ccb_info *ccb;4464	struct set_nvm_data_req nvmd_req;4465	struct fw_control_ex *fw_control_context;4466	struct pm8001_ioctl_payload *ioctl_payload = payload;4467 4468	nvmd_type = ioctl_payload->minor_function;4469	fw_control_context = kzalloc(sizeof(struct fw_control_ex), GFP_KERNEL);4470	if (!fw_control_context)4471		return -ENOMEM;4472 4473	memcpy(pm8001_ha->memoryMap.region[NVMD].virt_ptr,4474		&ioctl_payload->func_specific,4475		ioctl_payload->wr_length);4476	memset(&nvmd_req, 0, sizeof(nvmd_req));4477 4478	ccb = pm8001_ccb_alloc(pm8001_ha, NULL, NULL);4479	if (!ccb) {4480		kfree(fw_control_context);4481		return -SAS_QUEUE_FULL;4482	}4483	ccb->fw_control_context = fw_control_context;4484 4485	nvmd_req.tag = cpu_to_le32(ccb->ccb_tag);4486	switch (nvmd_type) {4487	case TWI_DEVICE: {4488		u32 twi_addr, twi_page_size;4489		twi_addr = 0xa8;4490		twi_page_size = 2;4491		nvmd_req.reserved[0] = cpu_to_le32(0xFEDCBA98);4492		nvmd_req.len_ir_vpdd = cpu_to_le32(IPMode | twi_addr << 16 |4493			twi_page_size << 8 | TWI_DEVICE);4494		nvmd_req.resp_len = cpu_to_le32(ioctl_payload->wr_length);4495		nvmd_req.resp_addr_hi =4496		    cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_hi);4497		nvmd_req.resp_addr_lo =4498		    cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_lo);4499		break;4500	}4501	case C_SEEPROM:4502		nvmd_req.len_ir_vpdd = cpu_to_le32(IPMode | C_SEEPROM);4503		nvmd_req.resp_len = cpu_to_le32(ioctl_payload->wr_length);4504		nvmd_req.reserved[0] = cpu_to_le32(0xFEDCBA98);4505		nvmd_req.resp_addr_hi =4506		    cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_hi);4507		nvmd_req.resp_addr_lo =4508		    cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_lo);4509		break;4510	case VPD_FLASH:4511		nvmd_req.len_ir_vpdd = cpu_to_le32(IPMode | VPD_FLASH);4512		nvmd_req.resp_len = cpu_to_le32(ioctl_payload->wr_length);4513		nvmd_req.reserved[0] = cpu_to_le32(0xFEDCBA98);4514		nvmd_req.resp_addr_hi =4515		    cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_hi);4516		nvmd_req.resp_addr_lo =4517		    cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_lo);4518		break;4519	case EXPAN_ROM:4520		nvmd_req.len_ir_vpdd = cpu_to_le32(IPMode | EXPAN_ROM);4521		nvmd_req.resp_len = cpu_to_le32(ioctl_payload->wr_length);4522		nvmd_req.reserved[0] = cpu_to_le32(0xFEDCBA98);4523		nvmd_req.resp_addr_hi =4524		    cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_hi);4525		nvmd_req.resp_addr_lo =4526		    cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_lo);4527		break;4528	default:4529		break;4530	}4531 4532	rc = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &nvmd_req,4533			sizeof(nvmd_req), 0);4534	if (rc) {4535		kfree(fw_control_context);4536		pm8001_ccb_free(pm8001_ha, ccb);4537	}4538	return rc;4539}4540 4541/**4542 * pm8001_chip_fw_flash_update_build - support the firmware update operation4543 * @pm8001_ha: our hba card information.4544 * @fw_flash_updata_info: firmware flash update param4545 * @tag: Tag to apply to the payload4546 */4547int4548pm8001_chip_fw_flash_update_build(struct pm8001_hba_info *pm8001_ha,4549	void *fw_flash_updata_info, u32 tag)4550{4551	struct fw_flash_Update_req payload;4552	struct fw_flash_updata_info *info;4553	u32 opc = OPC_INB_FW_FLASH_UPDATE;4554 4555	memset(&payload, 0, sizeof(struct fw_flash_Update_req));4556	info = fw_flash_updata_info;4557	payload.tag = cpu_to_le32(tag);4558	payload.cur_image_len = cpu_to_le32(info->cur_image_len);4559	payload.cur_image_offset = cpu_to_le32(info->cur_image_offset);4560	payload.total_image_len = cpu_to_le32(info->total_image_len);4561	payload.len = info->sgl.im_len.len ;4562	payload.sgl_addr_lo =4563		cpu_to_le32(lower_32_bits(le64_to_cpu(info->sgl.addr)));4564	payload.sgl_addr_hi =4565		cpu_to_le32(upper_32_bits(le64_to_cpu(info->sgl.addr)));4566 4567	return pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &payload,4568				    sizeof(payload), 0);4569}4570 4571int4572pm8001_chip_fw_flash_update_req(struct pm8001_hba_info *pm8001_ha,4573	void *payload)4574{4575	struct fw_flash_updata_info flash_update_info;4576	struct fw_control_info *fw_control;4577	struct fw_control_ex *fw_control_context;4578	int rc;4579	struct pm8001_ccb_info *ccb;4580	void *buffer = pm8001_ha->memoryMap.region[FW_FLASH].virt_ptr;4581	dma_addr_t phys_addr = pm8001_ha->memoryMap.region[FW_FLASH].phys_addr;4582	struct pm8001_ioctl_payload *ioctl_payload = payload;4583 4584	fw_control_context = kzalloc(sizeof(struct fw_control_ex), GFP_KERNEL);4585	if (!fw_control_context)4586		return -ENOMEM;4587	fw_control = (struct fw_control_info *)&ioctl_payload->func_specific;4588	pm8001_dbg(pm8001_ha, DEVIO,4589		   "dma fw_control context input length :%x\n",4590		   fw_control->len);4591	memcpy(buffer, fw_control->buffer, fw_control->len);4592	flash_update_info.sgl.addr = cpu_to_le64(phys_addr);4593	flash_update_info.sgl.im_len.len = cpu_to_le32(fw_control->len);4594	flash_update_info.sgl.im_len.e = 0;4595	flash_update_info.cur_image_offset = fw_control->offset;4596	flash_update_info.cur_image_len = fw_control->len;4597	flash_update_info.total_image_len = fw_control->size;4598	fw_control_context->fw_control = fw_control;4599	fw_control_context->virtAddr = buffer;4600	fw_control_context->phys_addr = phys_addr;4601	fw_control_context->len = fw_control->len;4602 4603	ccb = pm8001_ccb_alloc(pm8001_ha, NULL, NULL);4604	if (!ccb) {4605		kfree(fw_control_context);4606		return -SAS_QUEUE_FULL;4607	}4608	ccb->fw_control_context = fw_control_context;4609 4610	rc = pm8001_chip_fw_flash_update_build(pm8001_ha, &flash_update_info,4611					       ccb->ccb_tag);4612	if (rc) {4613		kfree(fw_control_context);4614		pm8001_ccb_free(pm8001_ha, ccb);4615	}4616 4617	return rc;4618}4619 4620ssize_t4621pm8001_get_gsm_dump(struct device *cdev, u32 length, char *buf)4622{4623	u32 value, rem, offset = 0, bar = 0;4624	u32 index, work_offset, dw_length;4625	u32 shift_value, gsm_base, gsm_dump_offset;4626	char *direct_data;4627	struct Scsi_Host *shost = class_to_shost(cdev);4628	struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);4629	struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;4630 4631	direct_data = buf;4632	gsm_dump_offset = pm8001_ha->fatal_forensic_shift_offset;4633 4634	/* check max is 1 Mbytes */4635	if ((length > 0x100000) || (gsm_dump_offset & 3) ||4636		((gsm_dump_offset + length) > 0x1000000))4637			return -EINVAL;4638 4639	if (pm8001_ha->chip_id == chip_8001)4640		bar = 2;4641	else4642		bar = 1;4643 4644	work_offset = gsm_dump_offset & 0xFFFF0000;4645	offset = gsm_dump_offset & 0x0000FFFF;4646	gsm_dump_offset = work_offset;4647	/* adjust length to dword boundary */4648	rem = length & 3;4649	dw_length = length >> 2;4650 4651	for (index = 0; index < dw_length; index++) {4652		if ((work_offset + offset) & 0xFFFF0000) {4653			if (pm8001_ha->chip_id == chip_8001)4654				shift_value = ((gsm_dump_offset + offset) &4655						SHIFT_REG_64K_MASK);4656			else4657				shift_value = (((gsm_dump_offset + offset) &4658						SHIFT_REG_64K_MASK) >>4659						SHIFT_REG_BIT_SHIFT);4660 4661			if (pm8001_ha->chip_id == chip_8001) {4662				gsm_base = GSM_BASE;4663				if (-1 == pm8001_bar4_shift(pm8001_ha,4664						(gsm_base + shift_value)))4665					return -EIO;4666			} else {4667				gsm_base = 0;4668				if (-1 == pm80xx_bar4_shift(pm8001_ha,4669						(gsm_base + shift_value)))4670					return -EIO;4671			}4672			gsm_dump_offset = (gsm_dump_offset + offset) &4673						0xFFFF0000;4674			work_offset = 0;4675			offset = offset & 0x0000FFFF;4676		}4677		value = pm8001_cr32(pm8001_ha, bar, (work_offset + offset) &4678						0x0000FFFF);4679		direct_data += sprintf(direct_data, "%08x ", value);4680		offset += 4;4681	}4682	if (rem != 0) {4683		value = pm8001_cr32(pm8001_ha, bar, (work_offset + offset) &4684						0x0000FFFF);4685		/* xfr for non_dw */4686		direct_data += sprintf(direct_data, "%08x ", value);4687	}4688	/* Shift back to BAR4 original address */4689	if (-1 == pm8001_bar4_shift(pm8001_ha, 0))4690			return -EIO;4691	pm8001_ha->fatal_forensic_shift_offset += 1024;4692 4693	if (pm8001_ha->fatal_forensic_shift_offset >= 0x100000)4694		pm8001_ha->fatal_forensic_shift_offset = 0;4695	return direct_data - buf;4696}4697 4698int4699pm8001_chip_set_dev_state_req(struct pm8001_hba_info *pm8001_ha,4700	struct pm8001_device *pm8001_dev, u32 state)4701{4702	struct set_dev_state_req payload;4703	struct pm8001_ccb_info *ccb;4704	int rc;4705	u32 opc = OPC_INB_SET_DEVICE_STATE;4706 4707	memset(&payload, 0, sizeof(payload));4708 4709	ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_dev, NULL);4710	if (!ccb)4711		return -SAS_QUEUE_FULL;4712 4713	payload.tag = cpu_to_le32(ccb->ccb_tag);4714	payload.device_id = cpu_to_le32(pm8001_dev->device_id);4715	payload.nds = cpu_to_le32(state);4716 4717	rc = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &payload,4718				  sizeof(payload), 0);4719	if (rc)4720		pm8001_ccb_free(pm8001_ha, ccb);4721 4722	return rc;4723}4724 4725static int4726pm8001_chip_sas_re_initialization(struct pm8001_hba_info *pm8001_ha)4727{4728	struct sas_re_initialization_req payload;4729	struct pm8001_ccb_info *ccb;4730	int rc;4731	u32 opc = OPC_INB_SAS_RE_INITIALIZE;4732 4733	memset(&payload, 0, sizeof(payload));4734 4735	ccb = pm8001_ccb_alloc(pm8001_ha, NULL, NULL);4736	if (!ccb)4737		return -SAS_QUEUE_FULL;4738 4739	payload.tag = cpu_to_le32(ccb->ccb_tag);4740	payload.SSAHOLT = cpu_to_le32(0xd << 25);4741	payload.sata_hol_tmo = cpu_to_le32(80);4742	payload.open_reject_cmdretries_data_retries = cpu_to_le32(0xff00ff);4743 4744	rc = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &payload,4745				  sizeof(payload), 0);4746	if (rc)4747		pm8001_ccb_free(pm8001_ha, ccb);4748 4749	return rc;4750}4751 4752const struct pm8001_dispatch pm8001_8001_dispatch = {4753	.name			= "pmc8001",4754	.chip_init		= pm8001_chip_init,4755	.chip_post_init		= pm8001_chip_post_init,4756	.chip_soft_rst		= pm8001_chip_soft_rst,4757	.chip_rst		= pm8001_hw_chip_rst,4758	.chip_iounmap		= pm8001_chip_iounmap,4759	.isr			= pm8001_chip_isr,4760	.is_our_interrupt	= pm8001_chip_is_our_interrupt,4761	.isr_process_oq		= process_oq,4762	.interrupt_enable 	= pm8001_chip_interrupt_enable,4763	.interrupt_disable	= pm8001_chip_interrupt_disable,4764	.make_prd		= pm8001_chip_make_sg,4765	.smp_req		= pm8001_chip_smp_req,4766	.ssp_io_req		= pm8001_chip_ssp_io_req,4767	.sata_req		= pm8001_chip_sata_req,4768	.phy_start_req		= pm8001_chip_phy_start_req,4769	.phy_stop_req		= pm8001_chip_phy_stop_req,4770	.reg_dev_req		= pm8001_chip_reg_dev_req,4771	.dereg_dev_req		= pm8001_chip_dereg_dev_req,4772	.phy_ctl_req		= pm8001_chip_phy_ctl_req,4773	.task_abort		= pm8001_chip_abort_task,4774	.ssp_tm_req		= pm8001_chip_ssp_tm_req,4775	.get_nvmd_req		= pm8001_chip_get_nvmd_req,4776	.set_nvmd_req		= pm8001_chip_set_nvmd_req,4777	.fw_flash_update_req	= pm8001_chip_fw_flash_update_req,4778	.set_dev_state_req	= pm8001_chip_set_dev_state_req,4779	.sas_re_init_req	= pm8001_chip_sas_re_initialization,4780	.fatal_errors		= pm80xx_fatal_errors,4781};4782