^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) * Marvell 88SE64xx/88SE94xx main function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 2007 Red Hat, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright 2008 Marvell. <kewei@marvell.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright 2009-2011 Marvell. <yuxiangl@marvell.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "mv_sas.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) static int mvs_find_tag(struct mvs_info *mvi, struct sas_task *task, u32 *tag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) if (task->lldd_task) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) struct mvs_slot_info *slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) slot = task->lldd_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *tag = slot->slot_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) void mvs_tag_clear(struct mvs_info *mvi, u32 tag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) void *bitmap = mvi->tags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) clear_bit(tag, bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) void mvs_tag_free(struct mvs_info *mvi, u32 tag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) mvs_tag_clear(mvi, tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) void mvs_tag_set(struct mvs_info *mvi, unsigned int tag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) void *bitmap = mvi->tags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) set_bit(tag, bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) inline int mvs_tag_alloc(struct mvs_info *mvi, u32 *tag_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) unsigned int index, tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) void *bitmap = mvi->tags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) index = find_first_zero_bit(bitmap, mvi->tags_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) tag = index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) if (tag >= mvi->tags_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) return -SAS_QUEUE_FULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) mvs_tag_set(mvi, tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) *tag_out = tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) void mvs_tag_init(struct mvs_info *mvi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) for (i = 0; i < mvi->tags_num; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) mvs_tag_clear(mvi, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static struct mvs_info *mvs_find_dev_mvi(struct domain_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) unsigned long i = 0, j = 0, hi = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct sas_ha_struct *sha = dev->port->ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct mvs_info *mvi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct asd_sas_phy *phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) while (sha->sas_port[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) if (sha->sas_port[i] == dev->port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) phy = container_of(sha->sas_port[i]->phy_list.next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct asd_sas_phy, port_phy_el);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) j = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) while (sha->sas_phy[j]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (sha->sas_phy[j] == phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) j++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) hi = j/((struct mvs_prv_info *)sha->lldd_ha)->n_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[hi];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return mvi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static int mvs_find_dev_phyno(struct domain_device *dev, int *phyno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) unsigned long i = 0, j = 0, n = 0, num = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct mvs_device *mvi_dev = (struct mvs_device *)dev->lldd_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) struct mvs_info *mvi = mvi_dev->mvi_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) struct sas_ha_struct *sha = dev->port->ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) while (sha->sas_port[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (sha->sas_port[i] == dev->port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct asd_sas_phy *phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) list_for_each_entry(phy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) &sha->sas_port[i]->phy_list, port_phy_el) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) j = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) while (sha->sas_phy[j]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if (sha->sas_phy[j] == phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) j++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) phyno[n] = (j >= mvi->chip->n_phy) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) (j - mvi->chip->n_phy) : j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) num++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) n++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) return num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct mvs_device *mvs_find_dev_by_reg_set(struct mvs_info *mvi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) u8 reg_set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) u32 dev_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) for (dev_no = 0; dev_no < MVS_MAX_DEVICES; dev_no++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (mvi->devices[dev_no].taskfileset == MVS_ID_NOT_MAPPED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (mvi->devices[dev_no].taskfileset == reg_set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) return &mvi->devices[dev_no];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static inline void mvs_free_reg_set(struct mvs_info *mvi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct mvs_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) if (!dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) mv_printk("device has been free.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (dev->taskfileset == MVS_ID_NOT_MAPPED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) MVS_CHIP_DISP->free_reg_set(mvi, &dev->taskfileset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) static inline u8 mvs_assign_reg_set(struct mvs_info *mvi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) struct mvs_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (dev->taskfileset != MVS_ID_NOT_MAPPED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return MVS_CHIP_DISP->assign_reg_set(mvi, &dev->taskfileset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) void mvs_phys_reset(struct mvs_info *mvi, u32 phy_mask, int hard)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) u32 no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) for_each_phy(phy_mask, phy_mask, no) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (!(phy_mask & 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) MVS_CHIP_DISP->phy_reset(mvi, no, hard);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) int mvs_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) void *funcdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) int rc = 0, phy_id = sas_phy->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) u32 tmp, i = 0, hi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) struct sas_ha_struct *sha = sas_phy->ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) struct mvs_info *mvi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) while (sha->sas_phy[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (sha->sas_phy[i] == sas_phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) hi = i/((struct mvs_prv_info *)sha->lldd_ha)->n_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[hi];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) switch (func) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) case PHY_FUNC_SET_LINK_RATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) MVS_CHIP_DISP->phy_set_link_rate(mvi, phy_id, funcdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) case PHY_FUNC_HARD_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) tmp = MVS_CHIP_DISP->read_phy_ctl(mvi, phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (tmp & PHY_RST_HARD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) MVS_CHIP_DISP->phy_reset(mvi, phy_id, MVS_HARD_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) case PHY_FUNC_LINK_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) MVS_CHIP_DISP->phy_enable(mvi, phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) MVS_CHIP_DISP->phy_reset(mvi, phy_id, MVS_SOFT_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) case PHY_FUNC_DISABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) MVS_CHIP_DISP->phy_disable(mvi, phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) case PHY_FUNC_RELEASE_SPINUP_HOLD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) rc = -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) msleep(200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) void mvs_set_sas_addr(struct mvs_info *mvi, int port_id, u32 off_lo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) u32 off_hi, u64 sas_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) u32 lo = (u32)sas_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) u32 hi = (u32)(sas_addr>>32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) MVS_CHIP_DISP->write_port_cfg_addr(mvi, port_id, off_lo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) MVS_CHIP_DISP->write_port_cfg_data(mvi, port_id, lo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) MVS_CHIP_DISP->write_port_cfg_addr(mvi, port_id, off_hi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) MVS_CHIP_DISP->write_port_cfg_data(mvi, port_id, hi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) static void mvs_bytes_dmaed(struct mvs_info *mvi, int i, gfp_t gfp_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) struct mvs_phy *phy = &mvi->phy[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) struct asd_sas_phy *sas_phy = &phy->sas_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (!phy->phy_attached)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (!(phy->att_dev_info & PORT_DEV_TRGT_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) && phy->phy_type & PORT_TYPE_SAS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) sas_notify_phy_event_gfp(sas_phy, PHYE_OOB_DONE, gfp_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) if (sas_phy->phy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) struct sas_phy *sphy = sas_phy->phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) sphy->negotiated_linkrate = sas_phy->linkrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) sphy->minimum_linkrate = phy->minimum_linkrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) sphy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) sphy->maximum_linkrate = phy->maximum_linkrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) sphy->maximum_linkrate_hw = MVS_CHIP_DISP->phy_max_link_rate();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (phy->phy_type & PORT_TYPE_SAS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) struct sas_identify_frame *id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) id = (struct sas_identify_frame *)phy->frame_rcvd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) id->dev_type = phy->identify.device_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) id->initiator_bits = SAS_PROTOCOL_ALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) id->target_bits = phy->identify.target_port_protocols;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) /* direct attached SAS device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (phy->att_dev_info & PORT_SSP_TRGT_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) MVS_CHIP_DISP->write_port_cfg_addr(mvi, i, PHYR_PHY_STAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) MVS_CHIP_DISP->write_port_cfg_data(mvi, i, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) } else if (phy->phy_type & PORT_TYPE_SATA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) /*Nothing*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) mv_dprintk("phy %d byte dmaded.\n", i + mvi->id * mvi->chip->n_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) sas_phy->frame_rcvd_size = phy->frame_rcvd_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) sas_notify_port_event_gfp(sas_phy, PORTE_BYTES_DMAED, gfp_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) void mvs_scan_start(struct Scsi_Host *shost)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) unsigned short core_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) struct mvs_info *mvi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) struct mvs_prv_info *mvs_prv = sha->lldd_ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) core_nr = ((struct mvs_prv_info *)sha->lldd_ha)->n_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) for (j = 0; j < core_nr; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) for (i = 0; i < mvi->chip->n_phy; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) mvs_bytes_dmaed(mvi, i, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) mvs_prv->scan_finished = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) int mvs_scan_finished(struct Scsi_Host *shost, unsigned long time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) struct mvs_prv_info *mvs_prv = sha->lldd_ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if (mvs_prv->scan_finished == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) sas_drain_work(sha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) static int mvs_task_prep_smp(struct mvs_info *mvi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) struct mvs_task_exec_info *tei)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) int elem, rc, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) struct sas_ha_struct *sha = mvi->sas;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) struct sas_task *task = tei->task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) struct mvs_cmd_hdr *hdr = tei->hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) struct domain_device *dev = task->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) struct asd_sas_port *sas_port = dev->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) struct sas_phy *sphy = dev->phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) struct asd_sas_phy *sas_phy = sha->sas_phy[sphy->number];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) struct scatterlist *sg_req, *sg_resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) u32 req_len, resp_len, tag = tei->tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) void *buf_tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) u8 *buf_oaf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) dma_addr_t buf_tmp_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) void *buf_prd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) struct mvs_slot_info *slot = &mvi->slot_info[tag];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) u32 flags = (tei->n_elem << MCH_PRD_LEN_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * DMA-map SMP request, response buffers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) sg_req = &task->smp_task.smp_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) elem = dma_map_sg(mvi->dev, sg_req, 1, DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (!elem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) req_len = sg_dma_len(sg_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) sg_resp = &task->smp_task.smp_resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) elem = dma_map_sg(mvi->dev, sg_resp, 1, DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) if (!elem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) resp_len = SB_RFB_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) /* must be in dwords */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if ((req_len & 0x3) || (resp_len & 0x3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) goto err_out_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) * arrange MVS_SLOT_BUF_SZ-sized DMA buffer according to our needs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) /* region 1: command table area (MVS_SSP_CMD_SZ bytes) ***** */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) buf_tmp = slot->buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) buf_tmp_dma = slot->buf_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) hdr->cmd_tbl = cpu_to_le64(sg_dma_address(sg_req));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) /* region 2: open address frame area (MVS_OAF_SZ bytes) ********* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) buf_oaf = buf_tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) hdr->open_frame = cpu_to_le64(buf_tmp_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) buf_tmp += MVS_OAF_SZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) buf_tmp_dma += MVS_OAF_SZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) /* region 3: PRD table *********************************** */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) buf_prd = buf_tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (tei->n_elem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) hdr->prd_tbl = cpu_to_le64(buf_tmp_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) hdr->prd_tbl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) i = MVS_CHIP_DISP->prd_size() * tei->n_elem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) buf_tmp += i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) buf_tmp_dma += i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) /* region 4: status buffer (larger the PRD, smaller this buf) ****** */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) slot->response = buf_tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) hdr->status_buf = cpu_to_le64(buf_tmp_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (mvi->flags & MVF_FLAG_SOC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) hdr->reserved[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) * Fill in TX ring and command slot header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) slot->tx = mvi->tx_prod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) mvi->tx[mvi->tx_prod] = cpu_to_le32((TXQ_CMD_SMP << TXQ_CMD_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) TXQ_MODE_I | tag |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) (MVS_PHY_ID << TXQ_PHY_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) hdr->flags |= flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) hdr->lens = cpu_to_le32(((resp_len / 4) << 16) | ((req_len - 4) / 4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) hdr->tags = cpu_to_le32(tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) hdr->data_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) /* generate open address frame hdr (first 12 bytes) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) /* initiator, SMP, ftype 1h */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) buf_oaf[0] = (1 << 7) | (PROTOCOL_SMP << 4) | 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) buf_oaf[1] = min(sas_port->linkrate, dev->linkrate) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) *(u16 *)(buf_oaf + 2) = 0xFFFF; /* SAS SPEC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) memcpy(buf_oaf + 4, dev->sas_addr, SAS_ADDR_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) /* fill in PRD (scatter/gather) table, if any */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) MVS_CHIP_DISP->make_prd(task->scatter, tei->n_elem, buf_prd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) err_out_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) dma_unmap_sg(mvi->dev, &tei->task->smp_task.smp_resp, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) dma_unmap_sg(mvi->dev, &tei->task->smp_task.smp_req, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) static u32 mvs_get_ncq_tag(struct sas_task *task, u32 *tag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) struct ata_queued_cmd *qc = task->uldd_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) if (qc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (qc->tf.command == ATA_CMD_FPDMA_WRITE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) qc->tf.command == ATA_CMD_FPDMA_READ ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) qc->tf.command == ATA_CMD_FPDMA_RECV ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) qc->tf.command == ATA_CMD_FPDMA_SEND ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) qc->tf.command == ATA_CMD_NCQ_NON_DATA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) *tag = qc->tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) return 1;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) static int mvs_task_prep_ata(struct mvs_info *mvi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) struct mvs_task_exec_info *tei)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) struct sas_task *task = tei->task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) struct domain_device *dev = task->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) struct mvs_device *mvi_dev = dev->lldd_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) struct mvs_cmd_hdr *hdr = tei->hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) struct asd_sas_port *sas_port = dev->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) struct mvs_slot_info *slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) void *buf_prd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) u32 tag = tei->tag, hdr_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) u32 flags, del_q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) void *buf_tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) u8 *buf_cmd, *buf_oaf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) dma_addr_t buf_tmp_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) u32 i, req_len, resp_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) const u32 max_resp_len = SB_RFB_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (mvs_assign_reg_set(mvi, mvi_dev) == MVS_ID_NOT_MAPPED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) mv_dprintk("Have not enough regiset for dev %d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) mvi_dev->device_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) slot = &mvi->slot_info[tag];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) slot->tx = mvi->tx_prod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) del_q = TXQ_MODE_I | tag |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) (TXQ_CMD_STP << TXQ_CMD_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) ((sas_port->phy_mask & TXQ_PHY_MASK) << TXQ_PHY_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) (mvi_dev->taskfileset << TXQ_SRS_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) mvi->tx[mvi->tx_prod] = cpu_to_le32(del_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (task->data_dir == DMA_FROM_DEVICE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) flags = (MVS_CHIP_DISP->prd_count() << MCH_PRD_LEN_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) flags = (tei->n_elem << MCH_PRD_LEN_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (task->ata_task.use_ncq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) flags |= MCH_FPDMA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) if (dev->sata_dev.class == ATA_DEV_ATAPI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (task->ata_task.fis.command != ATA_CMD_ID_ATAPI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) flags |= MCH_ATAPI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) hdr->flags = cpu_to_le32(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) if (task->ata_task.use_ncq && mvs_get_ncq_tag(task, &hdr_tag))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) task->ata_task.fis.sector_count |= (u8) (hdr_tag << 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) hdr_tag = tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) hdr->tags = cpu_to_le32(hdr_tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) hdr->data_len = cpu_to_le32(task->total_xfer_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) * arrange MVS_SLOT_BUF_SZ-sized DMA buffer according to our needs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) /* region 1: command table area (MVS_ATA_CMD_SZ bytes) ************** */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) buf_cmd = buf_tmp = slot->buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) buf_tmp_dma = slot->buf_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) hdr->cmd_tbl = cpu_to_le64(buf_tmp_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) buf_tmp += MVS_ATA_CMD_SZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) buf_tmp_dma += MVS_ATA_CMD_SZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) /* region 2: open address frame area (MVS_OAF_SZ bytes) ********* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) /* used for STP. unused for SATA? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) buf_oaf = buf_tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) hdr->open_frame = cpu_to_le64(buf_tmp_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) buf_tmp += MVS_OAF_SZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) buf_tmp_dma += MVS_OAF_SZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) /* region 3: PRD table ********************************************* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) buf_prd = buf_tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (tei->n_elem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) hdr->prd_tbl = cpu_to_le64(buf_tmp_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) hdr->prd_tbl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) i = MVS_CHIP_DISP->prd_size() * MVS_CHIP_DISP->prd_count();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) buf_tmp += i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) buf_tmp_dma += i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) /* region 4: status buffer (larger the PRD, smaller this buf) ****** */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) slot->response = buf_tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) hdr->status_buf = cpu_to_le64(buf_tmp_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) if (mvi->flags & MVF_FLAG_SOC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) hdr->reserved[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) req_len = sizeof(struct host_to_dev_fis);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) resp_len = MVS_SLOT_BUF_SZ - MVS_ATA_CMD_SZ -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) sizeof(struct mvs_err_info) - i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) /* request, response lengths */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) resp_len = min(resp_len, max_resp_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) hdr->lens = cpu_to_le32(((resp_len / 4) << 16) | (req_len / 4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if (likely(!task->ata_task.device_control_reg_update))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) task->ata_task.fis.flags |= 0x80; /* C=1: update ATA cmd reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) /* fill in command FIS and ATAPI CDB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) memcpy(buf_cmd, &task->ata_task.fis, sizeof(struct host_to_dev_fis));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) if (dev->sata_dev.class == ATA_DEV_ATAPI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) memcpy(buf_cmd + STP_ATAPI_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) task->ata_task.atapi_packet, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) /* generate open address frame hdr (first 12 bytes) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) /* initiator, STP, ftype 1h */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) buf_oaf[0] = (1 << 7) | (PROTOCOL_STP << 4) | 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) buf_oaf[1] = min(sas_port->linkrate, dev->linkrate) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) *(u16 *)(buf_oaf + 2) = cpu_to_be16(mvi_dev->device_id + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) memcpy(buf_oaf + 4, dev->sas_addr, SAS_ADDR_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) /* fill in PRD (scatter/gather) table, if any */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) MVS_CHIP_DISP->make_prd(task->scatter, tei->n_elem, buf_prd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (task->data_dir == DMA_FROM_DEVICE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) MVS_CHIP_DISP->dma_fix(mvi, sas_port->phy_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) TRASH_BUCKET_SIZE, tei->n_elem, buf_prd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) static int mvs_task_prep_ssp(struct mvs_info *mvi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) struct mvs_task_exec_info *tei, int is_tmf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) struct mvs_tmf_task *tmf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) struct sas_task *task = tei->task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) struct mvs_cmd_hdr *hdr = tei->hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) struct mvs_port *port = tei->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) struct domain_device *dev = task->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) struct mvs_device *mvi_dev = dev->lldd_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) struct asd_sas_port *sas_port = dev->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) struct mvs_slot_info *slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) void *buf_prd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) struct ssp_frame_hdr *ssp_hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) void *buf_tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) u8 *buf_cmd, *buf_oaf, fburst = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) dma_addr_t buf_tmp_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) u32 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) u32 resp_len, req_len, i, tag = tei->tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) const u32 max_resp_len = SB_RFB_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) u32 phy_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) slot = &mvi->slot_info[tag];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) phy_mask = ((port->wide_port_phymap) ? port->wide_port_phymap :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) sas_port->phy_mask) & TXQ_PHY_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) slot->tx = mvi->tx_prod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) mvi->tx[mvi->tx_prod] = cpu_to_le32(TXQ_MODE_I | tag |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) (TXQ_CMD_SSP << TXQ_CMD_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) (phy_mask << TXQ_PHY_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) flags = MCH_RETRY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) if (task->ssp_task.enable_first_burst) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) flags |= MCH_FBURST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) fburst = (1 << 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) if (is_tmf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) flags |= (MCH_SSP_FR_TASK << MCH_SSP_FR_TYPE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) flags |= (MCH_SSP_FR_CMD << MCH_SSP_FR_TYPE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) hdr->flags = cpu_to_le32(flags | (tei->n_elem << MCH_PRD_LEN_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) hdr->tags = cpu_to_le32(tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) hdr->data_len = cpu_to_le32(task->total_xfer_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) * arrange MVS_SLOT_BUF_SZ-sized DMA buffer according to our needs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) /* region 1: command table area (MVS_SSP_CMD_SZ bytes) ************** */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) buf_cmd = buf_tmp = slot->buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) buf_tmp_dma = slot->buf_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) hdr->cmd_tbl = cpu_to_le64(buf_tmp_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) buf_tmp += MVS_SSP_CMD_SZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) buf_tmp_dma += MVS_SSP_CMD_SZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) /* region 2: open address frame area (MVS_OAF_SZ bytes) ********* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) buf_oaf = buf_tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) hdr->open_frame = cpu_to_le64(buf_tmp_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) buf_tmp += MVS_OAF_SZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) buf_tmp_dma += MVS_OAF_SZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) /* region 3: PRD table ********************************************* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) buf_prd = buf_tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) if (tei->n_elem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) hdr->prd_tbl = cpu_to_le64(buf_tmp_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) hdr->prd_tbl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) i = MVS_CHIP_DISP->prd_size() * tei->n_elem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) buf_tmp += i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) buf_tmp_dma += i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) /* region 4: status buffer (larger the PRD, smaller this buf) ****** */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) slot->response = buf_tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) hdr->status_buf = cpu_to_le64(buf_tmp_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) if (mvi->flags & MVF_FLAG_SOC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) hdr->reserved[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) resp_len = MVS_SLOT_BUF_SZ - MVS_SSP_CMD_SZ - MVS_OAF_SZ -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) sizeof(struct mvs_err_info) - i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) resp_len = min(resp_len, max_resp_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) req_len = sizeof(struct ssp_frame_hdr) + 28;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) /* request, response lengths */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) hdr->lens = cpu_to_le32(((resp_len / 4) << 16) | (req_len / 4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) /* generate open address frame hdr (first 12 bytes) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) /* initiator, SSP, ftype 1h */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) buf_oaf[0] = (1 << 7) | (PROTOCOL_SSP << 4) | 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) buf_oaf[1] = min(sas_port->linkrate, dev->linkrate) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) *(u16 *)(buf_oaf + 2) = cpu_to_be16(mvi_dev->device_id + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) memcpy(buf_oaf + 4, dev->sas_addr, SAS_ADDR_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) /* fill in SSP frame header (Command Table.SSP frame header) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) ssp_hdr = (struct ssp_frame_hdr *)buf_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) if (is_tmf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) ssp_hdr->frame_type = SSP_TASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) ssp_hdr->frame_type = SSP_COMMAND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) memcpy(ssp_hdr->hashed_dest_addr, dev->hashed_sas_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) HASHED_SAS_ADDR_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) memcpy(ssp_hdr->hashed_src_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) dev->hashed_sas_addr, HASHED_SAS_ADDR_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) ssp_hdr->tag = cpu_to_be16(tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) /* fill in IU for TASK and Command Frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) buf_cmd += sizeof(*ssp_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) memcpy(buf_cmd, &task->ssp_task.LUN, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) if (ssp_hdr->frame_type != SSP_TASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) buf_cmd[9] = fburst | task->ssp_task.task_attr |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) (task->ssp_task.task_prio << 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) memcpy(buf_cmd + 12, task->ssp_task.cmd->cmnd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) task->ssp_task.cmd->cmd_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) } else{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) buf_cmd[10] = tmf->tmf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) switch (tmf->tmf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) case TMF_ABORT_TASK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) case TMF_QUERY_TASK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) buf_cmd[12] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) (tmf->tag_of_task_to_be_managed >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) buf_cmd[13] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) tmf->tag_of_task_to_be_managed & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) /* fill in PRD (scatter/gather) table, if any */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) MVS_CHIP_DISP->make_prd(task->scatter, tei->n_elem, buf_prd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) #define DEV_IS_GONE(mvi_dev) ((!mvi_dev || (mvi_dev->dev_type == SAS_PHY_UNUSED)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) static int mvs_task_prep(struct sas_task *task, struct mvs_info *mvi, int is_tmf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) struct mvs_tmf_task *tmf, int *pass)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) struct domain_device *dev = task->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) struct mvs_device *mvi_dev = dev->lldd_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) struct mvs_task_exec_info tei;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) struct mvs_slot_info *slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) u32 tag = 0xdeadbeef, n_elem = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) if (!dev->port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) struct task_status_struct *tsm = &task->task_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) tsm->resp = SAS_TASK_UNDELIVERED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) tsm->stat = SAS_PHY_DOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) * libsas will use dev->port, should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) * not call task_done for sata
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if (dev->dev_type != SAS_SATA_DEV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) task->task_done(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) if (DEV_IS_GONE(mvi_dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) if (mvi_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) mv_dprintk("device %d not ready.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) mvi_dev->device_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) mv_dprintk("device %016llx not ready.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) SAS_ADDR(dev->sas_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) rc = SAS_PHY_DOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) tei.port = dev->port->lldd_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) if (tei.port && !tei.port->port_attached && !tmf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) if (sas_protocol_ata(task->task_proto)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) struct task_status_struct *ts = &task->task_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) mv_dprintk("SATA/STP port %d does not attach"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) "device.\n", dev->port->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) ts->resp = SAS_TASK_COMPLETE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) ts->stat = SAS_PHY_DOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) task->task_done(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) struct task_status_struct *ts = &task->task_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) mv_dprintk("SAS port %d does not attach"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) "device.\n", dev->port->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) ts->resp = SAS_TASK_UNDELIVERED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) ts->stat = SAS_PHY_DOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) task->task_done(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) if (!sas_protocol_ata(task->task_proto)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) if (task->num_scatter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) n_elem = dma_map_sg(mvi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) task->scatter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) task->num_scatter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) task->data_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) if (!n_elem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) goto prep_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) n_elem = task->num_scatter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) rc = mvs_tag_alloc(mvi, &tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) slot = &mvi->slot_info[tag];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) task->lldd_task = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) slot->n_elem = n_elem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) slot->slot_tag = tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) slot->buf = dma_pool_zalloc(mvi->dma_pool, GFP_ATOMIC, &slot->buf_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) if (!slot->buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) goto err_out_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) tei.task = task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) tei.hdr = &mvi->slot[tag];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) tei.tag = tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) tei.n_elem = n_elem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) switch (task->task_proto) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) case SAS_PROTOCOL_SMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) rc = mvs_task_prep_smp(mvi, &tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) case SAS_PROTOCOL_SSP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) rc = mvs_task_prep_ssp(mvi, &tei, is_tmf, tmf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) case SAS_PROTOCOL_SATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) case SAS_PROTOCOL_STP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) rc = mvs_task_prep_ata(mvi, &tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) dev_printk(KERN_ERR, mvi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) "unknown sas_task proto: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) task->task_proto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) mv_dprintk("rc is %x\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) goto err_out_slot_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) slot->task = task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) slot->port = tei.port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) task->lldd_task = slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) list_add_tail(&slot->entry, &tei.port->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) spin_lock(&task->task_state_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) task->task_state_flags |= SAS_TASK_AT_INITIATOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) spin_unlock(&task->task_state_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) mvi_dev->running_req++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) ++(*pass);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) mvi->tx_prod = (mvi->tx_prod + 1) & (MVS_CHIP_SLOT_SZ - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) err_out_slot_buf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) dma_pool_free(mvi->dma_pool, slot->buf, slot->buf_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) err_out_tag:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) mvs_tag_free(mvi, tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) dev_printk(KERN_ERR, mvi->dev, "mvsas prep failed[%d]!\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) if (!sas_protocol_ata(task->task_proto))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) if (n_elem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) dma_unmap_sg(mvi->dev, task->scatter, n_elem,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) task->data_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) prep_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) static int mvs_task_exec(struct sas_task *task, gfp_t gfp_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) struct completion *completion, int is_tmf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) struct mvs_tmf_task *tmf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) struct mvs_info *mvi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) u32 rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) u32 pass = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) mvi = ((struct mvs_device *)task->dev->lldd_dev)->mvi_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) spin_lock_irqsave(&mvi->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) rc = mvs_task_prep(task, mvi, is_tmf, tmf, &pass);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) dev_printk(KERN_ERR, mvi->dev, "mvsas exec failed[%d]!\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) if (likely(pass))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) MVS_CHIP_DISP->start_delivery(mvi, (mvi->tx_prod - 1) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) (MVS_CHIP_SLOT_SZ - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) spin_unlock_irqrestore(&mvi->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) int mvs_queue_command(struct sas_task *task, gfp_t gfp_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) return mvs_task_exec(task, gfp_flags, NULL, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) static void mvs_slot_free(struct mvs_info *mvi, u32 rx_desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) u32 slot_idx = rx_desc & RXQ_SLOT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) mvs_tag_clear(mvi, slot_idx);
^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) static void mvs_slot_task_free(struct mvs_info *mvi, struct sas_task *task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) struct mvs_slot_info *slot, u32 slot_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) if (!slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) if (!slot->task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) if (!sas_protocol_ata(task->task_proto))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) if (slot->n_elem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) dma_unmap_sg(mvi->dev, task->scatter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) slot->n_elem, task->data_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) switch (task->task_proto) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) case SAS_PROTOCOL_SMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) dma_unmap_sg(mvi->dev, &task->smp_task.smp_resp, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) dma_unmap_sg(mvi->dev, &task->smp_task.smp_req, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) case SAS_PROTOCOL_SATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) case SAS_PROTOCOL_STP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) case SAS_PROTOCOL_SSP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) /* do nothing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) if (slot->buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) dma_pool_free(mvi->dma_pool, slot->buf, slot->buf_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) slot->buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) list_del_init(&slot->entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) task->lldd_task = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) slot->task = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) slot->port = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) slot->slot_tag = 0xFFFFFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) mvs_slot_free(mvi, slot_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) static void mvs_update_wideport(struct mvs_info *mvi, int phy_no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) struct mvs_phy *phy = &mvi->phy[phy_no];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) struct mvs_port *port = phy->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) int j, no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) for_each_phy(port->wide_port_phymap, j, no) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) if (j & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) MVS_CHIP_DISP->write_port_cfg_addr(mvi, no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) PHYR_WIDE_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) MVS_CHIP_DISP->write_port_cfg_data(mvi, no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) port->wide_port_phymap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) MVS_CHIP_DISP->write_port_cfg_addr(mvi, no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) PHYR_WIDE_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) MVS_CHIP_DISP->write_port_cfg_data(mvi, no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) static u32 mvs_is_phy_ready(struct mvs_info *mvi, int i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) struct mvs_phy *phy = &mvi->phy[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) struct mvs_port *port = phy->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) tmp = MVS_CHIP_DISP->read_phy_ctl(mvi, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) if ((tmp & PHY_READY_MASK) && !(phy->irq_status & PHYEV_POOF)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) if (!port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) phy->phy_attached = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) return tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) if (port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) if (phy->phy_type & PORT_TYPE_SAS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) port->wide_port_phymap &= ~(1U << i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) if (!port->wide_port_phymap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) port->port_attached = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) mvs_update_wideport(mvi, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) } else if (phy->phy_type & PORT_TYPE_SATA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) port->port_attached = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) phy->port = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) phy->phy_attached = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) phy->phy_type &= ~(PORT_TYPE_SAS | PORT_TYPE_SATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) static void *mvs_get_d2h_reg(struct mvs_info *mvi, int i, void *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) u32 *s = (u32 *) buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) if (!s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) MVS_CHIP_DISP->write_port_cfg_addr(mvi, i, PHYR_SATA_SIG3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) s[3] = cpu_to_le32(MVS_CHIP_DISP->read_port_cfg_data(mvi, i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) MVS_CHIP_DISP->write_port_cfg_addr(mvi, i, PHYR_SATA_SIG2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) s[2] = cpu_to_le32(MVS_CHIP_DISP->read_port_cfg_data(mvi, i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) MVS_CHIP_DISP->write_port_cfg_addr(mvi, i, PHYR_SATA_SIG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) s[1] = cpu_to_le32(MVS_CHIP_DISP->read_port_cfg_data(mvi, i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) MVS_CHIP_DISP->write_port_cfg_addr(mvi, i, PHYR_SATA_SIG0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) s[0] = cpu_to_le32(MVS_CHIP_DISP->read_port_cfg_data(mvi, i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) if (((s[1] & 0x00FFFFFF) == 0x00EB1401) && (*(u8 *)&s[3] == 0x01))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) s[1] = 0x00EB1401 | (*((u8 *)&s[1] + 3) & 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) return s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) static u32 mvs_is_sig_fis_received(u32 irq_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) return irq_status & PHYEV_SIG_FIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) static void mvs_sig_remove_timer(struct mvs_phy *phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) if (phy->timer.function)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) del_timer(&phy->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) phy->timer.function = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) void mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) struct mvs_phy *phy = &mvi->phy[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) struct sas_identify_frame *id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) id = (struct sas_identify_frame *)phy->frame_rcvd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) if (get_st) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) phy->irq_status = MVS_CHIP_DISP->read_port_irq_stat(mvi, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) phy->phy_status = mvs_is_phy_ready(mvi, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) if (phy->phy_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) int oob_done = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) struct asd_sas_phy *sas_phy = &mvi->phy[i].sas_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) oob_done = MVS_CHIP_DISP->oob_done(mvi, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) MVS_CHIP_DISP->fix_phy_info(mvi, i, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) if (phy->phy_type & PORT_TYPE_SATA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) phy->identify.target_port_protocols = SAS_PROTOCOL_STP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) if (mvs_is_sig_fis_received(phy->irq_status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) mvs_sig_remove_timer(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) phy->phy_attached = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) phy->att_dev_sas_addr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) i + mvi->id * mvi->chip->n_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) if (oob_done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) sas_phy->oob_mode = SATA_OOB_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) phy->frame_rcvd_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) sizeof(struct dev_to_host_fis);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) mvs_get_d2h_reg(mvi, i, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) dev_printk(KERN_DEBUG, mvi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) "Phy%d : No sig fis\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) tmp = MVS_CHIP_DISP->read_port_irq_mask(mvi, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) MVS_CHIP_DISP->write_port_irq_mask(mvi, i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) tmp | PHYEV_SIG_FIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) phy->phy_attached = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) phy->phy_type &= ~PORT_TYPE_SATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) goto out_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) } else if (phy->phy_type & PORT_TYPE_SAS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) || phy->att_dev_info & PORT_SSP_INIT_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) phy->phy_attached = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) phy->identify.device_type =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) phy->att_dev_info & PORT_DEV_TYPE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) if (phy->identify.device_type == SAS_END_DEVICE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) phy->identify.target_port_protocols =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) SAS_PROTOCOL_SSP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) else if (phy->identify.device_type != SAS_PHY_UNUSED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) phy->identify.target_port_protocols =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) SAS_PROTOCOL_SMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) if (oob_done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) sas_phy->oob_mode = SAS_OOB_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) phy->frame_rcvd_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) sizeof(struct sas_identify_frame);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) memcpy(sas_phy->attached_sas_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) &phy->att_dev_sas_addr, SAS_ADDR_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) if (MVS_CHIP_DISP->phy_work_around)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) MVS_CHIP_DISP->phy_work_around(mvi, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) mv_dprintk("phy %d attach dev info is %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) i + mvi->id * mvi->chip->n_phy, phy->att_dev_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) mv_dprintk("phy %d attach sas addr is %llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) i + mvi->id * mvi->chip->n_phy, phy->att_dev_sas_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) out_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) if (get_st)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) MVS_CHIP_DISP->write_port_irq_stat(mvi, i, phy->irq_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) static void mvs_port_notify_formed(struct asd_sas_phy *sas_phy, int lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) struct sas_ha_struct *sas_ha = sas_phy->ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) struct mvs_info *mvi = NULL; int i = 0, hi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) struct mvs_phy *phy = sas_phy->lldd_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) struct asd_sas_port *sas_port = sas_phy->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) struct mvs_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) if (!sas_port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) while (sas_ha->sas_phy[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) if (sas_ha->sas_phy[i] == sas_phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) hi = i/((struct mvs_prv_info *)sas_ha->lldd_ha)->n_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) mvi = ((struct mvs_prv_info *)sas_ha->lldd_ha)->mvi[hi];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) if (i >= mvi->chip->n_phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) port = &mvi->port[i - mvi->chip->n_phy];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) port = &mvi->port[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) if (lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) spin_lock_irqsave(&mvi->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) port->port_attached = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) phy->port = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) sas_port->lldd_port = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) if (phy->phy_type & PORT_TYPE_SAS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) port->wide_port_phymap = sas_port->phy_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) mv_printk("set wide port phy map %x\n", sas_port->phy_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) mvs_update_wideport(mvi, sas_phy->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) /* direct attached SAS device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) if (phy->att_dev_info & PORT_SSP_TRGT_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) MVS_CHIP_DISP->write_port_cfg_addr(mvi, i, PHYR_PHY_STAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) MVS_CHIP_DISP->write_port_cfg_data(mvi, i, 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) if (lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) spin_unlock_irqrestore(&mvi->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) static void mvs_port_notify_deformed(struct asd_sas_phy *sas_phy, int lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) struct domain_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) struct mvs_phy *phy = sas_phy->lldd_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) struct mvs_info *mvi = phy->mvi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) struct asd_sas_port *port = sas_phy->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) int phy_no = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) while (phy != &mvi->phy[phy_no]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) phy_no++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) if (phy_no >= MVS_MAX_PHYS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) list_for_each_entry(dev, &port->dev_list, dev_list_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) mvs_do_release_task(phy->mvi, phy_no, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) void mvs_port_formed(struct asd_sas_phy *sas_phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) mvs_port_notify_formed(sas_phy, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) void mvs_port_deformed(struct asd_sas_phy *sas_phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) mvs_port_notify_deformed(sas_phy, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) static struct mvs_device *mvs_alloc_dev(struct mvs_info *mvi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) u32 dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) for (dev = 0; dev < MVS_MAX_DEVICES; dev++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) if (mvi->devices[dev].dev_type == SAS_PHY_UNUSED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) mvi->devices[dev].device_id = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) return &mvi->devices[dev];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) if (dev == MVS_MAX_DEVICES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) mv_printk("max support %d devices, ignore ..\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) MVS_MAX_DEVICES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) static void mvs_free_dev(struct mvs_device *mvi_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) u32 id = mvi_dev->device_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) memset(mvi_dev, 0, sizeof(*mvi_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) mvi_dev->device_id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) mvi_dev->dev_type = SAS_PHY_UNUSED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) mvi_dev->dev_status = MVS_DEV_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) mvi_dev->taskfileset = MVS_ID_NOT_MAPPED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) static int mvs_dev_found_notify(struct domain_device *dev, int lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) int res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) struct mvs_info *mvi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) struct domain_device *parent_dev = dev->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) struct mvs_device *mvi_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) mvi = mvs_find_dev_mvi(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) if (lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) spin_lock_irqsave(&mvi->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) mvi_device = mvs_alloc_dev(mvi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) if (!mvi_device) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) res = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) goto found_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) dev->lldd_dev = mvi_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) mvi_device->dev_status = MVS_DEV_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) mvi_device->dev_type = dev->dev_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) mvi_device->mvi_info = mvi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) mvi_device->sas_device = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) if (parent_dev && dev_is_expander(parent_dev->dev_type)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) int phy_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) u8 phy_num = parent_dev->ex_dev.num_phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) struct ex_phy *phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) for (phy_id = 0; phy_id < phy_num; phy_id++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) phy = &parent_dev->ex_dev.ex_phy[phy_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) if (SAS_ADDR(phy->attached_sas_addr) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) SAS_ADDR(dev->sas_addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) mvi_device->attached_phy = phy_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) if (phy_id == phy_num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) mv_printk("Error: no attached dev:%016llx"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) "at ex:%016llx.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) SAS_ADDR(dev->sas_addr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) SAS_ADDR(parent_dev->sas_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) res = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) found_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) if (lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) spin_unlock_irqrestore(&mvi->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) int mvs_dev_found(struct domain_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) return mvs_dev_found_notify(dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) static void mvs_dev_gone_notify(struct domain_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) struct mvs_device *mvi_dev = dev->lldd_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) struct mvs_info *mvi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) if (!mvi_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) mv_dprintk("found dev has gone.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) mvi = mvi_dev->mvi_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) spin_lock_irqsave(&mvi->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) mv_dprintk("found dev[%d:%x] is gone.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) mvi_dev->device_id, mvi_dev->dev_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) mvs_release_task(mvi, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) mvs_free_reg_set(mvi, mvi_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) mvs_free_dev(mvi_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) dev->lldd_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) mvi_dev->sas_device = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) spin_unlock_irqrestore(&mvi->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) void mvs_dev_gone(struct domain_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) mvs_dev_gone_notify(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) static void mvs_task_done(struct sas_task *task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) if (!del_timer(&task->slow_task->timer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) complete(&task->slow_task->completion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) static void mvs_tmf_timedout(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) struct sas_task_slow *slow = from_timer(slow, t, timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) struct sas_task *task = slow->task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) task->task_state_flags |= SAS_TASK_STATE_ABORTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) complete(&task->slow_task->completion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) #define MVS_TASK_TIMEOUT 20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) static int mvs_exec_internal_tmf_task(struct domain_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) void *parameter, u32 para_len, struct mvs_tmf_task *tmf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) int res, retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) struct sas_task *task = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) for (retry = 0; retry < 3; retry++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) task = sas_alloc_slow_task(GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) if (!task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) task->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) task->task_proto = dev->tproto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) memcpy(&task->ssp_task, parameter, para_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) task->task_done = mvs_task_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) task->slow_task->timer.function = mvs_tmf_timedout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) task->slow_task->timer.expires = jiffies + MVS_TASK_TIMEOUT*HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) add_timer(&task->slow_task->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) res = mvs_task_exec(task, GFP_KERNEL, NULL, 1, tmf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) if (res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) del_timer(&task->slow_task->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) mv_printk("executing internal task failed:%d\n", res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) goto ex_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) wait_for_completion(&task->slow_task->completion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) res = TMF_RESP_FUNC_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) /* Even TMF timed out, return direct. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) mv_printk("TMF task[%x] timeout.\n", tmf->tmf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) goto ex_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) if (task->task_status.resp == SAS_TASK_COMPLETE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) task->task_status.stat == SAM_STAT_GOOD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) res = TMF_RESP_FUNC_COMPLETE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) if (task->task_status.resp == SAS_TASK_COMPLETE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) task->task_status.stat == SAS_DATA_UNDERRUN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) /* no error, but return the number of bytes of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) * underrun */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) res = task->task_status.residual;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) if (task->task_status.resp == SAS_TASK_COMPLETE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) task->task_status.stat == SAS_DATA_OVERRUN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) mv_dprintk("blocked task error.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) res = -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) mv_dprintk(" task to dev %016llx response: 0x%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) "status 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) SAS_ADDR(dev->sas_addr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) task->task_status.resp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) task->task_status.stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) sas_free_task(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) task = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) ex_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) BUG_ON(retry == 3 && task != NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) sas_free_task(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) static int mvs_debug_issue_ssp_tmf(struct domain_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) u8 *lun, struct mvs_tmf_task *tmf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) struct sas_ssp_task ssp_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) if (!(dev->tproto & SAS_PROTOCOL_SSP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) return TMF_RESP_FUNC_ESUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) memcpy(ssp_task.LUN, lun, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) return mvs_exec_internal_tmf_task(dev, &ssp_task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) sizeof(ssp_task), tmf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) /* Standard mandates link reset for ATA (type 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) and hard reset for SSP (type 1) , only for RECOVERY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) static int mvs_debug_I_T_nexus_reset(struct domain_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) struct sas_phy *phy = sas_get_local_phy(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) int reset_type = (dev->dev_type == SAS_SATA_DEV ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) (dev->tproto & SAS_PROTOCOL_STP)) ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) rc = sas_phy_reset(phy, reset_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) sas_put_local_phy(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) msleep(2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) /* mandatory SAM-3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) int mvs_lu_reset(struct domain_device *dev, u8 *lun)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) int rc = TMF_RESP_FUNC_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) struct mvs_tmf_task tmf_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) struct mvs_device * mvi_dev = dev->lldd_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) struct mvs_info *mvi = mvi_dev->mvi_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) tmf_task.tmf = TMF_LU_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) mvi_dev->dev_status = MVS_DEV_EH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) rc = mvs_debug_issue_ssp_tmf(dev, lun, &tmf_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) if (rc == TMF_RESP_FUNC_COMPLETE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) spin_lock_irqsave(&mvi->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) mvs_release_task(mvi, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) spin_unlock_irqrestore(&mvi->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) /* If failed, fall-through I_T_Nexus reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) mv_printk("%s for device[%x]:rc= %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) mvi_dev->device_id, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) int mvs_I_T_nexus_reset(struct domain_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) int rc = TMF_RESP_FUNC_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) struct mvs_device *mvi_dev = (struct mvs_device *)dev->lldd_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) struct mvs_info *mvi = mvi_dev->mvi_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) if (mvi_dev->dev_status != MVS_DEV_EH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) return TMF_RESP_FUNC_COMPLETE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) mvi_dev->dev_status = MVS_DEV_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) rc = mvs_debug_I_T_nexus_reset(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) mv_printk("%s for device[%x]:rc= %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) __func__, mvi_dev->device_id, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) spin_lock_irqsave(&mvi->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) mvs_release_task(mvi, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) spin_unlock_irqrestore(&mvi->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) /* optional SAM-3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) int mvs_query_task(struct sas_task *task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) u32 tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) struct scsi_lun lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) struct mvs_tmf_task tmf_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) int rc = TMF_RESP_FUNC_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) if (task->lldd_task && task->task_proto & SAS_PROTOCOL_SSP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) struct scsi_cmnd * cmnd = (struct scsi_cmnd *)task->uldd_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) struct domain_device *dev = task->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) struct mvs_device *mvi_dev = (struct mvs_device *)dev->lldd_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) struct mvs_info *mvi = mvi_dev->mvi_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) int_to_scsilun(cmnd->device->lun, &lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) rc = mvs_find_tag(mvi, task, &tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) if (rc == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) rc = TMF_RESP_FUNC_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) tmf_task.tmf = TMF_QUERY_TASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) tmf_task.tag_of_task_to_be_managed = cpu_to_le16(tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) rc = mvs_debug_issue_ssp_tmf(dev, lun.scsi_lun, &tmf_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) switch (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) /* The task is still in Lun, release it then */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) case TMF_RESP_FUNC_SUCC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) /* The task is not in Lun or failed, reset the phy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) case TMF_RESP_FUNC_FAILED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) case TMF_RESP_FUNC_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) mv_printk("%s:rc= %d\n", __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) /* mandatory SAM-3, still need free task/slot info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) int mvs_abort_task(struct sas_task *task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) struct scsi_lun lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) struct mvs_tmf_task tmf_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) struct domain_device *dev = task->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) struct mvs_device *mvi_dev = (struct mvs_device *)dev->lldd_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) struct mvs_info *mvi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) int rc = TMF_RESP_FUNC_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) u32 tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) if (!mvi_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) mv_printk("Device has removed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) return TMF_RESP_FUNC_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) mvi = mvi_dev->mvi_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) spin_lock_irqsave(&task->task_state_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) if (task->task_state_flags & SAS_TASK_STATE_DONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) spin_unlock_irqrestore(&task->task_state_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) rc = TMF_RESP_FUNC_COMPLETE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) spin_unlock_irqrestore(&task->task_state_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) mvi_dev->dev_status = MVS_DEV_EH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) if (task->lldd_task && task->task_proto & SAS_PROTOCOL_SSP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) struct scsi_cmnd * cmnd = (struct scsi_cmnd *)task->uldd_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) int_to_scsilun(cmnd->device->lun, &lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) rc = mvs_find_tag(mvi, task, &tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) if (rc == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) mv_printk("No such tag in %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) rc = TMF_RESP_FUNC_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) tmf_task.tmf = TMF_ABORT_TASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) tmf_task.tag_of_task_to_be_managed = cpu_to_le16(tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) rc = mvs_debug_issue_ssp_tmf(dev, lun.scsi_lun, &tmf_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) /* if successful, clear the task and callback forwards.*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) if (rc == TMF_RESP_FUNC_COMPLETE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) u32 slot_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) struct mvs_slot_info *slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) if (task->lldd_task) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) slot = task->lldd_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) slot_no = (u32) (slot - mvi->slot_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) spin_lock_irqsave(&mvi->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) mvs_slot_complete(mvi, slot_no, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) spin_unlock_irqrestore(&mvi->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) } else if (task->task_proto & SAS_PROTOCOL_SATA ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) task->task_proto & SAS_PROTOCOL_STP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) if (SAS_SATA_DEV == dev->dev_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) struct mvs_slot_info *slot = task->lldd_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) u32 slot_idx = (u32)(slot - mvi->slot_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) mv_dprintk("mvs_abort_task() mvi=%p task=%p "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) "slot=%p slot_idx=x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) mvi, task, slot, slot_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) task->task_state_flags |= SAS_TASK_STATE_ABORTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) mvs_slot_task_free(mvi, task, slot, slot_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) rc = TMF_RESP_FUNC_COMPLETE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) if (rc != TMF_RESP_FUNC_COMPLETE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) mv_printk("%s:rc= %d\n", __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) int mvs_abort_task_set(struct domain_device *dev, u8 *lun)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) struct mvs_tmf_task tmf_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) tmf_task.tmf = TMF_ABORT_TASK_SET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) rc = mvs_debug_issue_ssp_tmf(dev, lun, &tmf_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) int mvs_clear_aca(struct domain_device *dev, u8 *lun)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) int rc = TMF_RESP_FUNC_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) struct mvs_tmf_task tmf_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) tmf_task.tmf = TMF_CLEAR_ACA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) rc = mvs_debug_issue_ssp_tmf(dev, lun, &tmf_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) int mvs_clear_task_set(struct domain_device *dev, u8 *lun)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) int rc = TMF_RESP_FUNC_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) struct mvs_tmf_task tmf_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) tmf_task.tmf = TMF_CLEAR_TASK_SET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) rc = mvs_debug_issue_ssp_tmf(dev, lun, &tmf_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) static int mvs_sata_done(struct mvs_info *mvi, struct sas_task *task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) u32 slot_idx, int err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) struct mvs_device *mvi_dev = task->dev->lldd_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) struct task_status_struct *tstat = &task->task_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) struct ata_task_resp *resp = (struct ata_task_resp *)tstat->buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) int stat = SAM_STAT_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) resp->frame_len = sizeof(struct dev_to_host_fis);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) memcpy(&resp->ending_fis[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) SATA_RECEIVED_D2H_FIS(mvi_dev->taskfileset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) sizeof(struct dev_to_host_fis));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) tstat->buf_valid_size = sizeof(*resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) if (unlikely(err)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) if (unlikely(err & CMD_ISS_STPD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) stat = SAS_OPEN_REJECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) stat = SAS_PROTO_RESPONSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) return stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) static void mvs_set_sense(u8 *buffer, int len, int d_sense,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) int key, int asc, int ascq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) memset(buffer, 0, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) if (d_sense) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) /* Descriptor format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) if (len < 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) mv_printk("Length %d of sense buffer too small to "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) "fit sense %x:%x:%x", len, key, asc, ascq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) buffer[0] = 0x72; /* Response Code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) if (len > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) buffer[1] = key; /* Sense Key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) if (len > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) buffer[2] = asc; /* ASC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) if (len > 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) buffer[3] = ascq; /* ASCQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) if (len < 14) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) mv_printk("Length %d of sense buffer too small to "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) "fit sense %x:%x:%x", len, key, asc, ascq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) buffer[0] = 0x70; /* Response Code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) if (len > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) buffer[2] = key; /* Sense Key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) if (len > 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) buffer[7] = 0x0a; /* Additional Sense Length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) if (len > 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) buffer[12] = asc; /* ASC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) if (len > 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) buffer[13] = ascq; /* ASCQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) static void mvs_fill_ssp_resp_iu(struct ssp_response_iu *iu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) u8 key, u8 asc, u8 asc_q)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) iu->datapres = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) iu->response_data_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) iu->sense_data_len = 17;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) iu->status = 02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) mvs_set_sense(iu->sense_data, 17, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) key, asc, asc_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) static int mvs_slot_err(struct mvs_info *mvi, struct sas_task *task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) u32 slot_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) struct mvs_slot_info *slot = &mvi->slot_info[slot_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) int stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) u32 err_dw0 = le32_to_cpu(*(u32 *)slot->response);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) u32 err_dw1 = le32_to_cpu(*((u32 *)slot->response + 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) u32 tfs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) enum mvs_port_type type = PORT_TYPE_SAS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) if (err_dw0 & CMD_ISS_STPD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) MVS_CHIP_DISP->issue_stop(mvi, type, tfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) MVS_CHIP_DISP->command_active(mvi, slot_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) stat = SAM_STAT_CHECK_CONDITION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) switch (task->task_proto) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) case SAS_PROTOCOL_SSP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) stat = SAS_ABORTED_TASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) if ((err_dw0 & NO_DEST) || err_dw1 & bit(31)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) struct ssp_response_iu *iu = slot->response +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) sizeof(struct mvs_err_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) mvs_fill_ssp_resp_iu(iu, NOT_READY, 0x04, 01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) sas_ssp_task_response(mvi->dev, task, iu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) stat = SAM_STAT_CHECK_CONDITION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) if (err_dw1 & bit(31))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) mv_printk("reuse same slot, retry command.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) case SAS_PROTOCOL_SMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) stat = SAM_STAT_CHECK_CONDITION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) case SAS_PROTOCOL_SATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) case SAS_PROTOCOL_STP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) task->ata_task.use_ncq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) stat = SAS_PROTO_RESPONSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) mvs_sata_done(mvi, task, slot_idx, err_dw0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) return stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) int mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc, u32 flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) u32 slot_idx = rx_desc & RXQ_SLOT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) struct mvs_slot_info *slot = &mvi->slot_info[slot_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) struct sas_task *task = slot->task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) struct mvs_device *mvi_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) struct task_status_struct *tstat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) struct domain_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) u32 aborted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) void *to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) enum exec_status sts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) if (unlikely(!task || !task->lldd_task || !task->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) tstat = &task->task_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) dev = task->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) mvi_dev = dev->lldd_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) spin_lock(&task->task_state_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) task->task_state_flags &=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) ~(SAS_TASK_STATE_PENDING | SAS_TASK_AT_INITIATOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) task->task_state_flags |= SAS_TASK_STATE_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) /* race condition*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) aborted = task->task_state_flags & SAS_TASK_STATE_ABORTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) spin_unlock(&task->task_state_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) memset(tstat, 0, sizeof(*tstat));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) tstat->resp = SAS_TASK_COMPLETE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) if (unlikely(aborted)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) tstat->stat = SAS_ABORTED_TASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) if (mvi_dev && mvi_dev->running_req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) mvi_dev->running_req--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) if (sas_protocol_ata(task->task_proto))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) mvs_free_reg_set(mvi, mvi_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) mvs_slot_task_free(mvi, task, slot, slot_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) /* when no device attaching, go ahead and complete by error handling*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) if (unlikely(!mvi_dev || flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) if (!mvi_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) mv_dprintk("port has not device.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) tstat->stat = SAS_PHY_DOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) * error info record present; slot->response is 32 bit aligned but may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) * not be 64 bit aligned, so check for zero in two 32 bit reads
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) if (unlikely((rx_desc & RXQ_ERR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) && (*((u32 *)slot->response)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) || *(((u32 *)slot->response) + 1)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) mv_dprintk("port %d slot %d rx_desc %X has error info"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) "%016llX.\n", slot->port->sas_port.id, slot_idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) rx_desc, get_unaligned_le64(slot->response));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) tstat->stat = mvs_slot_err(mvi, task, slot_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) tstat->resp = SAS_TASK_COMPLETE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) switch (task->task_proto) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) case SAS_PROTOCOL_SSP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) /* hw says status == 0, datapres == 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) if (rx_desc & RXQ_GOOD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) tstat->stat = SAM_STAT_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) tstat->resp = SAS_TASK_COMPLETE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) /* response frame present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) else if (rx_desc & RXQ_RSP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) struct ssp_response_iu *iu = slot->response +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) sizeof(struct mvs_err_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) sas_ssp_task_response(mvi->dev, task, iu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) tstat->stat = SAM_STAT_CHECK_CONDITION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) case SAS_PROTOCOL_SMP: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) struct scatterlist *sg_resp = &task->smp_task.smp_resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) tstat->stat = SAM_STAT_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) to = kmap_atomic(sg_page(sg_resp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) memcpy(to + sg_resp->offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) slot->response + sizeof(struct mvs_err_info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) sg_dma_len(sg_resp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) kunmap_atomic(to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) case SAS_PROTOCOL_SATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) case SAS_PROTOCOL_STP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) tstat->stat = mvs_sata_done(mvi, task, slot_idx, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) tstat->stat = SAM_STAT_CHECK_CONDITION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) if (!slot->port->port_attached) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) mv_dprintk("port %d has removed.\n", slot->port->sas_port.id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) tstat->stat = SAS_PHY_DOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) if (mvi_dev && mvi_dev->running_req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) mvi_dev->running_req--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) if (sas_protocol_ata(task->task_proto) && !mvi_dev->running_req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) mvs_free_reg_set(mvi, mvi_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) mvs_slot_task_free(mvi, task, slot, slot_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) sts = tstat->stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) spin_unlock(&mvi->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) if (task->task_done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) task->task_done(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) spin_lock(&mvi->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) return sts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) void mvs_do_release_task(struct mvs_info *mvi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) int phy_no, struct domain_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) u32 slot_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) struct mvs_phy *phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) struct mvs_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) struct mvs_slot_info *slot, *slot2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) phy = &mvi->phy[phy_no];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) port = phy->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) if (!port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) /* clean cmpl queue in case request is already finished */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) mvs_int_rx(mvi, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) list_for_each_entry_safe(slot, slot2, &port->list, entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) struct sas_task *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) slot_idx = (u32) (slot - mvi->slot_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) task = slot->task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) if (dev && task->dev != dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) mv_printk("Release slot [%x] tag[%x], task [%p]:\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) slot_idx, slot->slot_tag, task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) MVS_CHIP_DISP->command_active(mvi, slot_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) mvs_slot_complete(mvi, slot_idx, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) void mvs_release_task(struct mvs_info *mvi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) struct domain_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) int i, phyno[WIDE_PORT_MAX_PHY], num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) num = mvs_find_dev_phyno(dev, phyno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) for (i = 0; i < num; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) mvs_do_release_task(mvi, phyno[i], dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) static void mvs_phy_disconnected(struct mvs_phy *phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) phy->phy_attached = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) phy->att_dev_info = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) phy->att_dev_sas_addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) static void mvs_work_queue(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) struct delayed_work *dw = container_of(work, struct delayed_work, work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) struct mvs_wq *mwq = container_of(dw, struct mvs_wq, work_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) struct mvs_info *mvi = mwq->mvi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) u32 phy_no = (unsigned long) mwq->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) struct mvs_phy *phy = &mvi->phy[phy_no];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) struct asd_sas_phy *sas_phy = &phy->sas_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) spin_lock_irqsave(&mvi->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) if (mwq->handler & PHY_PLUG_EVENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) if (phy->phy_event & PHY_PLUG_OUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) tmp = MVS_CHIP_DISP->read_phy_ctl(mvi, phy_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) phy->phy_event &= ~PHY_PLUG_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) if (!(tmp & PHY_READY_MASK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) sas_phy_disconnected(sas_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) mvs_phy_disconnected(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) sas_notify_phy_event_gfp(sas_phy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) PHYE_LOSS_OF_SIGNAL, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) mv_dprintk("phy%d Removed Device\n", phy_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) MVS_CHIP_DISP->detect_porttype(mvi, phy_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) mvs_update_phyinfo(mvi, phy_no, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) mvs_bytes_dmaed(mvi, phy_no, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) mvs_port_notify_formed(sas_phy, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) mv_dprintk("phy%d Attached Device\n", phy_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) } else if (mwq->handler & EXP_BRCT_CHG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) phy->phy_event &= ~EXP_BRCT_CHG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) sas_notify_port_event_gfp(sas_phy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) PORTE_BROADCAST_RCVD, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) mv_dprintk("phy%d Got Broadcast Change\n", phy_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) list_del(&mwq->entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) spin_unlock_irqrestore(&mvi->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) kfree(mwq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) static int mvs_handle_event(struct mvs_info *mvi, void *data, int handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) struct mvs_wq *mwq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) mwq = kmalloc(sizeof(struct mvs_wq), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) if (mwq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) mwq->mvi = mvi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) mwq->data = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) mwq->handler = handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) MV_INIT_DELAYED_WORK(&mwq->work_q, mvs_work_queue, mwq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) list_add_tail(&mwq->entry, &mvi->wq_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) schedule_delayed_work(&mwq->work_q, HZ * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) static void mvs_sig_time_out(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) struct mvs_phy *phy = from_timer(phy, t, timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) struct mvs_info *mvi = phy->mvi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) u8 phy_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) for (phy_no = 0; phy_no < mvi->chip->n_phy; phy_no++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) if (&mvi->phy[phy_no] == phy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) mv_dprintk("Get signature time out, reset phy %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) phy_no+mvi->id*mvi->chip->n_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) MVS_CHIP_DISP->phy_reset(mvi, phy_no, MVS_HARD_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) struct mvs_phy *phy = &mvi->phy[phy_no];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) phy->irq_status = MVS_CHIP_DISP->read_port_irq_stat(mvi, phy_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) MVS_CHIP_DISP->write_port_irq_stat(mvi, phy_no, phy->irq_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) mv_dprintk("phy %d ctrl sts=0x%08X.\n", phy_no+mvi->id*mvi->chip->n_phy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) MVS_CHIP_DISP->read_phy_ctl(mvi, phy_no));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) mv_dprintk("phy %d irq sts = 0x%08X\n", phy_no+mvi->id*mvi->chip->n_phy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) phy->irq_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) * events is port event now ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) * we need check the interrupt status which belongs to per port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) if (phy->irq_status & PHYEV_DCDR_ERR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) mv_dprintk("phy %d STP decoding error.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) phy_no + mvi->id*mvi->chip->n_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) if (phy->irq_status & PHYEV_POOF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) mdelay(500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) if (!(phy->phy_event & PHY_PLUG_OUT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) int dev_sata = phy->phy_type & PORT_TYPE_SATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) int ready;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) mvs_do_release_task(mvi, phy_no, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) phy->phy_event |= PHY_PLUG_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) MVS_CHIP_DISP->clear_srs_irq(mvi, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) mvs_handle_event(mvi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) (void *)(unsigned long)phy_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) PHY_PLUG_EVENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) ready = mvs_is_phy_ready(mvi, phy_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) if (ready || dev_sata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) if (MVS_CHIP_DISP->stp_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) MVS_CHIP_DISP->stp_reset(mvi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) phy_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) MVS_CHIP_DISP->phy_reset(mvi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) phy_no, MVS_SOFT_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) if (phy->irq_status & PHYEV_COMWAKE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) tmp = MVS_CHIP_DISP->read_port_irq_mask(mvi, phy_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) MVS_CHIP_DISP->write_port_irq_mask(mvi, phy_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) tmp | PHYEV_SIG_FIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) if (phy->timer.function == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) phy->timer.function = mvs_sig_time_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) phy->timer.expires = jiffies + 5*HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) add_timer(&phy->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) if (phy->irq_status & (PHYEV_SIG_FIS | PHYEV_ID_DONE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) phy->phy_status = mvs_is_phy_ready(mvi, phy_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) mv_dprintk("notify plug in on phy[%d]\n", phy_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) if (phy->phy_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) mdelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) MVS_CHIP_DISP->detect_porttype(mvi, phy_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) if (phy->phy_type & PORT_TYPE_SATA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) tmp = MVS_CHIP_DISP->read_port_irq_mask(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) mvi, phy_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) tmp &= ~PHYEV_SIG_FIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) MVS_CHIP_DISP->write_port_irq_mask(mvi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) phy_no, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) mvs_update_phyinfo(mvi, phy_no, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) if (phy->phy_type & PORT_TYPE_SAS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) MVS_CHIP_DISP->phy_reset(mvi, phy_no, MVS_PHY_TUNE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) mdelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) mvs_bytes_dmaed(mvi, phy_no, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) /* whether driver is going to handle hot plug */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) if (phy->phy_event & PHY_PLUG_OUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) mvs_port_notify_formed(&phy->sas_phy, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) phy->phy_event &= ~PHY_PLUG_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) mv_dprintk("plugin interrupt but phy%d is gone\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) phy_no + mvi->id*mvi->chip->n_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) } else if (phy->irq_status & PHYEV_BROAD_CH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) mv_dprintk("phy %d broadcast change.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) phy_no + mvi->id*mvi->chip->n_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) mvs_handle_event(mvi, (void *)(unsigned long)phy_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) EXP_BRCT_CHG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) int mvs_int_rx(struct mvs_info *mvi, bool self_clear)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) u32 rx_prod_idx, rx_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) bool attn = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) /* the first dword in the RX ring is special: it contains
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) * a mirror of the hardware's RX producer index, so that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) * we don't have to stall the CPU reading that register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) * The actual RX ring is offset by one dword, due to this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) rx_prod_idx = mvi->rx_cons;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) mvi->rx_cons = le32_to_cpu(mvi->rx[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) if (mvi->rx_cons == 0xfff) /* h/w hasn't touched RX ring yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) /* The CMPL_Q may come late, read from register and try again
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) * note: if coalescing is enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) * it will need to read from register every time for sure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) if (unlikely(mvi->rx_cons == rx_prod_idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) mvi->rx_cons = MVS_CHIP_DISP->rx_update(mvi) & RX_RING_SZ_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) if (mvi->rx_cons == rx_prod_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) while (mvi->rx_cons != rx_prod_idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) /* increment our internal RX consumer pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) rx_prod_idx = (rx_prod_idx + 1) & (MVS_RX_RING_SZ - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) rx_desc = le32_to_cpu(mvi->rx[rx_prod_idx + 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) if (likely(rx_desc & RXQ_DONE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) mvs_slot_complete(mvi, rx_desc, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) if (rx_desc & RXQ_ATTN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) attn = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) } else if (rx_desc & RXQ_ERR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) if (!(rx_desc & RXQ_DONE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) mvs_slot_complete(mvi, rx_desc, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) } else if (rx_desc & RXQ_SLOT_RESET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) mvs_slot_free(mvi, rx_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) if (attn && self_clear)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) MVS_CHIP_DISP->int_full(mvi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) int mvs_gpio_write(struct sas_ha_struct *sha, u8 reg_type, u8 reg_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) u8 reg_count, u8 *write_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) struct mvs_prv_info *mvs_prv = sha->lldd_ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) struct mvs_info *mvi = mvs_prv->mvi[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) if (MVS_CHIP_DISP->gpio_write) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) return MVS_CHIP_DISP->gpio_write(mvs_prv, reg_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) reg_index, reg_count, write_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) }