Lines Matching +full:phy +full:- +full:device
1 // SPDX-License-Identifier: GPL-2.0
3 * driver for Microsemi PQI-based storage controllers
4 * Copyright (c) 2019-2020 Microchip Technology Inc. and its subsidiaries
5 * Copyright (c) 2016-2018 Microsemi Corporation
6 * Copyright (c) 2016 PMC-Sierra, Inc.
13 #include <linux/bsg-lib.h>
23 struct sas_phy *phy; in pqi_alloc_sas_phy() local
29 phy = sas_phy_alloc(pqi_sas_port->parent_node->parent_dev, in pqi_alloc_sas_phy()
30 pqi_sas_port->next_phy_index); in pqi_alloc_sas_phy()
31 if (!phy) { in pqi_alloc_sas_phy()
36 pqi_sas_port->next_phy_index++; in pqi_alloc_sas_phy()
37 pqi_sas_phy->phy = phy; in pqi_alloc_sas_phy()
38 pqi_sas_phy->parent_port = pqi_sas_port; in pqi_alloc_sas_phy()
45 struct sas_phy *phy = pqi_sas_phy->phy; in pqi_free_sas_phy() local
47 sas_port_delete_phy(pqi_sas_phy->parent_port->port, phy); in pqi_free_sas_phy()
48 if (pqi_sas_phy->added_to_port) in pqi_free_sas_phy()
49 list_del(&pqi_sas_phy->phy_list_entry); in pqi_free_sas_phy()
50 sas_phy_delete(phy); in pqi_free_sas_phy()
58 struct sas_phy *phy; in pqi_sas_port_add_phy() local
61 pqi_sas_port = pqi_sas_phy->parent_port; in pqi_sas_port_add_phy()
62 phy = pqi_sas_phy->phy; in pqi_sas_port_add_phy()
64 identify = &phy->identify; in pqi_sas_port_add_phy()
66 identify->sas_address = pqi_sas_port->sas_address; in pqi_sas_port_add_phy()
67 identify->device_type = SAS_END_DEVICE; in pqi_sas_port_add_phy()
68 identify->initiator_port_protocols = SAS_PROTOCOL_STP; in pqi_sas_port_add_phy()
69 identify->target_port_protocols = SAS_PROTOCOL_STP; in pqi_sas_port_add_phy()
70 phy->minimum_linkrate_hw = SAS_LINK_RATE_UNKNOWN; in pqi_sas_port_add_phy()
71 phy->maximum_linkrate_hw = SAS_LINK_RATE_UNKNOWN; in pqi_sas_port_add_phy()
72 phy->minimum_linkrate = SAS_LINK_RATE_UNKNOWN; in pqi_sas_port_add_phy()
73 phy->maximum_linkrate = SAS_LINK_RATE_UNKNOWN; in pqi_sas_port_add_phy()
74 phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN; in pqi_sas_port_add_phy()
76 rc = sas_phy_add(pqi_sas_phy->phy); in pqi_sas_port_add_phy()
80 sas_port_add_phy(pqi_sas_port->port, pqi_sas_phy->phy); in pqi_sas_port_add_phy()
81 list_add_tail(&pqi_sas_phy->phy_list_entry, in pqi_sas_port_add_phy()
82 &pqi_sas_port->phy_list_head); in pqi_sas_port_add_phy()
83 pqi_sas_phy->added_to_port = true; in pqi_sas_port_add_phy()
93 identify = &rphy->identify; in pqi_sas_port_add_rphy()
94 identify->sas_address = pqi_sas_port->sas_address; in pqi_sas_port_add_rphy()
96 if (pqi_sas_port->device && in pqi_sas_port_add_rphy()
97 pqi_sas_port->device->is_expander_smp_device) { in pqi_sas_port_add_rphy()
98 identify->initiator_port_protocols = SAS_PROTOCOL_SMP; in pqi_sas_port_add_rphy()
99 identify->target_port_protocols = SAS_PROTOCOL_SMP; in pqi_sas_port_add_rphy()
101 identify->initiator_port_protocols = SAS_PROTOCOL_STP; in pqi_sas_port_add_rphy()
102 identify->target_port_protocols = SAS_PROTOCOL_STP; in pqi_sas_port_add_rphy()
110 if (pqi_sas_port->device && in pqi_sas_rphy_alloc()
111 pqi_sas_port->device->is_expander_smp_device) in pqi_sas_rphy_alloc()
112 return sas_expander_alloc(pqi_sas_port->port, in pqi_sas_rphy_alloc()
115 return sas_end_device_alloc(pqi_sas_port->port); in pqi_sas_rphy_alloc()
120 struct pqi_scsi_dev *device) in pqi_alloc_sas_port() argument
130 INIT_LIST_HEAD(&pqi_sas_port->phy_list_head); in pqi_alloc_sas_port()
131 pqi_sas_port->parent_node = pqi_sas_node; in pqi_alloc_sas_port()
133 port = sas_port_alloc_num(pqi_sas_node->parent_dev); in pqi_alloc_sas_port()
141 pqi_sas_port->port = port; in pqi_alloc_sas_port()
142 pqi_sas_port->sas_address = sas_address; in pqi_alloc_sas_port()
143 pqi_sas_port->device = device; in pqi_alloc_sas_port()
144 list_add_tail(&pqi_sas_port->port_list_entry, in pqi_alloc_sas_port()
145 &pqi_sas_node->port_list_head); in pqi_alloc_sas_port()
163 &pqi_sas_port->phy_list_head, phy_list_entry) in pqi_free_sas_port()
166 sas_port_delete(pqi_sas_port->port); in pqi_free_sas_port()
167 list_del(&pqi_sas_port->port_list_entry); in pqi_free_sas_port()
171 static struct pqi_sas_node *pqi_alloc_sas_node(struct device *parent_dev) in pqi_alloc_sas_node()
177 pqi_sas_node->parent_dev = parent_dev; in pqi_alloc_sas_node()
178 INIT_LIST_HEAD(&pqi_sas_node->port_list_head); in pqi_alloc_sas_node()
193 &pqi_sas_node->port_list_head, port_list_entry) in pqi_free_sas_node()
202 struct pqi_scsi_dev *device; in pqi_find_device_by_sas_rphy() local
204 list_for_each_entry(device, &ctrl_info->scsi_device_list, in pqi_find_device_by_sas_rphy()
206 if (!device->sas_port) in pqi_find_device_by_sas_rphy()
208 if (device->sas_port->rphy == rphy) in pqi_find_device_by_sas_rphy()
209 return device; in pqi_find_device_by_sas_rphy()
218 struct device *parent_dev; in pqi_add_sas_host()
223 parent_dev = &shost->shost_dev; in pqi_add_sas_host()
227 return -ENOMEM; in pqi_add_sas_host()
230 ctrl_info->sas_address, NULL); in pqi_add_sas_host()
232 rc = -ENODEV; in pqi_add_sas_host()
238 rc = -ENODEV; in pqi_add_sas_host()
246 ctrl_info->sas_host = pqi_sas_node; in pqi_add_sas_host()
262 pqi_free_sas_node(ctrl_info->sas_host); in pqi_delete_sas_host()
266 struct pqi_scsi_dev *device) in pqi_add_sas_device() argument
273 device->sas_address, device); in pqi_add_sas_device()
275 return -ENOMEM; in pqi_add_sas_device()
279 rc = -ENODEV; in pqi_add_sas_device()
283 pqi_sas_port->rphy = rphy; in pqi_add_sas_device()
284 device->sas_port = pqi_sas_port; in pqi_add_sas_device()
294 device->sas_port = NULL; in pqi_add_sas_device()
299 void pqi_remove_sas_device(struct pqi_scsi_dev *device) in pqi_remove_sas_device() argument
301 if (device->sas_port) { in pqi_remove_sas_device()
302 pqi_free_sas_port(device->sas_port); in pqi_remove_sas_device()
303 device->sas_port = NULL; in pqi_remove_sas_device()
307 static int pqi_sas_get_linkerrors(struct sas_phy *phy) in pqi_sas_get_linkerrors() argument
320 struct pqi_scsi_dev *device; in pqi_sas_get_enclosure_identifier() local
323 return -ENODEV; in pqi_sas_get_enclosure_identifier()
327 spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags); in pqi_sas_get_enclosure_identifier()
331 rc = -ENODEV; in pqi_sas_get_enclosure_identifier()
335 if (found_device->devtype == TYPE_ENCLOSURE) { in pqi_sas_get_enclosure_identifier()
336 *identifier = get_unaligned_be64(&found_device->wwid); in pqi_sas_get_enclosure_identifier()
341 if (found_device->box_index == 0xff || in pqi_sas_get_enclosure_identifier()
342 found_device->phys_box_on_bus == 0 || in pqi_sas_get_enclosure_identifier()
343 found_device->bay == 0xff) { in pqi_sas_get_enclosure_identifier()
344 rc = -EINVAL; in pqi_sas_get_enclosure_identifier()
348 list_for_each_entry(device, &ctrl_info->scsi_device_list, in pqi_sas_get_enclosure_identifier()
350 if (device->devtype == TYPE_ENCLOSURE && in pqi_sas_get_enclosure_identifier()
351 device->box_index == found_device->box_index && in pqi_sas_get_enclosure_identifier()
352 device->phys_box_on_bus == in pqi_sas_get_enclosure_identifier()
353 found_device->phys_box_on_bus && in pqi_sas_get_enclosure_identifier()
354 memcmp(device->phys_connector, in pqi_sas_get_enclosure_identifier()
355 found_device->phys_connector, 2) == 0) { in pqi_sas_get_enclosure_identifier()
357 get_unaligned_be64(&device->wwid); in pqi_sas_get_enclosure_identifier()
363 if (found_device->phy_connected_dev_type != SA_DEVICE_TYPE_CONTROLLER) { in pqi_sas_get_enclosure_identifier()
364 rc = -EINVAL; in pqi_sas_get_enclosure_identifier()
368 list_for_each_entry(device, &ctrl_info->scsi_device_list, in pqi_sas_get_enclosure_identifier()
370 if (device->devtype == TYPE_ENCLOSURE && in pqi_sas_get_enclosure_identifier()
371 CISS_GET_DRIVE_NUMBER(device->scsi3addr) == in pqi_sas_get_enclosure_identifier()
373 *identifier = get_unaligned_be64(&device->wwid); in pqi_sas_get_enclosure_identifier()
379 rc = -EINVAL; in pqi_sas_get_enclosure_identifier()
381 spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); in pqi_sas_get_enclosure_identifier()
391 struct pqi_scsi_dev *device; in pqi_sas_get_bay_identifier() local
395 return -ENODEV; in pqi_sas_get_bay_identifier()
399 spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags); in pqi_sas_get_bay_identifier()
400 device = pqi_find_device_by_sas_rphy(ctrl_info, rphy); in pqi_sas_get_bay_identifier()
402 if (!device) { in pqi_sas_get_bay_identifier()
403 rc = -ENODEV; in pqi_sas_get_bay_identifier()
407 if (device->bay == 0xff) in pqi_sas_get_bay_identifier()
408 rc = -EINVAL; in pqi_sas_get_bay_identifier()
410 rc = device->bay; in pqi_sas_get_bay_identifier()
413 spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); in pqi_sas_get_bay_identifier()
418 static int pqi_sas_phy_reset(struct sas_phy *phy, int hard_reset) in pqi_sas_phy_reset() argument
423 static int pqi_sas_phy_enable(struct sas_phy *phy, int enable) in pqi_sas_phy_enable() argument
428 static int pqi_sas_phy_setup(struct sas_phy *phy) in pqi_sas_phy_setup() argument
433 static void pqi_sas_phy_release(struct sas_phy *phy) in pqi_sas_phy_release() argument
437 static int pqi_sas_phy_speed(struct sas_phy *phy, in pqi_sas_phy_speed() argument
440 return -EINVAL; in pqi_sas_phy_speed()
460 req_size = job->request_payload.payload_len; in pqi_build_csmi_smp_passthru_buffer()
461 resp_size = job->reply_payload.payload_len; in pqi_build_csmi_smp_passthru_buffer()
463 ioctl_header = &smp_buf->ioctl_header; in pqi_build_csmi_smp_passthru_buffer()
464 put_unaligned_le32(sizeof(smp_buf->ioctl_header), in pqi_build_csmi_smp_passthru_buffer()
465 &ioctl_header->header_length); in pqi_build_csmi_smp_passthru_buffer()
466 put_unaligned_le32(CSMI_IOCTL_TIMEOUT, &ioctl_header->timeout); in pqi_build_csmi_smp_passthru_buffer()
468 &ioctl_header->control_code); in pqi_build_csmi_smp_passthru_buffer()
469 put_unaligned_le32(sizeof(smp_buf->parameters), &ioctl_header->length); in pqi_build_csmi_smp_passthru_buffer()
471 parameters = &smp_buf->parameters; in pqi_build_csmi_smp_passthru_buffer()
472 parameters->phy_identifier = rphy->identify.phy_identifier; in pqi_build_csmi_smp_passthru_buffer()
473 parameters->port_identifier = 0; in pqi_build_csmi_smp_passthru_buffer()
474 parameters->connection_rate = 0; in pqi_build_csmi_smp_passthru_buffer()
475 put_unaligned_be64(rphy->identify.sas_address, in pqi_build_csmi_smp_passthru_buffer()
476 ¶meters->destination_sas_address); in pqi_build_csmi_smp_passthru_buffer()
479 req_size -= SMP_CRC_FIELD_LENGTH; in pqi_build_csmi_smp_passthru_buffer()
481 put_unaligned_le32(req_size, ¶meters->request_length); in pqi_build_csmi_smp_passthru_buffer()
482 put_unaligned_le32(resp_size, ¶meters->response_length); in pqi_build_csmi_smp_passthru_buffer()
484 sg_copy_to_buffer(job->request_payload.sg_list, in pqi_build_csmi_smp_passthru_buffer()
485 job->reply_payload.sg_cnt, ¶meters->request, in pqi_build_csmi_smp_passthru_buffer()
495 sg_copy_from_buffer(job->reply_payload.sg_list, in pqi_build_sas_smp_handler_reply()
496 job->reply_payload.sg_cnt, &smp_buf->parameters.response, in pqi_build_sas_smp_handler_reply()
497 le32_to_cpu(smp_buf->parameters.response_length)); in pqi_build_sas_smp_handler_reply()
499 job->reply_len = le16_to_cpu(error_info->sense_data_length); in pqi_build_sas_smp_handler_reply()
500 memcpy(job->reply, error_info->data, in pqi_build_sas_smp_handler_reply()
501 le16_to_cpu(error_info->sense_data_length)); in pqi_build_sas_smp_handler_reply()
503 return job->reply_payload.payload_len - in pqi_build_sas_smp_handler_reply()
504 get_unaligned_le32(&error_info->data_in_transferred); in pqi_build_sas_smp_handler_reply()
518 if (job->reply_payload.payload_len == 0) { in pqi_sas_smp_handler()
519 rc = -ENOMEM; in pqi_sas_smp_handler()
524 rc = -EINVAL; in pqi_sas_smp_handler()
528 if (rphy->identify.device_type != SAS_FANOUT_EXPANDER_DEVICE) { in pqi_sas_smp_handler()
529 rc = -EINVAL; in pqi_sas_smp_handler()
533 if (job->request_payload.sg_cnt > 1 || job->reply_payload.sg_cnt > 1) { in pqi_sas_smp_handler()
534 rc = -EINVAL; in pqi_sas_smp_handler()
540 rc = -ENOMEM; in pqi_sas_smp_handler()