diff options
author | Anirban Chakraborty <anirban.chakraborty@qlogic.com> | 2008-11-06 13:40:51 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-12-29 12:24:16 -0500 |
commit | e315cd28b9ef0d7b71e462ac16e18dbaa2f5adfe (patch) | |
tree | 1e20bdd40b56b36f211bde8fff0c63792b088a0a /drivers/scsi/qla2xxx/qla_os.c | |
parent | 7b867cf76fbcc8d77867cbec6f509f71dce8a98f (diff) |
[SCSI] qla2xxx: Code changes for qla data structure refactoring
Following changes have been made:
1. Outstanding commands are based on a request queue, scsi_qla_host
does not maintain it anymore.
2. start_scsi is accessed via isp_ops struct instead of direct
invocation.
3. Interrupt registrations are done using response queue instead of
device id.
Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_os.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 1265 |
1 files changed, 688 insertions, 577 deletions
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 35567203ef61..05db1660855e 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -183,42 +183,42 @@ struct scsi_transport_template *qla2xxx_transport_vport_template = NULL; | |||
183 | */ | 183 | */ |
184 | 184 | ||
185 | __inline__ void | 185 | __inline__ void |
186 | qla2x00_start_timer(scsi_qla_host_t *ha, void *func, unsigned long interval) | 186 | qla2x00_start_timer(scsi_qla_host_t *vha, void *func, unsigned long interval) |
187 | { | 187 | { |
188 | init_timer(&ha->timer); | 188 | init_timer(&vha->timer); |
189 | ha->timer.expires = jiffies + interval * HZ; | 189 | vha->timer.expires = jiffies + interval * HZ; |
190 | ha->timer.data = (unsigned long)ha; | 190 | vha->timer.data = (unsigned long)vha; |
191 | ha->timer.function = (void (*)(unsigned long))func; | 191 | vha->timer.function = (void (*)(unsigned long))func; |
192 | add_timer(&ha->timer); | 192 | add_timer(&vha->timer); |
193 | ha->timer_active = 1; | 193 | vha->timer_active = 1; |
194 | } | 194 | } |
195 | 195 | ||
196 | static inline void | 196 | static inline void |
197 | qla2x00_restart_timer(scsi_qla_host_t *ha, unsigned long interval) | 197 | qla2x00_restart_timer(scsi_qla_host_t *vha, unsigned long interval) |
198 | { | 198 | { |
199 | mod_timer(&ha->timer, jiffies + interval * HZ); | 199 | mod_timer(&vha->timer, jiffies + interval * HZ); |
200 | } | 200 | } |
201 | 201 | ||
202 | static __inline__ void | 202 | static __inline__ void |
203 | qla2x00_stop_timer(scsi_qla_host_t *ha) | 203 | qla2x00_stop_timer(scsi_qla_host_t *vha) |
204 | { | 204 | { |
205 | del_timer_sync(&ha->timer); | 205 | del_timer_sync(&vha->timer); |
206 | ha->timer_active = 0; | 206 | vha->timer_active = 0; |
207 | } | 207 | } |
208 | 208 | ||
209 | static int qla2x00_do_dpc(void *data); | 209 | static int qla2x00_do_dpc(void *data); |
210 | 210 | ||
211 | static void qla2x00_rst_aen(scsi_qla_host_t *); | 211 | static void qla2x00_rst_aen(scsi_qla_host_t *); |
212 | 212 | ||
213 | static int qla2x00_mem_alloc(scsi_qla_host_t *); | 213 | static int qla2x00_mem_alloc(struct qla_hw_data *, uint16_t, uint16_t); |
214 | static void qla2x00_mem_free(scsi_qla_host_t *ha); | 214 | static void qla2x00_mem_free(struct qla_hw_data *); |
215 | static void qla2x00_sp_free_dma(scsi_qla_host_t *, srb_t *); | 215 | static void qla2x00_sp_free_dma(srb_t *); |
216 | 216 | ||
217 | /* -------------------------------------------------------------------------- */ | 217 | /* -------------------------------------------------------------------------- */ |
218 | |||
219 | static char * | 218 | static char * |
220 | qla2x00_pci_info_str(struct scsi_qla_host *ha, char *str) | 219 | qla2x00_pci_info_str(struct scsi_qla_host *vha, char *str) |
221 | { | 220 | { |
221 | struct qla_hw_data *ha = vha->hw; | ||
222 | static char *pci_bus_modes[] = { | 222 | static char *pci_bus_modes[] = { |
223 | "33", "66", "100", "133", | 223 | "33", "66", "100", "133", |
224 | }; | 224 | }; |
@@ -240,9 +240,10 @@ qla2x00_pci_info_str(struct scsi_qla_host *ha, char *str) | |||
240 | } | 240 | } |
241 | 241 | ||
242 | static char * | 242 | static char * |
243 | qla24xx_pci_info_str(struct scsi_qla_host *ha, char *str) | 243 | qla24xx_pci_info_str(struct scsi_qla_host *vha, char *str) |
244 | { | 244 | { |
245 | static char *pci_bus_modes[] = { "33", "66", "100", "133", }; | 245 | static char *pci_bus_modes[] = { "33", "66", "100", "133", }; |
246 | struct qla_hw_data *ha = vha->hw; | ||
246 | uint32_t pci_bus; | 247 | uint32_t pci_bus; |
247 | int pcie_reg; | 248 | int pcie_reg; |
248 | 249 | ||
@@ -290,9 +291,10 @@ qla24xx_pci_info_str(struct scsi_qla_host *ha, char *str) | |||
290 | } | 291 | } |
291 | 292 | ||
292 | static char * | 293 | static char * |
293 | qla2x00_fw_version_str(struct scsi_qla_host *ha, char *str) | 294 | qla2x00_fw_version_str(struct scsi_qla_host *vha, char *str) |
294 | { | 295 | { |
295 | char un_str[10]; | 296 | char un_str[10]; |
297 | struct qla_hw_data *ha = vha->hw; | ||
296 | 298 | ||
297 | sprintf(str, "%d.%02d.%02d ", ha->fw_major_version, | 299 | sprintf(str, "%d.%02d.%02d ", ha->fw_major_version, |
298 | ha->fw_minor_version, | 300 | ha->fw_minor_version, |
@@ -328,8 +330,9 @@ qla2x00_fw_version_str(struct scsi_qla_host *ha, char *str) | |||
328 | } | 330 | } |
329 | 331 | ||
330 | static char * | 332 | static char * |
331 | qla24xx_fw_version_str(struct scsi_qla_host *ha, char *str) | 333 | qla24xx_fw_version_str(struct scsi_qla_host *vha, char *str) |
332 | { | 334 | { |
335 | struct qla_hw_data *ha = vha->hw; | ||
333 | sprintf(str, "%d.%02d.%02d ", ha->fw_major_version, | 336 | sprintf(str, "%d.%02d.%02d ", ha->fw_major_version, |
334 | ha->fw_minor_version, | 337 | ha->fw_minor_version, |
335 | ha->fw_subminor_version); | 338 | ha->fw_subminor_version); |
@@ -354,16 +357,17 @@ qla24xx_fw_version_str(struct scsi_qla_host *ha, char *str) | |||
354 | } | 357 | } |
355 | 358 | ||
356 | static inline srb_t * | 359 | static inline srb_t * |
357 | qla2x00_get_new_sp(scsi_qla_host_t *ha, fc_port_t *fcport, | 360 | qla2x00_get_new_sp(scsi_qla_host_t *vha, fc_port_t *fcport, |
358 | struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) | 361 | struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) |
359 | { | 362 | { |
360 | srb_t *sp; | 363 | srb_t *sp; |
364 | struct qla_hw_data *ha = vha->hw; | ||
361 | 365 | ||
362 | sp = mempool_alloc(ha->srb_mempool, GFP_ATOMIC); | 366 | sp = mempool_alloc(ha->srb_mempool, GFP_ATOMIC); |
363 | if (!sp) | 367 | if (!sp) |
364 | return sp; | 368 | return sp; |
365 | 369 | ||
366 | sp->ha = ha; | 370 | sp->vha = vha; |
367 | sp->fcport = fcport; | 371 | sp->fcport = fcport; |
368 | sp->cmd = cmd; | 372 | sp->cmd = cmd; |
369 | sp->flags = 0; | 373 | sp->flags = 0; |
@@ -376,9 +380,10 @@ qla2x00_get_new_sp(scsi_qla_host_t *ha, fc_port_t *fcport, | |||
376 | static int | 380 | static int |
377 | qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) | 381 | qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) |
378 | { | 382 | { |
379 | scsi_qla_host_t *ha = shost_priv(cmd->device->host); | 383 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); |
380 | fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; | 384 | fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; |
381 | struct fc_rport *rport = starget_to_rport(scsi_target(cmd->device)); | 385 | struct fc_rport *rport = starget_to_rport(scsi_target(cmd->device)); |
386 | struct qla_hw_data *ha = vha->hw; | ||
382 | srb_t *sp; | 387 | srb_t *sp; |
383 | int rval; | 388 | int rval; |
384 | 389 | ||
@@ -399,33 +404,33 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) | |||
399 | 404 | ||
400 | if (atomic_read(&fcport->state) != FCS_ONLINE) { | 405 | if (atomic_read(&fcport->state) != FCS_ONLINE) { |
401 | if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD || | 406 | if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD || |
402 | atomic_read(&ha->loop_state) == LOOP_DEAD) { | 407 | atomic_read(&vha->loop_state) == LOOP_DEAD) { |
403 | cmd->result = DID_NO_CONNECT << 16; | 408 | cmd->result = DID_NO_CONNECT << 16; |
404 | goto qc_fail_command; | 409 | goto qc_fail_command; |
405 | } | 410 | } |
406 | goto qc_target_busy; | 411 | goto qc_target_busy; |
407 | } | 412 | } |
408 | 413 | ||
409 | spin_unlock_irq(ha->host->host_lock); | 414 | spin_unlock_irq(vha->host->host_lock); |
410 | 415 | ||
411 | sp = qla2x00_get_new_sp(ha, fcport, cmd, done); | 416 | sp = qla2x00_get_new_sp(vha, fcport, cmd, done); |
412 | if (!sp) | 417 | if (!sp) |
413 | goto qc_host_busy_lock; | 418 | goto qc_host_busy_lock; |
414 | 419 | ||
415 | rval = qla2x00_start_scsi(sp); | 420 | rval = ha->isp_ops->start_scsi(sp); |
416 | if (rval != QLA_SUCCESS) | 421 | if (rval != QLA_SUCCESS) |
417 | goto qc_host_busy_free_sp; | 422 | goto qc_host_busy_free_sp; |
418 | 423 | ||
419 | spin_lock_irq(ha->host->host_lock); | 424 | spin_lock_irq(vha->host->host_lock); |
420 | 425 | ||
421 | return 0; | 426 | return 0; |
422 | 427 | ||
423 | qc_host_busy_free_sp: | 428 | qc_host_busy_free_sp: |
424 | qla2x00_sp_free_dma(ha, sp); | 429 | qla2x00_sp_free_dma(sp); |
425 | mempool_free(sp, ha->srb_mempool); | 430 | mempool_free(sp, ha->srb_mempool); |
426 | 431 | ||
427 | qc_host_busy_lock: | 432 | qc_host_busy_lock: |
428 | spin_lock_irq(ha->host->host_lock); | 433 | spin_lock_irq(vha->host->host_lock); |
429 | return SCSI_MLQUEUE_HOST_BUSY; | 434 | return SCSI_MLQUEUE_HOST_BUSY; |
430 | 435 | ||
431 | qc_target_busy: | 436 | qc_target_busy: |
@@ -441,14 +446,15 @@ qc_fail_command: | |||
441 | static int | 446 | static int |
442 | qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) | 447 | qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) |
443 | { | 448 | { |
444 | scsi_qla_host_t *ha = shost_priv(cmd->device->host); | 449 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); |
445 | fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; | 450 | fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; |
446 | struct fc_rport *rport = starget_to_rport(scsi_target(cmd->device)); | 451 | struct fc_rport *rport = starget_to_rport(scsi_target(cmd->device)); |
452 | struct qla_hw_data *ha = vha->hw; | ||
453 | struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); | ||
447 | srb_t *sp; | 454 | srb_t *sp; |
448 | int rval; | 455 | int rval; |
449 | scsi_qla_host_t *pha = to_qla_parent(ha); | ||
450 | 456 | ||
451 | if (unlikely(pci_channel_offline(pha->pdev))) { | 457 | if (unlikely(pci_channel_offline(ha->pdev))) { |
452 | cmd->result = DID_REQUEUE << 16; | 458 | cmd->result = DID_REQUEUE << 16; |
453 | goto qc24_fail_command; | 459 | goto qc24_fail_command; |
454 | } | 460 | } |
@@ -465,33 +471,33 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) | |||
465 | 471 | ||
466 | if (atomic_read(&fcport->state) != FCS_ONLINE) { | 472 | if (atomic_read(&fcport->state) != FCS_ONLINE) { |
467 | if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD || | 473 | if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD || |
468 | atomic_read(&pha->loop_state) == LOOP_DEAD) { | 474 | atomic_read(&base_vha->loop_state) == LOOP_DEAD) { |
469 | cmd->result = DID_NO_CONNECT << 16; | 475 | cmd->result = DID_NO_CONNECT << 16; |
470 | goto qc24_fail_command; | 476 | goto qc24_fail_command; |
471 | } | 477 | } |
472 | goto qc24_target_busy; | 478 | goto qc24_target_busy; |
473 | } | 479 | } |
474 | 480 | ||
475 | spin_unlock_irq(ha->host->host_lock); | 481 | spin_unlock_irq(vha->host->host_lock); |
476 | 482 | ||
477 | sp = qla2x00_get_new_sp(pha, fcport, cmd, done); | 483 | sp = qla2x00_get_new_sp(base_vha, fcport, cmd, done); |
478 | if (!sp) | 484 | if (!sp) |
479 | goto qc24_host_busy_lock; | 485 | goto qc24_host_busy_lock; |
480 | 486 | ||
481 | rval = qla24xx_start_scsi(sp); | 487 | rval = ha->isp_ops->start_scsi(sp); |
482 | if (rval != QLA_SUCCESS) | 488 | if (rval != QLA_SUCCESS) |
483 | goto qc24_host_busy_free_sp; | 489 | goto qc24_host_busy_free_sp; |
484 | 490 | ||
485 | spin_lock_irq(ha->host->host_lock); | 491 | spin_lock_irq(vha->host->host_lock); |
486 | 492 | ||
487 | return 0; | 493 | return 0; |
488 | 494 | ||
489 | qc24_host_busy_free_sp: | 495 | qc24_host_busy_free_sp: |
490 | qla2x00_sp_free_dma(pha, sp); | 496 | qla2x00_sp_free_dma(sp); |
491 | mempool_free(sp, pha->srb_mempool); | 497 | mempool_free(sp, ha->srb_mempool); |
492 | 498 | ||
493 | qc24_host_busy_lock: | 499 | qc24_host_busy_lock: |
494 | spin_lock_irq(ha->host->host_lock); | 500 | spin_lock_irq(vha->host->host_lock); |
495 | return SCSI_MLQUEUE_HOST_BUSY; | 501 | return SCSI_MLQUEUE_HOST_BUSY; |
496 | 502 | ||
497 | qc24_target_busy: | 503 | qc24_target_busy: |
@@ -510,17 +516,14 @@ qc24_fail_command: | |||
510 | * max time. | 516 | * max time. |
511 | * | 517 | * |
512 | * Input: | 518 | * Input: |
513 | * ha = actual ha whose done queue will contain the command | ||
514 | * returned by firmware. | ||
515 | * cmd = Scsi Command to wait on. | 519 | * cmd = Scsi Command to wait on. |
516 | * flag = Abort/Reset(Bus or Device Reset) | ||
517 | * | 520 | * |
518 | * Return: | 521 | * Return: |
519 | * Not Found : 0 | 522 | * Not Found : 0 |
520 | * Found : 1 | 523 | * Found : 1 |
521 | */ | 524 | */ |
522 | static int | 525 | static int |
523 | qla2x00_eh_wait_on_command(scsi_qla_host_t *ha, struct scsi_cmnd *cmd) | 526 | qla2x00_eh_wait_on_command(struct scsi_cmnd *cmd) |
524 | { | 527 | { |
525 | #define ABORT_POLLING_PERIOD 1000 | 528 | #define ABORT_POLLING_PERIOD 1000 |
526 | #define ABORT_WAIT_ITER ((10 * 1000) / (ABORT_POLLING_PERIOD)) | 529 | #define ABORT_WAIT_ITER ((10 * 1000) / (ABORT_POLLING_PERIOD)) |
@@ -557,21 +560,22 @@ qla2x00_eh_wait_on_command(scsi_qla_host_t *ha, struct scsi_cmnd *cmd) | |||
557 | * Failed (Adapter is offline/disabled) : 1 | 560 | * Failed (Adapter is offline/disabled) : 1 |
558 | */ | 561 | */ |
559 | int | 562 | int |
560 | qla2x00_wait_for_hba_online(scsi_qla_host_t *ha) | 563 | qla2x00_wait_for_hba_online(scsi_qla_host_t *vha) |
561 | { | 564 | { |
562 | int return_status; | 565 | int return_status; |
563 | unsigned long wait_online; | 566 | unsigned long wait_online; |
564 | scsi_qla_host_t *pha = to_qla_parent(ha); | 567 | struct qla_hw_data *ha = vha->hw; |
568 | scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); | ||
565 | 569 | ||
566 | wait_online = jiffies + (MAX_LOOP_TIMEOUT * HZ); | 570 | wait_online = jiffies + (MAX_LOOP_TIMEOUT * HZ); |
567 | while (((test_bit(ISP_ABORT_NEEDED, &pha->dpc_flags)) || | 571 | while (((test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags)) || |
568 | test_bit(ABORT_ISP_ACTIVE, &pha->dpc_flags) || | 572 | test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) || |
569 | test_bit(ISP_ABORT_RETRY, &pha->dpc_flags) || | 573 | test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) || |
570 | pha->dpc_active) && time_before(jiffies, wait_online)) { | 574 | ha->dpc_active) && time_before(jiffies, wait_online)) { |
571 | 575 | ||
572 | msleep(1000); | 576 | msleep(1000); |
573 | } | 577 | } |
574 | if (pha->flags.online) | 578 | if (base_vha->flags.online) |
575 | return_status = QLA_SUCCESS; | 579 | return_status = QLA_SUCCESS; |
576 | else | 580 | else |
577 | return_status = QLA_FUNCTION_FAILED; | 581 | return_status = QLA_FUNCTION_FAILED; |
@@ -596,19 +600,20 @@ qla2x00_wait_for_hba_online(scsi_qla_host_t *ha) | |||
596 | * Failed (LOOP_NOT_READY) : 1 | 600 | * Failed (LOOP_NOT_READY) : 1 |
597 | */ | 601 | */ |
598 | static inline int | 602 | static inline int |
599 | qla2x00_wait_for_loop_ready(scsi_qla_host_t *ha) | 603 | qla2x00_wait_for_loop_ready(scsi_qla_host_t *vha) |
600 | { | 604 | { |
601 | int return_status = QLA_SUCCESS; | 605 | int return_status = QLA_SUCCESS; |
602 | unsigned long loop_timeout ; | 606 | unsigned long loop_timeout ; |
603 | scsi_qla_host_t *pha = to_qla_parent(ha); | 607 | struct qla_hw_data *ha = vha->hw; |
608 | scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); | ||
604 | 609 | ||
605 | /* wait for 5 min at the max for loop to be ready */ | 610 | /* wait for 5 min at the max for loop to be ready */ |
606 | loop_timeout = jiffies + (MAX_LOOP_TIMEOUT * HZ); | 611 | loop_timeout = jiffies + (MAX_LOOP_TIMEOUT * HZ); |
607 | 612 | ||
608 | while ((!atomic_read(&pha->loop_down_timer) && | 613 | while ((!atomic_read(&base_vha->loop_down_timer) && |
609 | atomic_read(&pha->loop_state) == LOOP_DOWN) || | 614 | atomic_read(&base_vha->loop_state) == LOOP_DOWN) || |
610 | atomic_read(&pha->loop_state) != LOOP_READY) { | 615 | atomic_read(&base_vha->loop_state) != LOOP_READY) { |
611 | if (atomic_read(&pha->loop_state) == LOOP_DEAD) { | 616 | if (atomic_read(&base_vha->loop_state) == LOOP_DEAD) { |
612 | return_status = QLA_FUNCTION_FAILED; | 617 | return_status = QLA_FUNCTION_FAILED; |
613 | break; | 618 | break; |
614 | } | 619 | } |
@@ -627,32 +632,33 @@ qla2x00_abort_fcport_cmds(fc_port_t *fcport) | |||
627 | int cnt; | 632 | int cnt; |
628 | unsigned long flags; | 633 | unsigned long flags; |
629 | srb_t *sp; | 634 | srb_t *sp; |
630 | scsi_qla_host_t *ha = fcport->ha; | 635 | scsi_qla_host_t *vha = fcport->vha; |
631 | scsi_qla_host_t *pha = to_qla_parent(ha); | 636 | struct qla_hw_data *ha = vha->hw; |
637 | struct req_que *req = ha->req; | ||
632 | 638 | ||
633 | spin_lock_irqsave(&pha->hardware_lock, flags); | 639 | spin_lock_irqsave(&ha->hardware_lock, flags); |
634 | for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { | 640 | for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { |
635 | sp = pha->outstanding_cmds[cnt]; | 641 | sp = req->outstanding_cmds[cnt]; |
636 | if (!sp) | 642 | if (!sp) |
637 | continue; | 643 | continue; |
638 | if (sp->fcport != fcport) | 644 | if (sp->fcport != fcport) |
639 | continue; | 645 | continue; |
640 | 646 | ||
641 | spin_unlock_irqrestore(&pha->hardware_lock, flags); | 647 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
642 | if (ha->isp_ops->abort_command(ha, sp)) { | 648 | if (ha->isp_ops->abort_command(vha, sp)) { |
643 | DEBUG2(qla_printk(KERN_WARNING, ha, | 649 | DEBUG2(qla_printk(KERN_WARNING, ha, |
644 | "Abort failed -- %lx\n", sp->cmd->serial_number)); | 650 | "Abort failed -- %lx\n", sp->cmd->serial_number)); |
645 | } else { | 651 | } else { |
646 | if (qla2x00_eh_wait_on_command(ha, sp->cmd) != | 652 | if (qla2x00_eh_wait_on_command(sp->cmd) != |
647 | QLA_SUCCESS) | 653 | QLA_SUCCESS) |
648 | DEBUG2(qla_printk(KERN_WARNING, ha, | 654 | DEBUG2(qla_printk(KERN_WARNING, ha, |
649 | "Abort failed while waiting -- %lx\n", | 655 | "Abort failed while waiting -- %lx\n", |
650 | sp->cmd->serial_number)); | 656 | sp->cmd->serial_number)); |
651 | 657 | ||
652 | } | 658 | } |
653 | spin_lock_irqsave(&pha->hardware_lock, flags); | 659 | spin_lock_irqsave(&ha->hardware_lock, flags); |
654 | } | 660 | } |
655 | spin_unlock_irqrestore(&pha->hardware_lock, flags); | 661 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
656 | } | 662 | } |
657 | 663 | ||
658 | static void | 664 | static void |
@@ -690,14 +696,15 @@ qla2x00_block_error_handler(struct scsi_cmnd *cmnd) | |||
690 | static int | 696 | static int |
691 | qla2xxx_eh_abort(struct scsi_cmnd *cmd) | 697 | qla2xxx_eh_abort(struct scsi_cmnd *cmd) |
692 | { | 698 | { |
693 | scsi_qla_host_t *ha = shost_priv(cmd->device->host); | 699 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); |
694 | srb_t *sp; | 700 | srb_t *sp; |
695 | int ret, i; | 701 | int ret, i; |
696 | unsigned int id, lun; | 702 | unsigned int id, lun; |
697 | unsigned long serial; | 703 | unsigned long serial; |
698 | unsigned long flags; | 704 | unsigned long flags; |
699 | int wait = 0; | 705 | int wait = 0; |
700 | scsi_qla_host_t *pha = to_qla_parent(ha); | 706 | struct qla_hw_data *ha = vha->hw; |
707 | struct req_que *req = ha->req; | ||
701 | 708 | ||
702 | qla2x00_block_error_handler(cmd); | 709 | qla2x00_block_error_handler(cmd); |
703 | 710 | ||
@@ -711,9 +718,9 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) | |||
711 | serial = cmd->serial_number; | 718 | serial = cmd->serial_number; |
712 | 719 | ||
713 | /* Check active list for command command. */ | 720 | /* Check active list for command command. */ |
714 | spin_lock_irqsave(&pha->hardware_lock, flags); | 721 | spin_lock_irqsave(&ha->hardware_lock, flags); |
715 | for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) { | 722 | for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) { |
716 | sp = pha->outstanding_cmds[i]; | 723 | sp = req->outstanding_cmds[i]; |
717 | 724 | ||
718 | if (sp == NULL) | 725 | if (sp == NULL) |
719 | continue; | 726 | continue; |
@@ -722,37 +729,37 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) | |||
722 | continue; | 729 | continue; |
723 | 730 | ||
724 | DEBUG2(printk("%s(%ld): aborting sp %p from RISC. pid=%ld.\n", | 731 | DEBUG2(printk("%s(%ld): aborting sp %p from RISC. pid=%ld.\n", |
725 | __func__, ha->host_no, sp, serial)); | 732 | __func__, vha->host_no, sp, serial)); |
726 | 733 | ||
727 | spin_unlock_irqrestore(&pha->hardware_lock, flags); | 734 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
728 | if (ha->isp_ops->abort_command(ha, sp)) { | 735 | if (ha->isp_ops->abort_command(vha, sp)) { |
729 | DEBUG2(printk("%s(%ld): abort_command " | 736 | DEBUG2(printk("%s(%ld): abort_command " |
730 | "mbx failed.\n", __func__, ha->host_no)); | 737 | "mbx failed.\n", __func__, vha->host_no)); |
731 | ret = FAILED; | 738 | ret = FAILED; |
732 | } else { | 739 | } else { |
733 | DEBUG3(printk("%s(%ld): abort_command " | 740 | DEBUG3(printk("%s(%ld): abort_command " |
734 | "mbx success.\n", __func__, ha->host_no)); | 741 | "mbx success.\n", __func__, vha->host_no)); |
735 | wait = 1; | 742 | wait = 1; |
736 | } | 743 | } |
737 | spin_lock_irqsave(&pha->hardware_lock, flags); | 744 | spin_lock_irqsave(&ha->hardware_lock, flags); |
738 | 745 | ||
739 | break; | 746 | break; |
740 | } | 747 | } |
741 | spin_unlock_irqrestore(&pha->hardware_lock, flags); | 748 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
742 | 749 | ||
743 | /* Wait for the command to be returned. */ | 750 | /* Wait for the command to be returned. */ |
744 | if (wait) { | 751 | if (wait) { |
745 | if (qla2x00_eh_wait_on_command(ha, cmd) != QLA_SUCCESS) { | 752 | if (qla2x00_eh_wait_on_command(cmd) != QLA_SUCCESS) { |
746 | qla_printk(KERN_ERR, ha, | 753 | qla_printk(KERN_ERR, ha, |
747 | "scsi(%ld:%d:%d): Abort handler timed out -- %lx " | 754 | "scsi(%ld:%d:%d): Abort handler timed out -- %lx " |
748 | "%x.\n", ha->host_no, id, lun, serial, ret); | 755 | "%x.\n", vha->host_no, id, lun, serial, ret); |
749 | ret = FAILED; | 756 | ret = FAILED; |
750 | } | 757 | } |
751 | } | 758 | } |
752 | 759 | ||
753 | qla_printk(KERN_INFO, ha, | 760 | qla_printk(KERN_INFO, ha, |
754 | "scsi(%ld:%d:%d): Abort command issued -- %d %lx %x.\n", | 761 | "scsi(%ld:%d:%d): Abort command issued -- %d %lx %x.\n", |
755 | ha->host_no, id, lun, wait, serial, ret); | 762 | vha->host_no, id, lun, wait, serial, ret); |
756 | 763 | ||
757 | return ret; | 764 | return ret; |
758 | } | 765 | } |
@@ -764,23 +771,24 @@ enum nexus_wait_type { | |||
764 | }; | 771 | }; |
765 | 772 | ||
766 | static int | 773 | static int |
767 | qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha, unsigned int t, | 774 | qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t, |
768 | unsigned int l, enum nexus_wait_type type) | 775 | unsigned int l, enum nexus_wait_type type) |
769 | { | 776 | { |
770 | int cnt, match, status; | 777 | int cnt, match, status; |
771 | srb_t *sp; | 778 | srb_t *sp; |
772 | unsigned long flags; | 779 | unsigned long flags; |
773 | scsi_qla_host_t *pha = to_qla_parent(ha); | 780 | struct qla_hw_data *ha = vha->hw; |
781 | struct req_que *req = ha->req; | ||
774 | 782 | ||
775 | status = QLA_SUCCESS; | 783 | status = QLA_SUCCESS; |
776 | spin_lock_irqsave(&pha->hardware_lock, flags); | 784 | spin_lock_irqsave(&ha->hardware_lock, flags); |
777 | for (cnt = 1; status == QLA_SUCCESS && cnt < MAX_OUTSTANDING_COMMANDS; | 785 | for (cnt = 1; status == QLA_SUCCESS && cnt < MAX_OUTSTANDING_COMMANDS; |
778 | cnt++) { | 786 | cnt++) { |
779 | sp = pha->outstanding_cmds[cnt]; | 787 | sp = req->outstanding_cmds[cnt]; |
780 | if (!sp) | 788 | if (!sp) |
781 | continue; | 789 | continue; |
782 | 790 | ||
783 | if (ha->vp_idx != sp->fcport->ha->vp_idx) | 791 | if (vha->vp_idx != sp->fcport->vha->vp_idx) |
784 | continue; | 792 | continue; |
785 | match = 0; | 793 | match = 0; |
786 | switch (type) { | 794 | switch (type) { |
@@ -798,11 +806,11 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha, unsigned int t, | |||
798 | if (!match) | 806 | if (!match) |
799 | continue; | 807 | continue; |
800 | 808 | ||
801 | spin_unlock_irqrestore(&pha->hardware_lock, flags); | 809 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
802 | status = qla2x00_eh_wait_on_command(ha, sp->cmd); | 810 | status = qla2x00_eh_wait_on_command(sp->cmd); |
803 | spin_lock_irqsave(&pha->hardware_lock, flags); | 811 | spin_lock_irqsave(&ha->hardware_lock, flags); |
804 | } | 812 | } |
805 | spin_unlock_irqrestore(&pha->hardware_lock, flags); | 813 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
806 | 814 | ||
807 | return status; | 815 | return status; |
808 | } | 816 | } |
@@ -818,7 +826,7 @@ static int | |||
818 | __qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type, | 826 | __qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type, |
819 | struct scsi_cmnd *cmd, int (*do_reset)(struct fc_port *, unsigned int)) | 827 | struct scsi_cmnd *cmd, int (*do_reset)(struct fc_port *, unsigned int)) |
820 | { | 828 | { |
821 | scsi_qla_host_t *ha = shost_priv(cmd->device->host); | 829 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); |
822 | fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; | 830 | fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; |
823 | int err; | 831 | int err; |
824 | 832 | ||
@@ -827,31 +835,31 @@ __qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type, | |||
827 | if (!fcport) | 835 | if (!fcport) |
828 | return FAILED; | 836 | return FAILED; |
829 | 837 | ||
830 | qla_printk(KERN_INFO, ha, "scsi(%ld:%d:%d): %s RESET ISSUED.\n", | 838 | qla_printk(KERN_INFO, vha->hw, "scsi(%ld:%d:%d): %s RESET ISSUED.\n", |
831 | ha->host_no, cmd->device->id, cmd->device->lun, name); | 839 | vha->host_no, cmd->device->id, cmd->device->lun, name); |
832 | 840 | ||
833 | err = 0; | 841 | err = 0; |
834 | if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS) | 842 | if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) |
835 | goto eh_reset_failed; | 843 | goto eh_reset_failed; |
836 | err = 1; | 844 | err = 1; |
837 | if (qla2x00_wait_for_loop_ready(ha) != QLA_SUCCESS) | 845 | if (qla2x00_wait_for_loop_ready(vha) != QLA_SUCCESS) |
838 | goto eh_reset_failed; | 846 | goto eh_reset_failed; |
839 | err = 2; | 847 | err = 2; |
840 | if (do_reset(fcport, cmd->device->lun) != QLA_SUCCESS) | 848 | if (do_reset(fcport, cmd->device->lun) != QLA_SUCCESS) |
841 | goto eh_reset_failed; | 849 | goto eh_reset_failed; |
842 | err = 3; | 850 | err = 3; |
843 | if (qla2x00_eh_wait_for_pending_commands(ha, cmd->device->id, | 851 | if (qla2x00_eh_wait_for_pending_commands(vha, cmd->device->id, |
844 | cmd->device->lun, type) != QLA_SUCCESS) | 852 | cmd->device->lun, type) != QLA_SUCCESS) |
845 | goto eh_reset_failed; | 853 | goto eh_reset_failed; |
846 | 854 | ||
847 | qla_printk(KERN_INFO, ha, "scsi(%ld:%d:%d): %s RESET SUCCEEDED.\n", | 855 | qla_printk(KERN_INFO, vha->hw, "scsi(%ld:%d:%d): %s RESET SUCCEEDED.\n", |
848 | ha->host_no, cmd->device->id, cmd->device->lun, name); | 856 | vha->host_no, cmd->device->id, cmd->device->lun, name); |
849 | 857 | ||
850 | return SUCCESS; | 858 | return SUCCESS; |
851 | 859 | ||
852 | eh_reset_failed: | 860 | eh_reset_failed: |
853 | qla_printk(KERN_INFO, ha, "scsi(%ld:%d:%d): %s RESET FAILED: %s.\n", | 861 | qla_printk(KERN_INFO, vha->hw, "scsi(%ld:%d:%d): %s RESET FAILED: %s.\n" |
854 | ha->host_no, cmd->device->id, cmd->device->lun, name, | 862 | , vha->host_no, cmd->device->id, cmd->device->lun, name, |
855 | reset_errors[err]); | 863 | reset_errors[err]); |
856 | return FAILED; | 864 | return FAILED; |
857 | } | 865 | } |
@@ -859,7 +867,8 @@ __qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type, | |||
859 | static int | 867 | static int |
860 | qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) | 868 | qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) |
861 | { | 869 | { |
862 | scsi_qla_host_t *ha = shost_priv(cmd->device->host); | 870 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); |
871 | struct qla_hw_data *ha = vha->hw; | ||
863 | 872 | ||
864 | return __qla2xxx_eh_generic_reset("DEVICE", WAIT_LUN, cmd, | 873 | return __qla2xxx_eh_generic_reset("DEVICE", WAIT_LUN, cmd, |
865 | ha->isp_ops->lun_reset); | 874 | ha->isp_ops->lun_reset); |
@@ -868,7 +877,8 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) | |||
868 | static int | 877 | static int |
869 | qla2xxx_eh_target_reset(struct scsi_cmnd *cmd) | 878 | qla2xxx_eh_target_reset(struct scsi_cmnd *cmd) |
870 | { | 879 | { |
871 | scsi_qla_host_t *ha = shost_priv(cmd->device->host); | 880 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); |
881 | struct qla_hw_data *ha = vha->hw; | ||
872 | 882 | ||
873 | return __qla2xxx_eh_generic_reset("TARGET", WAIT_TARGET, cmd, | 883 | return __qla2xxx_eh_generic_reset("TARGET", WAIT_TARGET, cmd, |
874 | ha->isp_ops->target_reset); | 884 | ha->isp_ops->target_reset); |
@@ -892,8 +902,7 @@ qla2xxx_eh_target_reset(struct scsi_cmnd *cmd) | |||
892 | static int | 902 | static int |
893 | qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) | 903 | qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) |
894 | { | 904 | { |
895 | scsi_qla_host_t *ha = shost_priv(cmd->device->host); | 905 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); |
896 | scsi_qla_host_t *pha = to_qla_parent(ha); | ||
897 | fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; | 906 | fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; |
898 | int ret = FAILED; | 907 | int ret = FAILED; |
899 | unsigned int id, lun; | 908 | unsigned int id, lun; |
@@ -908,28 +917,28 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) | |||
908 | if (!fcport) | 917 | if (!fcport) |
909 | return ret; | 918 | return ret; |
910 | 919 | ||
911 | qla_printk(KERN_INFO, ha, | 920 | qla_printk(KERN_INFO, vha->hw, |
912 | "scsi(%ld:%d:%d): LOOP RESET ISSUED.\n", ha->host_no, id, lun); | 921 | "scsi(%ld:%d:%d): LOOP RESET ISSUED.\n", vha->host_no, id, lun); |
913 | 922 | ||
914 | if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS) { | 923 | if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) { |
915 | DEBUG2(printk("%s failed:board disabled\n",__func__)); | 924 | DEBUG2(printk("%s failed:board disabled\n",__func__)); |
916 | goto eh_bus_reset_done; | 925 | goto eh_bus_reset_done; |
917 | } | 926 | } |
918 | 927 | ||
919 | if (qla2x00_wait_for_loop_ready(ha) == QLA_SUCCESS) { | 928 | if (qla2x00_wait_for_loop_ready(vha) == QLA_SUCCESS) { |
920 | if (qla2x00_loop_reset(ha) == QLA_SUCCESS) | 929 | if (qla2x00_loop_reset(vha) == QLA_SUCCESS) |
921 | ret = SUCCESS; | 930 | ret = SUCCESS; |
922 | } | 931 | } |
923 | if (ret == FAILED) | 932 | if (ret == FAILED) |
924 | goto eh_bus_reset_done; | 933 | goto eh_bus_reset_done; |
925 | 934 | ||
926 | /* Flush outstanding commands. */ | 935 | /* Flush outstanding commands. */ |
927 | if (qla2x00_eh_wait_for_pending_commands(pha, 0, 0, WAIT_HOST) != | 936 | if (qla2x00_eh_wait_for_pending_commands(vha, 0, 0, WAIT_HOST) != |
928 | QLA_SUCCESS) | 937 | QLA_SUCCESS) |
929 | ret = FAILED; | 938 | ret = FAILED; |
930 | 939 | ||
931 | eh_bus_reset_done: | 940 | eh_bus_reset_done: |
932 | qla_printk(KERN_INFO, ha, "%s: reset %s\n", __func__, | 941 | qla_printk(KERN_INFO, vha->hw, "%s: reset %s\n", __func__, |
933 | (ret == FAILED) ? "failed" : "succeded"); | 942 | (ret == FAILED) ? "failed" : "succeded"); |
934 | 943 | ||
935 | return ret; | 944 | return ret; |
@@ -953,12 +962,13 @@ eh_bus_reset_done: | |||
953 | static int | 962 | static int |
954 | qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) | 963 | qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) |
955 | { | 964 | { |
956 | scsi_qla_host_t *ha = shost_priv(cmd->device->host); | 965 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); |
957 | fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; | 966 | fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; |
967 | struct qla_hw_data *ha = vha->hw; | ||
958 | int ret = FAILED; | 968 | int ret = FAILED; |
959 | unsigned int id, lun; | 969 | unsigned int id, lun; |
960 | unsigned long serial; | 970 | unsigned long serial; |
961 | scsi_qla_host_t *pha = to_qla_parent(ha); | 971 | scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); |
962 | 972 | ||
963 | qla2x00_block_error_handler(cmd); | 973 | qla2x00_block_error_handler(cmd); |
964 | 974 | ||
@@ -970,9 +980,9 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) | |||
970 | return ret; | 980 | return ret; |
971 | 981 | ||
972 | qla_printk(KERN_INFO, ha, | 982 | qla_printk(KERN_INFO, ha, |
973 | "scsi(%ld:%d:%d): ADAPTER RESET ISSUED.\n", ha->host_no, id, lun); | 983 | "scsi(%ld:%d:%d): ADAPTER RESET ISSUED.\n", vha->host_no, id, lun); |
974 | 984 | ||
975 | if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS) | 985 | if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) |
976 | goto eh_host_reset_lock; | 986 | goto eh_host_reset_lock; |
977 | 987 | ||
978 | /* | 988 | /* |
@@ -983,26 +993,28 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) | |||
983 | * devices as lost kicking of the port_down_timer | 993 | * devices as lost kicking of the port_down_timer |
984 | * while dpc is stuck for the mailbox to complete. | 994 | * while dpc is stuck for the mailbox to complete. |
985 | */ | 995 | */ |
986 | qla2x00_wait_for_loop_ready(ha); | 996 | qla2x00_wait_for_loop_ready(vha); |
987 | set_bit(ABORT_ISP_ACTIVE, &pha->dpc_flags); | 997 | if (vha != base_vha) { |
988 | if (qla2x00_abort_isp(pha)) { | 998 | if (qla2x00_vp_abort_isp(vha)) |
989 | clear_bit(ABORT_ISP_ACTIVE, &pha->dpc_flags); | ||
990 | /* failed. schedule dpc to try */ | ||
991 | set_bit(ISP_ABORT_NEEDED, &pha->dpc_flags); | ||
992 | |||
993 | if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS) | ||
994 | goto eh_host_reset_lock; | 999 | goto eh_host_reset_lock; |
1000 | } else { | ||
1001 | set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); | ||
1002 | if (qla2x00_abort_isp(base_vha)) { | ||
1003 | clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); | ||
1004 | /* failed. schedule dpc to try */ | ||
1005 | set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags); | ||
1006 | |||
1007 | if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) | ||
1008 | goto eh_host_reset_lock; | ||
1009 | } | ||
1010 | clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); | ||
995 | } | 1011 | } |
996 | clear_bit(ABORT_ISP_ACTIVE, &pha->dpc_flags); | ||
997 | 1012 | ||
998 | /* Waiting for our command in done_queue to be returned to OS.*/ | 1013 | /* Waiting for command to be returned to OS.*/ |
999 | if (qla2x00_eh_wait_for_pending_commands(pha, 0, 0, WAIT_HOST) == | 1014 | if (qla2x00_eh_wait_for_pending_commands(vha, 0, 0, WAIT_HOST) == |
1000 | QLA_SUCCESS) | 1015 | QLA_SUCCESS) |
1001 | ret = SUCCESS; | 1016 | ret = SUCCESS; |
1002 | 1017 | ||
1003 | if (ha->parent) | ||
1004 | qla2x00_vp_abort_isp(ha); | ||
1005 | |||
1006 | eh_host_reset_lock: | 1018 | eh_host_reset_lock: |
1007 | qla_printk(KERN_INFO, ha, "%s: reset %s\n", __func__, | 1019 | qla_printk(KERN_INFO, ha, "%s: reset %s\n", __func__, |
1008 | (ret == FAILED) ? "failed" : "succeded"); | 1020 | (ret == FAILED) ? "failed" : "succeded"); |
@@ -1021,35 +1033,33 @@ eh_host_reset_lock: | |||
1021 | * 0 = success | 1033 | * 0 = success |
1022 | */ | 1034 | */ |
1023 | int | 1035 | int |
1024 | qla2x00_loop_reset(scsi_qla_host_t *ha) | 1036 | qla2x00_loop_reset(scsi_qla_host_t *vha) |
1025 | { | 1037 | { |
1026 | int ret; | 1038 | int ret; |
1027 | struct fc_port *fcport; | 1039 | struct fc_port *fcport; |
1040 | struct qla_hw_data *ha = vha->hw; | ||
1028 | 1041 | ||
1029 | if (ha->flags.enable_lip_full_login) { | 1042 | if (ha->flags.enable_lip_full_login) { |
1030 | ret = qla2x00_full_login_lip(ha); | 1043 | ret = qla2x00_full_login_lip(vha); |
1031 | if (ret != QLA_SUCCESS) { | 1044 | if (ret != QLA_SUCCESS) { |
1032 | DEBUG2_3(printk("%s(%ld): bus_reset failed: " | 1045 | DEBUG2_3(printk("%s(%ld): bus_reset failed: " |
1033 | "full_login_lip=%d.\n", __func__, ha->host_no, | 1046 | "full_login_lip=%d.\n", __func__, vha->host_no, |
1034 | ret)); | 1047 | ret)); |
1035 | } | 1048 | } else |
1036 | atomic_set(&ha->loop_state, LOOP_DOWN); | 1049 | qla2x00_wait_for_loop_ready(vha); |
1037 | atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME); | ||
1038 | qla2x00_mark_all_devices_lost(ha, 0); | ||
1039 | qla2x00_wait_for_loop_ready(ha); | ||
1040 | } | 1050 | } |
1041 | 1051 | ||
1042 | if (ha->flags.enable_lip_reset) { | 1052 | if (ha->flags.enable_lip_reset) { |
1043 | ret = qla2x00_lip_reset(ha); | 1053 | ret = qla2x00_lip_reset(vha); |
1044 | if (ret != QLA_SUCCESS) { | 1054 | if (ret != QLA_SUCCESS) { |
1045 | DEBUG2_3(printk("%s(%ld): bus_reset failed: " | 1055 | DEBUG2_3(printk("%s(%ld): bus_reset failed: " |
1046 | "lip_reset=%d.\n", __func__, ha->host_no, ret)); | 1056 | "lip_reset=%d.\n", __func__, vha->host_no, ret)); |
1047 | } | 1057 | } else |
1048 | qla2x00_wait_for_loop_ready(ha); | 1058 | qla2x00_wait_for_loop_ready(vha); |
1049 | } | 1059 | } |
1050 | 1060 | ||
1051 | if (ha->flags.enable_target_reset) { | 1061 | if (ha->flags.enable_target_reset) { |
1052 | list_for_each_entry(fcport, &ha->fcports, list) { | 1062 | list_for_each_entry(fcport, &vha->vp_fcports, list) { |
1053 | if (fcport->port_type != FCT_TARGET) | 1063 | if (fcport->port_type != FCT_TARGET) |
1054 | continue; | 1064 | continue; |
1055 | 1065 | ||
@@ -1057,31 +1067,33 @@ qla2x00_loop_reset(scsi_qla_host_t *ha) | |||
1057 | if (ret != QLA_SUCCESS) { | 1067 | if (ret != QLA_SUCCESS) { |
1058 | DEBUG2_3(printk("%s(%ld): bus_reset failed: " | 1068 | DEBUG2_3(printk("%s(%ld): bus_reset failed: " |
1059 | "target_reset=%d d_id=%x.\n", __func__, | 1069 | "target_reset=%d d_id=%x.\n", __func__, |
1060 | ha->host_no, ret, fcport->d_id.b24)); | 1070 | vha->host_no, ret, fcport->d_id.b24)); |
1061 | } | 1071 | } |
1062 | } | 1072 | } |
1063 | } | 1073 | } |
1064 | 1074 | ||
1065 | /* Issue marker command only when we are going to start the I/O */ | 1075 | /* Issue marker command only when we are going to start the I/O */ |
1066 | ha->marker_needed = 1; | 1076 | vha->marker_needed = 1; |
1067 | 1077 | ||
1068 | return QLA_SUCCESS; | 1078 | return QLA_SUCCESS; |
1069 | } | 1079 | } |
1070 | 1080 | ||
1071 | void | 1081 | void |
1072 | qla2x00_abort_all_cmds(scsi_qla_host_t *ha, int res) | 1082 | qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res) |
1073 | { | 1083 | { |
1074 | int cnt; | 1084 | int cnt; |
1075 | unsigned long flags; | 1085 | unsigned long flags; |
1076 | srb_t *sp; | 1086 | srb_t *sp; |
1087 | struct qla_hw_data *ha = vha->hw; | ||
1088 | struct req_que *req = ha->req; | ||
1077 | 1089 | ||
1078 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1090 | spin_lock_irqsave(&ha->hardware_lock, flags); |
1079 | for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { | 1091 | for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { |
1080 | sp = ha->outstanding_cmds[cnt]; | 1092 | sp = req->outstanding_cmds[cnt]; |
1081 | if (sp) { | 1093 | if (sp) { |
1082 | ha->outstanding_cmds[cnt] = NULL; | 1094 | req->outstanding_cmds[cnt] = NULL; |
1083 | sp->cmd->result = res; | 1095 | sp->cmd->result = res; |
1084 | qla2x00_sp_compl(ha, sp); | 1096 | qla2x00_sp_compl(vha, sp); |
1085 | } | 1097 | } |
1086 | } | 1098 | } |
1087 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 1099 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
@@ -1103,13 +1115,14 @@ qla2xxx_slave_alloc(struct scsi_device *sdev) | |||
1103 | static int | 1115 | static int |
1104 | qla2xxx_slave_configure(struct scsi_device *sdev) | 1116 | qla2xxx_slave_configure(struct scsi_device *sdev) |
1105 | { | 1117 | { |
1106 | scsi_qla_host_t *ha = shost_priv(sdev->host); | 1118 | scsi_qla_host_t *vha = shost_priv(sdev->host); |
1119 | struct qla_hw_data *ha = vha->hw; | ||
1107 | struct fc_rport *rport = starget_to_rport(sdev->sdev_target); | 1120 | struct fc_rport *rport = starget_to_rport(sdev->sdev_target); |
1108 | 1121 | ||
1109 | if (sdev->tagged_supported) | 1122 | if (sdev->tagged_supported) |
1110 | scsi_activate_tcq(sdev, ha->max_q_depth); | 1123 | scsi_activate_tcq(sdev, ha->req->max_q_depth); |
1111 | else | 1124 | else |
1112 | scsi_deactivate_tcq(sdev, ha->max_q_depth); | 1125 | scsi_deactivate_tcq(sdev, ha->req->max_q_depth); |
1113 | 1126 | ||
1114 | rport->dev_loss_tmo = ha->port_down_retry_count; | 1127 | rport->dev_loss_tmo = ha->port_down_retry_count; |
1115 | 1128 | ||
@@ -1152,8 +1165,9 @@ qla2x00_change_queue_type(struct scsi_device *sdev, int tag_type) | |||
1152 | * supported addressing method. | 1165 | * supported addressing method. |
1153 | */ | 1166 | */ |
1154 | static void | 1167 | static void |
1155 | qla2x00_config_dma_addressing(scsi_qla_host_t *ha) | 1168 | qla2x00_config_dma_addressing(scsi_qla_host_t *vha) |
1156 | { | 1169 | { |
1170 | struct qla_hw_data *ha = vha->hw; | ||
1157 | /* Assume a 32bit DMA mask. */ | 1171 | /* Assume a 32bit DMA mask. */ |
1158 | ha->flags.enable_64bit_addressing = 0; | 1172 | ha->flags.enable_64bit_addressing = 0; |
1159 | 1173 | ||
@@ -1174,7 +1188,7 @@ qla2x00_config_dma_addressing(scsi_qla_host_t *ha) | |||
1174 | } | 1188 | } |
1175 | 1189 | ||
1176 | static void | 1190 | static void |
1177 | qla2x00_enable_intrs(scsi_qla_host_t *ha) | 1191 | qla2x00_enable_intrs(struct qla_hw_data *ha) |
1178 | { | 1192 | { |
1179 | unsigned long flags = 0; | 1193 | unsigned long flags = 0; |
1180 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | 1194 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; |
@@ -1189,7 +1203,7 @@ qla2x00_enable_intrs(scsi_qla_host_t *ha) | |||
1189 | } | 1203 | } |
1190 | 1204 | ||
1191 | static void | 1205 | static void |
1192 | qla2x00_disable_intrs(scsi_qla_host_t *ha) | 1206 | qla2x00_disable_intrs(struct qla_hw_data *ha) |
1193 | { | 1207 | { |
1194 | unsigned long flags = 0; | 1208 | unsigned long flags = 0; |
1195 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | 1209 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; |
@@ -1203,7 +1217,7 @@ qla2x00_disable_intrs(scsi_qla_host_t *ha) | |||
1203 | } | 1217 | } |
1204 | 1218 | ||
1205 | static void | 1219 | static void |
1206 | qla24xx_enable_intrs(scsi_qla_host_t *ha) | 1220 | qla24xx_enable_intrs(struct qla_hw_data *ha) |
1207 | { | 1221 | { |
1208 | unsigned long flags = 0; | 1222 | unsigned long flags = 0; |
1209 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 1223 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
@@ -1216,7 +1230,7 @@ qla24xx_enable_intrs(scsi_qla_host_t *ha) | |||
1216 | } | 1230 | } |
1217 | 1231 | ||
1218 | static void | 1232 | static void |
1219 | qla24xx_disable_intrs(scsi_qla_host_t *ha) | 1233 | qla24xx_disable_intrs(struct qla_hw_data *ha) |
1220 | { | 1234 | { |
1221 | unsigned long flags = 0; | 1235 | unsigned long flags = 0; |
1222 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 1236 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
@@ -1260,6 +1274,7 @@ static struct isp_operations qla2100_isp_ops = { | |||
1260 | .read_optrom = qla2x00_read_optrom_data, | 1274 | .read_optrom = qla2x00_read_optrom_data, |
1261 | .write_optrom = qla2x00_write_optrom_data, | 1275 | .write_optrom = qla2x00_write_optrom_data, |
1262 | .get_flash_version = qla2x00_get_flash_version, | 1276 | .get_flash_version = qla2x00_get_flash_version, |
1277 | .start_scsi = qla2x00_start_scsi, | ||
1263 | }; | 1278 | }; |
1264 | 1279 | ||
1265 | static struct isp_operations qla2300_isp_ops = { | 1280 | static struct isp_operations qla2300_isp_ops = { |
@@ -1294,6 +1309,7 @@ static struct isp_operations qla2300_isp_ops = { | |||
1294 | .read_optrom = qla2x00_read_optrom_data, | 1309 | .read_optrom = qla2x00_read_optrom_data, |
1295 | .write_optrom = qla2x00_write_optrom_data, | 1310 | .write_optrom = qla2x00_write_optrom_data, |
1296 | .get_flash_version = qla2x00_get_flash_version, | 1311 | .get_flash_version = qla2x00_get_flash_version, |
1312 | .start_scsi = qla2x00_start_scsi, | ||
1297 | }; | 1313 | }; |
1298 | 1314 | ||
1299 | static struct isp_operations qla24xx_isp_ops = { | 1315 | static struct isp_operations qla24xx_isp_ops = { |
@@ -1328,6 +1344,7 @@ static struct isp_operations qla24xx_isp_ops = { | |||
1328 | .read_optrom = qla24xx_read_optrom_data, | 1344 | .read_optrom = qla24xx_read_optrom_data, |
1329 | .write_optrom = qla24xx_write_optrom_data, | 1345 | .write_optrom = qla24xx_write_optrom_data, |
1330 | .get_flash_version = qla24xx_get_flash_version, | 1346 | .get_flash_version = qla24xx_get_flash_version, |
1347 | .start_scsi = qla24xx_start_scsi, | ||
1331 | }; | 1348 | }; |
1332 | 1349 | ||
1333 | static struct isp_operations qla25xx_isp_ops = { | 1350 | static struct isp_operations qla25xx_isp_ops = { |
@@ -1362,10 +1379,11 @@ static struct isp_operations qla25xx_isp_ops = { | |||
1362 | .read_optrom = qla25xx_read_optrom_data, | 1379 | .read_optrom = qla25xx_read_optrom_data, |
1363 | .write_optrom = qla24xx_write_optrom_data, | 1380 | .write_optrom = qla24xx_write_optrom_data, |
1364 | .get_flash_version = qla24xx_get_flash_version, | 1381 | .get_flash_version = qla24xx_get_flash_version, |
1382 | .start_scsi = qla24xx_start_scsi, | ||
1365 | }; | 1383 | }; |
1366 | 1384 | ||
1367 | static inline void | 1385 | static inline void |
1368 | qla2x00_set_isp_flags(scsi_qla_host_t *ha) | 1386 | qla2x00_set_isp_flags(struct qla_hw_data *ha) |
1369 | { | 1387 | { |
1370 | ha->device_type = DT_EXTENDED_IDS; | 1388 | ha->device_type = DT_EXTENDED_IDS; |
1371 | switch (ha->pdev->device) { | 1389 | switch (ha->pdev->device) { |
@@ -1447,7 +1465,7 @@ qla2x00_set_isp_flags(scsi_qla_host_t *ha) | |||
1447 | } | 1465 | } |
1448 | 1466 | ||
1449 | static int | 1467 | static int |
1450 | qla2x00_iospace_config(scsi_qla_host_t *ha) | 1468 | qla2x00_iospace_config(struct qla_hw_data *ha) |
1451 | { | 1469 | { |
1452 | resource_size_t pio; | 1470 | resource_size_t pio; |
1453 | 1471 | ||
@@ -1511,25 +1529,25 @@ iospace_error_exit: | |||
1511 | static void | 1529 | static void |
1512 | qla2xxx_scan_start(struct Scsi_Host *shost) | 1530 | qla2xxx_scan_start(struct Scsi_Host *shost) |
1513 | { | 1531 | { |
1514 | scsi_qla_host_t *ha = shost_priv(shost); | 1532 | scsi_qla_host_t *vha = shost_priv(shost); |
1515 | 1533 | ||
1516 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); | 1534 | set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); |
1517 | set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags); | 1535 | set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); |
1518 | set_bit(RSCN_UPDATE, &ha->dpc_flags); | 1536 | set_bit(RSCN_UPDATE, &vha->dpc_flags); |
1519 | set_bit(NPIV_CONFIG_NEEDED, &ha->dpc_flags); | 1537 | set_bit(NPIV_CONFIG_NEEDED, &vha->dpc_flags); |
1520 | } | 1538 | } |
1521 | 1539 | ||
1522 | static int | 1540 | static int |
1523 | qla2xxx_scan_finished(struct Scsi_Host *shost, unsigned long time) | 1541 | qla2xxx_scan_finished(struct Scsi_Host *shost, unsigned long time) |
1524 | { | 1542 | { |
1525 | scsi_qla_host_t *ha = shost_priv(shost); | 1543 | scsi_qla_host_t *vha = shost_priv(shost); |
1526 | 1544 | ||
1527 | if (!ha->host) | 1545 | if (!vha->host) |
1528 | return 1; | 1546 | return 1; |
1529 | if (time > ha->loop_reset_delay * HZ) | 1547 | if (time > vha->hw->loop_reset_delay * HZ) |
1530 | return 1; | 1548 | return 1; |
1531 | 1549 | ||
1532 | return atomic_read(&ha->loop_state) == LOOP_READY; | 1550 | return atomic_read(&vha->loop_state) == LOOP_READY; |
1533 | } | 1551 | } |
1534 | 1552 | ||
1535 | /* | 1553 | /* |
@@ -1540,11 +1558,13 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1540 | { | 1558 | { |
1541 | int ret = -ENODEV; | 1559 | int ret = -ENODEV; |
1542 | struct Scsi_Host *host; | 1560 | struct Scsi_Host *host; |
1543 | scsi_qla_host_t *ha; | 1561 | scsi_qla_host_t *base_vha = NULL; |
1562 | struct qla_hw_data *ha; | ||
1544 | char pci_info[30]; | 1563 | char pci_info[30]; |
1545 | char fw_str[30]; | 1564 | char fw_str[30]; |
1546 | struct scsi_host_template *sht; | 1565 | struct scsi_host_template *sht; |
1547 | int bars, mem_only = 0; | 1566 | int bars, mem_only, max_id = 0; |
1567 | uint16_t req_length = 0, rsp_length = 0; | ||
1548 | 1568 | ||
1549 | bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO); | 1569 | bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO); |
1550 | sht = &qla2x00_driver_template; | 1570 | sht = &qla2x00_driver_template; |
@@ -1570,33 +1590,24 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1570 | /* This may fail but that's ok */ | 1590 | /* This may fail but that's ok */ |
1571 | pci_enable_pcie_error_reporting(pdev); | 1591 | pci_enable_pcie_error_reporting(pdev); |
1572 | 1592 | ||
1573 | host = scsi_host_alloc(sht, sizeof(scsi_qla_host_t)); | 1593 | ha = kzalloc(sizeof(struct qla_hw_data), GFP_KERNEL); |
1574 | if (host == NULL) { | 1594 | if (!ha) { |
1575 | printk(KERN_WARNING | 1595 | DEBUG(printk("Unable to allocate memory for ha\n")); |
1576 | "qla2xxx: Couldn't allocate host from scsi layer!\n"); | 1596 | goto probe_out; |
1577 | goto probe_disable_device; | ||
1578 | } | 1597 | } |
1598 | ha->pdev = pdev; | ||
1579 | 1599 | ||
1580 | /* Clear our data area */ | 1600 | /* Clear our data area */ |
1581 | ha = shost_priv(host); | ||
1582 | memset(ha, 0, sizeof(scsi_qla_host_t)); | ||
1583 | |||
1584 | ha->pdev = pdev; | ||
1585 | ha->host = host; | ||
1586 | ha->host_no = host->host_no; | ||
1587 | sprintf(ha->host_str, "%s_%ld", QLA2XXX_DRIVER_NAME, ha->host_no); | ||
1588 | ha->parent = NULL; | ||
1589 | ha->bars = bars; | 1601 | ha->bars = bars; |
1590 | ha->mem_only = mem_only; | 1602 | ha->mem_only = mem_only; |
1591 | spin_lock_init(&ha->hardware_lock); | 1603 | spin_lock_init(&ha->hardware_lock); |
1592 | 1604 | ||
1593 | /* Set ISP-type information. */ | 1605 | /* Set ISP-type information. */ |
1594 | qla2x00_set_isp_flags(ha); | 1606 | qla2x00_set_isp_flags(ha); |
1595 | |||
1596 | /* Configure PCI I/O space */ | 1607 | /* Configure PCI I/O space */ |
1597 | ret = qla2x00_iospace_config(ha); | 1608 | ret = qla2x00_iospace_config(ha); |
1598 | if (ret) | 1609 | if (ret) |
1599 | goto probe_failed; | 1610 | goto probe_hw_failed; |
1600 | 1611 | ||
1601 | qla_printk(KERN_INFO, ha, | 1612 | qla_printk(KERN_INFO, ha, |
1602 | "Found an ISP%04X, irq %d, iobase 0x%p\n", pdev->device, pdev->irq, | 1613 | "Found an ISP%04X, irq %d, iobase 0x%p\n", pdev->device, pdev->irq, |
@@ -1604,105 +1615,128 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1604 | 1615 | ||
1605 | ha->prev_topology = 0; | 1616 | ha->prev_topology = 0; |
1606 | ha->init_cb_size = sizeof(init_cb_t); | 1617 | ha->init_cb_size = sizeof(init_cb_t); |
1607 | ha->mgmt_svr_loop_id = MANAGEMENT_SERVER + ha->vp_idx; | ||
1608 | ha->link_data_rate = PORT_SPEED_UNKNOWN; | 1618 | ha->link_data_rate = PORT_SPEED_UNKNOWN; |
1609 | ha->optrom_size = OPTROM_SIZE_2300; | 1619 | ha->optrom_size = OPTROM_SIZE_2300; |
1610 | 1620 | ||
1611 | ha->max_q_depth = MAX_Q_DEPTH; | ||
1612 | if (ql2xmaxqdepth != 0 && ql2xmaxqdepth <= 0xffffU) | ||
1613 | ha->max_q_depth = ql2xmaxqdepth; | ||
1614 | |||
1615 | /* Assign ISP specific operations. */ | 1621 | /* Assign ISP specific operations. */ |
1622 | max_id = MAX_TARGETS_2200; | ||
1616 | if (IS_QLA2100(ha)) { | 1623 | if (IS_QLA2100(ha)) { |
1617 | host->max_id = MAX_TARGETS_2100; | 1624 | max_id = MAX_TARGETS_2100; |
1618 | ha->mbx_count = MAILBOX_REGISTER_COUNT_2100; | 1625 | ha->mbx_count = MAILBOX_REGISTER_COUNT_2100; |
1619 | ha->request_q_length = REQUEST_ENTRY_CNT_2100; | 1626 | req_length = REQUEST_ENTRY_CNT_2100; |
1620 | ha->response_q_length = RESPONSE_ENTRY_CNT_2100; | 1627 | rsp_length = RESPONSE_ENTRY_CNT_2100; |
1621 | ha->last_loop_id = SNS_LAST_LOOP_ID_2100; | 1628 | ha->max_loop_id = SNS_LAST_LOOP_ID_2100; |
1622 | host->sg_tablesize = 32; | ||
1623 | ha->gid_list_info_size = 4; | 1629 | ha->gid_list_info_size = 4; |
1624 | ha->isp_ops = &qla2100_isp_ops; | 1630 | ha->isp_ops = &qla2100_isp_ops; |
1625 | } else if (IS_QLA2200(ha)) { | 1631 | } else if (IS_QLA2200(ha)) { |
1626 | host->max_id = MAX_TARGETS_2200; | ||
1627 | ha->mbx_count = MAILBOX_REGISTER_COUNT; | 1632 | ha->mbx_count = MAILBOX_REGISTER_COUNT; |
1628 | ha->request_q_length = REQUEST_ENTRY_CNT_2200; | 1633 | req_length = REQUEST_ENTRY_CNT_2200; |
1629 | ha->response_q_length = RESPONSE_ENTRY_CNT_2100; | 1634 | rsp_length = RESPONSE_ENTRY_CNT_2100; |
1630 | ha->last_loop_id = SNS_LAST_LOOP_ID_2100; | 1635 | ha->max_loop_id = SNS_LAST_LOOP_ID_2100; |
1631 | ha->gid_list_info_size = 4; | 1636 | ha->gid_list_info_size = 4; |
1632 | ha->isp_ops = &qla2100_isp_ops; | 1637 | ha->isp_ops = &qla2100_isp_ops; |
1633 | } else if (IS_QLA23XX(ha)) { | 1638 | } else if (IS_QLA23XX(ha)) { |
1634 | host->max_id = MAX_TARGETS_2200; | ||
1635 | ha->mbx_count = MAILBOX_REGISTER_COUNT; | 1639 | ha->mbx_count = MAILBOX_REGISTER_COUNT; |
1636 | ha->request_q_length = REQUEST_ENTRY_CNT_2200; | 1640 | req_length = REQUEST_ENTRY_CNT_2200; |
1637 | ha->response_q_length = RESPONSE_ENTRY_CNT_2300; | 1641 | rsp_length = RESPONSE_ENTRY_CNT_2300; |
1638 | ha->last_loop_id = SNS_LAST_LOOP_ID_2300; | 1642 | ha->max_loop_id = SNS_LAST_LOOP_ID_2300; |
1639 | ha->gid_list_info_size = 6; | 1643 | ha->gid_list_info_size = 6; |
1640 | if (IS_QLA2322(ha) || IS_QLA6322(ha)) | 1644 | if (IS_QLA2322(ha) || IS_QLA6322(ha)) |
1641 | ha->optrom_size = OPTROM_SIZE_2322; | 1645 | ha->optrom_size = OPTROM_SIZE_2322; |
1642 | ha->isp_ops = &qla2300_isp_ops; | 1646 | ha->isp_ops = &qla2300_isp_ops; |
1643 | } else if (IS_QLA24XX_TYPE(ha)) { | 1647 | } else if (IS_QLA24XX_TYPE(ha)) { |
1644 | host->max_id = MAX_TARGETS_2200; | ||
1645 | ha->mbx_count = MAILBOX_REGISTER_COUNT; | 1648 | ha->mbx_count = MAILBOX_REGISTER_COUNT; |
1646 | ha->request_q_length = REQUEST_ENTRY_CNT_24XX; | 1649 | req_length = REQUEST_ENTRY_CNT_24XX; |
1647 | ha->response_q_length = RESPONSE_ENTRY_CNT_2300; | 1650 | rsp_length = RESPONSE_ENTRY_CNT_2300; |
1648 | ha->last_loop_id = SNS_LAST_LOOP_ID_2300; | 1651 | ha->max_loop_id = SNS_LAST_LOOP_ID_2300; |
1649 | ha->init_cb_size = sizeof(struct mid_init_cb_24xx); | 1652 | ha->init_cb_size = sizeof(struct mid_init_cb_24xx); |
1650 | ha->mgmt_svr_loop_id = 10 + ha->vp_idx; | ||
1651 | ha->gid_list_info_size = 8; | 1653 | ha->gid_list_info_size = 8; |
1652 | ha->optrom_size = OPTROM_SIZE_24XX; | 1654 | ha->optrom_size = OPTROM_SIZE_24XX; |
1653 | ha->isp_ops = &qla24xx_isp_ops; | 1655 | ha->isp_ops = &qla24xx_isp_ops; |
1654 | } else if (IS_QLA25XX(ha)) { | 1656 | } else if (IS_QLA25XX(ha)) { |
1655 | host->max_id = MAX_TARGETS_2200; | ||
1656 | ha->mbx_count = MAILBOX_REGISTER_COUNT; | 1657 | ha->mbx_count = MAILBOX_REGISTER_COUNT; |
1657 | ha->request_q_length = REQUEST_ENTRY_CNT_24XX; | 1658 | req_length = REQUEST_ENTRY_CNT_24XX; |
1658 | ha->response_q_length = RESPONSE_ENTRY_CNT_2300; | 1659 | rsp_length = RESPONSE_ENTRY_CNT_2300; |
1659 | ha->last_loop_id = SNS_LAST_LOOP_ID_2300; | 1660 | ha->max_loop_id = SNS_LAST_LOOP_ID_2300; |
1660 | ha->init_cb_size = sizeof(struct mid_init_cb_24xx); | 1661 | ha->init_cb_size = sizeof(struct mid_init_cb_24xx); |
1661 | ha->mgmt_svr_loop_id = 10 + ha->vp_idx; | ||
1662 | ha->gid_list_info_size = 8; | 1662 | ha->gid_list_info_size = 8; |
1663 | ha->optrom_size = OPTROM_SIZE_25XX; | 1663 | ha->optrom_size = OPTROM_SIZE_25XX; |
1664 | ha->isp_ops = &qla25xx_isp_ops; | 1664 | ha->isp_ops = &qla25xx_isp_ops; |
1665 | } | 1665 | } |
1666 | host->can_queue = ha->request_q_length + 128; | ||
1667 | 1666 | ||
1668 | mutex_init(&ha->vport_lock); | 1667 | mutex_init(&ha->vport_lock); |
1669 | init_completion(&ha->mbx_cmd_comp); | 1668 | init_completion(&ha->mbx_cmd_comp); |
1670 | complete(&ha->mbx_cmd_comp); | 1669 | complete(&ha->mbx_cmd_comp); |
1671 | init_completion(&ha->mbx_intr_comp); | 1670 | init_completion(&ha->mbx_intr_comp); |
1672 | 1671 | ||
1673 | INIT_LIST_HEAD(&ha->list); | ||
1674 | INIT_LIST_HEAD(&ha->fcports); | ||
1675 | INIT_LIST_HEAD(&ha->vp_list); | ||
1676 | INIT_LIST_HEAD(&ha->work_list); | ||
1677 | |||
1678 | set_bit(0, (unsigned long *) ha->vp_idx_map); | 1672 | set_bit(0, (unsigned long *) ha->vp_idx_map); |
1679 | 1673 | ||
1680 | qla2x00_config_dma_addressing(ha); | 1674 | ret = qla2x00_mem_alloc(ha, req_length, rsp_length); |
1681 | if (qla2x00_mem_alloc(ha)) { | 1675 | if (!ret) { |
1682 | qla_printk(KERN_WARNING, ha, | 1676 | qla_printk(KERN_WARNING, ha, |
1683 | "[ERROR] Failed to allocate memory for adapter\n"); | 1677 | "[ERROR] Failed to allocate memory for adapter\n"); |
1684 | 1678 | ||
1679 | goto probe_hw_failed; | ||
1680 | } | ||
1681 | |||
1682 | ha->req->max_q_depth = MAX_Q_DEPTH; | ||
1683 | if (ql2xmaxqdepth != 0 && ql2xmaxqdepth <= 0xffffU) | ||
1684 | ha->req->max_q_depth = ql2xmaxqdepth; | ||
1685 | |||
1686 | base_vha = qla2x00_create_host(sht, ha); | ||
1687 | if (!base_vha) { | ||
1688 | qla_printk(KERN_WARNING, ha, | ||
1689 | "[ERROR] Failed to allocate memory for scsi_host\n"); | ||
1690 | |||
1685 | ret = -ENOMEM; | 1691 | ret = -ENOMEM; |
1686 | goto probe_failed; | 1692 | goto probe_hw_failed; |
1687 | } | 1693 | } |
1688 | 1694 | ||
1689 | if (qla2x00_initialize_adapter(ha)) { | 1695 | pci_set_drvdata(pdev, base_vha); |
1696 | |||
1697 | qla2x00_config_dma_addressing(base_vha); | ||
1698 | |||
1699 | host = base_vha->host; | ||
1700 | host->can_queue = ha->req->length + 128; | ||
1701 | if (IS_QLA2XXX_MIDTYPE(ha)) { | ||
1702 | base_vha->mgmt_svr_loop_id = 10 + base_vha->vp_idx; | ||
1703 | } else { | ||
1704 | base_vha->mgmt_svr_loop_id = MANAGEMENT_SERVER + | ||
1705 | base_vha->vp_idx; | ||
1706 | } | ||
1707 | if (IS_QLA2100(ha)) | ||
1708 | host->sg_tablesize = 32; | ||
1709 | host->max_id = max_id; | ||
1710 | host->this_id = 255; | ||
1711 | host->cmd_per_lun = 3; | ||
1712 | host->unique_id = host->host_no; | ||
1713 | host->max_cmd_len = MAX_CMDSZ; | ||
1714 | host->max_channel = MAX_BUSES - 1; | ||
1715 | host->max_lun = MAX_LUNS; | ||
1716 | host->transportt = qla2xxx_transport_template; | ||
1717 | |||
1718 | if (qla2x00_initialize_adapter(base_vha)) { | ||
1690 | qla_printk(KERN_WARNING, ha, | 1719 | qla_printk(KERN_WARNING, ha, |
1691 | "Failed to initialize adapter\n"); | 1720 | "Failed to initialize adapter\n"); |
1692 | 1721 | ||
1693 | DEBUG2(printk("scsi(%ld): Failed to initialize adapter - " | 1722 | DEBUG2(printk("scsi(%ld): Failed to initialize adapter - " |
1694 | "Adapter flags %x.\n", | 1723 | "Adapter flags %x.\n", |
1695 | ha->host_no, ha->device_flags)); | 1724 | base_vha->host_no, base_vha->device_flags)); |
1696 | 1725 | ||
1697 | ret = -ENODEV; | 1726 | ret = -ENODEV; |
1698 | goto probe_failed; | 1727 | goto probe_failed; |
1699 | } | 1728 | } |
1700 | 1729 | ||
1730 | /* Set up the irqs */ | ||
1731 | ret = qla2x00_request_irqs(ha); | ||
1732 | if (ret) | ||
1733 | goto probe_failed; | ||
1734 | |||
1701 | /* | 1735 | /* |
1702 | * Startup the kernel thread for this host adapter | 1736 | * Startup the kernel thread for this host adapter |
1703 | */ | 1737 | */ |
1704 | ha->dpc_thread = kthread_create(qla2x00_do_dpc, ha, | 1738 | ha->dpc_thread = kthread_create(qla2x00_do_dpc, ha, |
1705 | "%s_dpc", ha->host_str); | 1739 | "%s_dpc", base_vha->host_str); |
1706 | if (IS_ERR(ha->dpc_thread)) { | 1740 | if (IS_ERR(ha->dpc_thread)) { |
1707 | qla_printk(KERN_WARNING, ha, | 1741 | qla_printk(KERN_WARNING, ha, |
1708 | "Unable to start DPC thread!\n"); | 1742 | "Unable to start DPC thread!\n"); |
@@ -1710,28 +1744,17 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1710 | goto probe_failed; | 1744 | goto probe_failed; |
1711 | } | 1745 | } |
1712 | 1746 | ||
1713 | host->this_id = 255; | 1747 | list_add_tail(&base_vha->list, &ha->vp_list); |
1714 | host->cmd_per_lun = 3; | 1748 | base_vha->host->irq = ha->pdev->irq; |
1715 | host->unique_id = host->host_no; | ||
1716 | host->max_cmd_len = MAX_CMDSZ; | ||
1717 | host->max_channel = MAX_BUSES - 1; | ||
1718 | host->max_lun = MAX_LUNS; | ||
1719 | host->transportt = qla2xxx_transport_template; | ||
1720 | |||
1721 | ret = qla2x00_request_irqs(ha); | ||
1722 | if (ret) | ||
1723 | goto probe_failed; | ||
1724 | 1749 | ||
1725 | /* Initialized the timer */ | 1750 | /* Initialized the timer */ |
1726 | qla2x00_start_timer(ha, qla2x00_timer, WATCH_INTERVAL); | 1751 | qla2x00_start_timer(base_vha, qla2x00_timer, WATCH_INTERVAL); |
1727 | 1752 | ||
1728 | DEBUG2(printk("DEBUG: detect hba %ld at address = %p\n", | 1753 | DEBUG2(printk("DEBUG: detect hba %ld at address = %p\n", |
1729 | ha->host_no, ha)); | 1754 | base_vha->host_no, ha)); |
1730 | |||
1731 | pci_set_drvdata(pdev, ha); | ||
1732 | 1755 | ||
1733 | ha->flags.init_done = 1; | 1756 | base_vha->flags.init_done = 1; |
1734 | ha->flags.online = 1; | 1757 | base_vha->flags.online = 1; |
1735 | 1758 | ||
1736 | ret = scsi_add_host(host, &pdev->dev); | 1759 | ret = scsi_add_host(host, &pdev->dev); |
1737 | if (ret) | 1760 | if (ret) |
@@ -1741,76 +1764,94 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1741 | 1764 | ||
1742 | scsi_scan_host(host); | 1765 | scsi_scan_host(host); |
1743 | 1766 | ||
1744 | qla2x00_alloc_sysfs_attr(ha); | 1767 | qla2x00_alloc_sysfs_attr(base_vha); |
1745 | 1768 | ||
1746 | qla2x00_init_host_attr(ha); | 1769 | qla2x00_init_host_attr(base_vha); |
1747 | 1770 | ||
1748 | qla2x00_dfs_setup(ha); | 1771 | qla2x00_dfs_setup(base_vha); |
1749 | 1772 | ||
1750 | qla_printk(KERN_INFO, ha, "\n" | 1773 | qla_printk(KERN_INFO, ha, "\n" |
1751 | " QLogic Fibre Channel HBA Driver: %s\n" | 1774 | " QLogic Fibre Channel HBA Driver: %s\n" |
1752 | " QLogic %s - %s\n" | 1775 | " QLogic %s - %s\n" |
1753 | " ISP%04X: %s @ %s hdma%c, host#=%ld, fw=%s\n", | 1776 | " ISP%04X: %s @ %s hdma%c, host#=%ld, fw=%s\n", |
1754 | qla2x00_version_str, ha->model_number, | 1777 | qla2x00_version_str, ha->model_number, |
1755 | ha->model_desc ? ha->model_desc: "", pdev->device, | 1778 | ha->model_desc ? ha->model_desc : "", pdev->device, |
1756 | ha->isp_ops->pci_info_str(ha, pci_info), pci_name(pdev), | 1779 | ha->isp_ops->pci_info_str(base_vha, pci_info), pci_name(pdev), |
1757 | ha->flags.enable_64bit_addressing ? '+': '-', ha->host_no, | 1780 | ha->flags.enable_64bit_addressing ? '+' : '-', base_vha->host_no, |
1758 | ha->isp_ops->fw_version_str(ha, fw_str)); | 1781 | ha->isp_ops->fw_version_str(base_vha, fw_str)); |
1759 | 1782 | ||
1760 | return 0; | 1783 | return 0; |
1761 | 1784 | ||
1762 | probe_failed: | 1785 | probe_failed: |
1763 | qla2x00_free_device(ha); | 1786 | qla2x00_free_device(base_vha); |
1764 | 1787 | ||
1765 | scsi_host_put(host); | 1788 | scsi_host_put(base_vha->host); |
1766 | 1789 | ||
1767 | probe_disable_device: | 1790 | probe_hw_failed: |
1768 | pci_disable_device(pdev); | 1791 | if (ha->iobase) |
1792 | iounmap(ha->iobase); | ||
1793 | |||
1794 | pci_release_selected_regions(ha->pdev, ha->bars); | ||
1795 | kfree(ha); | ||
1796 | ha = NULL; | ||
1769 | 1797 | ||
1770 | probe_out: | 1798 | probe_out: |
1799 | pci_disable_device(pdev); | ||
1771 | return ret; | 1800 | return ret; |
1772 | } | 1801 | } |
1773 | 1802 | ||
1774 | static void | 1803 | static void |
1775 | qla2x00_remove_one(struct pci_dev *pdev) | 1804 | qla2x00_remove_one(struct pci_dev *pdev) |
1776 | { | 1805 | { |
1777 | scsi_qla_host_t *ha, *vha, *temp; | 1806 | scsi_qla_host_t *base_vha, *vha, *temp; |
1807 | struct qla_hw_data *ha; | ||
1808 | |||
1809 | base_vha = pci_get_drvdata(pdev); | ||
1810 | ha = base_vha->hw; | ||
1811 | |||
1812 | list_for_each_entry_safe(vha, temp, &ha->vp_list, list) { | ||
1813 | if (vha && vha->fc_vport) | ||
1814 | fc_vport_terminate(vha->fc_vport); | ||
1815 | } | ||
1778 | 1816 | ||
1779 | ha = pci_get_drvdata(pdev); | 1817 | set_bit(UNLOADING, &base_vha->dpc_flags); |
1780 | 1818 | ||
1781 | list_for_each_entry_safe(vha, temp, &ha->vp_list, vp_list) | 1819 | qla2x00_dfs_remove(base_vha); |
1782 | fc_vport_terminate(vha->fc_vport); | ||
1783 | 1820 | ||
1784 | set_bit(UNLOADING, &ha->dpc_flags); | 1821 | qla84xx_put_chip(base_vha); |
1785 | 1822 | ||
1786 | qla2x00_dfs_remove(ha); | 1823 | qla2x00_free_sysfs_attr(base_vha); |
1787 | 1824 | ||
1788 | qla84xx_put_chip(ha); | 1825 | fc_remove_host(base_vha->host); |
1789 | 1826 | ||
1790 | qla2x00_free_sysfs_attr(ha); | 1827 | scsi_remove_host(base_vha->host); |
1791 | 1828 | ||
1792 | fc_remove_host(ha->host); | 1829 | qla2x00_free_device(base_vha); |
1793 | 1830 | ||
1794 | scsi_remove_host(ha->host); | 1831 | scsi_host_put(base_vha->host); |
1795 | 1832 | ||
1796 | qla2x00_free_device(ha); | 1833 | if (ha->iobase) |
1834 | iounmap(ha->iobase); | ||
1797 | 1835 | ||
1798 | scsi_host_put(ha->host); | 1836 | pci_release_selected_regions(ha->pdev, ha->bars); |
1837 | kfree(ha); | ||
1838 | ha = NULL; | ||
1799 | 1839 | ||
1800 | pci_disable_device(pdev); | 1840 | pci_disable_device(pdev); |
1801 | pci_set_drvdata(pdev, NULL); | 1841 | pci_set_drvdata(pdev, NULL); |
1802 | } | 1842 | } |
1803 | 1843 | ||
1804 | static void | 1844 | static void |
1805 | qla2x00_free_device(scsi_qla_host_t *ha) | 1845 | qla2x00_free_device(scsi_qla_host_t *vha) |
1806 | { | 1846 | { |
1807 | qla2x00_abort_all_cmds(ha, DID_NO_CONNECT << 16); | 1847 | struct qla_hw_data *ha = vha->hw; |
1848 | qla2x00_abort_all_cmds(vha, DID_NO_CONNECT << 16); | ||
1808 | 1849 | ||
1809 | /* Disable timer */ | 1850 | /* Disable timer */ |
1810 | if (ha->timer_active) | 1851 | if (vha->timer_active) |
1811 | qla2x00_stop_timer(ha); | 1852 | qla2x00_stop_timer(vha); |
1812 | 1853 | ||
1813 | ha->flags.online = 0; | 1854 | vha->flags.online = 0; |
1814 | 1855 | ||
1815 | /* Kill the kernel thread for this host */ | 1856 | /* Kill the kernel thread for this host */ |
1816 | if (ha->dpc_thread) { | 1857 | if (ha->dpc_thread) { |
@@ -1825,45 +1866,39 @@ qla2x00_free_device(scsi_qla_host_t *ha) | |||
1825 | } | 1866 | } |
1826 | 1867 | ||
1827 | if (ha->flags.fce_enabled) | 1868 | if (ha->flags.fce_enabled) |
1828 | qla2x00_disable_fce_trace(ha, NULL, NULL); | 1869 | qla2x00_disable_fce_trace(vha, NULL, NULL); |
1829 | 1870 | ||
1830 | if (ha->eft) | 1871 | if (ha->eft) |
1831 | qla2x00_disable_eft_trace(ha); | 1872 | qla2x00_disable_eft_trace(vha); |
1832 | 1873 | ||
1833 | /* Stop currently executing firmware. */ | 1874 | /* Stop currently executing firmware. */ |
1834 | qla2x00_try_to_stop_firmware(ha); | 1875 | qla2x00_try_to_stop_firmware(vha); |
1835 | 1876 | ||
1836 | /* turn-off interrupts on the card */ | 1877 | /* turn-off interrupts on the card */ |
1837 | if (ha->interrupts_on) | 1878 | if (ha->interrupts_on) |
1838 | ha->isp_ops->disable_intrs(ha); | 1879 | ha->isp_ops->disable_intrs(ha); |
1839 | 1880 | ||
1840 | qla2x00_mem_free(ha); | 1881 | qla2x00_free_irqs(vha); |
1841 | |||
1842 | qla2x00_free_irqs(ha); | ||
1843 | 1882 | ||
1844 | /* release io space registers */ | 1883 | qla2x00_mem_free(ha); |
1845 | if (ha->iobase) | ||
1846 | iounmap(ha->iobase); | ||
1847 | pci_release_selected_regions(ha->pdev, ha->bars); | ||
1848 | } | 1884 | } |
1849 | 1885 | ||
1850 | static inline void | 1886 | static inline void |
1851 | qla2x00_schedule_rport_del(struct scsi_qla_host *ha, fc_port_t *fcport, | 1887 | qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport, |
1852 | int defer) | 1888 | int defer) |
1853 | { | 1889 | { |
1854 | struct fc_rport *rport; | 1890 | struct fc_rport *rport; |
1855 | scsi_qla_host_t *pha = to_qla_parent(ha); | ||
1856 | 1891 | ||
1857 | if (!fcport->rport) | 1892 | if (!fcport->rport) |
1858 | return; | 1893 | return; |
1859 | 1894 | ||
1860 | rport = fcport->rport; | 1895 | rport = fcport->rport; |
1861 | if (defer) { | 1896 | if (defer) { |
1862 | spin_lock_irq(ha->host->host_lock); | 1897 | spin_lock_irq(vha->host->host_lock); |
1863 | fcport->drport = rport; | 1898 | fcport->drport = rport; |
1864 | spin_unlock_irq(ha->host->host_lock); | 1899 | spin_unlock_irq(vha->host->host_lock); |
1865 | set_bit(FCPORT_UPDATE_NEEDED, &pha->dpc_flags); | 1900 | set_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags); |
1866 | qla2xxx_wake_dpc(pha); | 1901 | qla2xxx_wake_dpc(vha); |
1867 | } else | 1902 | } else |
1868 | fc_remote_port_delete(rport); | 1903 | fc_remote_port_delete(rport); |
1869 | } | 1904 | } |
@@ -1877,13 +1912,14 @@ qla2x00_schedule_rport_del(struct scsi_qla_host *ha, fc_port_t *fcport, | |||
1877 | * | 1912 | * |
1878 | * Context: | 1913 | * Context: |
1879 | */ | 1914 | */ |
1880 | void qla2x00_mark_device_lost(scsi_qla_host_t *ha, fc_port_t *fcport, | 1915 | void qla2x00_mark_device_lost(scsi_qla_host_t *vha, fc_port_t *fcport, |
1881 | int do_login, int defer) | 1916 | int do_login, int defer) |
1882 | { | 1917 | { |
1883 | if (atomic_read(&fcport->state) == FCS_ONLINE && | 1918 | if (atomic_read(&fcport->state) == FCS_ONLINE && |
1884 | ha->vp_idx == fcport->vp_idx) | 1919 | vha->vp_idx == fcport->vp_idx) { |
1885 | qla2x00_schedule_rport_del(ha, fcport, defer); | 1920 | atomic_set(&fcport->state, FCS_DEVICE_LOST); |
1886 | 1921 | qla2x00_schedule_rport_del(vha, fcport, defer); | |
1922 | } | ||
1887 | /* | 1923 | /* |
1888 | * We may need to retry the login, so don't change the state of the | 1924 | * We may need to retry the login, so don't change the state of the |
1889 | * port but do the retries. | 1925 | * port but do the retries. |
@@ -1895,13 +1931,13 @@ void qla2x00_mark_device_lost(scsi_qla_host_t *ha, fc_port_t *fcport, | |||
1895 | return; | 1931 | return; |
1896 | 1932 | ||
1897 | if (fcport->login_retry == 0) { | 1933 | if (fcport->login_retry == 0) { |
1898 | fcport->login_retry = ha->login_retry_count; | 1934 | fcport->login_retry = vha->hw->login_retry_count; |
1899 | set_bit(RELOGIN_NEEDED, &ha->dpc_flags); | 1935 | set_bit(RELOGIN_NEEDED, &vha->dpc_flags); |
1900 | 1936 | ||
1901 | DEBUG(printk("scsi(%ld): Port login retry: " | 1937 | DEBUG(printk("scsi(%ld): Port login retry: " |
1902 | "%02x%02x%02x%02x%02x%02x%02x%02x, " | 1938 | "%02x%02x%02x%02x%02x%02x%02x%02x, " |
1903 | "id = 0x%04x retry cnt=%d\n", | 1939 | "id = 0x%04x retry cnt=%d\n", |
1904 | ha->host_no, | 1940 | vha->host_no, |
1905 | fcport->port_name[0], | 1941 | fcport->port_name[0], |
1906 | fcport->port_name[1], | 1942 | fcport->port_name[1], |
1907 | fcport->port_name[2], | 1943 | fcport->port_name[2], |
@@ -1929,13 +1965,12 @@ void qla2x00_mark_device_lost(scsi_qla_host_t *ha, fc_port_t *fcport, | |||
1929 | * Context: | 1965 | * Context: |
1930 | */ | 1966 | */ |
1931 | void | 1967 | void |
1932 | qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha, int defer) | 1968 | qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha, int defer) |
1933 | { | 1969 | { |
1934 | fc_port_t *fcport; | 1970 | fc_port_t *fcport; |
1935 | scsi_qla_host_t *pha = to_qla_parent(ha); | ||
1936 | 1971 | ||
1937 | list_for_each_entry(fcport, &pha->fcports, list) { | 1972 | list_for_each_entry(fcport, &vha->vp_fcports, list) { |
1938 | if (ha->vp_idx != fcport->vp_idx) | 1973 | if (vha->vp_idx != fcport->vp_idx) |
1939 | continue; | 1974 | continue; |
1940 | /* | 1975 | /* |
1941 | * No point in marking the device as lost, if the device is | 1976 | * No point in marking the device as lost, if the device is |
@@ -1943,9 +1978,11 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha, int defer) | |||
1943 | */ | 1978 | */ |
1944 | if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD) | 1979 | if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD) |
1945 | continue; | 1980 | continue; |
1946 | if (atomic_read(&fcport->state) == FCS_ONLINE) | 1981 | if (atomic_read(&fcport->state) == FCS_ONLINE) { |
1947 | qla2x00_schedule_rport_del(ha, fcport, defer); | 1982 | atomic_set(&fcport->state, FCS_DEVICE_LOST); |
1948 | atomic_set(&fcport->state, FCS_DEVICE_LOST); | 1983 | qla2x00_schedule_rport_del(vha, fcport, defer); |
1984 | } else | ||
1985 | atomic_set(&fcport->state, FCS_DEVICE_LOST); | ||
1949 | } | 1986 | } |
1950 | } | 1987 | } |
1951 | 1988 | ||
@@ -1958,105 +1995,139 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha, int defer) | |||
1958 | * !0 = failure. | 1995 | * !0 = failure. |
1959 | */ | 1996 | */ |
1960 | static int | 1997 | static int |
1961 | qla2x00_mem_alloc(scsi_qla_host_t *ha) | 1998 | qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len) |
1962 | { | 1999 | { |
1963 | char name[16]; | 2000 | char name[16]; |
2001 | struct req_que *req = NULL; | ||
2002 | struct rsp_que *rsp = NULL; | ||
1964 | 2003 | ||
1965 | ha->request_ring = dma_alloc_coherent(&ha->pdev->dev, | 2004 | ha->init_cb_size = sizeof(init_cb_t); |
1966 | (ha->request_q_length + 1) * sizeof(request_t), &ha->request_dma, | 2005 | if (IS_QLA2XXX_MIDTYPE(ha)) |
1967 | GFP_KERNEL); | 2006 | ha->init_cb_size = sizeof(struct mid_init_cb_24xx); |
1968 | if (!ha->request_ring) | ||
1969 | goto fail; | ||
1970 | |||
1971 | ha->response_ring = dma_alloc_coherent(&ha->pdev->dev, | ||
1972 | (ha->response_q_length + 1) * sizeof(response_t), | ||
1973 | &ha->response_dma, GFP_KERNEL); | ||
1974 | if (!ha->response_ring) | ||
1975 | goto fail_free_request_ring; | ||
1976 | |||
1977 | ha->gid_list = dma_alloc_coherent(&ha->pdev->dev, GID_LIST_SIZE, | ||
1978 | &ha->gid_list_dma, GFP_KERNEL); | ||
1979 | if (!ha->gid_list) | ||
1980 | goto fail_free_response_ring; | ||
1981 | 2007 | ||
1982 | ha->init_cb = dma_alloc_coherent(&ha->pdev->dev, ha->init_cb_size, | 2008 | ha->init_cb = dma_alloc_coherent(&ha->pdev->dev, ha->init_cb_size, |
1983 | &ha->init_cb_dma, GFP_KERNEL); | 2009 | &ha->init_cb_dma, GFP_KERNEL); |
1984 | if (!ha->init_cb) | 2010 | if (!ha->init_cb) |
1985 | goto fail_free_gid_list; | 2011 | goto fail; |
1986 | 2012 | ||
1987 | snprintf(name, sizeof(name), "%s_%ld", QLA2XXX_DRIVER_NAME, | 2013 | ha->gid_list = dma_alloc_coherent(&ha->pdev->dev, GID_LIST_SIZE, |
1988 | ha->host_no); | 2014 | &ha->gid_list_dma, GFP_KERNEL); |
1989 | ha->s_dma_pool = dma_pool_create(name, &ha->pdev->dev, | 2015 | if (!ha->gid_list) |
1990 | DMA_POOL_SIZE, 8, 0); | ||
1991 | if (!ha->s_dma_pool) | ||
1992 | goto fail_free_init_cb; | 2016 | goto fail_free_init_cb; |
1993 | 2017 | ||
1994 | ha->srb_mempool = mempool_create_slab_pool(SRB_MIN_REQ, srb_cachep); | 2018 | ha->srb_mempool = mempool_create_slab_pool(SRB_MIN_REQ, srb_cachep); |
1995 | if (!ha->srb_mempool) | 2019 | if (!ha->srb_mempool) |
1996 | goto fail_free_s_dma_pool; | 2020 | goto fail_free_gid_list; |
1997 | 2021 | ||
1998 | /* Get memory for cached NVRAM */ | 2022 | /* Get memory for cached NVRAM */ |
1999 | ha->nvram = kzalloc(MAX_NVRAM_SIZE, GFP_KERNEL); | 2023 | ha->nvram = kzalloc(MAX_NVRAM_SIZE, GFP_KERNEL); |
2000 | if (!ha->nvram) | 2024 | if (!ha->nvram) |
2001 | goto fail_free_srb_mempool; | 2025 | goto fail_free_srb_mempool; |
2002 | 2026 | ||
2027 | snprintf(name, sizeof(name), "%s_%d", QLA2XXX_DRIVER_NAME, | ||
2028 | ha->pdev->device); | ||
2029 | ha->s_dma_pool = dma_pool_create(name, &ha->pdev->dev, | ||
2030 | DMA_POOL_SIZE, 8, 0); | ||
2031 | if (!ha->s_dma_pool) | ||
2032 | goto fail_free_nvram; | ||
2033 | |||
2003 | /* Allocate memory for SNS commands */ | 2034 | /* Allocate memory for SNS commands */ |
2004 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) { | 2035 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) { |
2005 | /* Get consistent memory allocated for SNS commands */ | 2036 | /* Get consistent memory allocated for SNS commands */ |
2006 | ha->sns_cmd = dma_alloc_coherent(&ha->pdev->dev, | 2037 | ha->sns_cmd = dma_alloc_coherent(&ha->pdev->dev, |
2007 | sizeof(struct sns_cmd_pkt), &ha->sns_cmd_dma, GFP_KERNEL); | 2038 | sizeof(struct sns_cmd_pkt), &ha->sns_cmd_dma, GFP_KERNEL); |
2008 | if (!ha->sns_cmd) | 2039 | if (!ha->sns_cmd) |
2009 | goto fail_free_nvram; | 2040 | goto fail_dma_pool; |
2010 | } else { | 2041 | } else { |
2011 | /* Get consistent memory allocated for MS IOCB */ | 2042 | /* Get consistent memory allocated for MS IOCB */ |
2012 | ha->ms_iocb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, | 2043 | ha->ms_iocb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, |
2013 | &ha->ms_iocb_dma); | 2044 | &ha->ms_iocb_dma); |
2014 | if (!ha->ms_iocb) | 2045 | if (!ha->ms_iocb) |
2015 | goto fail_free_nvram; | 2046 | goto fail_dma_pool; |
2016 | 2047 | /* Get consistent memory allocated for CT SNS commands */ | |
2017 | /* Get consistent memory allocated for CT SNS commands */ | ||
2018 | ha->ct_sns = dma_alloc_coherent(&ha->pdev->dev, | 2048 | ha->ct_sns = dma_alloc_coherent(&ha->pdev->dev, |
2019 | sizeof(struct ct_sns_pkt), &ha->ct_sns_dma, GFP_KERNEL); | 2049 | sizeof(struct ct_sns_pkt), &ha->ct_sns_dma, GFP_KERNEL); |
2020 | if (!ha->ct_sns) | 2050 | if (!ha->ct_sns) |
2021 | goto fail_free_ms_iocb; | 2051 | goto fail_free_ms_iocb; |
2022 | } | 2052 | } |
2023 | 2053 | ||
2024 | return 0; | 2054 | /* Allocate memory for request ring */ |
2055 | req = kzalloc(sizeof(struct req_que), GFP_KERNEL); | ||
2056 | if (!req) { | ||
2057 | DEBUG(printk("Unable to allocate memory for req\n")); | ||
2058 | goto fail_req; | ||
2059 | } | ||
2060 | ha->req = req; | ||
2061 | req->length = req_len; | ||
2062 | req->ring = dma_alloc_coherent(&ha->pdev->dev, | ||
2063 | (req->length + 1) * sizeof(request_t), | ||
2064 | &req->dma, GFP_KERNEL); | ||
2065 | if (!req->ring) { | ||
2066 | DEBUG(printk("Unable to allocate memory for req_ring\n")); | ||
2067 | goto fail_req_ring; | ||
2068 | } | ||
2069 | /* Allocate memory for response ring */ | ||
2070 | rsp = kzalloc(sizeof(struct rsp_que), GFP_KERNEL); | ||
2071 | if (!rsp) { | ||
2072 | DEBUG(printk("Unable to allocate memory for rsp\n")); | ||
2073 | goto fail_rsp; | ||
2074 | } | ||
2075 | ha->rsp = rsp; | ||
2076 | rsp->hw = ha; | ||
2077 | rsp->length = rsp_len; | ||
2078 | |||
2079 | rsp->ring = dma_alloc_coherent(&ha->pdev->dev, | ||
2080 | (rsp->length + 1) * sizeof(response_t), | ||
2081 | &rsp->dma, GFP_KERNEL); | ||
2082 | if (!rsp->ring) { | ||
2083 | DEBUG(printk("Unable to allocate memory for rsp_ring\n")); | ||
2084 | goto fail_rsp_ring; | ||
2085 | } | ||
2025 | 2086 | ||
2087 | INIT_LIST_HEAD(&ha->vp_list); | ||
2088 | return 1; | ||
2089 | |||
2090 | fail_rsp_ring: | ||
2091 | kfree(rsp); | ||
2092 | ha->rsp = NULL; | ||
2093 | fail_rsp: | ||
2094 | dma_free_coherent(&ha->pdev->dev, (req->length + 1) * | ||
2095 | sizeof(request_t), req->ring, req->dma); | ||
2096 | req->ring = NULL; | ||
2097 | req->dma = 0; | ||
2098 | fail_req_ring: | ||
2099 | kfree(req); | ||
2100 | ha->req = NULL; | ||
2101 | fail_req: | ||
2102 | dma_free_coherent(&ha->pdev->dev, sizeof(struct ct_sns_pkt), | ||
2103 | ha->ct_sns, ha->ct_sns_dma); | ||
2104 | ha->ct_sns = NULL; | ||
2105 | ha->ct_sns_dma = 0; | ||
2026 | fail_free_ms_iocb: | 2106 | fail_free_ms_iocb: |
2027 | dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma); | 2107 | dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma); |
2028 | ha->ms_iocb = NULL; | 2108 | ha->ms_iocb = NULL; |
2029 | ha->ms_iocb_dma = 0; | 2109 | ha->ms_iocb_dma = 0; |
2110 | fail_dma_pool: | ||
2111 | dma_pool_destroy(ha->s_dma_pool); | ||
2112 | ha->s_dma_pool = NULL; | ||
2030 | fail_free_nvram: | 2113 | fail_free_nvram: |
2031 | kfree(ha->nvram); | 2114 | kfree(ha->nvram); |
2032 | ha->nvram = NULL; | 2115 | ha->nvram = NULL; |
2033 | fail_free_srb_mempool: | 2116 | fail_free_srb_mempool: |
2034 | mempool_destroy(ha->srb_mempool); | 2117 | mempool_destroy(ha->srb_mempool); |
2035 | ha->srb_mempool = NULL; | 2118 | ha->srb_mempool = NULL; |
2036 | fail_free_s_dma_pool: | ||
2037 | dma_pool_destroy(ha->s_dma_pool); | ||
2038 | ha->s_dma_pool = NULL; | ||
2039 | fail_free_init_cb: | ||
2040 | dma_free_coherent(&ha->pdev->dev, ha->init_cb_size, ha->init_cb, | ||
2041 | ha->init_cb_dma); | ||
2042 | ha->init_cb = NULL; | ||
2043 | ha->init_cb_dma = 0; | ||
2044 | fail_free_gid_list: | 2119 | fail_free_gid_list: |
2045 | dma_free_coherent(&ha->pdev->dev, GID_LIST_SIZE, ha->gid_list, | 2120 | dma_free_coherent(&ha->pdev->dev, GID_LIST_SIZE, ha->gid_list, |
2046 | ha->gid_list_dma); | 2121 | ha->gid_list_dma); |
2047 | ha->gid_list = NULL; | 2122 | ha->gid_list = NULL; |
2048 | ha->gid_list_dma = 0; | 2123 | ha->gid_list_dma = 0; |
2049 | fail_free_response_ring: | 2124 | fail_free_init_cb: |
2050 | dma_free_coherent(&ha->pdev->dev, (ha->response_q_length + 1) * | 2125 | dma_free_coherent(&ha->pdev->dev, ha->init_cb_size, ha->init_cb, |
2051 | sizeof(response_t), ha->response_ring, ha->response_dma); | 2126 | ha->init_cb_dma); |
2052 | ha->response_ring = NULL; | 2127 | ha->init_cb = NULL; |
2053 | ha->response_dma = 0; | 2128 | ha->init_cb_dma = 0; |
2054 | fail_free_request_ring: | ||
2055 | dma_free_coherent(&ha->pdev->dev, (ha->request_q_length + 1) * | ||
2056 | sizeof(request_t), ha->request_ring, ha->request_dma); | ||
2057 | ha->request_ring = NULL; | ||
2058 | ha->request_dma = 0; | ||
2059 | fail: | 2129 | fail: |
2130 | DEBUG(printk("%s: Memory allocation failure\n", __func__)); | ||
2060 | return -ENOMEM; | 2131 | return -ENOMEM; |
2061 | } | 2132 | } |
2062 | 2133 | ||
@@ -2068,32 +2139,32 @@ fail: | |||
2068 | * ha = adapter block pointer. | 2139 | * ha = adapter block pointer. |
2069 | */ | 2140 | */ |
2070 | static void | 2141 | static void |
2071 | qla2x00_mem_free(scsi_qla_host_t *ha) | 2142 | qla2x00_mem_free(struct qla_hw_data *ha) |
2072 | { | 2143 | { |
2073 | struct list_head *fcpl, *fcptemp; | 2144 | struct req_que *req = ha->req; |
2074 | fc_port_t *fcport; | 2145 | struct rsp_que *rsp = ha->rsp; |
2075 | 2146 | ||
2076 | if (ha->srb_mempool) | 2147 | if (ha->srb_mempool) |
2077 | mempool_destroy(ha->srb_mempool); | 2148 | mempool_destroy(ha->srb_mempool); |
2078 | 2149 | ||
2079 | if (ha->fce) | 2150 | if (ha->fce) |
2080 | dma_free_coherent(&ha->pdev->dev, FCE_SIZE, ha->fce, | 2151 | dma_free_coherent(&ha->pdev->dev, FCE_SIZE, ha->fce, |
2081 | ha->fce_dma); | 2152 | ha->fce_dma); |
2082 | 2153 | ||
2083 | if (ha->fw_dump) { | 2154 | if (ha->fw_dump) { |
2084 | if (ha->eft) | 2155 | if (ha->eft) |
2085 | dma_free_coherent(&ha->pdev->dev, | 2156 | dma_free_coherent(&ha->pdev->dev, |
2086 | ntohl(ha->fw_dump->eft_size), ha->eft, ha->eft_dma); | 2157 | ntohl(ha->fw_dump->eft_size), ha->eft, ha->eft_dma); |
2087 | vfree(ha->fw_dump); | 2158 | vfree(ha->fw_dump); |
2088 | } | 2159 | } |
2089 | 2160 | ||
2090 | if (ha->sns_cmd) | 2161 | if (ha->sns_cmd) |
2091 | dma_free_coherent(&ha->pdev->dev, sizeof(struct sns_cmd_pkt), | 2162 | dma_free_coherent(&ha->pdev->dev, sizeof(struct sns_cmd_pkt), |
2092 | ha->sns_cmd, ha->sns_cmd_dma); | 2163 | ha->sns_cmd, ha->sns_cmd_dma); |
2093 | 2164 | ||
2094 | if (ha->ct_sns) | 2165 | if (ha->ct_sns) |
2095 | dma_free_coherent(&ha->pdev->dev, sizeof(struct ct_sns_pkt), | 2166 | dma_free_coherent(&ha->pdev->dev, sizeof(struct ct_sns_pkt), |
2096 | ha->ct_sns, ha->ct_sns_dma); | 2167 | ha->ct_sns, ha->ct_sns_dma); |
2097 | 2168 | ||
2098 | if (ha->sfp_data) | 2169 | if (ha->sfp_data) |
2099 | dma_pool_free(ha->s_dma_pool, ha->sfp_data, ha->sfp_data_dma); | 2170 | dma_pool_free(ha->s_dma_pool, ha->sfp_data, ha->sfp_data_dma); |
@@ -2104,23 +2175,17 @@ qla2x00_mem_free(scsi_qla_host_t *ha) | |||
2104 | if (ha->s_dma_pool) | 2175 | if (ha->s_dma_pool) |
2105 | dma_pool_destroy(ha->s_dma_pool); | 2176 | dma_pool_destroy(ha->s_dma_pool); |
2106 | 2177 | ||
2107 | if (ha->init_cb) | ||
2108 | dma_free_coherent(&ha->pdev->dev, ha->init_cb_size, | ||
2109 | ha->init_cb, ha->init_cb_dma); | ||
2110 | 2178 | ||
2111 | if (ha->gid_list) | 2179 | if (ha->gid_list) |
2112 | dma_free_coherent(&ha->pdev->dev, GID_LIST_SIZE, ha->gid_list, | 2180 | dma_free_coherent(&ha->pdev->dev, GID_LIST_SIZE, ha->gid_list, |
2113 | ha->gid_list_dma); | 2181 | ha->gid_list_dma); |
2114 | 2182 | ||
2115 | if (ha->response_ring) | ||
2116 | dma_free_coherent(&ha->pdev->dev, | ||
2117 | (ha->response_q_length + 1) * sizeof(response_t), | ||
2118 | ha->response_ring, ha->response_dma); | ||
2119 | 2183 | ||
2120 | if (ha->request_ring) | 2184 | if (ha->init_cb) |
2121 | dma_free_coherent(&ha->pdev->dev, | 2185 | dma_free_coherent(&ha->pdev->dev, ha->init_cb_size, |
2122 | (ha->request_q_length + 1) * sizeof(request_t), | 2186 | ha->init_cb, ha->init_cb_dma); |
2123 | ha->request_ring, ha->request_dma); | 2187 | vfree(ha->optrom_buffer); |
2188 | kfree(ha->nvram); | ||
2124 | 2189 | ||
2125 | ha->srb_mempool = NULL; | 2190 | ha->srb_mempool = NULL; |
2126 | ha->eft = NULL; | 2191 | ha->eft = NULL; |
@@ -2139,30 +2204,65 @@ qla2x00_mem_free(scsi_qla_host_t *ha) | |||
2139 | ha->gid_list = NULL; | 2204 | ha->gid_list = NULL; |
2140 | ha->gid_list_dma = 0; | 2205 | ha->gid_list_dma = 0; |
2141 | 2206 | ||
2142 | ha->response_ring = NULL; | 2207 | ha->fw_dump = NULL; |
2143 | ha->response_dma = 0; | 2208 | ha->fw_dumped = 0; |
2144 | ha->request_ring = NULL; | 2209 | ha->fw_dump_reading = 0; |
2145 | ha->request_dma = 0; | 2210 | |
2211 | if (rsp) { | ||
2212 | if (rsp->ring) | ||
2213 | dma_free_coherent(&ha->pdev->dev, | ||
2214 | (rsp->length + 1) * sizeof(response_t), | ||
2215 | rsp->ring, rsp->dma); | ||
2216 | |||
2217 | kfree(rsp); | ||
2218 | rsp = NULL; | ||
2219 | } | ||
2146 | 2220 | ||
2147 | list_for_each_safe(fcpl, fcptemp, &ha->fcports) { | 2221 | if (req) { |
2148 | fcport = list_entry(fcpl, fc_port_t, list); | 2222 | if (req->ring) |
2223 | dma_free_coherent(&ha->pdev->dev, | ||
2224 | (req->length + 1) * sizeof(request_t), | ||
2225 | req->ring, req->dma); | ||
2149 | 2226 | ||
2150 | /* fc ports */ | 2227 | kfree(req); |
2151 | list_del_init(&fcport->list); | 2228 | req = NULL; |
2152 | kfree(fcport); | ||
2153 | } | 2229 | } |
2154 | INIT_LIST_HEAD(&ha->fcports); | 2230 | } |
2155 | 2231 | ||
2156 | ha->fw_dump = NULL; | 2232 | struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht, |
2157 | ha->fw_dumped = 0; | 2233 | struct qla_hw_data *ha) |
2158 | ha->fw_dump_reading = 0; | 2234 | { |
2235 | struct Scsi_Host *host; | ||
2236 | struct scsi_qla_host *vha = NULL; | ||
2159 | 2237 | ||
2160 | vfree(ha->optrom_buffer); | 2238 | host = scsi_host_alloc(sht, sizeof(scsi_qla_host_t)); |
2161 | kfree(ha->nvram); | 2239 | if (host == NULL) { |
2240 | printk(KERN_WARNING | ||
2241 | "qla2xxx: Couldn't allocate host from scsi layer!\n"); | ||
2242 | goto fail; | ||
2243 | } | ||
2244 | |||
2245 | /* Clear our data area */ | ||
2246 | vha = shost_priv(host); | ||
2247 | memset(vha, 0, sizeof(scsi_qla_host_t)); | ||
2248 | |||
2249 | vha->host = host; | ||
2250 | vha->host_no = host->host_no; | ||
2251 | vha->hw = ha; | ||
2252 | |||
2253 | INIT_LIST_HEAD(&vha->vp_fcports); | ||
2254 | INIT_LIST_HEAD(&vha->work_list); | ||
2255 | INIT_LIST_HEAD(&vha->list); | ||
2256 | |||
2257 | sprintf(vha->host_str, "%s_%ld", QLA2XXX_DRIVER_NAME, vha->host_no); | ||
2258 | return vha; | ||
2259 | |||
2260 | fail: | ||
2261 | return vha; | ||
2162 | } | 2262 | } |
2163 | 2263 | ||
2164 | static struct qla_work_evt * | 2264 | static struct qla_work_evt * |
2165 | qla2x00_alloc_work(struct scsi_qla_host *ha, enum qla_work_type type, | 2265 | qla2x00_alloc_work(struct scsi_qla_host *vha, enum qla_work_type type, |
2166 | int locked) | 2266 | int locked) |
2167 | { | 2267 | { |
2168 | struct qla_work_evt *e; | 2268 | struct qla_work_evt *e; |
@@ -2179,42 +2279,42 @@ qla2x00_alloc_work(struct scsi_qla_host *ha, enum qla_work_type type, | |||
2179 | } | 2279 | } |
2180 | 2280 | ||
2181 | static int | 2281 | static int |
2182 | qla2x00_post_work(struct scsi_qla_host *ha, struct qla_work_evt *e, int locked) | 2282 | qla2x00_post_work(struct scsi_qla_host *vha, struct qla_work_evt *e, int locked) |
2183 | { | 2283 | { |
2184 | unsigned long uninitialized_var(flags); | 2284 | unsigned long uninitialized_var(flags); |
2185 | scsi_qla_host_t *pha = to_qla_parent(ha); | 2285 | struct qla_hw_data *ha = vha->hw; |
2186 | 2286 | ||
2187 | if (!locked) | 2287 | if (!locked) |
2188 | spin_lock_irqsave(&pha->hardware_lock, flags); | 2288 | spin_lock_irqsave(&ha->hardware_lock, flags); |
2189 | list_add_tail(&e->list, &ha->work_list); | 2289 | list_add_tail(&e->list, &vha->work_list); |
2190 | qla2xxx_wake_dpc(ha); | 2290 | qla2xxx_wake_dpc(vha); |
2191 | if (!locked) | 2291 | if (!locked) |
2192 | spin_unlock_irqrestore(&pha->hardware_lock, flags); | 2292 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
2193 | return QLA_SUCCESS; | 2293 | return QLA_SUCCESS; |
2194 | } | 2294 | } |
2195 | 2295 | ||
2196 | int | 2296 | int |
2197 | qla2x00_post_aen_work(struct scsi_qla_host *ha, enum fc_host_event_code code, | 2297 | qla2x00_post_aen_work(struct scsi_qla_host *vha, enum fc_host_event_code code, |
2198 | u32 data) | 2298 | u32 data) |
2199 | { | 2299 | { |
2200 | struct qla_work_evt *e; | 2300 | struct qla_work_evt *e; |
2201 | 2301 | ||
2202 | e = qla2x00_alloc_work(ha, QLA_EVT_AEN, 1); | 2302 | e = qla2x00_alloc_work(vha, QLA_EVT_AEN, 1); |
2203 | if (!e) | 2303 | if (!e) |
2204 | return QLA_FUNCTION_FAILED; | 2304 | return QLA_FUNCTION_FAILED; |
2205 | 2305 | ||
2206 | e->u.aen.code = code; | 2306 | e->u.aen.code = code; |
2207 | e->u.aen.data = data; | 2307 | e->u.aen.data = data; |
2208 | return qla2x00_post_work(ha, e, 1); | 2308 | return qla2x00_post_work(vha, e, 1); |
2209 | } | 2309 | } |
2210 | 2310 | ||
2211 | int | 2311 | int |
2212 | qla2x00_post_hwe_work(struct scsi_qla_host *ha, uint16_t code, uint16_t d1, | 2312 | qla2x00_post_hwe_work(struct scsi_qla_host *vha, uint16_t code, uint16_t d1, |
2213 | uint16_t d2, uint16_t d3) | 2313 | uint16_t d2, uint16_t d3) |
2214 | { | 2314 | { |
2215 | struct qla_work_evt *e; | 2315 | struct qla_work_evt *e; |
2216 | 2316 | ||
2217 | e = qla2x00_alloc_work(ha, QLA_EVT_HWE_LOG, 1); | 2317 | e = qla2x00_alloc_work(vha, QLA_EVT_HWE_LOG, 1); |
2218 | if (!e) | 2318 | if (!e) |
2219 | return QLA_FUNCTION_FAILED; | 2319 | return QLA_FUNCTION_FAILED; |
2220 | 2320 | ||
@@ -2222,36 +2322,95 @@ qla2x00_post_hwe_work(struct scsi_qla_host *ha, uint16_t code, uint16_t d1, | |||
2222 | e->u.hwe.d1 = d1; | 2322 | e->u.hwe.d1 = d1; |
2223 | e->u.hwe.d2 = d2; | 2323 | e->u.hwe.d2 = d2; |
2224 | e->u.hwe.d3 = d3; | 2324 | e->u.hwe.d3 = d3; |
2225 | return qla2x00_post_work(ha, e, 1); | 2325 | return qla2x00_post_work(vha, e, 1); |
2226 | } | 2326 | } |
2227 | 2327 | ||
2228 | static void | 2328 | static void |
2229 | qla2x00_do_work(struct scsi_qla_host *ha) | 2329 | qla2x00_do_work(struct scsi_qla_host *vha) |
2230 | { | 2330 | { |
2231 | struct qla_work_evt *e; | 2331 | struct qla_work_evt *e; |
2232 | scsi_qla_host_t *pha = to_qla_parent(ha); | 2332 | struct qla_hw_data *ha = vha->hw; |
2233 | 2333 | ||
2234 | spin_lock_irq(&pha->hardware_lock); | 2334 | spin_lock_irq(&ha->hardware_lock); |
2235 | while (!list_empty(&ha->work_list)) { | 2335 | while (!list_empty(&vha->work_list)) { |
2236 | e = list_entry(ha->work_list.next, struct qla_work_evt, list); | 2336 | e = list_entry(vha->work_list.next, struct qla_work_evt, list); |
2237 | list_del_init(&e->list); | 2337 | list_del_init(&e->list); |
2238 | spin_unlock_irq(&pha->hardware_lock); | 2338 | spin_unlock_irq(&ha->hardware_lock); |
2239 | 2339 | ||
2240 | switch (e->type) { | 2340 | switch (e->type) { |
2241 | case QLA_EVT_AEN: | 2341 | case QLA_EVT_AEN: |
2242 | fc_host_post_event(ha->host, fc_get_event_number(), | 2342 | fc_host_post_event(vha->host, fc_get_event_number(), |
2243 | e->u.aen.code, e->u.aen.data); | 2343 | e->u.aen.code, e->u.aen.data); |
2244 | break; | 2344 | break; |
2245 | case QLA_EVT_HWE_LOG: | 2345 | case QLA_EVT_HWE_LOG: |
2246 | qla2xxx_hw_event_log(ha, e->u.hwe.code, e->u.hwe.d1, | 2346 | qla2xxx_hw_event_log(vha, e->u.hwe.code, e->u.hwe.d1, |
2247 | e->u.hwe.d2, e->u.hwe.d3); | 2347 | e->u.hwe.d2, e->u.hwe.d3); |
2248 | break; | 2348 | break; |
2249 | } | 2349 | } |
2250 | if (e->flags & QLA_EVT_FLAG_FREE) | 2350 | if (e->flags & QLA_EVT_FLAG_FREE) |
2251 | kfree(e); | 2351 | kfree(e); |
2252 | spin_lock_irq(&pha->hardware_lock); | 2352 | spin_lock_irq(&ha->hardware_lock); |
2353 | } | ||
2354 | spin_unlock_irq(&ha->hardware_lock); | ||
2355 | } | ||
2356 | /* Relogins all the fcports of a vport | ||
2357 | * Context: dpc thread | ||
2358 | */ | ||
2359 | void qla2x00_relogin(struct scsi_qla_host *vha) | ||
2360 | { | ||
2361 | fc_port_t *fcport; | ||
2362 | uint8_t status; | ||
2363 | uint16_t next_loopid = 0; | ||
2364 | struct qla_hw_data *ha = vha->hw; | ||
2365 | |||
2366 | list_for_each_entry(fcport, &vha->vp_fcports, list) { | ||
2367 | /* | ||
2368 | * If the port is not ONLINE then try to login | ||
2369 | * to it if we haven't run out of retries. | ||
2370 | */ | ||
2371 | if (atomic_read(&fcport->state) != | ||
2372 | FCS_ONLINE && fcport->login_retry) { | ||
2373 | |||
2374 | if (fcport->flags & FCF_FABRIC_DEVICE) { | ||
2375 | if (fcport->flags & FCF_TAPE_PRESENT) | ||
2376 | ha->isp_ops->fabric_logout(vha, | ||
2377 | fcport->loop_id, | ||
2378 | fcport->d_id.b.domain, | ||
2379 | fcport->d_id.b.area, | ||
2380 | fcport->d_id.b.al_pa); | ||
2381 | |||
2382 | status = qla2x00_fabric_login(vha, fcport, | ||
2383 | &next_loopid); | ||
2384 | } else | ||
2385 | status = qla2x00_local_device_login(vha, | ||
2386 | fcport); | ||
2387 | |||
2388 | fcport->login_retry--; | ||
2389 | if (status == QLA_SUCCESS) { | ||
2390 | fcport->old_loop_id = fcport->loop_id; | ||
2391 | |||
2392 | DEBUG(printk("scsi(%ld): port login OK: logged " | ||
2393 | "in ID 0x%x\n", vha->host_no, fcport->loop_id)); | ||
2394 | |||
2395 | qla2x00_update_fcport(vha, fcport); | ||
2396 | |||
2397 | } else if (status == 1) { | ||
2398 | set_bit(RELOGIN_NEEDED, &vha->dpc_flags); | ||
2399 | /* retry the login again */ | ||
2400 | DEBUG(printk("scsi(%ld): Retrying" | ||
2401 | " %d login again loop_id 0x%x\n", | ||
2402 | vha->host_no, fcport->login_retry, | ||
2403 | fcport->loop_id)); | ||
2404 | } else { | ||
2405 | fcport->login_retry = 0; | ||
2406 | } | ||
2407 | |||
2408 | if (fcport->login_retry == 0 && status != QLA_SUCCESS) | ||
2409 | fcport->loop_id = FC_NO_LOOP_ID; | ||
2410 | } | ||
2411 | if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) | ||
2412 | break; | ||
2253 | } | 2413 | } |
2254 | spin_unlock_irq(&pha->hardware_lock); | ||
2255 | } | 2414 | } |
2256 | 2415 | ||
2257 | /************************************************************************** | 2416 | /************************************************************************** |
@@ -2271,15 +2430,11 @@ static int | |||
2271 | qla2x00_do_dpc(void *data) | 2430 | qla2x00_do_dpc(void *data) |
2272 | { | 2431 | { |
2273 | int rval; | 2432 | int rval; |
2274 | scsi_qla_host_t *ha; | 2433 | scsi_qla_host_t *base_vha; |
2275 | fc_port_t *fcport; | 2434 | struct qla_hw_data *ha; |
2276 | uint8_t status; | ||
2277 | uint16_t next_loopid; | ||
2278 | struct scsi_qla_host *vha; | ||
2279 | int i; | ||
2280 | |||
2281 | 2435 | ||
2282 | ha = (scsi_qla_host_t *)data; | 2436 | ha = (struct qla_hw_data *)data; |
2437 | base_vha = pci_get_drvdata(ha->pdev); | ||
2283 | 2438 | ||
2284 | set_user_nice(current, -20); | 2439 | set_user_nice(current, -20); |
2285 | 2440 | ||
@@ -2293,10 +2448,10 @@ qla2x00_do_dpc(void *data) | |||
2293 | DEBUG3(printk("qla2x00: DPC handler waking up\n")); | 2448 | DEBUG3(printk("qla2x00: DPC handler waking up\n")); |
2294 | 2449 | ||
2295 | /* Initialization not yet finished. Don't do anything yet. */ | 2450 | /* Initialization not yet finished. Don't do anything yet. */ |
2296 | if (!ha->flags.init_done) | 2451 | if (!base_vha->flags.init_done) |
2297 | continue; | 2452 | continue; |
2298 | 2453 | ||
2299 | DEBUG3(printk("scsi(%ld): DPC handler\n", ha->host_no)); | 2454 | DEBUG3(printk("scsi(%ld): DPC handler\n", base_vha->host_no)); |
2300 | 2455 | ||
2301 | ha->dpc_active = 1; | 2456 | ha->dpc_active = 1; |
2302 | 2457 | ||
@@ -2305,149 +2460,98 @@ qla2x00_do_dpc(void *data) | |||
2305 | continue; | 2460 | continue; |
2306 | } | 2461 | } |
2307 | 2462 | ||
2308 | qla2x00_do_work(ha); | 2463 | qla2x00_do_work(base_vha); |
2309 | 2464 | ||
2310 | if (test_and_clear_bit(ISP_ABORT_NEEDED, &ha->dpc_flags)) { | 2465 | if (test_and_clear_bit(ISP_ABORT_NEEDED, |
2466 | &base_vha->dpc_flags)) { | ||
2311 | 2467 | ||
2312 | DEBUG(printk("scsi(%ld): dpc: sched " | 2468 | DEBUG(printk("scsi(%ld): dpc: sched " |
2313 | "qla2x00_abort_isp ha = %p\n", | 2469 | "qla2x00_abort_isp ha = %p\n", |
2314 | ha->host_no, ha)); | 2470 | base_vha->host_no, ha)); |
2315 | if (!(test_and_set_bit(ABORT_ISP_ACTIVE, | 2471 | if (!(test_and_set_bit(ABORT_ISP_ACTIVE, |
2316 | &ha->dpc_flags))) { | 2472 | &base_vha->dpc_flags))) { |
2317 | 2473 | ||
2318 | if (qla2x00_abort_isp(ha)) { | 2474 | if (qla2x00_abort_isp(base_vha)) { |
2319 | /* failed. retry later */ | 2475 | /* failed. retry later */ |
2320 | set_bit(ISP_ABORT_NEEDED, | 2476 | set_bit(ISP_ABORT_NEEDED, |
2321 | &ha->dpc_flags); | 2477 | &base_vha->dpc_flags); |
2322 | } | ||
2323 | clear_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags); | ||
2324 | } | ||
2325 | |||
2326 | for_each_mapped_vp_idx(ha, i) { | ||
2327 | list_for_each_entry(vha, &ha->vp_list, | ||
2328 | vp_list) { | ||
2329 | if (i == vha->vp_idx) { | ||
2330 | set_bit(ISP_ABORT_NEEDED, | ||
2331 | &vha->dpc_flags); | ||
2332 | break; | ||
2333 | } | ||
2334 | } | 2478 | } |
2479 | clear_bit(ABORT_ISP_ACTIVE, | ||
2480 | &base_vha->dpc_flags); | ||
2335 | } | 2481 | } |
2336 | 2482 | ||
2337 | DEBUG(printk("scsi(%ld): dpc: qla2x00_abort_isp end\n", | 2483 | DEBUG(printk("scsi(%ld): dpc: qla2x00_abort_isp end\n", |
2338 | ha->host_no)); | 2484 | base_vha->host_no)); |
2339 | } | 2485 | } |
2340 | 2486 | ||
2341 | if (test_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags)) { | 2487 | if (test_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags)) { |
2342 | qla2x00_update_fcports(ha); | 2488 | qla2x00_update_fcports(base_vha); |
2343 | clear_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags); | 2489 | clear_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags); |
2344 | } | 2490 | } |
2345 | 2491 | ||
2346 | if (test_and_clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) && | 2492 | if (test_and_clear_bit(RESET_MARKER_NEEDED, |
2347 | (!(test_and_set_bit(RESET_ACTIVE, &ha->dpc_flags)))) { | 2493 | &base_vha->dpc_flags) && |
2494 | (!(test_and_set_bit(RESET_ACTIVE, &base_vha->dpc_flags)))) { | ||
2348 | 2495 | ||
2349 | DEBUG(printk("scsi(%ld): qla2x00_reset_marker()\n", | 2496 | DEBUG(printk("scsi(%ld): qla2x00_reset_marker()\n", |
2350 | ha->host_no)); | 2497 | base_vha->host_no)); |
2351 | 2498 | ||
2352 | qla2x00_rst_aen(ha); | 2499 | qla2x00_rst_aen(base_vha); |
2353 | clear_bit(RESET_ACTIVE, &ha->dpc_flags); | 2500 | clear_bit(RESET_ACTIVE, &base_vha->dpc_flags); |
2354 | } | 2501 | } |
2355 | 2502 | ||
2356 | /* Retry each device up to login retry count */ | 2503 | /* Retry each device up to login retry count */ |
2357 | if ((test_and_clear_bit(RELOGIN_NEEDED, &ha->dpc_flags)) && | 2504 | if ((test_and_clear_bit(RELOGIN_NEEDED, |
2358 | !test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) && | 2505 | &base_vha->dpc_flags)) && |
2359 | atomic_read(&ha->loop_state) != LOOP_DOWN) { | 2506 | !test_bit(LOOP_RESYNC_NEEDED, &base_vha->dpc_flags) && |
2507 | atomic_read(&base_vha->loop_state) != LOOP_DOWN) { | ||
2360 | 2508 | ||
2361 | DEBUG(printk("scsi(%ld): qla2x00_port_login()\n", | 2509 | DEBUG(printk("scsi(%ld): qla2x00_port_login()\n", |
2362 | ha->host_no)); | 2510 | base_vha->host_no)); |
2363 | 2511 | qla2x00_relogin(base_vha); | |
2364 | next_loopid = 0; | 2512 | |
2365 | list_for_each_entry(fcport, &ha->fcports, list) { | ||
2366 | /* | ||
2367 | * If the port is not ONLINE then try to login | ||
2368 | * to it if we haven't run out of retries. | ||
2369 | */ | ||
2370 | if (atomic_read(&fcport->state) != FCS_ONLINE && | ||
2371 | fcport->login_retry) { | ||
2372 | |||
2373 | if (fcport->flags & FCF_FABRIC_DEVICE) { | ||
2374 | if (fcport->flags & | ||
2375 | FCF_TAPE_PRESENT) | ||
2376 | ha->isp_ops->fabric_logout( | ||
2377 | ha, fcport->loop_id, | ||
2378 | fcport->d_id.b.domain, | ||
2379 | fcport->d_id.b.area, | ||
2380 | fcport->d_id.b.al_pa); | ||
2381 | status = qla2x00_fabric_login( | ||
2382 | ha, fcport, &next_loopid); | ||
2383 | } else | ||
2384 | status = | ||
2385 | qla2x00_local_device_login( | ||
2386 | ha, fcport); | ||
2387 | |||
2388 | fcport->login_retry--; | ||
2389 | if (status == QLA_SUCCESS) { | ||
2390 | fcport->old_loop_id = fcport->loop_id; | ||
2391 | |||
2392 | DEBUG(printk("scsi(%ld): port login OK: logged in ID 0x%x\n", | ||
2393 | ha->host_no, fcport->loop_id)); | ||
2394 | |||
2395 | qla2x00_update_fcport(ha, | ||
2396 | fcport); | ||
2397 | } else if (status == 1) { | ||
2398 | set_bit(RELOGIN_NEEDED, &ha->dpc_flags); | ||
2399 | /* retry the login again */ | ||
2400 | DEBUG(printk("scsi(%ld): Retrying %d login again loop_id 0x%x\n", | ||
2401 | ha->host_no, | ||
2402 | fcport->login_retry, fcport->loop_id)); | ||
2403 | } else { | ||
2404 | fcport->login_retry = 0; | ||
2405 | } | ||
2406 | if (fcport->login_retry == 0 && status != QLA_SUCCESS) | ||
2407 | fcport->loop_id = FC_NO_LOOP_ID; | ||
2408 | } | ||
2409 | if (test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) | ||
2410 | break; | ||
2411 | } | ||
2412 | DEBUG(printk("scsi(%ld): qla2x00_port_login - end\n", | 2513 | DEBUG(printk("scsi(%ld): qla2x00_port_login - end\n", |
2413 | ha->host_no)); | 2514 | base_vha->host_no)); |
2414 | } | 2515 | } |
2415 | 2516 | ||
2416 | if (test_and_clear_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) { | 2517 | if (test_and_clear_bit(LOOP_RESYNC_NEEDED, |
2518 | &base_vha->dpc_flags)) { | ||
2417 | 2519 | ||
2418 | DEBUG(printk("scsi(%ld): qla2x00_loop_resync()\n", | 2520 | DEBUG(printk("scsi(%ld): qla2x00_loop_resync()\n", |
2419 | ha->host_no)); | 2521 | base_vha->host_no)); |
2420 | 2522 | ||
2421 | if (!(test_and_set_bit(LOOP_RESYNC_ACTIVE, | 2523 | if (!(test_and_set_bit(LOOP_RESYNC_ACTIVE, |
2422 | &ha->dpc_flags))) { | 2524 | &base_vha->dpc_flags))) { |
2423 | 2525 | ||
2424 | rval = qla2x00_loop_resync(ha); | 2526 | rval = qla2x00_loop_resync(base_vha); |
2425 | 2527 | ||
2426 | clear_bit(LOOP_RESYNC_ACTIVE, &ha->dpc_flags); | 2528 | clear_bit(LOOP_RESYNC_ACTIVE, |
2529 | &base_vha->dpc_flags); | ||
2427 | } | 2530 | } |
2428 | 2531 | ||
2429 | DEBUG(printk("scsi(%ld): qla2x00_loop_resync - end\n", | 2532 | DEBUG(printk("scsi(%ld): qla2x00_loop_resync - end\n", |
2430 | ha->host_no)); | 2533 | base_vha->host_no)); |
2431 | } | 2534 | } |
2432 | 2535 | ||
2433 | if (test_bit(NPIV_CONFIG_NEEDED, &ha->dpc_flags) && | 2536 | if (test_bit(NPIV_CONFIG_NEEDED, &base_vha->dpc_flags) && |
2434 | atomic_read(&ha->loop_state) == LOOP_READY) { | 2537 | atomic_read(&base_vha->loop_state) == LOOP_READY) { |
2435 | clear_bit(NPIV_CONFIG_NEEDED, &ha->dpc_flags); | 2538 | clear_bit(NPIV_CONFIG_NEEDED, &base_vha->dpc_flags); |
2436 | qla2xxx_flash_npiv_conf(ha); | 2539 | qla2xxx_flash_npiv_conf(base_vha); |
2437 | } | 2540 | } |
2438 | 2541 | ||
2439 | if (!ha->interrupts_on) | 2542 | if (!ha->interrupts_on) |
2440 | ha->isp_ops->enable_intrs(ha); | 2543 | ha->isp_ops->enable_intrs(ha); |
2441 | 2544 | ||
2442 | if (test_and_clear_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags)) | 2545 | if (test_and_clear_bit(BEACON_BLINK_NEEDED, |
2443 | ha->isp_ops->beacon_blink(ha); | 2546 | &base_vha->dpc_flags)) |
2547 | ha->isp_ops->beacon_blink(base_vha); | ||
2444 | 2548 | ||
2445 | qla2x00_do_dpc_all_vps(ha); | 2549 | qla2x00_do_dpc_all_vps(base_vha); |
2446 | 2550 | ||
2447 | ha->dpc_active = 0; | 2551 | ha->dpc_active = 0; |
2448 | } /* End of while(1) */ | 2552 | } /* End of while(1) */ |
2449 | 2553 | ||
2450 | DEBUG(printk("scsi(%ld): DPC handler exiting\n", ha->host_no)); | 2554 | DEBUG(printk("scsi(%ld): DPC handler exiting\n", base_vha->host_no)); |
2451 | 2555 | ||
2452 | /* | 2556 | /* |
2453 | * Make sure that nobody tries to wake us up again. | 2557 | * Make sure that nobody tries to wake us up again. |
@@ -2458,11 +2562,12 @@ qla2x00_do_dpc(void *data) | |||
2458 | } | 2562 | } |
2459 | 2563 | ||
2460 | void | 2564 | void |
2461 | qla2xxx_wake_dpc(scsi_qla_host_t *ha) | 2565 | qla2xxx_wake_dpc(struct scsi_qla_host *vha) |
2462 | { | 2566 | { |
2567 | struct qla_hw_data *ha = vha->hw; | ||
2463 | struct task_struct *t = ha->dpc_thread; | 2568 | struct task_struct *t = ha->dpc_thread; |
2464 | 2569 | ||
2465 | if (!test_bit(UNLOADING, &ha->dpc_flags) && t) | 2570 | if (!test_bit(UNLOADING, &vha->dpc_flags) && t) |
2466 | wake_up_process(t); | 2571 | wake_up_process(t); |
2467 | } | 2572 | } |
2468 | 2573 | ||
@@ -2474,26 +2579,26 @@ qla2xxx_wake_dpc(scsi_qla_host_t *ha) | |||
2474 | * ha = adapter block pointer. | 2579 | * ha = adapter block pointer. |
2475 | */ | 2580 | */ |
2476 | static void | 2581 | static void |
2477 | qla2x00_rst_aen(scsi_qla_host_t *ha) | 2582 | qla2x00_rst_aen(scsi_qla_host_t *vha) |
2478 | { | 2583 | { |
2479 | if (ha->flags.online && !ha->flags.reset_active && | 2584 | if (vha->flags.online && !vha->flags.reset_active && |
2480 | !atomic_read(&ha->loop_down_timer) && | 2585 | !atomic_read(&vha->loop_down_timer) && |
2481 | !(test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags))) { | 2586 | !(test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags))) { |
2482 | do { | 2587 | do { |
2483 | clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); | 2588 | clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags); |
2484 | 2589 | ||
2485 | /* | 2590 | /* |
2486 | * Issue marker command only when we are going to start | 2591 | * Issue marker command only when we are going to start |
2487 | * the I/O. | 2592 | * the I/O. |
2488 | */ | 2593 | */ |
2489 | ha->marker_needed = 1; | 2594 | vha->marker_needed = 1; |
2490 | } while (!atomic_read(&ha->loop_down_timer) && | 2595 | } while (!atomic_read(&vha->loop_down_timer) && |
2491 | (test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags))); | 2596 | (test_bit(RESET_MARKER_NEEDED, &vha->dpc_flags))); |
2492 | } | 2597 | } |
2493 | } | 2598 | } |
2494 | 2599 | ||
2495 | static void | 2600 | static void |
2496 | qla2x00_sp_free_dma(scsi_qla_host_t *ha, srb_t *sp) | 2601 | qla2x00_sp_free_dma(srb_t *sp) |
2497 | { | 2602 | { |
2498 | struct scsi_cmnd *cmd = sp->cmd; | 2603 | struct scsi_cmnd *cmd = sp->cmd; |
2499 | 2604 | ||
@@ -2505,11 +2610,12 @@ qla2x00_sp_free_dma(scsi_qla_host_t *ha, srb_t *sp) | |||
2505 | } | 2610 | } |
2506 | 2611 | ||
2507 | void | 2612 | void |
2508 | qla2x00_sp_compl(scsi_qla_host_t *ha, srb_t *sp) | 2613 | qla2x00_sp_compl(scsi_qla_host_t *vha, srb_t *sp) |
2509 | { | 2614 | { |
2615 | struct qla_hw_data *ha = vha->hw; | ||
2510 | struct scsi_cmnd *cmd = sp->cmd; | 2616 | struct scsi_cmnd *cmd = sp->cmd; |
2511 | 2617 | ||
2512 | qla2x00_sp_free_dma(ha, sp); | 2618 | qla2x00_sp_free_dma(sp); |
2513 | 2619 | ||
2514 | mempool_free(sp, ha->srb_mempool); | 2620 | mempool_free(sp, ha->srb_mempool); |
2515 | 2621 | ||
@@ -2525,7 +2631,7 @@ qla2x00_sp_compl(scsi_qla_host_t *ha, srb_t *sp) | |||
2525 | * Context: Interrupt | 2631 | * Context: Interrupt |
2526 | ***************************************************************************/ | 2632 | ***************************************************************************/ |
2527 | void | 2633 | void |
2528 | qla2x00_timer(scsi_qla_host_t *ha) | 2634 | qla2x00_timer(scsi_qla_host_t *vha) |
2529 | { | 2635 | { |
2530 | unsigned long cpu_flags = 0; | 2636 | unsigned long cpu_flags = 0; |
2531 | fc_port_t *fcport; | 2637 | fc_port_t *fcport; |
@@ -2533,8 +2639,8 @@ qla2x00_timer(scsi_qla_host_t *ha) | |||
2533 | int index; | 2639 | int index; |
2534 | srb_t *sp; | 2640 | srb_t *sp; |
2535 | int t; | 2641 | int t; |
2536 | scsi_qla_host_t *pha = to_qla_parent(ha); | 2642 | struct qla_hw_data *ha = vha->hw; |
2537 | 2643 | struct req_que *req = ha->req; | |
2538 | /* | 2644 | /* |
2539 | * Ports - Port down timer. | 2645 | * Ports - Port down timer. |
2540 | * | 2646 | * |
@@ -2543,7 +2649,7 @@ qla2x00_timer(scsi_qla_host_t *ha) | |||
2543 | * the port it marked DEAD. | 2649 | * the port it marked DEAD. |
2544 | */ | 2650 | */ |
2545 | t = 0; | 2651 | t = 0; |
2546 | list_for_each_entry(fcport, &ha->fcports, list) { | 2652 | list_for_each_entry(fcport, &vha->vp_fcports, list) { |
2547 | if (fcport->port_type != FCT_TARGET) | 2653 | if (fcport->port_type != FCT_TARGET) |
2548 | continue; | 2654 | continue; |
2549 | 2655 | ||
@@ -2557,7 +2663,7 @@ qla2x00_timer(scsi_qla_host_t *ha) | |||
2557 | 2663 | ||
2558 | DEBUG(printk("scsi(%ld): fcport-%d - port retry count: " | 2664 | DEBUG(printk("scsi(%ld): fcport-%d - port retry count: " |
2559 | "%d remaining\n", | 2665 | "%d remaining\n", |
2560 | ha->host_no, | 2666 | vha->host_no, |
2561 | t, atomic_read(&fcport->port_down_timer))); | 2667 | t, atomic_read(&fcport->port_down_timer))); |
2562 | } | 2668 | } |
2563 | t++; | 2669 | t++; |
@@ -2565,22 +2671,23 @@ qla2x00_timer(scsi_qla_host_t *ha) | |||
2565 | 2671 | ||
2566 | 2672 | ||
2567 | /* Loop down handler. */ | 2673 | /* Loop down handler. */ |
2568 | if (atomic_read(&ha->loop_down_timer) > 0 && | 2674 | if (atomic_read(&vha->loop_down_timer) > 0 && |
2569 | !(test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags)) && ha->flags.online) { | 2675 | !(test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags)) |
2676 | && vha->flags.online) { | ||
2570 | 2677 | ||
2571 | if (atomic_read(&ha->loop_down_timer) == | 2678 | if (atomic_read(&vha->loop_down_timer) == |
2572 | ha->loop_down_abort_time) { | 2679 | vha->loop_down_abort_time) { |
2573 | 2680 | ||
2574 | DEBUG(printk("scsi(%ld): Loop Down - aborting the " | 2681 | DEBUG(printk("scsi(%ld): Loop Down - aborting the " |
2575 | "queues before time expire\n", | 2682 | "queues before time expire\n", |
2576 | ha->host_no)); | 2683 | vha->host_no)); |
2577 | 2684 | ||
2578 | if (!IS_QLA2100(ha) && ha->link_down_timeout) | 2685 | if (!IS_QLA2100(ha) && vha->link_down_timeout) |
2579 | atomic_set(&ha->loop_state, LOOP_DEAD); | 2686 | atomic_set(&vha->loop_state, LOOP_DEAD); |
2580 | 2687 | ||
2581 | /* Schedule an ISP abort to return any tape commands. */ | 2688 | /* Schedule an ISP abort to return any tape commands. */ |
2582 | /* NPIV - scan physical port only */ | 2689 | /* NPIV - scan physical port only */ |
2583 | if (!ha->parent) { | 2690 | if (!vha->vp_idx) { |
2584 | spin_lock_irqsave(&ha->hardware_lock, | 2691 | spin_lock_irqsave(&ha->hardware_lock, |
2585 | cpu_flags); | 2692 | cpu_flags); |
2586 | for (index = 1; | 2693 | for (index = 1; |
@@ -2588,7 +2695,7 @@ qla2x00_timer(scsi_qla_host_t *ha) | |||
2588 | index++) { | 2695 | index++) { |
2589 | fc_port_t *sfcp; | 2696 | fc_port_t *sfcp; |
2590 | 2697 | ||
2591 | sp = ha->outstanding_cmds[index]; | 2698 | sp = req->outstanding_cmds[index]; |
2592 | if (!sp) | 2699 | if (!sp) |
2593 | continue; | 2700 | continue; |
2594 | sfcp = sp->fcport; | 2701 | sfcp = sp->fcport; |
@@ -2596,63 +2703,63 @@ qla2x00_timer(scsi_qla_host_t *ha) | |||
2596 | continue; | 2703 | continue; |
2597 | 2704 | ||
2598 | set_bit(ISP_ABORT_NEEDED, | 2705 | set_bit(ISP_ABORT_NEEDED, |
2599 | &ha->dpc_flags); | 2706 | &vha->dpc_flags); |
2600 | break; | 2707 | break; |
2601 | } | 2708 | } |
2602 | spin_unlock_irqrestore(&ha->hardware_lock, | 2709 | spin_unlock_irqrestore(&ha->hardware_lock, |
2603 | cpu_flags); | 2710 | cpu_flags); |
2604 | } | 2711 | } |
2605 | set_bit(ABORT_QUEUES_NEEDED, &ha->dpc_flags); | 2712 | set_bit(ABORT_QUEUES_NEEDED, &vha->dpc_flags); |
2606 | start_dpc++; | 2713 | start_dpc++; |
2607 | } | 2714 | } |
2608 | 2715 | ||
2609 | /* if the loop has been down for 4 minutes, reinit adapter */ | 2716 | /* if the loop has been down for 4 minutes, reinit adapter */ |
2610 | if (atomic_dec_and_test(&ha->loop_down_timer) != 0) { | 2717 | if (atomic_dec_and_test(&vha->loop_down_timer) != 0) { |
2611 | DEBUG(printk("scsi(%ld): Loop down exceed 4 mins - " | 2718 | DEBUG(printk("scsi(%ld): Loop down exceed 4 mins - " |
2612 | "restarting queues.\n", | 2719 | "restarting queues.\n", |
2613 | ha->host_no)); | 2720 | vha->host_no)); |
2614 | 2721 | ||
2615 | set_bit(RESTART_QUEUES_NEEDED, &ha->dpc_flags); | 2722 | set_bit(RESTART_QUEUES_NEEDED, &vha->dpc_flags); |
2616 | start_dpc++; | 2723 | start_dpc++; |
2617 | 2724 | ||
2618 | if (!(ha->device_flags & DFLG_NO_CABLE) && | 2725 | if (!(vha->device_flags & DFLG_NO_CABLE) && |
2619 | !ha->parent) { | 2726 | !vha->vp_idx) { |
2620 | DEBUG(printk("scsi(%ld): Loop down - " | 2727 | DEBUG(printk("scsi(%ld): Loop down - " |
2621 | "aborting ISP.\n", | 2728 | "aborting ISP.\n", |
2622 | ha->host_no)); | 2729 | vha->host_no)); |
2623 | qla_printk(KERN_WARNING, ha, | 2730 | qla_printk(KERN_WARNING, ha, |
2624 | "Loop down - aborting ISP.\n"); | 2731 | "Loop down - aborting ISP.\n"); |
2625 | 2732 | ||
2626 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | 2733 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); |
2627 | } | 2734 | } |
2628 | } | 2735 | } |
2629 | DEBUG3(printk("scsi(%ld): Loop Down - seconds remaining %d\n", | 2736 | DEBUG3(printk("scsi(%ld): Loop Down - seconds remaining %d\n", |
2630 | ha->host_no, | 2737 | vha->host_no, |
2631 | atomic_read(&ha->loop_down_timer))); | 2738 | atomic_read(&vha->loop_down_timer))); |
2632 | } | 2739 | } |
2633 | 2740 | ||
2634 | /* Check if beacon LED needs to be blinked */ | 2741 | /* Check if beacon LED needs to be blinked */ |
2635 | if (ha->beacon_blink_led == 1) { | 2742 | if (ha->beacon_blink_led == 1) { |
2636 | set_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags); | 2743 | set_bit(BEACON_BLINK_NEEDED, &vha->dpc_flags); |
2637 | start_dpc++; | 2744 | start_dpc++; |
2638 | } | 2745 | } |
2639 | 2746 | ||
2640 | /* Process any deferred work. */ | 2747 | /* Process any deferred work. */ |
2641 | if (!list_empty(&ha->work_list)) | 2748 | if (!list_empty(&vha->work_list)) |
2642 | start_dpc++; | 2749 | start_dpc++; |
2643 | 2750 | ||
2644 | /* Schedule the DPC routine if needed */ | 2751 | /* Schedule the DPC routine if needed */ |
2645 | if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) || | 2752 | if ((test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) || |
2646 | test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || | 2753 | test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags) || |
2647 | test_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags) || | 2754 | test_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags) || |
2648 | start_dpc || | 2755 | start_dpc || |
2649 | test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) || | 2756 | test_bit(RESET_MARKER_NEEDED, &vha->dpc_flags) || |
2650 | test_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags) || | 2757 | test_bit(BEACON_BLINK_NEEDED, &vha->dpc_flags) || |
2651 | test_bit(VP_DPC_NEEDED, &ha->dpc_flags) || | 2758 | test_bit(VP_DPC_NEEDED, &vha->dpc_flags) || |
2652 | test_bit(RELOGIN_NEEDED, &ha->dpc_flags))) | 2759 | test_bit(RELOGIN_NEEDED, &vha->dpc_flags))) |
2653 | qla2xxx_wake_dpc(pha); | 2760 | qla2xxx_wake_dpc(vha); |
2654 | 2761 | ||
2655 | qla2x00_restart_timer(ha, WATCH_INTERVAL); | 2762 | qla2x00_restart_timer(vha, WATCH_INTERVAL); |
2656 | } | 2763 | } |
2657 | 2764 | ||
2658 | /* Firmware interface routines. */ | 2765 | /* Firmware interface routines. */ |
@@ -2684,8 +2791,9 @@ static struct fw_blob qla_fw_blobs[FW_BLOBS] = { | |||
2684 | }; | 2791 | }; |
2685 | 2792 | ||
2686 | struct fw_blob * | 2793 | struct fw_blob * |
2687 | qla2x00_request_firmware(scsi_qla_host_t *ha) | 2794 | qla2x00_request_firmware(scsi_qla_host_t *vha) |
2688 | { | 2795 | { |
2796 | struct qla_hw_data *ha = vha->hw; | ||
2689 | struct fw_blob *blob; | 2797 | struct fw_blob *blob; |
2690 | 2798 | ||
2691 | blob = NULL; | 2799 | blob = NULL; |
@@ -2709,7 +2817,7 @@ qla2x00_request_firmware(scsi_qla_host_t *ha) | |||
2709 | 2817 | ||
2710 | if (request_firmware(&blob->fw, blob->name, &ha->pdev->dev)) { | 2818 | if (request_firmware(&blob->fw, blob->name, &ha->pdev->dev)) { |
2711 | DEBUG2(printk("scsi(%ld): Failed to load firmware image " | 2819 | DEBUG2(printk("scsi(%ld): Failed to load firmware image " |
2712 | "(%s).\n", ha->host_no, blob->name)); | 2820 | "(%s).\n", vha->host_no, blob->name)); |
2713 | blob->fw = NULL; | 2821 | blob->fw = NULL; |
2714 | blob = NULL; | 2822 | blob = NULL; |
2715 | goto out; | 2823 | goto out; |
@@ -2754,7 +2862,8 @@ qla2xxx_pci_mmio_enabled(struct pci_dev *pdev) | |||
2754 | int risc_paused = 0; | 2862 | int risc_paused = 0; |
2755 | uint32_t stat; | 2863 | uint32_t stat; |
2756 | unsigned long flags; | 2864 | unsigned long flags; |
2757 | scsi_qla_host_t *ha = pci_get_drvdata(pdev); | 2865 | scsi_qla_host_t *base_vha = pci_get_drvdata(pdev); |
2866 | struct qla_hw_data *ha = base_vha->hw; | ||
2758 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | 2867 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; |
2759 | struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24; | 2868 | struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24; |
2760 | 2869 | ||
@@ -2777,7 +2886,7 @@ qla2xxx_pci_mmio_enabled(struct pci_dev *pdev) | |||
2777 | if (risc_paused) { | 2886 | if (risc_paused) { |
2778 | qla_printk(KERN_INFO, ha, "RISC paused -- mmio_enabled, " | 2887 | qla_printk(KERN_INFO, ha, "RISC paused -- mmio_enabled, " |
2779 | "Dumping firmware!\n"); | 2888 | "Dumping firmware!\n"); |
2780 | ha->isp_ops->fw_dump(ha, 0); | 2889 | ha->isp_ops->fw_dump(base_vha, 0); |
2781 | 2890 | ||
2782 | return PCI_ERS_RESULT_NEED_RESET; | 2891 | return PCI_ERS_RESULT_NEED_RESET; |
2783 | } else | 2892 | } else |
@@ -2788,7 +2897,8 @@ static pci_ers_result_t | |||
2788 | qla2xxx_pci_slot_reset(struct pci_dev *pdev) | 2897 | qla2xxx_pci_slot_reset(struct pci_dev *pdev) |
2789 | { | 2898 | { |
2790 | pci_ers_result_t ret = PCI_ERS_RESULT_DISCONNECT; | 2899 | pci_ers_result_t ret = PCI_ERS_RESULT_DISCONNECT; |
2791 | scsi_qla_host_t *ha = pci_get_drvdata(pdev); | 2900 | scsi_qla_host_t *base_vha = pci_get_drvdata(pdev); |
2901 | struct qla_hw_data *ha = base_vha->hw; | ||
2792 | int rc; | 2902 | int rc; |
2793 | 2903 | ||
2794 | if (ha->mem_only) | 2904 | if (ha->mem_only) |
@@ -2804,13 +2914,13 @@ qla2xxx_pci_slot_reset(struct pci_dev *pdev) | |||
2804 | } | 2914 | } |
2805 | pci_set_master(pdev); | 2915 | pci_set_master(pdev); |
2806 | 2916 | ||
2807 | if (ha->isp_ops->pci_config(ha)) | 2917 | if (ha->isp_ops->pci_config(base_vha)) |
2808 | return ret; | 2918 | return ret; |
2809 | 2919 | ||
2810 | set_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags); | 2920 | set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); |
2811 | if (qla2x00_abort_isp(ha)== QLA_SUCCESS) | 2921 | if (qla2x00_abort_isp(base_vha) == QLA_SUCCESS) |
2812 | ret = PCI_ERS_RESULT_RECOVERED; | 2922 | ret = PCI_ERS_RESULT_RECOVERED; |
2813 | clear_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags); | 2923 | clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); |
2814 | 2924 | ||
2815 | return ret; | 2925 | return ret; |
2816 | } | 2926 | } |
@@ -2818,10 +2928,11 @@ qla2xxx_pci_slot_reset(struct pci_dev *pdev) | |||
2818 | static void | 2928 | static void |
2819 | qla2xxx_pci_resume(struct pci_dev *pdev) | 2929 | qla2xxx_pci_resume(struct pci_dev *pdev) |
2820 | { | 2930 | { |
2821 | scsi_qla_host_t *ha = pci_get_drvdata(pdev); | 2931 | scsi_qla_host_t *base_vha = pci_get_drvdata(pdev); |
2932 | struct qla_hw_data *ha = base_vha->hw; | ||
2822 | int ret; | 2933 | int ret; |
2823 | 2934 | ||
2824 | ret = qla2x00_wait_for_hba_online(ha); | 2935 | ret = qla2x00_wait_for_hba_online(base_vha); |
2825 | if (ret != QLA_SUCCESS) { | 2936 | if (ret != QLA_SUCCESS) { |
2826 | qla_printk(KERN_ERR, ha, | 2937 | qla_printk(KERN_ERR, ha, |
2827 | "the device failed to resume I/O " | 2938 | "the device failed to resume I/O " |