Lines Matching +full:phy +full:- +full:device

1 // SPDX-License-Identifier: GPL-2.0
3 * driver for Microchip PQI-based storage controllers
4 * Copyright (c) 2019-2023 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_ALL; in pqi_sas_port_add_phy()
69 identify->target_port_protocols = SAS_PROTOCOL_ALL; 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()
95 identify->phy_identifier = pqi_sas_port->device->phy_id; in pqi_sas_port_add_rphy()
97 identify->initiator_port_protocols = SAS_PROTOCOL_ALL; in pqi_sas_port_add_rphy()
98 identify->target_port_protocols = SAS_PROTOCOL_STP; in pqi_sas_port_add_rphy()
100 switch (pqi_sas_port->device->device_type) { in pqi_sas_port_add_rphy()
104 identify->target_port_protocols = SAS_PROTOCOL_SSP; in pqi_sas_port_add_rphy()
107 identify->target_port_protocols = SAS_PROTOCOL_SMP; in pqi_sas_port_add_rphy()
119 if (pqi_sas_port->device && pqi_sas_port->device->is_expander_smp_device) in pqi_sas_rphy_alloc()
120 return sas_expander_alloc(pqi_sas_port->port, in pqi_sas_rphy_alloc()
123 return sas_end_device_alloc(pqi_sas_port->port); in pqi_sas_rphy_alloc()
128 struct pqi_scsi_dev *device) in pqi_alloc_sas_port() argument
138 INIT_LIST_HEAD(&pqi_sas_port->phy_list_head); in pqi_alloc_sas_port()
139 pqi_sas_port->parent_node = pqi_sas_node; in pqi_alloc_sas_port()
141 port = sas_port_alloc_num(pqi_sas_node->parent_dev); in pqi_alloc_sas_port()
149 pqi_sas_port->port = port; in pqi_alloc_sas_port()
150 pqi_sas_port->sas_address = sas_address; in pqi_alloc_sas_port()
151 pqi_sas_port->device = device; in pqi_alloc_sas_port()
152 list_add_tail(&pqi_sas_port->port_list_entry, in pqi_alloc_sas_port()
153 &pqi_sas_node->port_list_head); in pqi_alloc_sas_port()
171 &pqi_sas_port->phy_list_head, phy_list_entry) in pqi_free_sas_port()
174 sas_port_delete(pqi_sas_port->port); in pqi_free_sas_port()
175 list_del(&pqi_sas_port->port_list_entry); in pqi_free_sas_port()
179 static struct pqi_sas_node *pqi_alloc_sas_node(struct device *parent_dev) in pqi_alloc_sas_node()
185 pqi_sas_node->parent_dev = parent_dev; in pqi_alloc_sas_node()
186 INIT_LIST_HEAD(&pqi_sas_node->port_list_head); in pqi_alloc_sas_node()
201 &pqi_sas_node->port_list_head, port_list_entry) in pqi_free_sas_node()
210 struct pqi_scsi_dev *device; in pqi_find_device_by_sas_rphy() local
212 list_for_each_entry(device, &ctrl_info->scsi_device_list, in pqi_find_device_by_sas_rphy()
214 if (!device->sas_port) in pqi_find_device_by_sas_rphy()
216 if (device->sas_port->rphy == rphy) in pqi_find_device_by_sas_rphy()
217 return device; in pqi_find_device_by_sas_rphy()
226 struct device *parent_dev; in pqi_add_sas_host()
231 parent_dev = &shost->shost_dev; in pqi_add_sas_host()
235 return -ENOMEM; in pqi_add_sas_host()
238 ctrl_info->sas_address, NULL); in pqi_add_sas_host()
240 rc = -ENODEV; in pqi_add_sas_host()
246 rc = -ENODEV; in pqi_add_sas_host()
254 ctrl_info->sas_host = pqi_sas_node; in pqi_add_sas_host()
270 pqi_free_sas_node(ctrl_info->sas_host); in pqi_delete_sas_host()
274 struct pqi_scsi_dev *device) in pqi_add_sas_device() argument
281 device->sas_address, device); in pqi_add_sas_device()
283 return -ENOMEM; in pqi_add_sas_device()
287 rc = -ENODEV; in pqi_add_sas_device()
291 pqi_sas_port->rphy = rphy; in pqi_add_sas_device()
292 device->sas_port = pqi_sas_port; in pqi_add_sas_device()
304 device->sas_port = NULL; in pqi_add_sas_device()
309 void pqi_remove_sas_device(struct pqi_scsi_dev *device) in pqi_remove_sas_device() argument
311 if (device->sas_port) { in pqi_remove_sas_device()
312 pqi_free_sas_port(device->sas_port); in pqi_remove_sas_device()
313 device->sas_port = NULL; in pqi_remove_sas_device()
317 static int pqi_sas_get_linkerrors(struct sas_phy *phy) in pqi_sas_get_linkerrors() argument
330 struct pqi_scsi_dev *device; in pqi_sas_get_enclosure_identifier() local
333 return -ENODEV; in pqi_sas_get_enclosure_identifier()
337 spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags); in pqi_sas_get_enclosure_identifier()
341 rc = -ENODEV; in pqi_sas_get_enclosure_identifier()
345 if (found_device->devtype == TYPE_ENCLOSURE) { in pqi_sas_get_enclosure_identifier()
346 *identifier = get_unaligned_be64(&found_device->wwid[8]); in pqi_sas_get_enclosure_identifier()
351 if (found_device->box_index == 0xff || in pqi_sas_get_enclosure_identifier()
352 found_device->phys_box_on_bus == 0 || in pqi_sas_get_enclosure_identifier()
353 found_device->bay == 0xff) { in pqi_sas_get_enclosure_identifier()
354 rc = -EINVAL; in pqi_sas_get_enclosure_identifier()
358 list_for_each_entry(device, &ctrl_info->scsi_device_list, in pqi_sas_get_enclosure_identifier()
360 if (device->devtype == TYPE_ENCLOSURE && in pqi_sas_get_enclosure_identifier()
361 device->box_index == found_device->box_index && in pqi_sas_get_enclosure_identifier()
362 device->phys_box_on_bus == in pqi_sas_get_enclosure_identifier()
363 found_device->phys_box_on_bus && in pqi_sas_get_enclosure_identifier()
364 memcmp(device->phys_connector, in pqi_sas_get_enclosure_identifier()
365 found_device->phys_connector, 2) == 0) { in pqi_sas_get_enclosure_identifier()
367 get_unaligned_be64(&device->wwid[8]); in pqi_sas_get_enclosure_identifier()
373 if (found_device->phy_connected_dev_type != SA_DEVICE_TYPE_CONTROLLER) { in pqi_sas_get_enclosure_identifier()
374 rc = -EINVAL; in pqi_sas_get_enclosure_identifier()
378 list_for_each_entry(device, &ctrl_info->scsi_device_list, in pqi_sas_get_enclosure_identifier()
380 if (device->devtype == TYPE_ENCLOSURE && in pqi_sas_get_enclosure_identifier()
381 CISS_GET_DRIVE_NUMBER(device->scsi3addr) == in pqi_sas_get_enclosure_identifier()
383 *identifier = get_unaligned_be64(&device->wwid[8]); in pqi_sas_get_enclosure_identifier()
389 rc = -EINVAL; in pqi_sas_get_enclosure_identifier()
391 spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); in pqi_sas_get_enclosure_identifier()
401 struct pqi_scsi_dev *device; in pqi_sas_get_bay_identifier() local
405 return -ENODEV; in pqi_sas_get_bay_identifier()
409 spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags); in pqi_sas_get_bay_identifier()
410 device = pqi_find_device_by_sas_rphy(ctrl_info, rphy); in pqi_sas_get_bay_identifier()
412 if (!device) { in pqi_sas_get_bay_identifier()
413 rc = -ENODEV; in pqi_sas_get_bay_identifier()
417 if (device->bay == 0xff) in pqi_sas_get_bay_identifier()
418 rc = -EINVAL; in pqi_sas_get_bay_identifier()
420 rc = device->bay; in pqi_sas_get_bay_identifier()
423 spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); in pqi_sas_get_bay_identifier()
428 static int pqi_sas_phy_reset(struct sas_phy *phy, int hard_reset) in pqi_sas_phy_reset() argument
433 static int pqi_sas_phy_enable(struct sas_phy *phy, int enable) in pqi_sas_phy_enable() argument
438 static int pqi_sas_phy_setup(struct sas_phy *phy) in pqi_sas_phy_setup() argument
443 static void pqi_sas_phy_release(struct sas_phy *phy) in pqi_sas_phy_release() argument
447 static int pqi_sas_phy_speed(struct sas_phy *phy, in pqi_sas_phy_speed() argument
450 return -EINVAL; in pqi_sas_phy_speed()
470 req_size = job->request_payload.payload_len; in pqi_build_csmi_smp_passthru_buffer()
471 resp_size = job->reply_payload.payload_len; in pqi_build_csmi_smp_passthru_buffer()
473 ioctl_header = &smp_buf->ioctl_header; in pqi_build_csmi_smp_passthru_buffer()
474 put_unaligned_le32(sizeof(smp_buf->ioctl_header), in pqi_build_csmi_smp_passthru_buffer()
475 &ioctl_header->header_length); in pqi_build_csmi_smp_passthru_buffer()
476 put_unaligned_le32(CSMI_IOCTL_TIMEOUT, &ioctl_header->timeout); in pqi_build_csmi_smp_passthru_buffer()
478 &ioctl_header->control_code); in pqi_build_csmi_smp_passthru_buffer()
479 put_unaligned_le32(sizeof(smp_buf->parameters), &ioctl_header->length); in pqi_build_csmi_smp_passthru_buffer()
481 parameters = &smp_buf->parameters; in pqi_build_csmi_smp_passthru_buffer()
482 parameters->phy_identifier = rphy->identify.phy_identifier; in pqi_build_csmi_smp_passthru_buffer()
483 parameters->port_identifier = 0; in pqi_build_csmi_smp_passthru_buffer()
484 parameters->connection_rate = 0; in pqi_build_csmi_smp_passthru_buffer()
485 put_unaligned_be64(rphy->identify.sas_address, in pqi_build_csmi_smp_passthru_buffer()
486 &parameters->destination_sas_address); in pqi_build_csmi_smp_passthru_buffer()
489 req_size -= SMP_CRC_FIELD_LENGTH; in pqi_build_csmi_smp_passthru_buffer()
491 put_unaligned_le32(req_size, &parameters->request_length); in pqi_build_csmi_smp_passthru_buffer()
492 put_unaligned_le32(resp_size, &parameters->response_length); in pqi_build_csmi_smp_passthru_buffer()
494 sg_copy_to_buffer(job->request_payload.sg_list, in pqi_build_csmi_smp_passthru_buffer()
495 job->reply_payload.sg_cnt, &parameters->request, in pqi_build_csmi_smp_passthru_buffer()
505 sg_copy_from_buffer(job->reply_payload.sg_list, in pqi_build_sas_smp_handler_reply()
506 job->reply_payload.sg_cnt, &smp_buf->parameters.response, in pqi_build_sas_smp_handler_reply()
507 le32_to_cpu(smp_buf->parameters.response_length)); in pqi_build_sas_smp_handler_reply()
509 job->reply_len = le16_to_cpu(error_info->sense_data_length); in pqi_build_sas_smp_handler_reply()
510 memcpy(job->reply, error_info->data, in pqi_build_sas_smp_handler_reply()
511 le16_to_cpu(error_info->sense_data_length)); in pqi_build_sas_smp_handler_reply()
513 return job->reply_payload.payload_len - in pqi_build_sas_smp_handler_reply()
514 get_unaligned_le32(&error_info->data_in_transferred); in pqi_build_sas_smp_handler_reply()
528 if (job->reply_payload.payload_len == 0) { in pqi_sas_smp_handler()
529 rc = -ENOMEM; in pqi_sas_smp_handler()
534 rc = -EINVAL; in pqi_sas_smp_handler()
538 if (rphy->identify.device_type != SAS_FANOUT_EXPANDER_DEVICE) { in pqi_sas_smp_handler()
539 rc = -EINVAL; in pqi_sas_smp_handler()
543 if (job->request_payload.sg_cnt > 1 || job->reply_payload.sg_cnt > 1) { in pqi_sas_smp_handler()
544 rc = -EINVAL; in pqi_sas_smp_handler()
550 rc = -ENOMEM; in pqi_sas_smp_handler()