linux/drivers/scsi/libsas/sas_scsi_host.c
<<
>>
Prefs
   1/*
   2 * Serial Attached SCSI (SAS) class SCSI Host glue.
   3 *
   4 * Copyright (C) 2005 Adaptec, Inc.  All rights reserved.
   5 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
   6 *
   7 * This file is licensed under GPLv2.
   8 *
   9 * This program is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU General Public License as
  11 * published by the Free Software Foundation; either version 2 of the
  12 * License, or (at your option) any later version.
  13 *
  14 * This program is distributed in the hope that it will be useful, but
  15 * WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17 * General Public License for more details.
  18 *
  19 * You should have received a copy of the GNU General Public License
  20 * along with this program; if not, write to the Free Software
  21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  22 * USA
  23 *
  24 */
  25
  26#include <linux/kthread.h>
  27
  28#include "sas_internal.h"
  29
  30#include <scsi/scsi_host.h>
  31#include <scsi/scsi_device.h>
  32#include <scsi/scsi_tcq.h>
  33#include <scsi/scsi.h>
  34#include <scsi/scsi_eh.h>
  35#include <scsi/scsi_transport.h>
  36#include <scsi/scsi_transport_sas.h>
  37#include <scsi/sas_ata.h>
  38#include "../scsi_sas_internal.h"
  39#include "../scsi_transport_api.h"
  40#include "../scsi_priv.h"
  41
  42#include <linux/err.h>
  43#include <linux/blkdev.h>
  44#include <linux/freezer.h>
  45#include <linux/scatterlist.h>
  46#include <linux/libata.h>
  47
  48/* ---------- SCSI Host glue ---------- */
  49
  50static void sas_scsi_task_done(struct sas_task *task)
  51{
  52        struct task_status_struct *ts = &task->task_status;
  53        struct scsi_cmnd *sc = task->uldd_task;
  54        int hs = 0, stat = 0;
  55
  56        if (unlikely(task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
  57                /* Aborted tasks will be completed by the error handler */
  58                SAS_DPRINTK("task done but aborted\n");
  59                return;
  60        }
  61
  62        if (unlikely(!sc)) {
  63                SAS_DPRINTK("task_done called with non existing SCSI cmnd!\n");
  64                list_del_init(&task->list);
  65                sas_free_task(task);
  66                return;
  67        }
  68
  69        if (ts->resp == SAS_TASK_UNDELIVERED) {
  70                /* transport error */
  71                hs = DID_NO_CONNECT;
  72        } else { /* ts->resp == SAS_TASK_COMPLETE */
  73                /* task delivered, what happened afterwards? */
  74                switch (ts->stat) {
  75                case SAS_DEV_NO_RESPONSE:
  76                case SAS_INTERRUPTED:
  77                case SAS_PHY_DOWN:
  78                case SAS_NAK_R_ERR:
  79                case SAS_OPEN_TO:
  80                        hs = DID_NO_CONNECT;
  81                        break;
  82                case SAS_DATA_UNDERRUN:
  83                        scsi_set_resid(sc, ts->residual);
  84                        if (scsi_bufflen(sc) - scsi_get_resid(sc) < sc->underflow)
  85                                hs = DID_ERROR;
  86                        break;
  87                case SAS_DATA_OVERRUN:
  88                        hs = DID_ERROR;
  89                        break;
  90                case SAS_QUEUE_FULL:
  91                        hs = DID_SOFT_ERROR; /* retry */
  92                        break;
  93                case SAS_DEVICE_UNKNOWN:
  94                        hs = DID_BAD_TARGET;
  95                        break;
  96                case SAS_SG_ERR:
  97                        hs = DID_PARITY;
  98                        break;
  99                case SAS_OPEN_REJECT:
 100                        if (ts->open_rej_reason == SAS_OREJ_RSVD_RETRY)
 101                                hs = DID_SOFT_ERROR; /* retry */
 102                        else
 103                                hs = DID_ERROR;
 104                        break;
 105                case SAS_PROTO_RESPONSE:
 106                        SAS_DPRINTK("LLDD:%s sent SAS_PROTO_RESP for an SSP "
 107                                    "task; please report this\n",
 108                                    task->dev->port->ha->sas_ha_name);
 109                        break;
 110                case SAS_ABORTED_TASK:
 111                        hs = DID_ABORT;
 112                        break;
 113                case SAM_CHECK_COND:
 114                        memcpy(sc->sense_buffer, ts->buf,
 115                               min(SCSI_SENSE_BUFFERSIZE, ts->buf_valid_size));
 116                        stat = SAM_CHECK_COND;
 117                        break;
 118                default:
 119                        stat = ts->stat;
 120                        break;
 121                }
 122        }
 123        ASSIGN_SAS_TASK(sc, NULL);
 124        sc->result = (hs << 16) | stat;
 125        list_del_init(&task->list);
 126        sas_free_task(task);
 127        sc->scsi_done(sc);
 128}
 129
 130static enum task_attribute sas_scsi_get_task_attr(struct scsi_cmnd *cmd)
 131{
 132        enum task_attribute ta = TASK_ATTR_SIMPLE;
 133        if (cmd->request && blk_rq_tagged(cmd->request)) {
 134                if (cmd->device->ordered_tags &&
 135                    (cmd->request->cmd_flags & REQ_HARDBARRIER))
 136                        ta = TASK_ATTR_ORDERED;
 137        }
 138        return ta;
 139}
 140
 141static struct sas_task *sas_create_task(struct scsi_cmnd *cmd,
 142                                               struct domain_device *dev,
 143                                               gfp_t gfp_flags)
 144{
 145        struct sas_task *task = sas_alloc_task(gfp_flags);
 146        struct scsi_lun lun;
 147
 148        if (!task)
 149                return NULL;
 150
 151        task->uldd_task = cmd;
 152        ASSIGN_SAS_TASK(cmd, task);
 153
 154        task->dev = dev;
 155        task->task_proto = task->dev->tproto; /* BUG_ON(!SSP) */
 156
 157        task->ssp_task.retry_count = 1;
 158        int_to_scsilun(cmd->device->lun, &lun);
 159        memcpy(task->ssp_task.LUN, &lun.scsi_lun, 8);
 160        task->ssp_task.task_attr = sas_scsi_get_task_attr(cmd);
 161        memcpy(task->ssp_task.cdb, cmd->cmnd, 16);
 162
 163        task->scatter = scsi_sglist(cmd);
 164        task->num_scatter = scsi_sg_count(cmd);
 165        task->total_xfer_len = scsi_bufflen(cmd);
 166        task->data_dir = cmd->sc_data_direction;
 167
 168        task->task_done = sas_scsi_task_done;
 169
 170        return task;
 171}
 172
 173int sas_queue_up(struct sas_task *task)
 174{
 175        struct sas_ha_struct *sas_ha = task->dev->port->ha;
 176        struct scsi_core *core = &sas_ha->core;
 177        unsigned long flags;
 178        LIST_HEAD(list);
 179
 180        spin_lock_irqsave(&core->task_queue_lock, flags);
 181        if (sas_ha->lldd_queue_size < core->task_queue_size + 1) {
 182                spin_unlock_irqrestore(&core->task_queue_lock, flags);
 183                return -SAS_QUEUE_FULL;
 184        }
 185        list_add_tail(&task->list, &core->task_queue);
 186        core->task_queue_size += 1;
 187        spin_unlock_irqrestore(&core->task_queue_lock, flags);
 188        wake_up_process(core->queue_thread);
 189
 190        return 0;
 191}
 192
 193/**
 194 * sas_queuecommand -- Enqueue a command for processing
 195 * @parameters: See SCSI Core documentation
 196 *
 197 * Note: XXX: Remove the host unlock/lock pair when SCSI Core can
 198 * call us without holding an IRQ spinlock...
 199 */
 200int sas_queuecommand(struct scsi_cmnd *cmd,
 201                     void (*scsi_done)(struct scsi_cmnd *))
 202        __releases(host->host_lock)
 203        __acquires(dev->sata_dev.ap->lock)
 204        __releases(dev->sata_dev.ap->lock)
 205        __acquires(host->host_lock)
 206{
 207        int res = 0;
 208        struct domain_device *dev = cmd_to_domain_dev(cmd);
 209        struct Scsi_Host *host = cmd->device->host;
 210        struct sas_internal *i = to_sas_internal(host->transportt);
 211
 212        spin_unlock_irq(host->host_lock);
 213
 214        {
 215                struct sas_ha_struct *sas_ha = dev->port->ha;
 216                struct sas_task *task;
 217
 218                if (dev_is_sata(dev)) {
 219                        unsigned long flags;
 220
 221                        spin_lock_irqsave(dev->sata_dev.ap->lock, flags);
 222                        res = ata_sas_queuecmd(cmd, scsi_done,
 223                                               dev->sata_dev.ap);
 224                        spin_unlock_irqrestore(dev->sata_dev.ap->lock, flags);
 225                        goto out;
 226                }
 227
 228                res = -ENOMEM;
 229                task = sas_create_task(cmd, dev, GFP_ATOMIC);
 230                if (!task)
 231                        goto out;
 232
 233                cmd->scsi_done = scsi_done;
 234                /* Queue up, Direct Mode or Task Collector Mode. */
 235                if (sas_ha->lldd_max_execute_num < 2)
 236                        res = i->dft->lldd_execute_task(task, 1, GFP_ATOMIC);
 237                else
 238                        res = sas_queue_up(task);
 239
 240                /* Examine */
 241                if (res) {
 242                        SAS_DPRINTK("lldd_execute_task returned: %d\n", res);
 243                        ASSIGN_SAS_TASK(cmd, NULL);
 244                        sas_free_task(task);
 245                        if (res == -SAS_QUEUE_FULL) {
 246                                cmd->result = DID_SOFT_ERROR << 16; /* retry */
 247                                res = 0;
 248                                scsi_done(cmd);
 249                        }
 250                        goto out;
 251                }
 252        }
 253out:
 254        spin_lock_irq(host->host_lock);
 255        return res;
 256}
 257
 258static void sas_eh_finish_cmd(struct scsi_cmnd *cmd)
 259{
 260        struct sas_task *task = TO_SAS_TASK(cmd);
 261        struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(cmd->device->host);
 262
 263        /* remove the aborted task flag to allow the task to be
 264         * completed now. At this point, we only get called following
 265         * an actual abort of the task, so we should be guaranteed not
 266         * to be racing with any completions from the LLD (hence we
 267         * don't need the task state lock to clear the flag) */
 268        task->task_state_flags &= ~SAS_TASK_STATE_ABORTED;
 269        /* Now call task_done.  However, task will be free'd after
 270         * this */
 271        task->task_done(task);
 272        /* now finish the command and move it on to the error
 273         * handler done list, this also takes it off the
 274         * error handler pending list */
 275        scsi_eh_finish_cmd(cmd, &sas_ha->eh_done_q);
 276}
 277
 278static void sas_scsi_clear_queue_lu(struct list_head *error_q, struct scsi_cmnd *my_cmd)
 279{
 280        struct scsi_cmnd *cmd, *n;
 281
 282        list_for_each_entry_safe(cmd, n, error_q, eh_entry) {
 283                if (cmd->device->sdev_target == my_cmd->device->sdev_target &&
 284                    cmd->device->lun == my_cmd->device->lun)
 285                        sas_eh_finish_cmd(cmd);
 286        }
 287}
 288
 289static void sas_scsi_clear_queue_I_T(struct list_head *error_q,
 290                                     struct domain_device *dev)
 291{
 292        struct scsi_cmnd *cmd, *n;
 293
 294        list_for_each_entry_safe(cmd, n, error_q, eh_entry) {
 295                struct domain_device *x = cmd_to_domain_dev(cmd);
 296
 297                if (x == dev)
 298                        sas_eh_finish_cmd(cmd);
 299        }
 300}
 301
 302static void sas_scsi_clear_queue_port(struct list_head *error_q,
 303                                      struct asd_sas_port *port)
 304{
 305        struct scsi_cmnd *cmd, *n;
 306
 307        list_for_each_entry_safe(cmd, n, error_q, eh_entry) {
 308                struct domain_device *dev = cmd_to_domain_dev(cmd);
 309                struct asd_sas_port *x = dev->port;
 310
 311                if (x == port)
 312                        sas_eh_finish_cmd(cmd);
 313        }
 314}
 315
 316enum task_disposition {
 317        TASK_IS_DONE,
 318        TASK_IS_ABORTED,
 319        TASK_IS_AT_LU,
 320        TASK_IS_NOT_AT_LU,
 321        TASK_ABORT_FAILED,
 322};
 323
 324static enum task_disposition sas_scsi_find_task(struct sas_task *task)
 325{
 326        struct sas_ha_struct *ha = task->dev->port->ha;
 327        unsigned long flags;
 328        int i, res;
 329        struct sas_internal *si =
 330                to_sas_internal(task->dev->port->ha->core.shost->transportt);
 331
 332        if (ha->lldd_max_execute_num > 1) {
 333                struct scsi_core *core = &ha->core;
 334                struct sas_task *t, *n;
 335
 336                spin_lock_irqsave(&core->task_queue_lock, flags);
 337                list_for_each_entry_safe(t, n, &core->task_queue, list) {
 338                        if (task == t) {
 339                                list_del_init(&t->list);
 340                                spin_unlock_irqrestore(&core->task_queue_lock,
 341                                                       flags);
 342                                SAS_DPRINTK("%s: task 0x%p aborted from "
 343                                            "task_queue\n",
 344                                            __FUNCTION__, task);
 345                                return TASK_IS_ABORTED;
 346                        }
 347                }
 348                spin_unlock_irqrestore(&core->task_queue_lock, flags);
 349        }
 350
 351        for (i = 0; i < 5; i++) {
 352                SAS_DPRINTK("%s: aborting task 0x%p\n", __FUNCTION__, task);
 353                res = si->dft->lldd_abort_task(task);
 354
 355                spin_lock_irqsave(&task->task_state_lock, flags);
 356                if (task->task_state_flags & SAS_TASK_STATE_DONE) {
 357                        spin_unlock_irqrestore(&task->task_state_lock, flags);
 358                        SAS_DPRINTK("%s: task 0x%p is done\n", __FUNCTION__,
 359                                    task);
 360                        return TASK_IS_DONE;
 361                }
 362                spin_unlock_irqrestore(&task->task_state_lock, flags);
 363
 364                if (res == TMF_RESP_FUNC_COMPLETE) {
 365                        SAS_DPRINTK("%s: task 0x%p is aborted\n",
 366                                    __FUNCTION__, task);
 367                        return TASK_IS_ABORTED;
 368                } else if (si->dft->lldd_query_task) {
 369                        SAS_DPRINTK("%s: querying task 0x%p\n",
 370                                    __FUNCTION__, task);
 371                        res = si->dft->lldd_query_task(task);
 372                        switch (res) {
 373                        case TMF_RESP_FUNC_SUCC:
 374                                SAS_DPRINTK("%s: task 0x%p at LU\n",
 375                                            __FUNCTION__, task);
 376                                return TASK_IS_AT_LU;
 377                        case TMF_RESP_FUNC_COMPLETE:
 378                                SAS_DPRINTK("%s: task 0x%p not at LU\n",
 379                                            __FUNCTION__, task);
 380                                return TASK_IS_NOT_AT_LU;
 381                        case TMF_RESP_FUNC_FAILED:
 382                                SAS_DPRINTK("%s: task 0x%p failed to abort\n",
 383                                                __FUNCTION__, task);
 384                                return TASK_ABORT_FAILED;
 385                        }
 386
 387                }
 388        }
 389        return res;
 390}
 391
 392static int sas_recover_lu(struct domain_device *dev, struct scsi_cmnd *cmd)
 393{
 394        int res = TMF_RESP_FUNC_FAILED;
 395        struct scsi_lun lun;
 396        struct sas_internal *i =
 397                to_sas_internal(dev->port->ha->core.shost->transportt);
 398
 399        int_to_scsilun(cmd->device->lun, &lun);
 400
 401        SAS_DPRINTK("eh: device %llx LUN %x has the task\n",
 402                    SAS_ADDR(dev->sas_addr),
 403                    cmd->device->lun);
 404
 405        if (i->dft->lldd_abort_task_set)
 406                res = i->dft->lldd_abort_task_set(dev, lun.scsi_lun);
 407
 408        if (res == TMF_RESP_FUNC_FAILED) {
 409                if (i->dft->lldd_clear_task_set)
 410                        res = i->dft->lldd_clear_task_set(dev, lun.scsi_lun);
 411        }
 412
 413        if (res == TMF_RESP_FUNC_FAILED) {
 414                if (i->dft->lldd_lu_reset)
 415                        res = i->dft->lldd_lu_reset(dev, lun.scsi_lun);
 416        }
 417
 418        return res;
 419}
 420
 421static int sas_recover_I_T(struct domain_device *dev)
 422{
 423        int res = TMF_RESP_FUNC_FAILED;
 424        struct sas_internal *i =
 425                to_sas_internal(dev->port->ha->core.shost->transportt);
 426
 427        SAS_DPRINTK("I_T nexus reset for dev %016llx\n",
 428                    SAS_ADDR(dev->sas_addr));
 429
 430        if (i->dft->lldd_I_T_nexus_reset)
 431                res = i->dft->lldd_I_T_nexus_reset(dev);
 432
 433        return res;
 434}
 435
 436/* Find the sas_phy that's attached to this device */
 437struct sas_phy *sas_find_local_phy(struct domain_device *dev)
 438{
 439        struct domain_device *pdev = dev->parent;
 440        struct ex_phy *exphy = NULL;
 441        int i;
 442
 443        /* Directly attached device */
 444        if (!pdev)
 445                return dev->port->phy;
 446
 447        /* Otherwise look in the expander */
 448        for (i = 0; i < pdev->ex_dev.num_phys; i++)
 449                if (!memcmp(dev->sas_addr,
 450                            pdev->ex_dev.ex_phy[i].attached_sas_addr,
 451                            SAS_ADDR_SIZE)) {
 452                        exphy = &pdev->ex_dev.ex_phy[i];
 453                        break;
 454                }
 455
 456        BUG_ON(!exphy);
 457        return exphy->phy;
 458}
 459EXPORT_SYMBOL_GPL(sas_find_local_phy);
 460
 461/* Attempt to send a LUN reset message to a device */
 462int sas_eh_device_reset_handler(struct scsi_cmnd *cmd)
 463{
 464        struct domain_device *dev = cmd_to_domain_dev(cmd);
 465        struct sas_internal *i =
 466                to_sas_internal(dev->port->ha->core.shost->transportt);
 467        struct scsi_lun lun;
 468        int res;
 469
 470        int_to_scsilun(cmd->device->lun, &lun);
 471
 472        if (!i->dft->lldd_lu_reset)
 473                return FAILED;
 474
 475        res = i->dft->lldd_lu_reset(dev, lun.scsi_lun);
 476        if (res == TMF_RESP_FUNC_SUCC || res == TMF_RESP_FUNC_COMPLETE)
 477                return SUCCESS;
 478
 479        return FAILED;
 480}
 481
 482/* Attempt to send a phy (bus) reset */
 483int sas_eh_bus_reset_handler(struct scsi_cmnd *cmd)
 484{
 485        struct domain_device *dev = cmd_to_domain_dev(cmd);
 486        struct sas_phy *phy = sas_find_local_phy(dev);
 487        int res;
 488
 489        res = sas_phy_reset(phy, 1);
 490        if (res)
 491                SAS_DPRINTK("Bus reset of %s failed 0x%x\n",
 492                            kobject_name(&phy->dev.kobj),
 493                            res);
 494        if (res == TMF_RESP_FUNC_SUCC || res == TMF_RESP_FUNC_COMPLETE)
 495                return SUCCESS;
 496
 497        return FAILED;
 498}
 499
 500/* Try to reset a device */
 501static int try_to_reset_cmd_device(struct scsi_cmnd *cmd)
 502{
 503        int res;
 504        struct Scsi_Host *shost = cmd->device->host;
 505
 506        if (!shost->hostt->eh_device_reset_handler)
 507                goto try_bus_reset;
 508
 509        res = shost->hostt->eh_device_reset_handler(cmd);
 510        if (res == SUCCESS)
 511                return res;
 512
 513try_bus_reset:
 514        if (shost->hostt->eh_bus_reset_handler)
 515                return shost->hostt->eh_bus_reset_handler(cmd);
 516
 517        return FAILED;
 518}
 519
 520static int sas_eh_handle_sas_errors(struct Scsi_Host *shost,
 521                                    struct list_head *work_q,
 522                                    struct list_head *done_q)
 523{
 524        struct scsi_cmnd *cmd, *n;
 525        enum task_disposition res = TASK_IS_DONE;
 526        int tmf_resp, need_reset;
 527        struct sas_internal *i = to_sas_internal(shost->transportt);
 528        unsigned long flags;
 529        struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost);
 530
 531Again:
 532        list_for_each_entry_safe(cmd, n, work_q, eh_entry) {
 533                struct sas_task *task = TO_SAS_TASK(cmd);
 534
 535                if (!task)
 536                        continue;
 537
 538                list_del_init(&cmd->eh_entry);
 539
 540                spin_lock_irqsave(&task->task_state_lock, flags);
 541                need_reset = task->task_state_flags & SAS_TASK_NEED_DEV_RESET;
 542                spin_unlock_irqrestore(&task->task_state_lock, flags);
 543
 544                if (need_reset) {
 545                        SAS_DPRINTK("%s: task 0x%p requests reset\n",
 546                                    __FUNCTION__, task);
 547                        goto reset;
 548                }
 549
 550                SAS_DPRINTK("trying to find task 0x%p\n", task);
 551                res = sas_scsi_find_task(task);
 552
 553                cmd->eh_eflags = 0;
 554
 555                switch (res) {
 556                case TASK_IS_DONE:
 557                        SAS_DPRINTK("%s: task 0x%p is done\n", __FUNCTION__,
 558                                    task);
 559                        sas_eh_finish_cmd(cmd);
 560                        continue;
 561                case TASK_IS_ABORTED:
 562                        SAS_DPRINTK("%s: task 0x%p is aborted\n",
 563                                    __FUNCTION__, task);
 564                        sas_eh_finish_cmd(cmd);
 565                        continue;
 566                case TASK_IS_AT_LU:
 567                        SAS_DPRINTK("task 0x%p is at LU: lu recover\n", task);
 568 reset:
 569                        tmf_resp = sas_recover_lu(task->dev, cmd);
 570                        if (tmf_resp == TMF_RESP_FUNC_COMPLETE) {
 571                                SAS_DPRINTK("dev %016llx LU %x is "
 572                                            "recovered\n",
 573                                            SAS_ADDR(task->dev),
 574                                            cmd->device->lun);
 575                                sas_eh_finish_cmd(cmd);
 576                                sas_scsi_clear_queue_lu(work_q, cmd);
 577                                goto Again;
 578                        }
 579                        /* fallthrough */
 580                case TASK_IS_NOT_AT_LU:
 581                case TASK_ABORT_FAILED:
 582                        SAS_DPRINTK("task 0x%p is not at LU: I_T recover\n",
 583                                    task);
 584                        tmf_resp = sas_recover_I_T(task->dev);
 585                        if (tmf_resp == TMF_RESP_FUNC_COMPLETE) {
 586                                struct domain_device *dev = task->dev;
 587                                SAS_DPRINTK("I_T %016llx recovered\n",
 588                                            SAS_ADDR(task->dev->sas_addr));
 589                                sas_eh_finish_cmd(cmd);
 590                                sas_scsi_clear_queue_I_T(work_q, dev);
 591                                goto Again;
 592                        }
 593                        /* Hammer time :-) */
 594                        try_to_reset_cmd_device(cmd);
 595                        if (i->dft->lldd_clear_nexus_port) {
 596                                struct asd_sas_port *port = task->dev->port;
 597                                SAS_DPRINTK("clearing nexus for port:%d\n",
 598                                            port->id);
 599                                res = i->dft->lldd_clear_nexus_port(port);
 600                                if (res == TMF_RESP_FUNC_COMPLETE) {
 601                                        SAS_DPRINTK("clear nexus port:%d "
 602                                                    "succeeded\n", port->id);
 603                                        sas_eh_finish_cmd(cmd);
 604                                        sas_scsi_clear_queue_port(work_q,
 605                                                                  port);
 606                                        goto Again;
 607                                }
 608                        }
 609                        if (i->dft->lldd_clear_nexus_ha) {
 610                                SAS_DPRINTK("clear nexus ha\n");
 611                                res = i->dft->lldd_clear_nexus_ha(ha);
 612                                if (res == TMF_RESP_FUNC_COMPLETE) {
 613                                        SAS_DPRINTK("clear nexus ha "
 614                                                    "succeeded\n");
 615                                        sas_eh_finish_cmd(cmd);
 616                                        goto clear_q;
 617                                }
 618                        }
 619                        /* If we are here -- this means that no amount
 620                         * of effort could recover from errors.  Quite
 621                         * possibly the HA just disappeared.
 622                         */
 623                        SAS_DPRINTK("error from  device %llx, LUN %x "
 624                                    "couldn't be recovered in any way\n",
 625                                    SAS_ADDR(task->dev->sas_addr),
 626                                    cmd->device->lun);
 627
 628                        sas_eh_finish_cmd(cmd);
 629                        goto clear_q;
 630                }
 631        }
 632        return list_empty(work_q);
 633clear_q:
 634        SAS_DPRINTK("--- Exit %s -- clear_q\n", __FUNCTION__);
 635        list_for_each_entry_safe(cmd, n, work_q, eh_entry)
 636                sas_eh_finish_cmd(cmd);
 637
 638        return list_empty(work_q);
 639}
 640
 641void sas_scsi_recover_host(struct Scsi_Host *shost)
 642{
 643        struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost);
 644        unsigned long flags;
 645        LIST_HEAD(eh_work_q);
 646
 647        spin_lock_irqsave(shost->host_lock, flags);
 648        list_splice_init(&shost->eh_cmd_q, &eh_work_q);
 649        spin_unlock_irqrestore(shost->host_lock, flags);
 650
 651        SAS_DPRINTK("Enter %s\n", __FUNCTION__);
 652        /*
 653         * Deal with commands that still have SAS tasks (i.e. they didn't
 654         * complete via the normal sas_task completion mechanism)
 655         */
 656        if (sas_eh_handle_sas_errors(shost, &eh_work_q, &ha->eh_done_q))
 657                goto out;
 658
 659        /*
 660         * Now deal with SCSI commands that completed ok but have a an error
 661         * code (and hopefully sense data) attached.  This is roughly what
 662         * scsi_unjam_host does, but we skip scsi_eh_abort_cmds because any
 663         * command we see here has no sas_task and is thus unknown to the HA.
 664         */
 665        if (!scsi_eh_get_sense(&eh_work_q, &ha->eh_done_q))
 666                scsi_eh_ready_devs(shost, &eh_work_q, &ha->eh_done_q);
 667
 668out:
 669        scsi_eh_flush_done_q(&ha->eh_done_q);
 670        SAS_DPRINTK("--- Exit %s\n", __FUNCTION__);
 671        return;
 672}
 673
 674enum scsi_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *cmd)
 675{
 676        struct sas_task *task = TO_SAS_TASK(cmd);
 677        unsigned long flags;
 678
 679        if (!task) {
 680                cmd->timeout_per_command /= 2;
 681                SAS_DPRINTK("command 0x%p, task 0x%p, gone: %s\n",
 682                            cmd, task, (cmd->timeout_per_command ?
 683                            "EH_RESET_TIMER" : "EH_NOT_HANDLED"));
 684                if (!cmd->timeout_per_command)
 685                        return EH_NOT_HANDLED;
 686                return EH_RESET_TIMER;
 687        }
 688
 689        spin_lock_irqsave(&task->task_state_lock, flags);
 690        BUG_ON(task->task_state_flags & SAS_TASK_STATE_ABORTED);
 691        if (task->task_state_flags & SAS_TASK_STATE_DONE) {
 692                spin_unlock_irqrestore(&task->task_state_lock, flags);
 693                SAS_DPRINTK("command 0x%p, task 0x%p, timed out: EH_HANDLED\n",
 694                            cmd, task);
 695                return EH_HANDLED;
 696        }
 697        if (!(task->task_state_flags & SAS_TASK_AT_INITIATOR)) {
 698                spin_unlock_irqrestore(&task->task_state_lock, flags);
 699                SAS_DPRINTK("command 0x%p, task 0x%p, not at initiator: "
 700                            "EH_RESET_TIMER\n",
 701                            cmd, task);
 702                return EH_RESET_TIMER;
 703        }
 704        task->task_state_flags |= SAS_TASK_STATE_ABORTED;
 705        spin_unlock_irqrestore(&task->task_state_lock, flags);
 706
 707        SAS_DPRINTK("command 0x%p, task 0x%p, timed out: EH_NOT_HANDLED\n",
 708                    cmd, task);
 709
 710        return EH_NOT_HANDLED;
 711}
 712
 713int sas_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
 714{
 715        struct domain_device *dev = sdev_to_domain_dev(sdev);
 716
 717        if (dev_is_sata(dev))
 718                return ata_scsi_ioctl(sdev, cmd, arg);
 719
 720        return -EINVAL;
 721}
 722
 723struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy)
 724{
 725        struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent);
 726        struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost);
 727        struct domain_device *found_dev = NULL;
 728        int i;
 729        unsigned long flags;
 730
 731        spin_lock_irqsave(&ha->phy_port_lock, flags);
 732        for (i = 0; i < ha->num_phys; i++) {
 733                struct asd_sas_port *port = ha->sas_port[i];
 734                struct domain_device *dev;
 735
 736                spin_lock(&port->dev_list_lock);
 737                list_for_each_entry(dev, &port->dev_list, dev_list_node) {
 738                        if (rphy == dev->rphy) {
 739                                found_dev = dev;
 740                                spin_unlock(&port->dev_list_lock);
 741                                goto found;
 742                        }
 743                }
 744                spin_unlock(&port->dev_list_lock);
 745        }
 746 found:
 747        spin_unlock_irqrestore(&ha->phy_port_lock, flags);
 748
 749        return found_dev;
 750}
 751
 752static inline struct domain_device *sas_find_target(struct scsi_target *starget)
 753{
 754        struct sas_rphy *rphy = dev_to_rphy(starget->dev.parent);
 755
 756        return sas_find_dev_by_rphy(rphy);
 757}
 758
 759int sas_target_alloc(struct scsi_target *starget)
 760{
 761        struct domain_device *found_dev = sas_find_target(starget);
 762        int res;
 763
 764        if (!found_dev)
 765                return -ENODEV;
 766
 767        if (dev_is_sata(found_dev)) {
 768                res = sas_ata_init_host_and_port(found_dev, starget);
 769                if (res)
 770                        return res;
 771        }
 772
 773        starget->hostdata = found_dev;
 774        return 0;
 775}
 776
 777#define SAS_DEF_QD 32
 778#define SAS_MAX_QD 64
 779
 780int sas_slave_configure(struct scsi_device *scsi_dev)
 781{
 782        struct domain_device *dev = sdev_to_domain_dev(scsi_dev);
 783        struct sas_ha_struct *sas_ha;
 784
 785        BUG_ON(dev->rphy->identify.device_type != SAS_END_DEVICE);
 786
 787        if (dev_is_sata(dev)) {
 788                ata_sas_slave_configure(scsi_dev, dev->sata_dev.ap);
 789                return 0;
 790        }
 791
 792        sas_ha = dev->port->ha;
 793
 794        sas_read_port_mode_page(scsi_dev);
 795
 796        if (scsi_dev->tagged_supported) {
 797                scsi_set_tag_type(scsi_dev, MSG_SIMPLE_TAG);
 798                scsi_activate_tcq(scsi_dev, SAS_DEF_QD);
 799        } else {
 800                SAS_DPRINTK("device %llx, LUN %x doesn't support "
 801                            "TCQ\n", SAS_ADDR(dev->sas_addr),
 802                            scsi_dev->lun);
 803                scsi_dev->tagged_supported = 0;
 804                scsi_set_tag_type(scsi_dev, 0);
 805                scsi_deactivate_tcq(scsi_dev, 1);
 806        }
 807
 808        scsi_dev->allow_restart = 1;
 809
 810        return 0;
 811}
 812
 813void sas_slave_destroy(struct scsi_device *scsi_dev)
 814{
 815        struct domain_device *dev = sdev_to_domain_dev(scsi_dev);
 816
 817        if (dev_is_sata(dev))
 818                ata_port_disable(dev->sata_dev.ap);
 819}
 820
 821int sas_change_queue_depth(struct scsi_device *scsi_dev, int new_depth)
 822{
 823        int res = min(new_depth, SAS_MAX_QD);
 824
 825        if (scsi_dev->tagged_supported)
 826                scsi_adjust_queue_depth(scsi_dev, scsi_get_tag_type(scsi_dev),
 827                                        res);
 828        else {
 829                struct domain_device *dev = sdev_to_domain_dev(scsi_dev);
 830                sas_printk("device %llx LUN %x queue depth changed to 1\n",
 831                           SAS_ADDR(dev->sas_addr),
 832                           scsi_dev->lun);
 833                scsi_adjust_queue_depth(scsi_dev, 0, 1);
 834                res = 1;
 835        }
 836
 837        return res;
 838}
 839
 840int sas_change_queue_type(struct scsi_device *scsi_dev, int qt)
 841{
 842        if (!scsi_dev->tagged_supported)
 843                return 0;
 844
 845        scsi_deactivate_tcq(scsi_dev, 1);
 846
 847        scsi_set_tag_type(scsi_dev, qt);
 848        scsi_activate_tcq(scsi_dev, scsi_dev->queue_depth);
 849
 850        return qt;
 851}
 852
 853int sas_bios_param(struct scsi_device *scsi_dev,
 854                          struct block_device *bdev,
 855                          sector_t capacity, int *hsc)
 856{
 857        hsc[0] = 255;
 858        hsc[1] = 63;
 859        sector_div(capacity, 255*63);
 860        hsc[2] = capacity;
 861
 862        return 0;
 863}
 864
 865/* ---------- Task Collector Thread implementation ---------- */
 866
 867static void sas_queue(struct sas_ha_struct *sas_ha)
 868{
 869        struct scsi_core *core = &sas_ha->core;
 870        unsigned long flags;
 871        LIST_HEAD(q);
 872        int can_queue;
 873        int res;
 874        struct sas_internal *i = to_sas_internal(core->shost->transportt);
 875
 876        spin_lock_irqsave(&core->task_queue_lock, flags);
 877        while (!kthread_should_stop() &&
 878               !list_empty(&core->task_queue)) {
 879
 880                can_queue = sas_ha->lldd_queue_size - core->task_queue_size;
 881                if (can_queue >= 0) {
 882                        can_queue = core->task_queue_size;
 883                        list_splice_init(&core->task_queue, &q);
 884                } else {
 885                        struct list_head *a, *n;
 886
 887                        can_queue = sas_ha->lldd_queue_size;
 888                        list_for_each_safe(a, n, &core->task_queue) {
 889                                list_move_tail(a, &q);
 890                                if (--can_queue == 0)
 891                                        break;
 892                        }
 893                        can_queue = sas_ha->lldd_queue_size;
 894                }
 895                core->task_queue_size -= can_queue;
 896                spin_unlock_irqrestore(&core->task_queue_lock, flags);
 897                {
 898                        struct sas_task *task = list_entry(q.next,
 899                                                           struct sas_task,
 900                                                           list);
 901                        list_del_init(&q);
 902                        res = i->dft->lldd_execute_task(task, can_queue,
 903                                                        GFP_KERNEL);
 904                        if (unlikely(res))
 905                                __list_add(&q, task->list.prev, &task->list);
 906                }
 907                spin_lock_irqsave(&core->task_queue_lock, flags);
 908                if (res) {
 909                        list_splice_init(&q, &core->task_queue); /*at head*/
 910                        core->task_queue_size += can_queue;
 911                }
 912        }
 913        spin_unlock_irqrestore(&core->task_queue_lock, flags);
 914}
 915
 916/**
 917 * sas_queue_thread -- The Task Collector thread
 918 * @_sas_ha: pointer to struct sas_ha
 919 */
 920static int sas_queue_thread(void *_sas_ha)
 921{
 922        struct sas_ha_struct *sas_ha = _sas_ha;
 923
 924        while (1) {
 925                set_current_state(TASK_INTERRUPTIBLE);
 926                schedule();
 927                sas_queue(sas_ha);
 928                if (kthread_should_stop())
 929                        break;
 930        }
 931
 932        return 0;
 933}
 934
 935int sas_init_queue(struct sas_ha_struct *sas_ha)
 936{
 937        struct scsi_core *core = &sas_ha->core;
 938
 939        spin_lock_init(&core->task_queue_lock);
 940        core->task_queue_size = 0;
 941        INIT_LIST_HEAD(&core->task_queue);
 942
 943        core->queue_thread = kthread_run(sas_queue_thread, sas_ha,
 944                                         "sas_queue_%d", core->shost->host_no);
 945        if (IS_ERR(core->queue_thread))
 946                return PTR_ERR(core->queue_thread);
 947        return 0;
 948}
 949
 950void sas_shutdown_queue(struct sas_ha_struct *sas_ha)
 951{
 952        unsigned long flags;
 953        struct scsi_core *core = &sas_ha->core;
 954        struct sas_task *task, *n;
 955
 956        kthread_stop(core->queue_thread);
 957
 958        if (!list_empty(&core->task_queue))
 959                SAS_DPRINTK("HA: %llx: scsi core task queue is NOT empty!?\n",
 960                            SAS_ADDR(sas_ha->sas_addr));
 961
 962        spin_lock_irqsave(&core->task_queue_lock, flags);
 963        list_for_each_entry_safe(task, n, &core->task_queue, list) {
 964                struct scsi_cmnd *cmd = task->uldd_task;
 965
 966                list_del_init(&task->list);
 967
 968                ASSIGN_SAS_TASK(cmd, NULL);
 969                sas_free_task(task);
 970                cmd->result = DID_ABORT << 16;
 971                cmd->scsi_done(cmd);
 972        }
 973        spin_unlock_irqrestore(&core->task_queue_lock, flags);
 974}
 975
 976/*
 977 * Call the LLDD task abort routine directly.  This function is intended for
 978 * use by upper layers that need to tell the LLDD to abort a task.
 979 */
 980int __sas_task_abort(struct sas_task *task)
 981{
 982        struct sas_internal *si =
 983                to_sas_internal(task->dev->port->ha->core.shost->transportt);
 984        unsigned long flags;
 985        int res;
 986
 987        spin_lock_irqsave(&task->task_state_lock, flags);
 988        if (task->task_state_flags & SAS_TASK_STATE_ABORTED ||
 989            task->task_state_flags & SAS_TASK_STATE_DONE) {
 990                spin_unlock_irqrestore(&task->task_state_lock, flags);
 991                SAS_DPRINTK("%s: Task %p already finished.\n", __FUNCTION__,
 992                            task);
 993                return 0;
 994        }
 995        task->task_state_flags |= SAS_TASK_STATE_ABORTED;
 996        spin_unlock_irqrestore(&task->task_state_lock, flags);
 997
 998        if (!si->dft->lldd_abort_task)
 999                return -ENODEV;
1000
1001        res = si->dft->lldd_abort_task(task);
1002
1003        spin_lock_irqsave(&task->task_state_lock, flags);
1004        if ((task->task_state_flags & SAS_TASK_STATE_DONE) ||
1005            (res == TMF_RESP_FUNC_COMPLETE))
1006        {
1007                spin_unlock_irqrestore(&task->task_state_lock, flags);
1008                task->task_done(task);
1009                return 0;
1010        }
1011
1012        if (!(task->task_state_flags & SAS_TASK_STATE_DONE))
1013                task->task_state_flags &= ~SAS_TASK_STATE_ABORTED;
1014        spin_unlock_irqrestore(&task->task_state_lock, flags);
1015
1016        return -EAGAIN;
1017}
1018
1019/*
1020 * Tell an upper layer that it needs to initiate an abort for a given task.
1021 * This should only ever be called by an LLDD.
1022 */
1023void sas_task_abort(struct sas_task *task)
1024{
1025        struct scsi_cmnd *sc = task->uldd_task;
1026
1027        /* Escape for libsas internal commands */
1028        if (!sc) {
1029                if (!del_timer(&task->timer))
1030                        return;
1031                task->timer.function(task->timer.data);
1032                return;
1033        }
1034
1035        if (dev_is_sata(task->dev)) {
1036                sas_ata_task_abort(task);
1037                return;
1038        }
1039
1040        scsi_req_abort_cmd(sc);
1041        scsi_schedule_eh(sc->device->host);
1042}
1043
1044int sas_slave_alloc(struct scsi_device *scsi_dev)
1045{
1046        struct domain_device *dev = sdev_to_domain_dev(scsi_dev);
1047
1048        if (dev_is_sata(dev))
1049                return ata_sas_port_init(dev->sata_dev.ap);
1050
1051        return 0;
1052}
1053
1054void sas_target_destroy(struct scsi_target *starget)
1055{
1056        struct domain_device *found_dev = sas_find_target(starget);
1057
1058        if (!found_dev)
1059                return;
1060
1061        if (dev_is_sata(found_dev))
1062                ata_sas_port_destroy(found_dev->sata_dev.ap);
1063
1064        return;
1065}
1066
1067EXPORT_SYMBOL_GPL(sas_queuecommand);
1068EXPORT_SYMBOL_GPL(sas_target_alloc);
1069EXPORT_SYMBOL_GPL(sas_slave_configure);
1070EXPORT_SYMBOL_GPL(sas_slave_destroy);
1071EXPORT_SYMBOL_GPL(sas_change_queue_depth);
1072EXPORT_SYMBOL_GPL(sas_change_queue_type);
1073EXPORT_SYMBOL_GPL(sas_bios_param);
1074EXPORT_SYMBOL_GPL(__sas_task_abort);
1075EXPORT_SYMBOL_GPL(sas_task_abort);
1076EXPORT_SYMBOL_GPL(sas_phy_reset);
1077EXPORT_SYMBOL_GPL(sas_phy_enable);
1078EXPORT_SYMBOL_GPL(sas_eh_device_reset_handler);
1079EXPORT_SYMBOL_GPL(sas_eh_bus_reset_handler);
1080EXPORT_SYMBOL_GPL(sas_slave_alloc);
1081EXPORT_SYMBOL_GPL(sas_target_destroy);
1082EXPORT_SYMBOL_GPL(sas_ioctl);
1083
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.