Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Aic94xx SAS/SATA driver SCB management.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2005 Adaptec, Inc.  All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/gfp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <scsi/scsi_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include "aic94xx.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include "aic94xx_reg.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include "aic94xx_hwi.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include "aic94xx_seq.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include "aic94xx_dump.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) /* ---------- EMPTY SCB ---------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #define DL_PHY_MASK      7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define BYTES_DMAED      0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define PRIMITIVE_RECVD  0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define PHY_EVENT        0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define LINK_RESET_ERROR 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define TIMER_EVENT      0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define REQ_TASK_ABORT   0xF0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define REQ_DEVICE_RESET 0xF1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define SIGNAL_NCQ_ERROR 0xF2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define CLEAR_NCQ_ERROR  0xF3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define PHY_EVENTS_STATUS (CURRENT_LOSS_OF_SIGNAL | CURRENT_OOB_DONE   \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 			   | CURRENT_SPINUP_HOLD | CURRENT_GTO_TIMEOUT \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 			   | CURRENT_OOB_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) static void get_lrate_mode(struct asd_phy *phy, u8 oob_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	struct sas_phy *sas_phy = phy->sas_phy.phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	switch (oob_mode & 7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	case PHY_SPEED_60:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 		/* FIXME: sas transport class doesn't have this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 		phy->sas_phy.linkrate = SAS_LINK_RATE_6_0_GBPS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 		phy->sas_phy.phy->negotiated_linkrate = SAS_LINK_RATE_6_0_GBPS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	case PHY_SPEED_30:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 		phy->sas_phy.linkrate = SAS_LINK_RATE_3_0_GBPS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		phy->sas_phy.phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	case PHY_SPEED_15:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 		phy->sas_phy.linkrate = SAS_LINK_RATE_1_5_GBPS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 		phy->sas_phy.phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	sas_phy->negotiated_linkrate = phy->sas_phy.linkrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	sas_phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	sas_phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	sas_phy->maximum_linkrate = phy->phy_desc->max_sas_lrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	sas_phy->minimum_linkrate = phy->phy_desc->min_sas_lrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	if (oob_mode & SAS_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		phy->sas_phy.oob_mode = SAS_OOB_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	else if (oob_mode & SATA_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		phy->sas_phy.oob_mode = SATA_OOB_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) static void asd_phy_event_tasklet(struct asd_ascb *ascb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 					 struct done_list_struct *dl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	struct asd_ha_struct *asd_ha = ascb->ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	int phy_id = dl->status_block[0] & DL_PHY_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	struct asd_phy *phy = &asd_ha->phys[phy_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	u8 oob_status = dl->status_block[1] & PHY_EVENTS_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	u8 oob_mode   = dl->status_block[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	switch (oob_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	case CURRENT_LOSS_OF_SIGNAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		/* directly attached device was removed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		ASD_DPRINTK("phy%d: device unplugged\n", phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		asd_turn_led(asd_ha, phy_id, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		sas_phy_disconnected(&phy->sas_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		sas_notify_phy_event(&phy->sas_phy, PHYE_LOSS_OF_SIGNAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	case CURRENT_OOB_DONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		/* hot plugged device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		asd_turn_led(asd_ha, phy_id, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		get_lrate_mode(phy, oob_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		ASD_DPRINTK("phy%d device plugged: lrate:0x%x, proto:0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 			    phy_id, phy->sas_phy.linkrate, phy->sas_phy.iproto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		sas_notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	case CURRENT_SPINUP_HOLD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		/* hot plug SATA, no COMWAKE sent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		asd_turn_led(asd_ha, phy_id, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		sas_notify_phy_event(&phy->sas_phy, PHYE_SPINUP_HOLD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	case CURRENT_GTO_TIMEOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	case CURRENT_OOB_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		ASD_DPRINTK("phy%d error while OOB: oob status:0x%x\n", phy_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 			    dl->status_block[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		asd_turn_led(asd_ha, phy_id, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		sas_phy_disconnected(&phy->sas_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		sas_notify_phy_event(&phy->sas_phy, PHYE_OOB_ERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /* If phys are enabled sparsely, this will do the right thing. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static unsigned ord_phy(struct asd_ha_struct *asd_ha, struct asd_phy *phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	u8 enabled_mask = asd_ha->hw_prof.enabled_phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	int i, k = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	for_each_phy(enabled_mask, enabled_mask, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		if (&asd_ha->phys[i] == phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 			return k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		k++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)  * asd_get_attached_sas_addr -- extract/generate attached SAS address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)  * @phy: pointer to asd_phy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)  * @sas_addr: pointer to buffer where the SAS address is to be written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)  * This function extracts the SAS address from an IDENTIFY frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)  * received.  If OOB is SATA, then a SAS address is generated from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)  * HA tables.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)  * LOCKING: the frame_rcvd_lock needs to be held since this parses the frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)  * buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) static void asd_get_attached_sas_addr(struct asd_phy *phy, u8 *sas_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	if (phy->sas_phy.frame_rcvd[0] == 0x34
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	    && phy->sas_phy.oob_mode == SATA_OOB_MODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		struct asd_ha_struct *asd_ha = phy->sas_phy.ha->lldd_ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		/* FIS device-to-host */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		u64 addr = be64_to_cpu(*(__be64 *)phy->phy_desc->sas_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		addr += asd_ha->hw_prof.sata_name_base + ord_phy(asd_ha, phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		*(__be64 *)sas_addr = cpu_to_be64(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		struct sas_identify_frame *idframe =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 			(void *) phy->sas_phy.frame_rcvd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		memcpy(sas_addr, idframe->sas_addr, SAS_ADDR_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) static void asd_form_port(struct asd_ha_struct *asd_ha, struct asd_phy *phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	struct asd_port *free_port = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	struct asd_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	struct asd_sas_phy *sas_phy = &phy->sas_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	spin_lock_irqsave(&asd_ha->asd_ports_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	if (!phy->asd_port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		for (i = 0; i < ASD_MAX_PHYS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 			port = &asd_ha->asd_ports[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 			/* Check for wide port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 			if (port->num_phys > 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 			    memcmp(port->sas_addr, sas_phy->sas_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 				   SAS_ADDR_SIZE) == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 			    memcmp(port->attached_sas_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 				   sas_phy->attached_sas_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 				   SAS_ADDR_SIZE) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 			/* Find a free port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 			if (port->num_phys == 0 && free_port == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 				free_port = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		/* Use a free port if this doesn't form a wide port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 		if (i >= ASD_MAX_PHYS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 			port = free_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 			BUG_ON(!port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 			memcpy(port->sas_addr, sas_phy->sas_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 			       SAS_ADDR_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 			memcpy(port->attached_sas_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 			       sas_phy->attached_sas_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 			       SAS_ADDR_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		port->num_phys++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		port->phy_mask |= (1U << sas_phy->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		phy->asd_port = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	ASD_DPRINTK("%s: updating phy_mask 0x%x for phy%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		    __func__, phy->asd_port->phy_mask, sas_phy->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	asd_update_port_links(asd_ha, phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	spin_unlock_irqrestore(&asd_ha->asd_ports_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static void asd_deform_port(struct asd_ha_struct *asd_ha, struct asd_phy *phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	struct asd_port *port = phy->asd_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	struct asd_sas_phy *sas_phy = &phy->sas_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	spin_lock_irqsave(&asd_ha->asd_ports_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	if (port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		port->num_phys--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		port->phy_mask &= ~(1U << sas_phy->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		phy->asd_port = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	spin_unlock_irqrestore(&asd_ha->asd_ports_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) static void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 				    struct done_list_struct *dl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 				    int edb_id, int phy_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	int edb_el = edb_id + ascb->edb_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	struct asd_dma_tok *edb = ascb->ha->seq.edb_arr[edb_el];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	struct asd_phy *phy = &ascb->ha->phys[phy_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	u16 size = ((dl->status_block[3] & 7) << 8) | dl->status_block[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	size = min(size, (u16) sizeof(phy->frame_rcvd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	spin_lock_irqsave(&phy->sas_phy.frame_rcvd_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	memcpy(phy->sas_phy.frame_rcvd, edb->vaddr, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	phy->sas_phy.frame_rcvd_size = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	asd_get_attached_sas_addr(phy, phy->sas_phy.attached_sas_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	asd_dump_frame_rcvd(phy, dl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	asd_form_port(ascb->ha, phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	sas_notify_port_event(&phy->sas_phy, PORTE_BYTES_DMAED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) static void asd_link_reset_err_tasklet(struct asd_ascb *ascb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 				       struct done_list_struct *dl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 				       int phy_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	struct asd_ha_struct *asd_ha = ascb->ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	struct sas_ha_struct *sas_ha = &asd_ha->sas_ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	struct asd_phy *phy = &asd_ha->phys[phy_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	u8 lr_error = dl->status_block[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	u8 retries_left = dl->status_block[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	switch (lr_error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 		ASD_DPRINTK("phy%d: Receive ID timer expired\n", phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 		ASD_DPRINTK("phy%d: Loss of signal\n", phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		ASD_DPRINTK("phy%d: Loss of dword sync\n", phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		ASD_DPRINTK("phy%d: Receive FIS timeout\n", phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 		ASD_DPRINTK("phy%d: unknown link reset error code: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 			    phy_id, lr_error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	asd_turn_led(asd_ha, phy_id, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	sas_phy_disconnected(sas_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	asd_deform_port(asd_ha, phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	if (retries_left == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 		int num = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		struct asd_ascb *cp = asd_ascb_alloc_list(ascb->ha, &num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 							  GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 		if (!cp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 			asd_printk("%s: out of memory\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		ASD_DPRINTK("phy%d: retries:0 performing link reset seq\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 			    phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		asd_build_control_phy(cp, phy_id, ENABLE_PHY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		if (asd_post_ascb_list(ascb->ha, cp, 1) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 			asd_ascb_free(cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) static void asd_primitive_rcvd_tasklet(struct asd_ascb *ascb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 				       struct done_list_struct *dl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 				       int phy_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	struct sas_ha_struct *sas_ha = &ascb->ha->sas_ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	struct asd_ha_struct *asd_ha = ascb->ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	struct asd_phy *phy = &asd_ha->phys[phy_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	u8  reg  = dl->status_block[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	u32 cont = dl->status_block[2] << ((reg & 3)*8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	reg &= ~3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	case LmPRMSTAT0BYTE0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 		switch (cont) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		case LmBROADCH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 		case LmBROADRVCH0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 		case LmBROADRVCH1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		case LmBROADSES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 			ASD_DPRINTK("phy%d: BROADCAST change received:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 				    phy_id, cont);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 			spin_lock_irqsave(&sas_phy->sas_prim_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 			sas_phy->sas_prim = ffs(cont);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 			spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 			sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 		case LmUNKNOWNP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 			ASD_DPRINTK("phy%d: unknown BREAK\n", phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 			ASD_DPRINTK("phy%d: primitive reg:0x%x, cont:0x%04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 				    phy_id, reg, cont);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	case LmPRMSTAT1BYTE0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		switch (cont) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 		case LmHARDRST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 			ASD_DPRINTK("phy%d: HARD_RESET primitive rcvd\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 				    phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 			/* The sequencer disables all phys on that port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 			 * We have to re-enable the phys ourselves. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 			asd_deform_port(asd_ha, phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 			sas_notify_port_event(sas_phy, PORTE_HARD_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 			ASD_DPRINTK("phy%d: primitive reg:0x%x, cont:0x%04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 				    phy_id, reg, cont);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 		ASD_DPRINTK("unknown primitive register:0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 			    dl->status_block[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)  * asd_invalidate_edb -- invalidate an EDB and if necessary post the ESCB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)  * @ascb: pointer to Empty SCB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)  * @edb_id: index [0,6] to the empty data buffer which is to be invalidated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)  * After an EDB has been invalidated, if all EDBs in this ESCB have been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)  * invalidated, the ESCB is posted back to the sequencer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)  * Context is tasklet/IRQ.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) void asd_invalidate_edb(struct asd_ascb *ascb, int edb_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	struct asd_seq_data *seq = &ascb->ha->seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	struct empty_scb *escb = &ascb->scb->escb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	struct sg_el     *eb   = &escb->eb[edb_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	struct asd_dma_tok *edb = seq->edb_arr[ascb->edb_index + edb_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	memset(edb->vaddr, 0, ASD_EDB_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	eb->flags |= ELEMENT_NOT_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	escb->num_valid--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	if (escb->num_valid == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 		int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 		/* ASD_DPRINTK("reposting escb: vaddr: 0x%p, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 			    "dma_handle: 0x%08llx, next: 0x%08llx, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 			    "index:%d, opcode:0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 			    ascb->dma_scb.vaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 			    (u64)ascb->dma_scb.dma_handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 			    le64_to_cpu(ascb->scb->header.next_scb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 			    le16_to_cpu(ascb->scb->header.index),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 			    ascb->scb->header.opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 		*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 		escb->num_valid = ASD_EDBS_PER_SCB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 		for (i = 0; i < ASD_EDBS_PER_SCB; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 			escb->eb[i].flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 		if (!list_empty(&ascb->list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 			list_del_init(&ascb->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		i = asd_post_escb_list(ascb->ha, ascb, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 		if (i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 			asd_printk("couldn't post escb, err:%d\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) static void escb_tasklet_complete(struct asd_ascb *ascb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 				  struct done_list_struct *dl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	struct asd_ha_struct *asd_ha = ascb->ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	struct sas_ha_struct *sas_ha = &asd_ha->sas_ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	int edb = (dl->opcode & DL_PHY_MASK) - 1; /* [0xc1,0xc7] -> [0,6] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	u8  sb_opcode = dl->status_block[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	int phy_id = sb_opcode & DL_PHY_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	struct asd_phy *phy = &asd_ha->phys[phy_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	if (edb > 6 || edb < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 		ASD_DPRINTK("edb is 0x%x! dl->opcode is 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 			    edb, dl->opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 		ASD_DPRINTK("sb_opcode : 0x%x, phy_id: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 			    sb_opcode, phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		ASD_DPRINTK("escb: vaddr: 0x%p, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 			    "dma_handle: 0x%llx, next: 0x%llx, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 			    "index:%d, opcode:0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 			    ascb->dma_scb.vaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 			    (unsigned long long)ascb->dma_scb.dma_handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 			    (unsigned long long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 			    le64_to_cpu(ascb->scb->header.next_scb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 			    le16_to_cpu(ascb->scb->header.index),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 			    ascb->scb->header.opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	/* Catch these before we mask off the sb_opcode bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	switch (sb_opcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	case REQ_TASK_ABORT: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 		struct asd_ascb *a, *b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 		u16 tc_abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 		struct domain_device *failed_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 		ASD_DPRINTK("%s: REQ_TASK_ABORT, reason=0x%X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 			    __func__, dl->status_block[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 		 * Find the task that caused the abort and abort it first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 		 * The sequencer won't put anything on the done list until
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 		 * that happens.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 		tc_abort = *((u16*)(&dl->status_block[1]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 		tc_abort = le16_to_cpu(tc_abort);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 		list_for_each_entry_safe(a, b, &asd_ha->seq.pend_q, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 			struct sas_task *task = a->uldd_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 			if (a->tc_index != tc_abort)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 			if (task) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 				failed_dev = task->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 				sas_task_abort(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 				ASD_DPRINTK("R_T_A for non TASK scb 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 					    a->scb->header.opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 		if (!failed_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 			ASD_DPRINTK("%s: Can't find task (tc=%d) to abort!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 				    __func__, tc_abort);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 		 * Now abort everything else for that device (hba?) so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 		 * that the EH will wake up and do something.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 		list_for_each_entry_safe(a, b, &asd_ha->seq.pend_q, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 			struct sas_task *task = a->uldd_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 			if (task &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 			    task->dev == failed_dev &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 			    a->tc_index != tc_abort)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 				sas_task_abort(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	case REQ_DEVICE_RESET: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 		struct asd_ascb *a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 		u16 conn_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 		unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 		struct sas_task *last_dev_task = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 		conn_handle = *((u16*)(&dl->status_block[1]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 		conn_handle = le16_to_cpu(conn_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 		ASD_DPRINTK("%s: REQ_DEVICE_RESET, reason=0x%X\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 			    dl->status_block[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 		/* Find the last pending task for the device... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 		list_for_each_entry(a, &asd_ha->seq.pend_q, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 			u16 x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 			struct domain_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 			struct sas_task *task = a->uldd_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 			if (!task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 			dev = task->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 			x = (unsigned long)dev->lldd_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 			if (x == conn_handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 				last_dev_task = task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 		if (!last_dev_task) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 			ASD_DPRINTK("%s: Device reset for idle device %d?\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 				    __func__, conn_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 		/* ...and set the reset flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 		spin_lock_irqsave(&last_dev_task->task_state_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 		last_dev_task->task_state_flags |= SAS_TASK_NEED_DEV_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 		spin_unlock_irqrestore(&last_dev_task->task_state_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 		/* Kill all pending tasks for the device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 		list_for_each_entry(a, &asd_ha->seq.pend_q, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 			u16 x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 			struct domain_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 			struct sas_task *task = a->uldd_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 			if (!task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 			dev = task->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 			x = (unsigned long)dev->lldd_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 			if (x == conn_handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 				sas_task_abort(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	case SIGNAL_NCQ_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 		ASD_DPRINTK("%s: SIGNAL_NCQ_ERROR\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	case CLEAR_NCQ_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 		ASD_DPRINTK("%s: CLEAR_NCQ_ERROR\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	sb_opcode &= ~DL_PHY_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	switch (sb_opcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	case BYTES_DMAED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 		ASD_DPRINTK("%s: phy%d: BYTES_DMAED\n", __func__, phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 		asd_bytes_dmaed_tasklet(ascb, dl, edb, phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 	case PRIMITIVE_RECVD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 		ASD_DPRINTK("%s: phy%d: PRIMITIVE_RECVD\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 			    phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 		asd_primitive_rcvd_tasklet(ascb, dl, phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 	case PHY_EVENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 		ASD_DPRINTK("%s: phy%d: PHY_EVENT\n", __func__, phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 		asd_phy_event_tasklet(ascb, dl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	case LINK_RESET_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 		ASD_DPRINTK("%s: phy%d: LINK_RESET_ERROR\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 			    phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 		asd_link_reset_err_tasklet(ascb, dl, phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 	case TIMER_EVENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 		ASD_DPRINTK("%s: phy%d: TIMER_EVENT, lost dw sync\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 			    __func__, phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 		asd_turn_led(asd_ha, phy_id, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 		/* the device is gone */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 		sas_phy_disconnected(sas_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 		asd_deform_port(asd_ha, phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 		sas_notify_port_event(sas_phy, PORTE_TIMER_EVENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 		ASD_DPRINTK("%s: phy%d: unknown event:0x%x\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 			    phy_id, sb_opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 		ASD_DPRINTK("edb is 0x%x! dl->opcode is 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 			    edb, dl->opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 		ASD_DPRINTK("sb_opcode : 0x%x, phy_id: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 			    sb_opcode, phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 		ASD_DPRINTK("escb: vaddr: 0x%p, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 			    "dma_handle: 0x%llx, next: 0x%llx, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 			    "index:%d, opcode:0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 			    ascb->dma_scb.vaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 			    (unsigned long long)ascb->dma_scb.dma_handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 			    (unsigned long long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 			    le64_to_cpu(ascb->scb->header.next_scb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 			    le16_to_cpu(ascb->scb->header.index),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 			    ascb->scb->header.opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	asd_invalidate_edb(ascb, edb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) int asd_init_post_escbs(struct asd_ha_struct *asd_ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	struct asd_seq_data *seq = &asd_ha->seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	for (i = 0; i < seq->num_escbs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 		seq->escb_arr[i]->tasklet_complete = escb_tasklet_complete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	ASD_DPRINTK("posting %d escbs\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 	return asd_post_escb_list(asd_ha, seq->escb_arr[0], seq->num_escbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) /* ---------- CONTROL PHY ---------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) #define CONTROL_PHY_STATUS (CURRENT_DEVICE_PRESENT | CURRENT_OOB_DONE   \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 			    | CURRENT_SPINUP_HOLD | CURRENT_GTO_TIMEOUT \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 			    | CURRENT_OOB_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)  * control_phy_tasklet_complete -- tasklet complete for CONTROL PHY ascb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)  * @ascb: pointer to an ascb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)  * @dl: pointer to the done list entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)  * This function completes a CONTROL PHY scb and frees the ascb.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)  * A note on LEDs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)  *  - an LED blinks if there is IO though it,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)  *  - if a device is connected to the LED, it is lit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)  *  - if no device is connected to the LED, is is dimmed (off).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) static void control_phy_tasklet_complete(struct asd_ascb *ascb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 					 struct done_list_struct *dl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	struct asd_ha_struct *asd_ha = ascb->ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 	struct scb *scb = ascb->scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 	struct control_phy *control_phy = &scb->control_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 	u8 phy_id = control_phy->phy_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	struct asd_phy *phy = &ascb->ha->phys[phy_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	u8 status     = dl->status_block[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	u8 oob_status = dl->status_block[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 	u8 oob_mode   = dl->status_block[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	/* u8 oob_signals= dl->status_block[3]; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 	if (status != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 		ASD_DPRINTK("%s: phy%d status block opcode:0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 			    __func__, phy_id, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 	switch (control_phy->sub_func) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 	case DISABLE_PHY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 		asd_ha->hw_prof.enabled_phys &= ~(1 << phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 		asd_turn_led(asd_ha, phy_id, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 		asd_control_led(asd_ha, phy_id, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 		ASD_DPRINTK("%s: disable phy%d\n", __func__, phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 	case ENABLE_PHY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 		asd_control_led(asd_ha, phy_id, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 		if (oob_status & CURRENT_OOB_DONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 			asd_ha->hw_prof.enabled_phys |= (1 << phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 			get_lrate_mode(phy, oob_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 			asd_turn_led(asd_ha, phy_id, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 			ASD_DPRINTK("%s: phy%d, lrate:0x%x, proto:0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 				    __func__, phy_id,phy->sas_phy.linkrate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 				    phy->sas_phy.iproto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 		} else if (oob_status & CURRENT_SPINUP_HOLD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 			asd_ha->hw_prof.enabled_phys |= (1 << phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 			asd_turn_led(asd_ha, phy_id, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 			ASD_DPRINTK("%s: phy%d, spinup hold\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 				    phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 		} else if (oob_status & CURRENT_ERR_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 			asd_turn_led(asd_ha, phy_id, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 			ASD_DPRINTK("%s: phy%d: error: oob status:0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 				    __func__, phy_id, oob_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 		} else if (oob_status & (CURRENT_HOT_PLUG_CNCT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 					 | CURRENT_DEVICE_PRESENT))  {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 			asd_ha->hw_prof.enabled_phys |= (1 << phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 			asd_turn_led(asd_ha, phy_id, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 			ASD_DPRINTK("%s: phy%d: hot plug or device present\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 				    __func__, phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 			asd_ha->hw_prof.enabled_phys |= (1 << phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 			asd_turn_led(asd_ha, phy_id, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 			ASD_DPRINTK("%s: phy%d: no device present: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 				    "oob_status:0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 				    __func__, phy_id, oob_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 	case RELEASE_SPINUP_HOLD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 	case PHY_NO_OP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 	case EXECUTE_HARD_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 		ASD_DPRINTK("%s: phy%d: sub_func:0x%x\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 			    phy_id, control_phy->sub_func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 		/* XXX finish */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 		ASD_DPRINTK("%s: phy%d: sub_func:0x%x?\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 			    phy_id, control_phy->sub_func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 	asd_ascb_free(ascb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) static void set_speed_mask(u8 *speed_mask, struct asd_phy_desc *pd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 	/* disable all speeds, then enable defaults */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 	*speed_mask = SAS_SPEED_60_DIS | SAS_SPEED_30_DIS | SAS_SPEED_15_DIS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 		| SATA_SPEED_30_DIS | SATA_SPEED_15_DIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 	switch (pd->max_sas_lrate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 	case SAS_LINK_RATE_6_0_GBPS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 		*speed_mask &= ~SAS_SPEED_60_DIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 	case SAS_LINK_RATE_3_0_GBPS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 		*speed_mask &= ~SAS_SPEED_30_DIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 	case SAS_LINK_RATE_1_5_GBPS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 		*speed_mask &= ~SAS_SPEED_15_DIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 	switch (pd->min_sas_lrate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 	case SAS_LINK_RATE_6_0_GBPS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 		*speed_mask |= SAS_SPEED_30_DIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 	case SAS_LINK_RATE_3_0_GBPS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 		*speed_mask |= SAS_SPEED_15_DIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 	case SAS_LINK_RATE_1_5_GBPS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 		/* nothing to do */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 		;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 	switch (pd->max_sata_lrate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 	case SAS_LINK_RATE_3_0_GBPS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 		*speed_mask &= ~SATA_SPEED_30_DIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 	case SAS_LINK_RATE_1_5_GBPS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 		*speed_mask &= ~SATA_SPEED_15_DIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	switch (pd->min_sata_lrate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 	case SAS_LINK_RATE_3_0_GBPS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 		*speed_mask |= SATA_SPEED_15_DIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 	case SAS_LINK_RATE_1_5_GBPS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 		/* nothing to do */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 		;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)  * asd_build_control_phy -- build a CONTROL PHY SCB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)  * @ascb: pointer to an ascb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)  * @phy_id: phy id to control, integer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)  * @subfunc: subfunction, what to actually to do the phy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)  * This function builds a CONTROL PHY scb.  No allocation of any kind
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)  * is performed. @ascb is allocated with the list function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)  * The caller can override the ascb->tasklet_complete to point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)  * to its own callback function.  It must call asd_ascb_free()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)  * at its tasklet complete function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)  * See the default implementation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) void asd_build_control_phy(struct asd_ascb *ascb, int phy_id, u8 subfunc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 	struct asd_phy *phy = &ascb->ha->phys[phy_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 	struct scb *scb = ascb->scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 	struct control_phy *control_phy = &scb->control_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 	scb->header.opcode = CONTROL_PHY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 	control_phy->phy_id = (u8) phy_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 	control_phy->sub_func = subfunc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 	switch (subfunc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 	case EXECUTE_HARD_RESET:  /* 0x81 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 	case ENABLE_PHY:          /* 0x01 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 		/* decide hot plug delay */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 		control_phy->hot_plug_delay = HOTPLUG_DELAY_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 		/* decide speed mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 		set_speed_mask(&control_phy->speed_mask, phy->phy_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 		/* initiator port settings are in the hi nibble */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 		if (phy->sas_phy.role == PHY_ROLE_INITIATOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 			control_phy->port_type = SAS_PROTOCOL_ALL << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 		else if (phy->sas_phy.role == PHY_ROLE_TARGET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 			control_phy->port_type = SAS_PROTOCOL_ALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 			control_phy->port_type =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 				(SAS_PROTOCOL_ALL << 4) | SAS_PROTOCOL_ALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 		/* link reset retries, this should be nominal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 		control_phy->link_reset_retries = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 	case RELEASE_SPINUP_HOLD: /* 0x02 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) 		/* decide the func_mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 		control_phy->func_mask = FUNCTION_MASK_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 		if (phy->phy_desc->flags & ASD_SATA_SPINUP_HOLD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 			control_phy->func_mask &= ~SPINUP_HOLD_DIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 			control_phy->func_mask |= SPINUP_HOLD_DIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 	control_phy->conn_handle = cpu_to_le16(0xFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 	ascb->tasklet_complete = control_phy_tasklet_complete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) /* ---------- INITIATE LINK ADM TASK ---------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) static void link_adm_tasklet_complete(struct asd_ascb *ascb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 				      struct done_list_struct *dl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 	u8 opcode = dl->opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 	struct initiate_link_adm *link_adm = &ascb->scb->link_adm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 	u8 phy_id = link_adm->phy_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 	if (opcode != TC_NO_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) 		asd_printk("phy%d: link adm task 0x%x completed with error "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 			   "0x%x\n", phy_id, link_adm->sub_func, opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 	ASD_DPRINTK("phy%d: link adm task 0x%x: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) 		    phy_id, link_adm->sub_func, opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) 	asd_ascb_free(ascb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) void asd_build_initiate_link_adm_task(struct asd_ascb *ascb, int phy_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) 				      u8 subfunc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 	struct scb *scb = ascb->scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) 	struct initiate_link_adm *link_adm = &scb->link_adm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 	scb->header.opcode = INITIATE_LINK_ADM_TASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) 	link_adm->phy_id = phy_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) 	link_adm->sub_func = subfunc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) 	link_adm->conn_handle = cpu_to_le16(0xFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) 	ascb->tasklet_complete = link_adm_tasklet_complete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) #endif  /*  0  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) /* ---------- SCB timer ---------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)  * asd_ascb_timedout -- called when a pending SCB's timer has expired
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)  * @t: Timer context used to fetch the SCB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)  * This is the default timeout function which does the most necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)  * Upper layers can implement their own timeout function, say to free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)  * resources they have with this SCB, and then call this one at the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)  * end of their timeout function.  To do this, one should initialize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)  * the ascb->timer.{function, expires} prior to calling the post
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)  * function. The timer is started by the post function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) void asd_ascb_timedout(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) 	struct asd_ascb *ascb = from_timer(ascb, t, timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) 	struct asd_seq_data *seq = &ascb->ha->seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) 	ASD_DPRINTK("scb:0x%x timed out\n", ascb->scb->header.opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) 	spin_lock_irqsave(&seq->pend_q_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) 	seq->pending--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) 	list_del_init(&ascb->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) 	spin_unlock_irqrestore(&seq->pend_q_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) 	asd_ascb_free(ascb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) /* ---------- CONTROL PHY ---------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) /* Given the spec value, return a driver value. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) static const int phy_func_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) 	[PHY_FUNC_NOP]        = PHY_NO_OP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) 	[PHY_FUNC_LINK_RESET] = ENABLE_PHY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) 	[PHY_FUNC_HARD_RESET] = EXECUTE_HARD_RESET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) 	[PHY_FUNC_DISABLE]    = DISABLE_PHY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) 	[PHY_FUNC_RELEASE_SPINUP_HOLD] = RELEASE_SPINUP_HOLD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) int asd_control_phy(struct asd_sas_phy *phy, enum phy_func func, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) 	struct asd_ha_struct *asd_ha = phy->ha->lldd_ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) 	struct asd_phy_desc *pd = asd_ha->phys[phy->id].phy_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) 	struct asd_ascb *ascb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) 	struct sas_phy_linkrates *rates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) 	int res = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) 	switch (func) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) 	case PHY_FUNC_CLEAR_ERROR_LOG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) 	case PHY_FUNC_GET_EVENTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) 		return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) 	case PHY_FUNC_SET_LINK_RATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) 		rates = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) 		if (rates->minimum_linkrate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) 			pd->min_sas_lrate = rates->minimum_linkrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) 			pd->min_sata_lrate = rates->minimum_linkrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) 		if (rates->maximum_linkrate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) 			pd->max_sas_lrate = rates->maximum_linkrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) 			pd->max_sata_lrate = rates->maximum_linkrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) 		func = PHY_FUNC_LINK_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) 	ascb = asd_ascb_alloc_list(asd_ha, &res, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) 	if (!ascb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) 	asd_build_control_phy(ascb, phy->id, phy_func_table[func]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) 	res = asd_post_ascb_list(asd_ha, ascb , 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) 	if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) 		asd_ascb_free(ascb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) 	return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) }