sas_scsi_host.c revision 2908d778ab3e244900c310974e1fc1c69066e450
1/* 2 * Serial Attached SCSI (SAS) class SCSI Host glue. 3 * 4 * Copyright (C) 2005 Adaptec, Inc. All rights reserved. 5 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com> 6 * 7 * This file is licensed under GPLv2. 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License as 11 * published by the Free Software Foundation; either version 2 of the 12 * License, or (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, but 15 * WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 22 * USA 23 * 24 */ 25 26#include "sas_internal.h" 27 28#include <scsi/scsi_host.h> 29#include <scsi/scsi_device.h> 30#include <scsi/scsi_tcq.h> 31#include <scsi/scsi.h> 32#include <scsi/scsi_transport.h> 33#include <scsi/scsi_transport_sas.h> 34#include "../scsi_sas_internal.h" 35 36#include <linux/err.h> 37#include <linux/blkdev.h> 38#include <linux/scatterlist.h> 39 40/* ---------- SCSI Host glue ---------- */ 41 42#define TO_SAS_TASK(_scsi_cmd) ((void *)(_scsi_cmd)->host_scribble) 43#define ASSIGN_SAS_TASK(_sc, _t) do { (_sc)->host_scribble = (void *) _t; } while (0) 44 45static void sas_scsi_task_done(struct sas_task *task) 46{ 47 struct task_status_struct *ts = &task->task_status; 48 struct scsi_cmnd *sc = task->uldd_task; 49 unsigned ts_flags = task->task_state_flags; 50 int hs = 0, stat = 0; 51 52 if (unlikely(!sc)) { 53 SAS_DPRINTK("task_done called with non existing SCSI cmnd!\n"); 54 list_del_init(&task->list); 55 sas_free_task(task); 56 return; 57 } 58 59 if (ts->resp == SAS_TASK_UNDELIVERED) { 60 /* transport error */ 61 hs = DID_NO_CONNECT; 62 } else { /* ts->resp == SAS_TASK_COMPLETE */ 63 /* task delivered, what happened afterwards? */ 64 switch (ts->stat) { 65 case SAS_DEV_NO_RESPONSE: 66 case SAS_INTERRUPTED: 67 case SAS_PHY_DOWN: 68 case SAS_NAK_R_ERR: 69 case SAS_OPEN_TO: 70 hs = DID_NO_CONNECT; 71 break; 72 case SAS_DATA_UNDERRUN: 73 sc->resid = ts->residual; 74 if (sc->request_bufflen - sc->resid < sc->underflow) 75 hs = DID_ERROR; 76 break; 77 case SAS_DATA_OVERRUN: 78 hs = DID_ERROR; 79 break; 80 case SAS_QUEUE_FULL: 81 hs = DID_SOFT_ERROR; /* retry */ 82 break; 83 case SAS_DEVICE_UNKNOWN: 84 hs = DID_BAD_TARGET; 85 break; 86 case SAS_SG_ERR: 87 hs = DID_PARITY; 88 break; 89 case SAS_OPEN_REJECT: 90 if (ts->open_rej_reason == SAS_OREJ_RSVD_RETRY) 91 hs = DID_SOFT_ERROR; /* retry */ 92 else 93 hs = DID_ERROR; 94 break; 95 case SAS_PROTO_RESPONSE: 96 SAS_DPRINTK("LLDD:%s sent SAS_PROTO_RESP for an SSP " 97 "task; please report this\n", 98 task->dev->port->ha->sas_ha_name); 99 break; 100 case SAS_ABORTED_TASK: 101 hs = DID_ABORT; 102 break; 103 case SAM_CHECK_COND: 104 memcpy(sc->sense_buffer, ts->buf, 105 max(SCSI_SENSE_BUFFERSIZE, ts->buf_valid_size)); 106 stat = SAM_CHECK_COND; 107 break; 108 default: 109 stat = ts->stat; 110 break; 111 } 112 } 113 ASSIGN_SAS_TASK(sc, NULL); 114 sc->result = (hs << 16) | stat; 115 list_del_init(&task->list); 116 sas_free_task(task); 117 /* This is very ugly but this is how SCSI Core works. */ 118 if (ts_flags & SAS_TASK_STATE_ABORTED) 119 scsi_finish_command(sc); 120 else 121 sc->scsi_done(sc); 122} 123 124static enum task_attribute sas_scsi_get_task_attr(struct scsi_cmnd *cmd) 125{ 126 enum task_attribute ta = TASK_ATTR_SIMPLE; 127 if (cmd->request && blk_rq_tagged(cmd->request)) { 128 if (cmd->device->ordered_tags && 129 (cmd->request->flags & REQ_HARDBARRIER)) 130 ta = TASK_ATTR_HOQ; 131 } 132 return ta; 133} 134 135static struct sas_task *sas_create_task(struct scsi_cmnd *cmd, 136 struct domain_device *dev, 137 unsigned long gfp_flags) 138{ 139 struct sas_task *task = sas_alloc_task(gfp_flags); 140 struct scsi_lun lun; 141 142 if (!task) 143 return NULL; 144 145 *(u32 *)cmd->sense_buffer = 0; 146 task->uldd_task = cmd; 147 ASSIGN_SAS_TASK(cmd, task); 148 149 task->dev = dev; 150 task->task_proto = task->dev->tproto; /* BUG_ON(!SSP) */ 151 152 task->ssp_task.retry_count = 1; 153 int_to_scsilun(cmd->device->lun, &lun); 154 memcpy(task->ssp_task.LUN, &lun.scsi_lun, 8); 155 task->ssp_task.task_attr = sas_scsi_get_task_attr(cmd); 156 memcpy(task->ssp_task.cdb, cmd->cmnd, 16); 157 158 task->scatter = cmd->request_buffer; 159 task->num_scatter = cmd->use_sg; 160 task->total_xfer_len = cmd->request_bufflen; 161 task->data_dir = cmd->sc_data_direction; 162 163 task->task_done = sas_scsi_task_done; 164 165 return task; 166} 167 168static int sas_queue_up(struct sas_task *task) 169{ 170 struct sas_ha_struct *sas_ha = task->dev->port->ha; 171 struct scsi_core *core = &sas_ha->core; 172 unsigned long flags; 173 LIST_HEAD(list); 174 175 spin_lock_irqsave(&core->task_queue_lock, flags); 176 if (sas_ha->lldd_queue_size < core->task_queue_size + 1) { 177 spin_unlock_irqrestore(&core->task_queue_lock, flags); 178 return -SAS_QUEUE_FULL; 179 } 180 list_add_tail(&task->list, &core->task_queue); 181 core->task_queue_size += 1; 182 spin_unlock_irqrestore(&core->task_queue_lock, flags); 183 up(&core->queue_thread_sema); 184 185 return 0; 186} 187 188/** 189 * sas_queuecommand -- Enqueue a command for processing 190 * @parameters: See SCSI Core documentation 191 * 192 * Note: XXX: Remove the host unlock/lock pair when SCSI Core can 193 * call us without holding an IRQ spinlock... 194 */ 195int sas_queuecommand(struct scsi_cmnd *cmd, 196 void (*scsi_done)(struct scsi_cmnd *)) 197{ 198 int res = 0; 199 struct domain_device *dev = cmd_to_domain_dev(cmd); 200 struct Scsi_Host *host = cmd->device->host; 201 struct sas_internal *i = to_sas_internal(host->transportt); 202 203 spin_unlock_irq(host->host_lock); 204 205 { 206 struct sas_ha_struct *sas_ha = dev->port->ha; 207 struct sas_task *task; 208 209 res = -ENOMEM; 210 task = sas_create_task(cmd, dev, GFP_ATOMIC); 211 if (!task) 212 goto out; 213 214 cmd->scsi_done = scsi_done; 215 /* Queue up, Direct Mode or Task Collector Mode. */ 216 if (sas_ha->lldd_max_execute_num < 2) 217 res = i->dft->lldd_execute_task(task, 1, GFP_ATOMIC); 218 else 219 res = sas_queue_up(task); 220 221 /* Examine */ 222 if (res) { 223 SAS_DPRINTK("lldd_execute_task returned: %d\n", res); 224 ASSIGN_SAS_TASK(cmd, NULL); 225 sas_free_task(task); 226 if (res == -SAS_QUEUE_FULL) { 227 cmd->result = DID_SOFT_ERROR << 16; /* retry */ 228 res = 0; 229 scsi_done(cmd); 230 } 231 goto out; 232 } 233 } 234out: 235 spin_lock_irq(host->host_lock); 236 return res; 237} 238 239static void sas_scsi_clear_queue_lu(struct list_head *error_q, struct scsi_cmnd *my_cmd) 240{ 241 struct scsi_cmnd *cmd, *n; 242 243 list_for_each_entry_safe(cmd, n, error_q, eh_entry) { 244 if (cmd == my_cmd) 245 list_del_init(&cmd->eh_entry); 246 } 247} 248 249static void sas_scsi_clear_queue_I_T(struct list_head *error_q, 250 struct domain_device *dev) 251{ 252 struct scsi_cmnd *cmd, *n; 253 254 list_for_each_entry_safe(cmd, n, error_q, eh_entry) { 255 struct domain_device *x = cmd_to_domain_dev(cmd); 256 257 if (x == dev) 258 list_del_init(&cmd->eh_entry); 259 } 260} 261 262static void sas_scsi_clear_queue_port(struct list_head *error_q, 263 struct asd_sas_port *port) 264{ 265 struct scsi_cmnd *cmd, *n; 266 267 list_for_each_entry_safe(cmd, n, error_q, eh_entry) { 268 struct domain_device *dev = cmd_to_domain_dev(cmd); 269 struct asd_sas_port *x = dev->port; 270 271 if (x == port) 272 list_del_init(&cmd->eh_entry); 273 } 274} 275 276enum task_disposition { 277 TASK_IS_DONE, 278 TASK_IS_ABORTED, 279 TASK_IS_AT_LU, 280 TASK_IS_NOT_AT_LU, 281}; 282 283static enum task_disposition sas_scsi_find_task(struct sas_task *task) 284{ 285 struct sas_ha_struct *ha = task->dev->port->ha; 286 unsigned long flags; 287 int i, res; 288 struct sas_internal *si = 289 to_sas_internal(task->dev->port->ha->core.shost->transportt); 290 291 if (ha->lldd_max_execute_num > 1) { 292 struct scsi_core *core = &ha->core; 293 struct sas_task *t, *n; 294 295 spin_lock_irqsave(&core->task_queue_lock, flags); 296 list_for_each_entry_safe(t, n, &core->task_queue, list) { 297 if (task == t) { 298 list_del_init(&t->list); 299 spin_unlock_irqrestore(&core->task_queue_lock, 300 flags); 301 SAS_DPRINTK("%s: task 0x%p aborted from " 302 "task_queue\n", 303 __FUNCTION__, task); 304 return TASK_IS_ABORTED; 305 } 306 } 307 spin_unlock_irqrestore(&core->task_queue_lock, flags); 308 } 309 310 for (i = 0; i < 5; i++) { 311 SAS_DPRINTK("%s: aborting task 0x%p\n", __FUNCTION__, task); 312 res = si->dft->lldd_abort_task(task); 313 314 spin_lock_irqsave(&task->task_state_lock, flags); 315 if (task->task_state_flags & SAS_TASK_STATE_DONE) { 316 spin_unlock_irqrestore(&task->task_state_lock, flags); 317 SAS_DPRINTK("%s: task 0x%p is done\n", __FUNCTION__, 318 task); 319 return TASK_IS_DONE; 320 } 321 spin_unlock_irqrestore(&task->task_state_lock, flags); 322 323 if (res == TMF_RESP_FUNC_COMPLETE) { 324 SAS_DPRINTK("%s: task 0x%p is aborted\n", 325 __FUNCTION__, task); 326 return TASK_IS_ABORTED; 327 } else if (si->dft->lldd_query_task) { 328 SAS_DPRINTK("%s: querying task 0x%p\n", 329 __FUNCTION__, task); 330 res = si->dft->lldd_query_task(task); 331 if (res == TMF_RESP_FUNC_SUCC) { 332 SAS_DPRINTK("%s: task 0x%p at LU\n", 333 __FUNCTION__, task); 334 return TASK_IS_AT_LU; 335 } else if (res == TMF_RESP_FUNC_COMPLETE) { 336 SAS_DPRINTK("%s: task 0x%p not at LU\n", 337 __FUNCTION__, task); 338 return TASK_IS_NOT_AT_LU; 339 } 340 } 341 } 342 return res; 343} 344 345static int sas_recover_lu(struct domain_device *dev, struct scsi_cmnd *cmd) 346{ 347 int res = TMF_RESP_FUNC_FAILED; 348 struct scsi_lun lun; 349 struct sas_internal *i = 350 to_sas_internal(dev->port->ha->core.shost->transportt); 351 352 int_to_scsilun(cmd->device->lun, &lun); 353 354 SAS_DPRINTK("eh: device %llx LUN %x has the task\n", 355 SAS_ADDR(dev->sas_addr), 356 cmd->device->lun); 357 358 if (i->dft->lldd_abort_task_set) 359 res = i->dft->lldd_abort_task_set(dev, lun.scsi_lun); 360 361 if (res == TMF_RESP_FUNC_FAILED) { 362 if (i->dft->lldd_clear_task_set) 363 res = i->dft->lldd_clear_task_set(dev, lun.scsi_lun); 364 } 365 366 if (res == TMF_RESP_FUNC_FAILED) { 367 if (i->dft->lldd_lu_reset) 368 res = i->dft->lldd_lu_reset(dev, lun.scsi_lun); 369 } 370 371 return res; 372} 373 374static int sas_recover_I_T(struct domain_device *dev) 375{ 376 int res = TMF_RESP_FUNC_FAILED; 377 struct sas_internal *i = 378 to_sas_internal(dev->port->ha->core.shost->transportt); 379 380 SAS_DPRINTK("I_T nexus reset for dev %016llx\n", 381 SAS_ADDR(dev->sas_addr)); 382 383 if (i->dft->lldd_I_T_nexus_reset) 384 res = i->dft->lldd_I_T_nexus_reset(dev); 385 386 return res; 387} 388 389void sas_scsi_recover_host(struct Scsi_Host *shost) 390{ 391 struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost); 392 unsigned long flags; 393 LIST_HEAD(error_q); 394 struct scsi_cmnd *cmd, *n; 395 enum task_disposition res = TASK_IS_DONE; 396 int tmf_resp; 397 struct sas_internal *i = to_sas_internal(shost->transportt); 398 399 spin_lock_irqsave(shost->host_lock, flags); 400 list_splice_init(&shost->eh_cmd_q, &error_q); 401 spin_unlock_irqrestore(shost->host_lock, flags); 402 403 SAS_DPRINTK("Enter %s\n", __FUNCTION__); 404 405 /* All tasks on this list were marked SAS_TASK_STATE_ABORTED 406 * by sas_scsi_timed_out() callback. 407 */ 408Again: 409 SAS_DPRINTK("going over list...\n"); 410 list_for_each_entry_safe(cmd, n, &error_q, eh_entry) { 411 struct sas_task *task = TO_SAS_TASK(cmd); 412 413 SAS_DPRINTK("trying to find task 0x%p\n", task); 414 list_del_init(&cmd->eh_entry); 415 res = sas_scsi_find_task(task); 416 417 cmd->eh_eflags = 0; 418 shost->host_failed--; 419 420 switch (res) { 421 case TASK_IS_DONE: 422 SAS_DPRINTK("%s: task 0x%p is done\n", __FUNCTION__, 423 task); 424 task->task_done(task); 425 continue; 426 case TASK_IS_ABORTED: 427 SAS_DPRINTK("%s: task 0x%p is aborted\n", 428 __FUNCTION__, task); 429 task->task_done(task); 430 continue; 431 case TASK_IS_AT_LU: 432 SAS_DPRINTK("task 0x%p is at LU: lu recover\n", task); 433 tmf_resp = sas_recover_lu(task->dev, cmd); 434 if (tmf_resp == TMF_RESP_FUNC_COMPLETE) { 435 SAS_DPRINTK("dev %016llx LU %x is " 436 "recovered\n", 437 SAS_ADDR(task->dev), 438 cmd->device->lun); 439 task->task_done(task); 440 sas_scsi_clear_queue_lu(&error_q, cmd); 441 goto Again; 442 } 443 /* fallthrough */ 444 case TASK_IS_NOT_AT_LU: 445 SAS_DPRINTK("task 0x%p is not at LU: I_T recover\n", 446 task); 447 tmf_resp = sas_recover_I_T(task->dev); 448 if (tmf_resp == TMF_RESP_FUNC_COMPLETE) { 449 SAS_DPRINTK("I_T %016llx recovered\n", 450 SAS_ADDR(task->dev->sas_addr)); 451 task->task_done(task); 452 sas_scsi_clear_queue_I_T(&error_q, task->dev); 453 goto Again; 454 } 455 /* Hammer time :-) */ 456 if (i->dft->lldd_clear_nexus_port) { 457 struct asd_sas_port *port = task->dev->port; 458 SAS_DPRINTK("clearing nexus for port:%d\n", 459 port->id); 460 res = i->dft->lldd_clear_nexus_port(port); 461 if (res == TMF_RESP_FUNC_COMPLETE) { 462 SAS_DPRINTK("clear nexus port:%d " 463 "succeeded\n", port->id); 464 task->task_done(task); 465 sas_scsi_clear_queue_port(&error_q, 466 port); 467 goto Again; 468 } 469 } 470 if (i->dft->lldd_clear_nexus_ha) { 471 SAS_DPRINTK("clear nexus ha\n"); 472 res = i->dft->lldd_clear_nexus_ha(ha); 473 if (res == TMF_RESP_FUNC_COMPLETE) { 474 SAS_DPRINTK("clear nexus ha " 475 "succeeded\n"); 476 task->task_done(task); 477 goto out; 478 } 479 } 480 /* If we are here -- this means that no amount 481 * of effort could recover from errors. Quite 482 * possibly the HA just disappeared. 483 */ 484 SAS_DPRINTK("error from device %llx, LUN %x " 485 "couldn't be recovered in any way\n", 486 SAS_ADDR(task->dev->sas_addr), 487 cmd->device->lun); 488 489 task->task_done(task); 490 goto clear_q; 491 } 492 } 493out: 494 SAS_DPRINTK("--- Exit %s\n", __FUNCTION__); 495 return; 496clear_q: 497 SAS_DPRINTK("--- Exit %s -- clear_q\n", __FUNCTION__); 498 list_for_each_entry_safe(cmd, n, &error_q, eh_entry) { 499 struct sas_task *task = TO_SAS_TASK(cmd); 500 list_del_init(&cmd->eh_entry); 501 task->task_done(task); 502 } 503} 504 505enum scsi_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *cmd) 506{ 507 struct sas_task *task = TO_SAS_TASK(cmd); 508 unsigned long flags; 509 510 if (!task) { 511 SAS_DPRINTK("command 0x%p, task 0x%p, timed out: EH_HANDLED\n", 512 cmd, task); 513 return EH_HANDLED; 514 } 515 516 spin_lock_irqsave(&task->task_state_lock, flags); 517 if (task->task_state_flags & SAS_TASK_STATE_DONE) { 518 spin_unlock_irqrestore(&task->task_state_lock, flags); 519 SAS_DPRINTK("command 0x%p, task 0x%p, timed out: EH_HANDLED\n", 520 cmd, task); 521 return EH_HANDLED; 522 } 523 task->task_state_flags |= SAS_TASK_STATE_ABORTED; 524 spin_unlock_irqrestore(&task->task_state_lock, flags); 525 526 SAS_DPRINTK("command 0x%p, task 0x%p, timed out: EH_NOT_HANDLED\n", 527 cmd, task); 528 529 return EH_NOT_HANDLED; 530} 531 532struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy) 533{ 534 struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent); 535 struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost); 536 struct domain_device *found_dev = NULL; 537 int i; 538 539 spin_lock(&ha->phy_port_lock); 540 for (i = 0; i < ha->num_phys; i++) { 541 struct asd_sas_port *port = ha->sas_port[i]; 542 struct domain_device *dev; 543 544 spin_lock(&port->dev_list_lock); 545 list_for_each_entry(dev, &port->dev_list, dev_list_node) { 546 if (rphy == dev->rphy) { 547 found_dev = dev; 548 spin_unlock(&port->dev_list_lock); 549 goto found; 550 } 551 } 552 spin_unlock(&port->dev_list_lock); 553 } 554 found: 555 spin_unlock(&ha->phy_port_lock); 556 557 return found_dev; 558} 559 560static inline struct domain_device *sas_find_target(struct scsi_target *starget) 561{ 562 struct sas_rphy *rphy = dev_to_rphy(starget->dev.parent); 563 564 return sas_find_dev_by_rphy(rphy); 565} 566 567int sas_target_alloc(struct scsi_target *starget) 568{ 569 struct domain_device *found_dev = sas_find_target(starget); 570 571 if (!found_dev) 572 return -ENODEV; 573 574 starget->hostdata = found_dev; 575 return 0; 576} 577 578#define SAS_DEF_QD 32 579#define SAS_MAX_QD 64 580 581int sas_slave_configure(struct scsi_device *scsi_dev) 582{ 583 struct domain_device *dev = sdev_to_domain_dev(scsi_dev); 584 struct sas_ha_struct *sas_ha; 585 586 BUG_ON(dev->rphy->identify.device_type != SAS_END_DEVICE); 587 588 sas_ha = dev->port->ha; 589 590 sas_read_port_mode_page(scsi_dev); 591 592 if (scsi_dev->tagged_supported) { 593 scsi_set_tag_type(scsi_dev, MSG_SIMPLE_TAG); 594 scsi_activate_tcq(scsi_dev, SAS_DEF_QD); 595 } else { 596 SAS_DPRINTK("device %llx, LUN %x doesn't support " 597 "TCQ\n", SAS_ADDR(dev->sas_addr), 598 scsi_dev->lun); 599 scsi_dev->tagged_supported = 0; 600 scsi_set_tag_type(scsi_dev, 0); 601 scsi_deactivate_tcq(scsi_dev, 1); 602 } 603 604 return 0; 605} 606 607void sas_slave_destroy(struct scsi_device *scsi_dev) 608{ 609} 610 611int sas_change_queue_depth(struct scsi_device *scsi_dev, int new_depth) 612{ 613 int res = min(new_depth, SAS_MAX_QD); 614 615 if (scsi_dev->tagged_supported) 616 scsi_adjust_queue_depth(scsi_dev, scsi_get_tag_type(scsi_dev), 617 res); 618 else { 619 struct domain_device *dev = sdev_to_domain_dev(scsi_dev); 620 sas_printk("device %llx LUN %x queue depth changed to 1\n", 621 SAS_ADDR(dev->sas_addr), 622 scsi_dev->lun); 623 scsi_adjust_queue_depth(scsi_dev, 0, 1); 624 res = 1; 625 } 626 627 return res; 628} 629 630int sas_change_queue_type(struct scsi_device *scsi_dev, int qt) 631{ 632 if (!scsi_dev->tagged_supported) 633 return 0; 634 635 scsi_deactivate_tcq(scsi_dev, 1); 636 637 scsi_set_tag_type(scsi_dev, qt); 638 scsi_activate_tcq(scsi_dev, scsi_dev->queue_depth); 639 640 return qt; 641} 642 643int sas_bios_param(struct scsi_device *scsi_dev, 644 struct block_device *bdev, 645 sector_t capacity, int *hsc) 646{ 647 hsc[0] = 255; 648 hsc[1] = 63; 649 sector_div(capacity, 255*63); 650 hsc[2] = capacity; 651 652 return 0; 653} 654 655/* ---------- Task Collector Thread implementation ---------- */ 656 657static void sas_queue(struct sas_ha_struct *sas_ha) 658{ 659 struct scsi_core *core = &sas_ha->core; 660 unsigned long flags; 661 LIST_HEAD(q); 662 int can_queue; 663 int res; 664 struct sas_internal *i = to_sas_internal(core->shost->transportt); 665 666 spin_lock_irqsave(&core->task_queue_lock, flags); 667 while (!core->queue_thread_kill && 668 !list_empty(&core->task_queue)) { 669 670 can_queue = sas_ha->lldd_queue_size - core->task_queue_size; 671 if (can_queue >= 0) { 672 can_queue = core->task_queue_size; 673 list_splice_init(&core->task_queue, &q); 674 } else { 675 struct list_head *a, *n; 676 677 can_queue = sas_ha->lldd_queue_size; 678 list_for_each_safe(a, n, &core->task_queue) { 679 list_move_tail(a, &q); 680 if (--can_queue == 0) 681 break; 682 } 683 can_queue = sas_ha->lldd_queue_size; 684 } 685 core->task_queue_size -= can_queue; 686 spin_unlock_irqrestore(&core->task_queue_lock, flags); 687 { 688 struct sas_task *task = list_entry(q.next, 689 struct sas_task, 690 list); 691 list_del_init(&q); 692 res = i->dft->lldd_execute_task(task, can_queue, 693 GFP_KERNEL); 694 if (unlikely(res)) 695 __list_add(&q, task->list.prev, &task->list); 696 } 697 spin_lock_irqsave(&core->task_queue_lock, flags); 698 if (res) { 699 list_splice_init(&q, &core->task_queue); /*at head*/ 700 core->task_queue_size += can_queue; 701 } 702 } 703 spin_unlock_irqrestore(&core->task_queue_lock, flags); 704} 705 706static DECLARE_COMPLETION(queue_th_comp); 707 708/** 709 * sas_queue_thread -- The Task Collector thread 710 * @_sas_ha: pointer to struct sas_ha 711 */ 712static int sas_queue_thread(void *_sas_ha) 713{ 714 struct sas_ha_struct *sas_ha = _sas_ha; 715 struct scsi_core *core = &sas_ha->core; 716 717 daemonize("sas_queue_%d", core->shost->host_no); 718 current->flags |= PF_NOFREEZE; 719 720 complete(&queue_th_comp); 721 722 while (1) { 723 down_interruptible(&core->queue_thread_sema); 724 sas_queue(sas_ha); 725 if (core->queue_thread_kill) 726 break; 727 } 728 729 complete(&queue_th_comp); 730 731 return 0; 732} 733 734int sas_init_queue(struct sas_ha_struct *sas_ha) 735{ 736 int res; 737 struct scsi_core *core = &sas_ha->core; 738 739 spin_lock_init(&core->task_queue_lock); 740 core->task_queue_size = 0; 741 INIT_LIST_HEAD(&core->task_queue); 742 init_MUTEX_LOCKED(&core->queue_thread_sema); 743 744 res = kernel_thread(sas_queue_thread, sas_ha, 0); 745 if (res >= 0) 746 wait_for_completion(&queue_th_comp); 747 748 return res < 0 ? res : 0; 749} 750 751void sas_shutdown_queue(struct sas_ha_struct *sas_ha) 752{ 753 unsigned long flags; 754 struct scsi_core *core = &sas_ha->core; 755 struct sas_task *task, *n; 756 757 init_completion(&queue_th_comp); 758 core->queue_thread_kill = 1; 759 up(&core->queue_thread_sema); 760 wait_for_completion(&queue_th_comp); 761 762 if (!list_empty(&core->task_queue)) 763 SAS_DPRINTK("HA: %llx: scsi core task queue is NOT empty!?\n", 764 SAS_ADDR(sas_ha->sas_addr)); 765 766 spin_lock_irqsave(&core->task_queue_lock, flags); 767 list_for_each_entry_safe(task, n, &core->task_queue, list) { 768 struct scsi_cmnd *cmd = task->uldd_task; 769 770 list_del_init(&task->list); 771 772 ASSIGN_SAS_TASK(cmd, NULL); 773 sas_free_task(task); 774 cmd->result = DID_ABORT << 16; 775 cmd->scsi_done(cmd); 776 } 777 spin_unlock_irqrestore(&core->task_queue_lock, flags); 778} 779 780EXPORT_SYMBOL_GPL(sas_queuecommand); 781EXPORT_SYMBOL_GPL(sas_target_alloc); 782EXPORT_SYMBOL_GPL(sas_slave_configure); 783EXPORT_SYMBOL_GPL(sas_slave_destroy); 784EXPORT_SYMBOL_GPL(sas_change_queue_depth); 785EXPORT_SYMBOL_GPL(sas_change_queue_type); 786EXPORT_SYMBOL_GPL(sas_bios_param); 787