• Home
  • Raw
  • Download

Lines Matching +full:d +full:- +full:phy

21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
49 spin_lock_init(&task->task_state_lock); in sas_alloc_task()
50 task->task_state_flags = SAS_TASK_STATE_PENDING; in sas_alloc_task()
69 task->slow_task = slow; in sas_alloc_slow_task()
70 slow->task = task; in sas_alloc_slow_task()
71 timer_setup(&slow->timer, NULL, 0); in sas_alloc_slow_task()
72 init_completion(&slow->completion); in sas_alloc_slow_task()
81 kfree(task->slow_task); in sas_free_task()
87 /*------------ SAS addr hash -----------*/
96 for (b = 7; b >= 0; b--) { in sas_hash_addr()
116 mutex_init(&sas_ha->disco_mutex); in sas_register_ha()
117 spin_lock_init(&sas_ha->phy_port_lock); in sas_register_ha()
118 sas_hash_addr(sas_ha->hashed_sas_addr, sas_ha->sas_addr); in sas_register_ha()
120 set_bit(SAS_HA_REGISTERED, &sas_ha->state); in sas_register_ha()
121 spin_lock_init(&sas_ha->lock); in sas_register_ha()
122 mutex_init(&sas_ha->drain_mutex); in sas_register_ha()
123 init_waitqueue_head(&sas_ha->eh_wait_q); in sas_register_ha()
124 INIT_LIST_HEAD(&sas_ha->defer_q); in sas_register_ha()
125 INIT_LIST_HEAD(&sas_ha->eh_dev_q); in sas_register_ha()
127 sas_ha->event_thres = SAS_PHY_SHUTDOWN_THRES; in sas_register_ha()
131 printk(KERN_NOTICE "couldn't register sas phys:%d\n", error); in sas_register_ha()
137 printk(KERN_NOTICE "couldn't register sas ports:%d\n", error); in sas_register_ha()
143 printk(KERN_NOTICE "couldn't start event thread:%d\n", error); in sas_register_ha()
147 error = -ENOMEM; in sas_register_ha()
148 snprintf(name, sizeof(name), "%s_event_q", dev_name(sas_ha->dev)); in sas_register_ha()
149 sas_ha->event_q = create_singlethread_workqueue(name); in sas_register_ha()
150 if (!sas_ha->event_q) in sas_register_ha()
153 snprintf(name, sizeof(name), "%s_disco_q", dev_name(sas_ha->dev)); in sas_register_ha()
154 sas_ha->disco_q = create_singlethread_workqueue(name); in sas_register_ha()
155 if (!sas_ha->disco_q) in sas_register_ha()
158 INIT_LIST_HEAD(&sas_ha->eh_done_q); in sas_register_ha()
159 INIT_LIST_HEAD(&sas_ha->eh_ata_q); in sas_register_ha()
164 destroy_workqueue(sas_ha->event_q); in sas_register_ha()
175 * events to be queued, and flush any in-progress drainers in sas_disable_events()
177 mutex_lock(&sas_ha->drain_mutex); in sas_disable_events()
178 spin_lock_irq(&sas_ha->lock); in sas_disable_events()
179 clear_bit(SAS_HA_REGISTERED, &sas_ha->state); in sas_disable_events()
180 spin_unlock_irq(&sas_ha->lock); in sas_disable_events()
182 mutex_unlock(&sas_ha->drain_mutex); in sas_disable_events()
191 mutex_lock(&sas_ha->drain_mutex); in sas_unregister_ha()
193 mutex_unlock(&sas_ha->drain_mutex); in sas_unregister_ha()
195 destroy_workqueue(sas_ha->disco_q); in sas_unregister_ha()
196 destroy_workqueue(sas_ha->event_q); in sas_unregister_ha()
201 static int sas_get_linkerrors(struct sas_phy *phy) in sas_get_linkerrors() argument
203 if (scsi_is_sas_phy_local(phy)) { in sas_get_linkerrors()
204 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent); in sas_get_linkerrors()
206 struct asd_sas_phy *asd_phy = sas_ha->sas_phy[phy->number]; in sas_get_linkerrors()
208 to_sas_internal(sas_ha->core.shost->transportt); in sas_get_linkerrors()
210 return i->dft->lldd_control_phy(asd_phy, PHY_FUNC_GET_EVENTS, NULL); in sas_get_linkerrors()
213 return sas_smp_get_phy_events(phy); in sas_get_linkerrors()
221 if (asd_phy->port) in sas_try_ata_reset()
222 dev = asd_phy->port->port_dev; in sas_try_ata_reset()
226 dev = sas_find_dev_by_rphy(dev->rphy); in sas_try_ata_reset()
234 return -ENODEV; in sas_try_ata_reset()
238 * transport_sas_phy_reset - reset a phy and permit libata to manage the link
240 * phy reset request via sysfs in host workqueue context so we know we
243 static int transport_sas_phy_reset(struct sas_phy *phy, int hard_reset) in transport_sas_phy_reset() argument
252 if (scsi_is_sas_phy_local(phy)) { in transport_sas_phy_reset()
253 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent); in transport_sas_phy_reset()
255 struct asd_sas_phy *asd_phy = sas_ha->sas_phy[phy->number]; in transport_sas_phy_reset()
257 to_sas_internal(sas_ha->core.shost->transportt); in transport_sas_phy_reset()
261 return i->dft->lldd_control_phy(asd_phy, reset_type, NULL); in transport_sas_phy_reset()
263 struct sas_rphy *rphy = dev_to_rphy(phy->dev.parent); in transport_sas_phy_reset()
265 struct domain_device *ata_dev = sas_ex_to_ata(ddev, phy->number); in transport_sas_phy_reset()
272 return sas_smp_phy_control(ddev, phy->number, reset_type, NULL); in transport_sas_phy_reset()
276 static int sas_phy_enable(struct sas_phy *phy, int enable) in sas_phy_enable() argument
286 if (scsi_is_sas_phy_local(phy)) { in sas_phy_enable()
287 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent); in sas_phy_enable()
289 struct asd_sas_phy *asd_phy = sas_ha->sas_phy[phy->number]; in sas_phy_enable()
291 to_sas_internal(sas_ha->core.shost->transportt); in sas_phy_enable()
294 ret = transport_sas_phy_reset(phy, 0); in sas_phy_enable()
296 ret = i->dft->lldd_control_phy(asd_phy, cmd, NULL); in sas_phy_enable()
298 struct sas_rphy *rphy = dev_to_rphy(phy->dev.parent); in sas_phy_enable()
302 ret = transport_sas_phy_reset(phy, 0); in sas_phy_enable()
304 ret = sas_smp_phy_control(ddev, phy->number, cmd, NULL); in sas_phy_enable()
309 int sas_phy_reset(struct sas_phy *phy, int hard_reset) in sas_phy_reset() argument
314 if (!phy->enabled) in sas_phy_reset()
315 return -ENODEV; in sas_phy_reset()
322 if (scsi_is_sas_phy_local(phy)) { in sas_phy_reset()
323 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent); in sas_phy_reset()
325 struct asd_sas_phy *asd_phy = sas_ha->sas_phy[phy->number]; in sas_phy_reset()
327 to_sas_internal(sas_ha->core.shost->transportt); in sas_phy_reset()
329 ret = i->dft->lldd_control_phy(asd_phy, reset_type, NULL); in sas_phy_reset()
331 struct sas_rphy *rphy = dev_to_rphy(phy->dev.parent); in sas_phy_reset()
333 ret = sas_smp_phy_control(ddev, phy->number, reset_type, NULL); in sas_phy_reset()
338 int sas_set_phy_speed(struct sas_phy *phy, in sas_set_phy_speed() argument
343 if ((rates->minimum_linkrate && in sas_set_phy_speed()
344 rates->minimum_linkrate > phy->maximum_linkrate) || in sas_set_phy_speed()
345 (rates->maximum_linkrate && in sas_set_phy_speed()
346 rates->maximum_linkrate < phy->minimum_linkrate)) in sas_set_phy_speed()
347 return -EINVAL; in sas_set_phy_speed()
349 if (rates->minimum_linkrate && in sas_set_phy_speed()
350 rates->minimum_linkrate < phy->minimum_linkrate_hw) in sas_set_phy_speed()
351 rates->minimum_linkrate = phy->minimum_linkrate_hw; in sas_set_phy_speed()
353 if (rates->maximum_linkrate && in sas_set_phy_speed()
354 rates->maximum_linkrate > phy->maximum_linkrate_hw) in sas_set_phy_speed()
355 rates->maximum_linkrate = phy->maximum_linkrate_hw; in sas_set_phy_speed()
357 if (scsi_is_sas_phy_local(phy)) { in sas_set_phy_speed()
358 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent); in sas_set_phy_speed()
360 struct asd_sas_phy *asd_phy = sas_ha->sas_phy[phy->number]; in sas_set_phy_speed()
362 to_sas_internal(sas_ha->core.shost->transportt); in sas_set_phy_speed()
364 ret = i->dft->lldd_control_phy(asd_phy, PHY_FUNC_SET_LINK_RATE, in sas_set_phy_speed()
367 struct sas_rphy *rphy = dev_to_rphy(phy->dev.parent); in sas_set_phy_speed()
369 ret = sas_smp_phy_control(ddev, phy->number, in sas_set_phy_speed()
381 set_bit(SAS_HA_REGISTERED, &ha->state); in sas_prep_resume_ha()
384 for (i = 0; i < ha->num_phys; i++) { in sas_prep_resume_ha()
385 struct asd_sas_phy *phy = ha->sas_phy[i]; in sas_prep_resume_ha() local
387 memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE); in sas_prep_resume_ha()
388 phy->frame_rcvd_size = 0; in sas_prep_resume_ha()
397 for (i = 0; i < ha->num_phys; i++) { in phys_suspended()
398 struct asd_sas_phy *phy = ha->sas_phy[i]; in phys_suspended() local
400 if (phy->suspended) in phys_suspended()
413 * at this point we may be racing the phy coming back (as posted in sas_resume_ha()
415 * libsas context check that the phy remains suspended before in sas_resume_ha()
420 dev_info(ha->dev, "waiting up to 25 seconds for %d phy%s to resume\n", in sas_resume_ha()
422 wait_event_timeout(ha->eh_wait_q, phys_suspended(ha) == 0, tmo); in sas_resume_ha()
423 for (i = 0; i < ha->num_phys; i++) { in sas_resume_ha()
424 struct asd_sas_phy *phy = ha->sas_phy[i]; in sas_resume_ha() local
426 if (phy->suspended) { in sas_resume_ha()
427 dev_warn(&phy->phy->dev, "resume timeout\n"); in sas_resume_ha()
428 sas_notify_phy_event(phy, PHYE_RESUME_TIMEOUT); in sas_resume_ha()
435 scsi_unblock_requests(ha->core.shost); in sas_resume_ha()
445 scsi_block_requests(ha->core.shost); in sas_suspend_ha()
446 for (i = 0; i < ha->num_phys; i++) { in sas_suspend_ha()
447 struct asd_sas_port *port = ha->sas_port[i]; in sas_suspend_ha()
453 mutex_lock(&ha->drain_mutex); in sas_suspend_ha()
455 mutex_unlock(&ha->drain_mutex); in sas_suspend_ha()
459 static void sas_phy_release(struct sas_phy *phy) in sas_phy_release() argument
461 kfree(phy->hostdata); in sas_phy_release()
462 phy->hostdata = NULL; in sas_phy_release()
467 struct sas_phy_data *d = container_of(work, typeof(*d), reset_work.work); in phy_reset_work() local
469 d->reset_result = transport_sas_phy_reset(d->phy, d->hard_reset); in phy_reset_work()
474 struct sas_phy_data *d = container_of(work, typeof(*d), enable_work.work); in phy_enable_work() local
476 d->enable_result = sas_phy_enable(d->phy, d->enable); in phy_enable_work()
479 static int sas_phy_setup(struct sas_phy *phy) in sas_phy_setup() argument
481 struct sas_phy_data *d = kzalloc(sizeof(*d), GFP_KERNEL); in sas_phy_setup() local
483 if (!d) in sas_phy_setup()
484 return -ENOMEM; in sas_phy_setup()
486 mutex_init(&d->event_lock); in sas_phy_setup()
487 INIT_SAS_WORK(&d->reset_work, phy_reset_work); in sas_phy_setup()
488 INIT_SAS_WORK(&d->enable_work, phy_enable_work); in sas_phy_setup()
489 d->phy = phy; in sas_phy_setup()
490 phy->hostdata = d; in sas_phy_setup()
495 static int queue_phy_reset(struct sas_phy *phy, int hard_reset) in queue_phy_reset() argument
497 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent); in queue_phy_reset()
499 struct sas_phy_data *d = phy->hostdata; in queue_phy_reset() local
502 if (!d) in queue_phy_reset()
503 return -ENOMEM; in queue_phy_reset()
505 /* libsas workqueue coordinates ata-eh reset with discovery */ in queue_phy_reset()
506 mutex_lock(&d->event_lock); in queue_phy_reset()
507 d->reset_result = 0; in queue_phy_reset()
508 d->hard_reset = hard_reset; in queue_phy_reset()
510 spin_lock_irq(&ha->lock); in queue_phy_reset()
511 sas_queue_work(ha, &d->reset_work); in queue_phy_reset()
512 spin_unlock_irq(&ha->lock); in queue_phy_reset()
516 rc = d->reset_result; in queue_phy_reset()
517 mutex_unlock(&d->event_lock); in queue_phy_reset()
522 static int queue_phy_enable(struct sas_phy *phy, int enable) in queue_phy_enable() argument
524 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent); in queue_phy_enable()
526 struct sas_phy_data *d = phy->hostdata; in queue_phy_enable() local
529 if (!d) in queue_phy_enable()
530 return -ENOMEM; in queue_phy_enable()
532 /* libsas workqueue coordinates ata-eh reset with discovery */ in queue_phy_enable()
533 mutex_lock(&d->event_lock); in queue_phy_enable()
534 d->enable_result = 0; in queue_phy_enable()
535 d->enable = enable; in queue_phy_enable()
537 spin_lock_irq(&ha->lock); in queue_phy_enable()
538 sas_queue_work(ha, &d->enable_work); in queue_phy_enable()
539 spin_unlock_irq(&ha->lock); in queue_phy_enable()
543 rc = d->enable_result; in queue_phy_enable()
544 mutex_unlock(&d->event_lock); in queue_phy_enable()
565 return scnprintf(buf, PAGE_SIZE, "%u\n", sha->event_thres); in phy_event_threshold_show()
575 sha->event_thres = simple_strtol(buf, NULL, 10); in phy_event_threshold_store()
578 if (sha->event_thres < 32) in phy_event_threshold_store()
579 sha->event_thres = 32; in phy_event_threshold_store()
600 i->dft = dft; in sas_domain_attach_transport()
601 stt->create_work_queue = 1; in sas_domain_attach_transport()
602 stt->eh_strategy_handler = sas_scsi_recover_host; in sas_domain_attach_transport()
609 struct asd_sas_event *sas_alloc_event(struct asd_sas_phy *phy) in sas_alloc_event() argument
613 struct sas_ha_struct *sas_ha = phy->ha; in sas_alloc_event()
615 to_sas_internal(sas_ha->core.shost->transportt); in sas_alloc_event()
621 atomic_inc(&phy->event_nr); in sas_alloc_event()
623 if (atomic_read(&phy->event_nr) > phy->ha->event_thres) { in sas_alloc_event()
624 if (i->dft->lldd_control_phy) { in sas_alloc_event()
625 if (cmpxchg(&phy->in_shutdown, 0, 1) == 0) { in sas_alloc_event()
626 sas_printk("The phy%02d bursting events, shut it down.\n", in sas_alloc_event()
627 phy->id); in sas_alloc_event()
628 sas_notify_phy_event(phy, PHYE_SHUTDOWN); in sas_alloc_event()
631 /* Do not support PHY control, stop allocating events */ in sas_alloc_event()
632 WARN_ONCE(1, "PHY control not supported.\n"); in sas_alloc_event()
634 atomic_dec(&phy->event_nr); in sas_alloc_event()
644 struct asd_sas_phy *phy = event->phy; in sas_free_event() local
647 atomic_dec(&phy->event_nr); in sas_free_event()
650 /* ---------- SAS Class register/unregister ---------- */
666 return -ENOMEM; in sas_class_init()