1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (C) 2026 LeapIO Tech Inc.
4 *
5 * LeapRAID storage and RAID controller driver.
6 */
7 #include <linux/module.h>
8
9 #include "leapraid_func.h"
10
11 static int poll_queues;
12 module_param(poll_queues, int, 0444);
13 MODULE_PARM_DESC(poll_queues,
14 "specifies the number of queues for io_uring poll mode.");
15
16 static int max_msix_vectors = LEAPRAID_INVALID_MSIX_VECTORS;
17 module_param(max_msix_vectors, int, 0444);
18 MODULE_PARM_DESC(max_msix_vectors, "max msix vectors");
19
20 static void leapraid_remove_device(struct leapraid_adapter *adapter,
21 struct leapraid_sas_dev *sas_dev);
22 static void leapraid_set_led(struct leapraid_adapter *adapter,
23 struct leapraid_sas_dev *sas_dev, bool on);
24 static void leapraid_ublk_io_dev(struct leapraid_adapter *adapter,
25 u64 sas_address,
26 struct leapraid_card_port *port);
27 static void leapraid_clear_cached_boot_dev(struct leapraid_adapter *adapter,
28 void *dev, u32 chnl);
29 static int leapraid_make_adapter_available(struct leapraid_adapter *adapter);
30 static void leapraid_sync_irqs_for_cleanup(struct leapraid_adapter *adapter);
31 static int leapraid_fw_log_init(struct leapraid_adapter *adapter);
32 static bool leapraid_should_skip_poll_work(struct leapraid_adapter *adapter);
33 static int leapraid_make_adapter_ready(struct leapraid_adapter *adapter,
34 enum reset_type type);
35
leapraid_shost_in_recovery(struct Scsi_Host * shost)36 static noinline bool leapraid_shost_in_recovery(struct Scsi_Host *shost)
37 {
38 enum scsi_host_state state;
39
40 state = scsi_get_host_state(shost);
41 return state == SHOST_RECOVERY ||
42 state == SHOST_CANCEL_RECOVERY ||
43 state == SHOST_DEL_RECOVERY ||
44 shost->tmf_in_progress;
45 }
46
leapraid_is_end_dev(u32 dev_type)47 static inline bool leapraid_is_end_dev(u32 dev_type)
48 {
49 return (dev_type & LEAPRAID_DEVTYP_END_DEV) &&
50 ((dev_type & LEAPRAID_DEVTYP_SSP_TGT) ||
51 (dev_type & LEAPRAID_DEVTYP_STP_TGT) ||
52 (dev_type & LEAPRAID_DEVTYP_SATA_DEV));
53 }
54
leapraid_pci_removed(struct leapraid_adapter * adapter)55 bool leapraid_pci_removed(struct leapraid_adapter *adapter)
56 {
57 struct pci_dev *pdev = adapter->pdev;
58 u32 vendor_id;
59
60 if (pci_bus_read_config_dword(pdev->bus,
61 pdev->devfn,
62 PCI_VENDOR_ID,
63 &vendor_id))
64 return true;
65
66 return (vendor_id & LEAPRAID_PCI_VENDOR_ID_MASK) !=
67 LEAPRAID_VENDOR_ID;
68 }
69
leapraid_pci_active(struct leapraid_adapter * adapter)70 static bool leapraid_pci_active(struct leapraid_adapter *adapter)
71 {
72 return !(adapter->access_ctrl.pcie_recovering ||
73 leapraid_pci_removed(adapter));
74 }
75
leapraid_get_reply_vaddr(struct leapraid_adapter * adapter,u32 rep_paddr)76 void *leapraid_get_reply_vaddr(struct leapraid_adapter *adapter, u32 rep_paddr)
77 {
78 if (!rep_paddr)
79 return NULL;
80
81 return adapter->mem_desc.rep_msg +
82 (rep_paddr - (u32)adapter->mem_desc.rep_msg_dma);
83 }
84
leapraid_get_task_desc(struct leapraid_adapter * adapter,u16 taskid)85 void *leapraid_get_task_desc(struct leapraid_adapter *adapter, u16 taskid)
86 {
87 return adapter->mem_desc.task_desc +
88 taskid * LEAPRAID_REQUEST_SIZE;
89 }
90
leapraid_get_sense_buffer(struct leapraid_adapter * adapter,u16 taskid)91 void *leapraid_get_sense_buffer(struct leapraid_adapter *adapter, u16 taskid)
92 {
93 return adapter->mem_desc.sense_data +
94 (taskid - 1) * SCSI_SENSE_BUFFERSIZE;
95 }
96
leapraid_get_sense_buffer_dma(struct leapraid_adapter * adapter,u16 taskid)97 __le32 leapraid_get_sense_buffer_dma(struct leapraid_adapter *adapter,
98 u16 taskid)
99 {
100 return cpu_to_le32(adapter->mem_desc.sense_data_dma +
101 ((taskid - 1) * SCSI_SENSE_BUFFERSIZE));
102 }
103
leapraid_mask_int(struct leapraid_adapter * adapter)104 void leapraid_mask_int(struct leapraid_adapter *adapter)
105 {
106 u32 reg;
107
108 adapter->mask_int = 1;
109 reg = leapraid_readl(&adapter->iomem_base->host_int_mask);
110 reg |= LEAPRAID_TO_SYS_DB_MASK + LEAPRAID_REPLY_INT_MASK +
111 LEAPRAID_RESET_IRQ_MASK;
112 writel(reg, &adapter->iomem_base->host_int_mask);
113 leapraid_readl(&adapter->iomem_base->host_int_mask);
114 }
115
leapraid_unmask_int(struct leapraid_adapter * adapter)116 void leapraid_unmask_int(struct leapraid_adapter *adapter)
117 {
118 u32 reg;
119
120 reg = leapraid_readl(&adapter->iomem_base->host_int_mask);
121 reg &= ~LEAPRAID_REPLY_INT_MASK;
122 writel(reg, &adapter->iomem_base->host_int_mask);
123 adapter->mask_int = 0;
124 }
125
leapraid_overheat_suspend(struct leapraid_adapter * adapter)126 static void leapraid_overheat_suspend(struct leapraid_adapter *adapter)
127 {
128 struct workqueue_struct *wq;
129 struct Scsi_Host *shost;
130 struct pci_dev *pdev;
131
132 if (!adapter)
133 return;
134
135 pdev = adapter->pdev;
136 shost = pci_get_drvdata(pdev);
137 if (!shost) {
138 dev_warn(&pdev->dev,
139 "Overheat suspend failed, invalid host or adapter\n");
140 return;
141 }
142
143 wq = adapter->overheat_desc.fault_overheat_wq;
144 if (!wq)
145 return;
146
147 if (atomic_cmpxchg(&adapter->overheat_desc.thermal_alert, 0, 1))
148 return;
149
150 queue_work(wq, &adapter->overheat_desc.fault_overheat_work);
151 }
152
leapraid_stop_adapter_on_fault(struct leapraid_adapter * adapter,u32 db)153 static void leapraid_stop_adapter_on_fault(struct leapraid_adapter *adapter,
154 u32 db)
155 {
156 u32 adapter_state = db & LEAPRAID_DB_MASK;
157 bool fault_1 = false;
158 bool fault_2 = false;
159
160 fault_1 = adapter_state == LEAPRAID_DB_MASK;
161 fault_2 = adapter_state == LEAPRAID_DB_FAULT &&
162 (db & LEAPRAID_DB_DATA_MASK) == LEAPRAID_DB_OVER_TEMPERATURE;
163
164 if (!fault_1 && !fault_2)
165 return;
166
167 if (fault_1)
168 dev_err(&adapter->pdev->dev,
169 "%s: Doorbell status 0xFFFF!\n", __func__);
170 else
171 dev_err(&adapter->pdev->dev,
172 "%s: Adapter overheating detected!\n", __func__);
173
174 leapraid_overheat_suspend(adapter);
175 }
176
leapraid_get_adapter_state(struct leapraid_adapter * adapter)177 u32 leapraid_get_adapter_state(struct leapraid_adapter *adapter)
178 {
179 u32 db;
180 u32 adapter_state;
181
182 db = leapraid_readl(&adapter->iomem_base->db);
183 adapter_state = db & LEAPRAID_DB_MASK;
184 leapraid_stop_adapter_on_fault(adapter, db);
185 return adapter_state;
186 }
187
leapraid_wait_adapter_ready(struct leapraid_adapter * adapter)188 static bool leapraid_wait_adapter_ready(struct leapraid_adapter *adapter)
189 {
190 u32 cur_state;
191 u32 cnt;
192
193 for (cnt = LEAPRAID_ADAPTER_READY_MAX_RETRY; cnt > 0; cnt--) {
194 cur_state = leapraid_get_adapter_state(adapter);
195
196 if (cur_state == LEAPRAID_DB_READY)
197 return true;
198 if (cur_state == LEAPRAID_DB_FAULT)
199 break;
200 usleep_range(LEAPRAID_ADAPTER_READY_SLEEP_MIN_US,
201 LEAPRAID_ADAPTER_READY_SLEEP_MAX_US);
202 }
203
204 return false;
205 }
206
leapraid_db_wait_int_host(struct leapraid_adapter * adapter)207 static int leapraid_db_wait_int_host(struct leapraid_adapter *adapter)
208 {
209 u32 cnt;
210
211 for (cnt = LEAPRAID_DB_WAIT_MAX_RETRY; cnt > 0; cnt--) {
212 if (leapraid_readl(&adapter->iomem_base->host_int_status) &
213 LEAPRAID_ADAPTER2HOST_DB_STATUS)
214 return 0;
215
216 udelay(LEAPRAID_DB_WAIT_DELAY_US);
217 }
218
219 return -EFAULT;
220 }
221
leapraid_db_wait_ack_and_clear_int(struct leapraid_adapter * adapter)222 static int leapraid_db_wait_ack_and_clear_int(struct leapraid_adapter *adapter)
223 {
224 u32 adapter_state;
225 u32 int_status;
226 u32 cnt;
227
228 for (cnt = LEAPRAID_ADAPTER_READY_MAX_RETRY; cnt > 0; cnt--) {
229 int_status =
230 leapraid_readl(&adapter->iomem_base->host_int_status);
231
232 if (int_status == 0xFFFFFFFF)
233 return -EFAULT;
234
235 if (!(int_status & LEAPRAID_HOST2ADAPTER_DB_STATUS))
236 return 0;
237
238 if (int_status & LEAPRAID_ADAPTER2HOST_DB_STATUS) {
239 adapter_state = leapraid_get_adapter_state(adapter);
240 if (adapter_state == LEAPRAID_DB_FAULT)
241 return -EFAULT;
242 }
243
244 usleep_range(LEAPRAID_ADAPTER_READY_SLEEP_MIN_US,
245 LEAPRAID_ADAPTER_READY_SLEEP_MAX_US);
246 }
247
248 return -EFAULT;
249 }
250
leapraid_handshake_func(struct leapraid_adapter * adapter,int req_bytes,u32 * req,int rep_bytes,u16 * rep)251 static int leapraid_handshake_func(struct leapraid_adapter *adapter,
252 int req_bytes, u32 *req,
253 int rep_bytes, u16 *rep)
254 {
255 int failed, i;
256
257 if (leapraid_readl(&adapter->iomem_base->db) & LEAPRAID_DB_USED) {
258 dev_err(&adapter->pdev->dev, "doorbell used\n");
259 return -EFAULT;
260 }
261
262 if (leapraid_readl(&adapter->iomem_base->host_int_status) &
263 LEAPRAID_ADAPTER2HOST_DB_STATUS)
264 writel(0, &adapter->iomem_base->host_int_status);
265
266 writel(((LEAPRAID_FUNC_HANDSHAKE << LEAPRAID_DB_FUNC_SHIFT) |
267 ((req_bytes / LEAPRAID_DWORDS_BYTE_SIZE) <<
268 LEAPRAID_DB_ADD_DWORDS_SHIFT)),
269 &adapter->iomem_base->db);
270
271 if (leapraid_db_wait_int_host(adapter)) {
272 dev_err(&adapter->pdev->dev, "%d: Wait db interrupt timeout\n",
273 __LINE__);
274 return -EFAULT;
275 }
276
277 writel(0, &adapter->iomem_base->host_int_status);
278
279 if (leapraid_db_wait_ack_and_clear_int(adapter)) {
280 dev_err(&adapter->pdev->dev, "%d: Wait ack failure\n",
281 __LINE__);
282 return -EFAULT;
283 }
284
285 for (i = 0, failed = 0;
286 i < req_bytes / LEAPRAID_DWORDS_BYTE_SIZE && !failed;
287 i++) {
288 writel((u32)req[i], &adapter->iomem_base->db);
289 if (leapraid_db_wait_ack_and_clear_int(adapter))
290 failed = 1;
291 }
292 if (failed) {
293 dev_err(&adapter->pdev->dev, "%d: Wait ack failure\n",
294 __LINE__);
295 return -EFAULT;
296 }
297
298 for (i = 0; i < rep_bytes / LEAPRAID_WORD_BYTE_SIZE; i++) {
299 if (leapraid_db_wait_int_host(adapter)) {
300 dev_err(&adapter->pdev->dev,
301 "%d: Wait db interrupt timeout\n", __LINE__);
302 return -EFAULT;
303 }
304 rep[i] = (u16)(leapraid_readl(&adapter->iomem_base->db)
305 & LEAPRAID_DB_DATA_MASK);
306 writel(0, &adapter->iomem_base->host_int_status);
307 }
308
309 if (leapraid_db_wait_int_host(adapter)) {
310 dev_err(&adapter->pdev->dev, "%d: Wait db interrupt timeout\n",
311 __LINE__);
312 return -EFAULT;
313 }
314
315 writel(0, &adapter->iomem_base->host_int_status);
316
317 return 0;
318 }
319
leapraid_check_adapter_is_op(struct leapraid_adapter * adapter,int wait,const char * caller)320 int leapraid_check_adapter_is_op(struct leapraid_adapter *adapter, int wait,
321 const char *caller)
322 {
323 int wait_count;
324
325 for (wait_count = wait; wait_count > 0; wait_count--) {
326 if (READ_ONCE(adapter->access_ctrl.host_removing)) {
327 dev_warn(&adapter->pdev->dev,
328 "%s: Host is removing\n", caller);
329 return -EFAULT;
330 }
331
332 if (leapraid_pci_removed(adapter)) {
333 dev_warn(&adapter->pdev->dev,
334 "%s: PCI device removed\n", __func__);
335 return -EFAULT;
336 }
337
338 if (leapraid_get_adapter_state(adapter) ==
339 LEAPRAID_DB_OPERATIONAL)
340 return 0;
341
342 dev_dbg(&adapter->pdev->dev,
343 "%s: Wait for adapter to become op status(cnt=%d)\n",
344 caller, wait - wait_count);
345
346 ssleep(1);
347 }
348
349 dev_err(&adapter->pdev->dev,
350 "%s: Adapter failed to become op state, last state=%d\n",
351 caller, leapraid_get_adapter_state(adapter));
352
353 return -EFAULT;
354 }
355
leapraid_get_io_tracker_from_taskid(struct leapraid_adapter * adapter,u16 taskid)356 struct leapraid_io_req_tracker *leapraid_get_io_tracker_from_taskid(
357 struct leapraid_adapter *adapter, u16 taskid)
358 {
359 struct scsi_cmnd *scmd;
360
361 if (WARN_ON(!taskid))
362 return NULL;
363
364 if (WARN_ON(taskid > adapter->shost->can_queue))
365 return NULL;
366
367 scmd = leapraid_get_scmd_from_taskid(adapter, taskid);
368 if (scmd)
369 return scsi_cmd_priv(scmd);
370
371 return NULL;
372 }
373
leapraid_get_cb_idx(struct leapraid_adapter * adapter,u16 taskid)374 static u8 leapraid_get_cb_idx(struct leapraid_adapter *adapter, u16 taskid)
375 {
376 struct leapraid_driver_cmd *sp_cmd;
377 u8 cb_idx = 0xFF;
378
379 if (WARN_ON(!taskid))
380 return cb_idx;
381
382 list_for_each_entry(sp_cmd, &adapter->driver_cmds.special_cmd_list,
383 list)
384 if (taskid == sp_cmd->taskid ||
385 taskid == sp_cmd->hp_taskid ||
386 taskid == sp_cmd->inter_taskid)
387 return sp_cmd->cb_idx;
388
389 WARN_ON(cb_idx == 0xFF);
390 return cb_idx;
391 }
392
leapraid_get_scmd_from_taskid(struct leapraid_adapter * adapter,u16 taskid)393 struct scsi_cmnd *leapraid_get_scmd_from_taskid(
394 struct leapraid_adapter *adapter,
395 u16 taskid)
396 {
397 struct leapraid_scsiio_req *leap_mpi_req;
398 struct leapraid_io_req_tracker *st;
399 struct scsi_cmnd *scmd;
400 u32 uniq_tag;
401
402 if (taskid <= 0 || taskid > adapter->shost->can_queue)
403 return NULL;
404
405 uniq_tag = adapter->mem_desc.taskid_to_uniq_tag[taskid - 1] <<
406 BLK_MQ_UNIQUE_TAG_BITS | (taskid - 1);
407 leap_mpi_req = leapraid_get_task_desc(adapter, taskid);
408 if (!leap_mpi_req->dev_hdl)
409 return NULL;
410
411 scmd = scsi_host_find_tag(adapter->shost, uniq_tag);
412 if (scmd) {
413 st = scsi_cmd_priv(scmd);
414 if (st && st->taskid == taskid)
415 return scmd;
416 }
417
418 return NULL;
419 }
420
leapraid_alloc_scsiio_taskid(struct leapraid_adapter * adapter,struct scsi_cmnd * scmd)421 u16 leapraid_alloc_scsiio_taskid(struct leapraid_adapter *adapter,
422 struct scsi_cmnd *scmd)
423 {
424 struct leapraid_io_req_tracker *request;
425 u16 taskid;
426 u32 tag = scsi_cmd_to_rq(scmd)->tag;
427 u32 unique_tag;
428
429 unique_tag = blk_mq_unique_tag(scsi_cmd_to_rq(scmd));
430 tag = blk_mq_unique_tag_to_tag(unique_tag);
431 adapter->mem_desc.taskid_to_uniq_tag[tag] =
432 blk_mq_unique_tag_to_hwq(unique_tag);
433
434 request = scsi_cmd_priv(scmd);
435 taskid = tag + 1;
436 request->taskid = taskid;
437 request->scmd = scmd;
438 return taskid;
439 }
440
leapraid_check_pending_io(struct leapraid_adapter * adapter)441 static void leapraid_check_pending_io(struct leapraid_adapter *adapter)
442 {
443 if (adapter->access_ctrl.shost_recovering &&
444 adapter->reset_desc.pending_io_cnt) {
445 if (adapter->reset_desc.pending_io_cnt == 1)
446 wake_up(&adapter->reset_desc.reset_wait_queue);
447 adapter->reset_desc.pending_io_cnt--;
448 }
449 }
450
leapraid_clear_io_tracker(struct leapraid_adapter * adapter,struct leapraid_io_req_tracker * io_tracker)451 static void leapraid_clear_io_tracker(
452 struct leapraid_adapter *adapter,
453 struct leapraid_io_req_tracker *io_tracker)
454 {
455 if (!io_tracker)
456 return;
457
458 if (WARN_ON(io_tracker->taskid == 0))
459 return;
460
461 io_tracker->scmd = NULL;
462 }
463
leapraid_is_fixed_taskid(struct leapraid_adapter * adapter,u16 taskid)464 static bool leapraid_is_fixed_taskid(struct leapraid_adapter *adapter,
465 u16 taskid)
466 {
467 struct leapraid_driver_cmds *driver_cmds = &adapter->driver_cmds;
468
469 return (taskid == driver_cmds->ctl_cmd.taskid ||
470 taskid == driver_cmds->tm_cmd.hp_taskid ||
471 taskid == driver_cmds->ctl_cmd.hp_taskid ||
472 taskid == driver_cmds->scan_dev_cmd.inter_taskid ||
473 taskid == driver_cmds->transport_cmd.inter_taskid ||
474 taskid == driver_cmds->cfg_op_cmd.inter_taskid ||
475 taskid == driver_cmds->enc_cmd.inter_taskid ||
476 taskid == driver_cmds->notify_event_cmd.inter_taskid);
477 }
478
leapraid_free_taskid(struct leapraid_adapter * adapter,u16 taskid)479 void leapraid_free_taskid(struct leapraid_adapter *adapter, u16 taskid)
480 {
481 struct leapraid_io_req_tracker *io_tracker;
482 void *task_desc;
483
484 if (leapraid_is_fixed_taskid(adapter, taskid))
485 return;
486
487 if (taskid <= adapter->shost->can_queue) {
488 io_tracker = leapraid_get_io_tracker_from_taskid(adapter,
489 taskid);
490 if (!io_tracker) {
491 leapraid_check_pending_io(adapter);
492 return;
493 }
494
495 task_desc = leapraid_get_task_desc(adapter, taskid);
496 memset(task_desc, 0, LEAPRAID_REQUEST_SIZE);
497 leapraid_clear_io_tracker(adapter, io_tracker);
498 leapraid_check_pending_io(adapter);
499 adapter->mem_desc.taskid_to_uniq_tag[taskid - 1] = 0xFFFF;
500 }
501 }
502
leapraid_get_msix_idx(struct leapraid_adapter * adapter,struct scsi_cmnd * scmd)503 static u8 leapraid_get_msix_idx(struct leapraid_adapter *adapter,
504 struct scsi_cmnd *scmd)
505 {
506 if (scmd && adapter->shost->nr_hw_queues > 1) {
507 u32 tag = blk_mq_unique_tag(scsi_cmd_to_rq(scmd));
508
509 return blk_mq_unique_tag_to_hwq(tag);
510 }
511 return adapter->notification_desc.msix_cpu_map[raw_smp_processor_id()];
512 }
513
leapraid_get_and_set_msix_idx_from_taskid(struct leapraid_adapter * adapter,u16 taskid)514 static u8 leapraid_get_and_set_msix_idx_from_taskid(
515 struct leapraid_adapter *adapter, u16 taskid)
516 {
517 struct leapraid_io_req_tracker *io_tracker = NULL;
518
519 if (taskid <= adapter->shost->can_queue)
520 io_tracker = leapraid_get_io_tracker_from_taskid(adapter,
521 taskid);
522
523 if (!io_tracker)
524 return leapraid_get_msix_idx(adapter, NULL);
525
526 io_tracker->msix_io = leapraid_get_msix_idx(adapter, io_tracker->scmd);
527
528 return io_tracker->msix_io;
529 }
530
leapraid_fire_scsi_io(struct leapraid_adapter * adapter,u16 taskid,u16 handle)531 void leapraid_fire_scsi_io(struct leapraid_adapter *adapter, u16 taskid,
532 u16 handle)
533 {
534 struct leapraid_atomic_req_desc desc;
535
536 desc.flg = LEAPRAID_REQ_DESC_FLG_SCSI_IO;
537 desc.msix_idx = leapraid_get_and_set_msix_idx_from_taskid(adapter,
538 taskid);
539 desc.taskid = cpu_to_le16(taskid);
540 writel((__force u32)cpu_to_le32(*((u32 *)&desc)),
541 &adapter->iomem_base->atomic_req_desc_post);
542 }
543
leapraid_fire_hpr_task(struct leapraid_adapter * adapter,u16 taskid,u16 msix_task)544 void leapraid_fire_hpr_task(struct leapraid_adapter *adapter, u16 taskid,
545 u16 msix_task)
546 {
547 struct leapraid_atomic_req_desc desc;
548
549 desc.flg = LEAPRAID_REQ_DESC_FLG_HPR;
550 desc.msix_idx = msix_task;
551 desc.taskid = cpu_to_le16(taskid);
552 writel((__force u32)cpu_to_le32(*((u32 *)&desc)),
553 &adapter->iomem_base->atomic_req_desc_post);
554 }
555
leapraid_fire_task(struct leapraid_adapter * adapter,u16 taskid)556 void leapraid_fire_task(struct leapraid_adapter *adapter, u16 taskid)
557 {
558 struct leapraid_atomic_req_desc desc;
559
560 desc.flg = LEAPRAID_REQ_DESC_FLG_DFLT_TYPE;
561 desc.msix_idx = leapraid_get_and_set_msix_idx_from_taskid(adapter,
562 taskid);
563 desc.taskid = cpu_to_le16(taskid);
564 writel((__force u32)cpu_to_le32(*((u32 *)&desc)),
565 &adapter->iomem_base->atomic_req_desc_post);
566 }
567
leapraid_clean_active_scsi_cmds(struct leapraid_adapter * adapter)568 void leapraid_clean_active_scsi_cmds(struct leapraid_adapter *adapter)
569 {
570 struct leapraid_io_req_tracker *io_tracker;
571 struct scsi_cmnd *scmd;
572 void *task_desc;
573 u16 taskid;
574
575 leapraid_sync_irqs_for_cleanup(adapter);
576
577 for (taskid = 1; taskid <= adapter->shost->can_queue; taskid++) {
578 scmd = leapraid_get_scmd_from_taskid(adapter, taskid);
579 if (!scmd)
580 continue;
581
582 io_tracker = scsi_cmd_priv(scmd);
583 if (io_tracker && io_tracker->taskid == 0)
584 continue;
585
586 scsi_dma_unmap(scmd);
587 task_desc = leapraid_get_task_desc(adapter, taskid);
588 memset(task_desc, 0, LEAPRAID_REQUEST_SIZE);
589 leapraid_clear_io_tracker(adapter, io_tracker);
590 if (!leapraid_pci_active(adapter) ||
591 adapter->reset_desc.adapter_reset_results != 0 ||
592 atomic_read(&adapter->overheat_desc.thermal_alert) ||
593 adapter->access_ctrl.host_removing)
594 scmd->result = DID_NO_CONNECT << 16;
595 else
596 scmd->result = DID_RESET << LEAPRAID_SCSI_HOST_SHIFT;
597 scsi_done(scmd);
598 }
599 }
600
leapraid_clean_active_driver_cmd(struct leapraid_driver_cmd * cmd)601 static void leapraid_clean_active_driver_cmd(struct leapraid_driver_cmd *cmd)
602 {
603 if (cmd->status & LEAPRAID_CMD_PENDING) {
604 cmd->status |= LEAPRAID_CMD_RESET;
605 complete(&cmd->done);
606 }
607 }
608
leapraid_clean_active_driver_cmds(struct leapraid_adapter * adapter)609 static void leapraid_clean_active_driver_cmds(struct leapraid_adapter *adapter)
610 {
611 struct leapraid_driver_cmds *driver_cmds;
612
613 driver_cmds = &adapter->driver_cmds;
614 leapraid_clean_active_driver_cmd(&driver_cmds->tm_cmd);
615 leapraid_clean_active_driver_cmd(&driver_cmds->transport_cmd);
616 leapraid_clean_active_driver_cmd(&driver_cmds->enc_cmd);
617 leapraid_clean_active_driver_cmd(&driver_cmds->notify_event_cmd);
618 leapraid_clean_active_driver_cmd(&driver_cmds->cfg_op_cmd);
619 leapraid_clean_active_driver_cmd(&driver_cmds->ctl_cmd);
620
621 if (driver_cmds->scan_dev_cmd.status & LEAPRAID_CMD_PENDING) {
622 adapter->scan_dev_desc.scan_dev_failed = 1;
623 driver_cmds->scan_dev_cmd.status |= LEAPRAID_CMD_RESET;
624 if (adapter->scan_dev_desc.driver_loading) {
625 adapter->scan_dev_desc.scan_start_failed =
626 LEAPRAID_ADAPTER_STATUS_INTERNAL_ERROR;
627 adapter->scan_dev_desc.scan_start = 0;
628 } else {
629 complete(&driver_cmds->scan_dev_cmd.done);
630 }
631 }
632 }
633
leapraid_clean_active_cmds(struct leapraid_adapter * adapter)634 static void leapraid_clean_active_cmds(struct leapraid_adapter *adapter)
635 {
636 leapraid_clean_active_driver_cmds(adapter);
637 leapraid_clean_active_fw_evt(adapter);
638 leapraid_clean_active_scsi_cmds(adapter);
639 }
640
leapraid_tgt_not_responding(struct leapraid_adapter * adapter,u16 hdl)641 static void leapraid_tgt_not_responding(struct leapraid_adapter *adapter,
642 u16 hdl)
643 {
644 struct leapraid_starget_priv *starget_priv = NULL;
645 struct leapraid_sas_dev *sas_dev;
646 unsigned long flags = 0;
647 u32 adapter_state;
648
649 if (adapter->access_ctrl.pcie_recovering)
650 return;
651
652 adapter_state = leapraid_get_adapter_state(adapter);
653 if (adapter_state != LEAPRAID_DB_OPERATIONAL)
654 return;
655
656 if (!hdl || hdl > adapter->adapter_attr.features.max_dev_handle ||
657 test_bit(hdl, adapter->dev_topo.pd_hdls))
658 return;
659
660 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags);
661 sas_dev = leapraid_hold_lock_get_sas_dev_by_hdl(adapter, hdl);
662 if (sas_dev && sas_dev->starget && sas_dev->starget->hostdata) {
663 starget_priv = sas_dev->starget->hostdata;
664 starget_priv->deleted = 1;
665 }
666 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags);
667
668 if (starget_priv)
669 starget_priv->hdl = LEAPRAID_INVALID_DEV_HANDLE;
670
671 if (sas_dev)
672 leapraid_sdev_put(sas_dev);
673 }
674
leapraid_tgt_rst_send(struct leapraid_adapter * adapter,u16 hdl)675 static void leapraid_tgt_rst_send(struct leapraid_adapter *adapter, u16 hdl)
676 {
677 struct leapraid_starget_priv *starget_priv = NULL;
678 struct leapraid_sas_dev *sas_dev;
679 struct leapraid_card_port *port;
680 u64 sas_address;
681 unsigned long flags;
682 u32 adapter_state;
683
684 if (adapter->access_ctrl.pcie_recovering)
685 return;
686
687 adapter_state = leapraid_get_adapter_state(adapter);
688 if (adapter_state != LEAPRAID_DB_OPERATIONAL)
689 return;
690
691 if (!hdl || hdl > adapter->adapter_attr.features.max_dev_handle ||
692 test_bit(hdl, adapter->dev_topo.pd_hdls))
693 return;
694
695 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags);
696 sas_dev = leapraid_hold_lock_get_sas_dev_by_hdl(adapter, hdl);
697 if (sas_dev && sas_dev->starget && sas_dev->starget->hostdata) {
698 starget_priv = sas_dev->starget->hostdata;
699 starget_priv->deleted = 1;
700 sas_address = sas_dev->sas_addr;
701 port = sas_dev->card_port;
702 }
703 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags);
704
705 if (starget_priv) {
706 leapraid_ublk_io_dev(adapter, sas_address, port);
707 starget_priv->hdl = LEAPRAID_INVALID_DEV_HANDLE;
708 }
709 if (sas_dev)
710 leapraid_sdev_put(sas_dev);
711 }
712
leapraid_single_mpi_sg_append(struct leapraid_adapter * adapter,void * sge,u32 flag_and_len,dma_addr_t dma_addr)713 static inline void leapraid_single_mpi_sg_append(
714 struct leapraid_adapter *adapter,
715 void *sge,
716 u32 flag_and_len,
717 dma_addr_t dma_addr)
718 {
719 if (adapter->adapter_attr.use_32_dma_mask) {
720 struct leapraid_sge_simple32 *sge32 = sge;
721
722 sge32->flg_and_len =
723 cpu_to_le32(flag_and_len |
724 (LEAPRAID_SGE_FLG_32 |
725 LEAPRAID_SGE_FLG_SYSTEM_ADDR) <<
726 LEAPRAID_SGE_FLG_SHIFT);
727 sge32->addr = cpu_to_le32(dma_addr);
728 } else {
729 struct leapraid_sge_simple64 *sge64 = sge;
730
731 sge64->flg_and_len =
732 cpu_to_le32(flag_and_len |
733 (LEAPRAID_SGE_FLG_64 |
734 LEAPRAID_SGE_FLG_SYSTEM_ADDR) <<
735 LEAPRAID_SGE_FLG_SHIFT);
736 sge64->addr = cpu_to_le64(dma_addr);
737 }
738 }
739
leapraid_single_ieee_sg_append(void * sge,u8 flag,u8 next_chain_offset,u32 len,dma_addr_t dma_addr)740 static inline void leapraid_single_ieee_sg_append(void *sge, u8 flag,
741 u8 next_chain_offset,
742 u32 len,
743 dma_addr_t dma_addr)
744 {
745 struct leapraid_chain64_ieee_sg *ieee_sg = sge;
746
747 ieee_sg->flg = flag;
748 ieee_sg->next_chain_offset = next_chain_offset;
749 ieee_sg->len = cpu_to_le32(len);
750 ieee_sg->addr = cpu_to_le64(dma_addr);
751 }
752
leapraid_build_nodata_mpi_sg(struct leapraid_adapter * adapter,void * sge)753 static void leapraid_build_nodata_mpi_sg(struct leapraid_adapter *adapter,
754 void *sge)
755 {
756 leapraid_single_mpi_sg_append(adapter,
757 sge,
758 (LEAPRAID_SGE_FLG_LAST_ONE |
759 LEAPRAID_SGE_FLG_EOB |
760 LEAPRAID_SGE_FLG_EOL |
761 LEAPRAID_SGE_FLG_SIMPLE_ONE) <<
762 LEAPRAID_SGE_FLG_SHIFT,
763 LEAPRAID_SGE_NO_DATA_ADDR);
764 }
765
leapraid_build_mpi_sg(struct leapraid_adapter * adapter,void * sge,dma_addr_t h2c_dma_addr,size_t h2c_size,dma_addr_t c2h_dma_addr,size_t c2h_size)766 void leapraid_build_mpi_sg(struct leapraid_adapter *adapter, void *sge,
767 dma_addr_t h2c_dma_addr, size_t h2c_size,
768 dma_addr_t c2h_dma_addr, size_t c2h_size)
769 {
770 if (h2c_size && !c2h_size) {
771 leapraid_single_mpi_sg_append(adapter,
772 sge,
773 ((LEAPRAID_SGE_FLG_SIMPLE_ONE |
774 LEAPRAID_SGE_FLG_LAST_ONE |
775 LEAPRAID_SGE_FLG_EOB |
776 LEAPRAID_SGE_FLG_EOL |
777 LEAPRAID_SGE_FLG_H2C) <<
778 LEAPRAID_SGE_FLG_SHIFT) |
779 h2c_size,
780 h2c_dma_addr);
781 } else if (!h2c_size && c2h_size) {
782 leapraid_single_mpi_sg_append(adapter,
783 sge,
784 ((LEAPRAID_SGE_FLG_SIMPLE_ONE |
785 LEAPRAID_SGE_FLG_LAST_ONE |
786 LEAPRAID_SGE_FLG_EOB |
787 LEAPRAID_SGE_FLG_EOL) <<
788 LEAPRAID_SGE_FLG_SHIFT) |
789 c2h_size,
790 c2h_dma_addr);
791 } else if (h2c_size && c2h_size) {
792 leapraid_single_mpi_sg_append(adapter,
793 sge,
794 ((LEAPRAID_SGE_FLG_SIMPLE_ONE |
795 LEAPRAID_SGE_FLG_EOB |
796 LEAPRAID_SGE_FLG_H2C) <<
797 LEAPRAID_SGE_FLG_SHIFT) |
798 h2c_size,
799 h2c_dma_addr);
800 if (adapter->adapter_attr.use_32_dma_mask)
801 sge += sizeof(struct leapraid_sge_simple32);
802 else
803 sge += sizeof(struct leapraid_sge_simple64);
804 leapraid_single_mpi_sg_append(adapter,
805 sge,
806 ((LEAPRAID_SGE_FLG_SIMPLE_ONE |
807 LEAPRAID_SGE_FLG_LAST_ONE |
808 LEAPRAID_SGE_FLG_EOB |
809 LEAPRAID_SGE_FLG_EOL) <<
810 LEAPRAID_SGE_FLG_SHIFT) |
811 c2h_size,
812 c2h_dma_addr);
813 } else {
814 leapraid_build_nodata_mpi_sg(adapter, sge);
815 }
816 }
817
leapraid_build_ieee_nodata_sg(struct leapraid_adapter * adapter,void * sge)818 void leapraid_build_ieee_nodata_sg(struct leapraid_adapter *adapter, void *sge)
819 {
820 leapraid_single_ieee_sg_append(sge,
821 (LEAPRAID_IEEE_SGE_FLG_SIMPLE_ONE |
822 LEAPRAID_IEEE_SGE_FLG_SYSTEM_ADDR |
823 LEAPRAID_IEEE_SGE_FLG_EOL),
824 0,
825 0,
826 LEAPRAID_SGE_NO_DATA_ADDR);
827 }
828
leapraid_build_scmd_ieee_sg(struct leapraid_adapter * adapter,struct scsi_cmnd * scmd,u16 taskid)829 int leapraid_build_scmd_ieee_sg(struct leapraid_adapter *adapter,
830 struct scsi_cmnd *scmd, u16 taskid)
831 {
832 struct leapraid_scsiio_req *scsiio_req;
833 struct leapraid_io_req_tracker *io_tracker;
834 struct scatterlist *scmd_sg_cur;
835 int sg_entries_left;
836 void *sg_entry_cur;
837 void *host_chain;
838 dma_addr_t host_chain_dma;
839 u8 host_chain_cursor;
840 u32 sg_entries_in_cur_seg;
841 u32 chain_offset_in_cur_seg;
842 u32 chain_len_in_cur_seg;
843
844 io_tracker = scsi_cmd_priv(scmd);
845 scsiio_req = leapraid_get_task_desc(adapter, taskid);
846 scmd_sg_cur = scsi_sglist(scmd);
847 sg_entries_left = scsi_dma_map(scmd);
848 if (sg_entries_left < 0)
849 return -ENOMEM;
850 sg_entry_cur = &scsiio_req->sgl;
851 if (sg_entries_left <= LEAPRAID_SGL_INLINE_THRESHOLD)
852 goto fill_last_seg;
853
854 scsiio_req->chain_offset = LEAPRAID_CHAIN_OFFSET_DWORDS;
855 leapraid_single_ieee_sg_append(sg_entry_cur,
856 LEAPRAID_IEEE_SGE_FLG_SIMPLE_ONE |
857 LEAPRAID_IEEE_SGE_FLG_SYSTEM_ADDR,
858 0, sg_dma_len(scmd_sg_cur),
859 sg_dma_address(scmd_sg_cur));
860 scmd_sg_cur = sg_next(scmd_sg_cur);
861 sg_entry_cur += LEAPRAID_IEEE_SGE64_ENTRY_SIZE;
862 sg_entries_left--;
863
864 host_chain_cursor = 0;
865 host_chain = io_tracker->chain +
866 host_chain_cursor * LEAPRAID_CHAIN_SEG_SIZE;
867 host_chain_dma = io_tracker->chain_dma +
868 host_chain_cursor * LEAPRAID_CHAIN_SEG_SIZE;
869 host_chain_cursor += 1;
870 for (;;) {
871 sg_entries_in_cur_seg =
872 (sg_entries_left <= LEAPRAID_MAX_SGES_IN_CHAIN) ?
873 sg_entries_left : LEAPRAID_MAX_SGES_IN_CHAIN;
874 chain_offset_in_cur_seg =
875 (sg_entries_left == (int)sg_entries_in_cur_seg) ?
876 0 : sg_entries_in_cur_seg;
877 chain_len_in_cur_seg = sg_entries_in_cur_seg *
878 LEAPRAID_IEEE_SGE64_ENTRY_SIZE;
879 if (chain_offset_in_cur_seg)
880 chain_len_in_cur_seg += LEAPRAID_IEEE_SGE64_ENTRY_SIZE;
881
882 leapraid_single_ieee_sg_append(
883 sg_entry_cur,
884 LEAPRAID_IEEE_SGE_FLG_CHAIN_ONE |
885 LEAPRAID_IEEE_SGE_FLG_SYSTEM_ADDR,
886 chain_offset_in_cur_seg, chain_len_in_cur_seg,
887 host_chain_dma);
888 sg_entry_cur = host_chain;
889 if (!chain_offset_in_cur_seg)
890 goto fill_last_seg;
891
892 while (sg_entries_in_cur_seg) {
893 leapraid_single_ieee_sg_append(
894 sg_entry_cur,
895 LEAPRAID_IEEE_SGE_FLG_SIMPLE_ONE |
896 LEAPRAID_IEEE_SGE_FLG_SYSTEM_ADDR,
897 0, sg_dma_len(scmd_sg_cur),
898 sg_dma_address(scmd_sg_cur));
899 scmd_sg_cur = sg_next(scmd_sg_cur);
900 sg_entry_cur += LEAPRAID_IEEE_SGE64_ENTRY_SIZE;
901 sg_entries_left--;
902 sg_entries_in_cur_seg--;
903 }
904 host_chain = io_tracker->chain +
905 host_chain_cursor * LEAPRAID_CHAIN_SEG_SIZE;
906 host_chain_dma = io_tracker->chain_dma +
907 host_chain_cursor * LEAPRAID_CHAIN_SEG_SIZE;
908 host_chain_cursor += 1;
909 }
910
911 fill_last_seg:
912 while (sg_entries_left > 0) {
913 u32 flags = LEAPRAID_IEEE_SGE_FLG_SIMPLE_ONE |
914 LEAPRAID_IEEE_SGE_FLG_SYSTEM_ADDR;
915 if (sg_entries_left == 1)
916 flags |= LEAPRAID_IEEE_SGE_FLG_EOL;
917 leapraid_single_ieee_sg_append(sg_entry_cur, flags,
918 0, sg_dma_len(scmd_sg_cur),
919 sg_dma_address(scmd_sg_cur));
920 scmd_sg_cur = sg_next(scmd_sg_cur);
921 sg_entry_cur += LEAPRAID_IEEE_SGE64_ENTRY_SIZE;
922 sg_entries_left--;
923 }
924 return 0;
925 }
926
leapraid_build_ieee_sg(struct leapraid_adapter * adapter,void * sge,dma_addr_t h2c_dma_addr,size_t h2c_size,dma_addr_t c2h_dma_addr,size_t c2h_size)927 void leapraid_build_ieee_sg(struct leapraid_adapter *adapter, void *sge,
928 dma_addr_t h2c_dma_addr, size_t h2c_size,
929 dma_addr_t c2h_dma_addr, size_t c2h_size)
930 {
931 u32 base_flag;
932 u32 flag;
933
934 base_flag = LEAPRAID_IEEE_SGE_FLG_SIMPLE_ONE |
935 LEAPRAID_IEEE_SGE_FLG_SYSTEM_ADDR;
936
937 if (h2c_size && !c2h_size) {
938 flag = base_flag | LEAPRAID_IEEE_SGE_FLG_EOL;
939
940 leapraid_single_ieee_sg_append(sge,
941 flag,
942 0,
943 h2c_size,
944 h2c_dma_addr);
945 } else if (!h2c_size && c2h_size) {
946 flag = base_flag | LEAPRAID_IEEE_SGE_FLG_EOL;
947
948 leapraid_single_ieee_sg_append(sge,
949 flag,
950 0,
951 c2h_size,
952 c2h_dma_addr);
953 } else if (h2c_size && c2h_size) {
954 leapraid_single_ieee_sg_append(sge,
955 base_flag,
956 0,
957 h2c_size,
958 h2c_dma_addr);
959 sge += LEAPRAID_IEEE_SGE64_ENTRY_SIZE;
960
961 flag = base_flag | LEAPRAID_IEEE_SGE_FLG_EOL;
962 leapraid_single_ieee_sg_append(sge,
963 flag,
964 0,
965 c2h_size,
966 c2h_dma_addr);
967 } else {
968 leapraid_build_ieee_nodata_sg(adapter, sge);
969 }
970 }
971
leapraid_hold_lock_get_sas_dev_from_tgt(struct leapraid_adapter * adapter,struct leapraid_starget_priv * tgt_priv)972 struct leapraid_sas_dev *leapraid_hold_lock_get_sas_dev_from_tgt(
973 struct leapraid_adapter *adapter,
974 struct leapraid_starget_priv *tgt_priv)
975 {
976 assert_spin_locked(&adapter->dev_topo.sas_dev_lock);
977 if (tgt_priv->sas_dev)
978 leapraid_sdev_get(tgt_priv->sas_dev);
979
980 return tgt_priv->sas_dev;
981 }
982
leapraid_get_sas_dev_from_tgt(struct leapraid_adapter * adapter,struct leapraid_starget_priv * tgt_priv)983 struct leapraid_sas_dev *leapraid_get_sas_dev_from_tgt(
984 struct leapraid_adapter *adapter,
985 struct leapraid_starget_priv *tgt_priv)
986 {
987 struct leapraid_sas_dev *sas_dev;
988 unsigned long flags;
989
990 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags);
991 sas_dev = leapraid_hold_lock_get_sas_dev_from_tgt(adapter, tgt_priv);
992 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags);
993 return sas_dev;
994 }
995
leapraid_get_port_by_id(struct leapraid_adapter * adapter,u8 port_id,bool skip_dirty)996 static struct leapraid_card_port *leapraid_get_port_by_id(
997 struct leapraid_adapter *adapter,
998 u8 port_id, bool skip_dirty)
999 {
1000 struct leapraid_card_port *port;
1001 struct leapraid_card_port *dirty_port = NULL;
1002
1003 if (!adapter->adapter_attr.enable_mp)
1004 port_id = LEAPRAID_DISABLE_MP_PORT_ID;
1005
1006 list_for_each_entry(port, &adapter->dev_topo.card_port_list, list) {
1007 if (port->port_id != port_id)
1008 continue;
1009
1010 if (!(port->flg & LEAPRAID_CARD_PORT_FLG_DIRTY))
1011 return port;
1012
1013 if (skip_dirty && !dirty_port)
1014 dirty_port = port;
1015 }
1016
1017 if (dirty_port)
1018 return dirty_port;
1019
1020 if (unlikely(!adapter->adapter_attr.enable_mp)) {
1021 port = kzalloc_obj(*port, GFP_ATOMIC);
1022 if (!port) {
1023 dev_warn(&adapter->pdev->dev,
1024 "%s: Failed to alloc port\n", __func__);
1025 return NULL;
1026 }
1027
1028 port->port_id = LEAPRAID_DISABLE_MP_PORT_ID;
1029 list_add_tail(&port->list, &adapter->dev_topo.card_port_list);
1030 return port;
1031 }
1032
1033 return NULL;
1034 }
1035
leapraid_get_vphy_by_phy(struct leapraid_card_port * port,u32 phy_seq_num)1036 struct leapraid_vphy *leapraid_get_vphy_by_phy(struct leapraid_card_port *port,
1037 u32 phy_seq_num)
1038 {
1039 struct leapraid_vphy *vphy;
1040
1041 if (!port || !port->vphys_mask)
1042 return NULL;
1043
1044 list_for_each_entry(vphy, &port->vphys_list, list) {
1045 if (vphy->phy_mask & BIT(phy_seq_num))
1046 return vphy;
1047 }
1048
1049 return NULL;
1050 }
1051
leapraid_hold_lock_get_sas_dev_by_addr_and_rphy(struct leapraid_adapter * adapter,u64 sas_address,struct sas_rphy * rphy)1052 struct leapraid_sas_dev *leapraid_hold_lock_get_sas_dev_by_addr_and_rphy(
1053 struct leapraid_adapter *adapter,
1054 u64 sas_address,
1055 struct sas_rphy *rphy)
1056 {
1057 struct leapraid_sas_dev *sas_dev;
1058
1059 assert_spin_locked(&adapter->dev_topo.sas_dev_lock);
1060 list_for_each_entry(sas_dev, &adapter->dev_topo.sas_dev_list, list)
1061 if (sas_dev->sas_addr == sas_address &&
1062 sas_dev->rphy == rphy) {
1063 leapraid_sdev_get(sas_dev);
1064 return sas_dev;
1065 }
1066
1067 list_for_each_entry(sas_dev, &adapter->dev_topo.sas_dev_init_list,
1068 list)
1069 if (sas_dev->sas_addr == sas_address &&
1070 sas_dev->rphy == rphy) {
1071 leapraid_sdev_get(sas_dev);
1072 return sas_dev;
1073 }
1074
1075 return NULL;
1076 }
1077
leapraid_hold_lock_get_sas_dev_by_addr(struct leapraid_adapter * adapter,u64 sas_address,struct leapraid_card_port * port)1078 struct leapraid_sas_dev *leapraid_hold_lock_get_sas_dev_by_addr(
1079 struct leapraid_adapter *adapter,
1080 u64 sas_address, struct leapraid_card_port *port)
1081 {
1082 struct leapraid_sas_dev *sas_dev;
1083
1084 if (!port) {
1085 dev_warn(&adapter->pdev->dev, "%s: Invalid port\n", __func__);
1086 return NULL;
1087 }
1088
1089 assert_spin_locked(&adapter->dev_topo.sas_dev_lock);
1090 list_for_each_entry(sas_dev, &adapter->dev_topo.sas_dev_list, list)
1091 if (sas_dev->sas_addr == sas_address &&
1092 sas_dev->card_port == port) {
1093 leapraid_sdev_get(sas_dev);
1094 return sas_dev;
1095 }
1096
1097 list_for_each_entry(sas_dev, &adapter->dev_topo.sas_dev_init_list,
1098 list)
1099 if (sas_dev->sas_addr == sas_address &&
1100 sas_dev->card_port == port) {
1101 leapraid_sdev_get(sas_dev);
1102 return sas_dev;
1103 }
1104
1105 return NULL;
1106 }
1107
leapraid_get_sas_dev_by_addr(struct leapraid_adapter * adapter,u64 sas_address,struct leapraid_card_port * port)1108 struct leapraid_sas_dev *leapraid_get_sas_dev_by_addr(
1109 struct leapraid_adapter *adapter,
1110 u64 sas_address, struct leapraid_card_port *port)
1111 {
1112 struct leapraid_sas_dev *sas_dev;
1113 unsigned long flags;
1114
1115 if (!port) {
1116 dev_warn(&adapter->pdev->dev, "%s: Invalid port\n", __func__);
1117 return NULL;
1118 }
1119
1120 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags);
1121 sas_dev = leapraid_hold_lock_get_sas_dev_by_addr(adapter, sas_address,
1122 port);
1123 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags);
1124 return sas_dev;
1125 }
1126
leapraid_hold_lock_get_sas_dev_by_hdl(struct leapraid_adapter * adapter,u16 hdl)1127 struct leapraid_sas_dev *leapraid_hold_lock_get_sas_dev_by_hdl(
1128 struct leapraid_adapter *adapter, u16 hdl)
1129 {
1130 struct leapraid_sas_dev *sas_dev;
1131
1132 assert_spin_locked(&adapter->dev_topo.sas_dev_lock);
1133 list_for_each_entry(sas_dev, &adapter->dev_topo.sas_dev_list, list)
1134 if (sas_dev->hdl == hdl) {
1135 leapraid_sdev_get(sas_dev);
1136 return sas_dev;
1137 }
1138
1139 list_for_each_entry(sas_dev, &adapter->dev_topo.sas_dev_init_list,
1140 list)
1141 if (sas_dev->hdl == hdl) {
1142 leapraid_sdev_get(sas_dev);
1143 return sas_dev;
1144 }
1145
1146 return NULL;
1147 }
1148
leapraid_get_sas_dev_by_hdl(struct leapraid_adapter * adapter,u16 hdl)1149 struct leapraid_sas_dev *leapraid_get_sas_dev_by_hdl(
1150 struct leapraid_adapter *adapter, u16 hdl)
1151 {
1152 struct leapraid_sas_dev *sas_dev;
1153 unsigned long flags;
1154
1155 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags);
1156 sas_dev = leapraid_hold_lock_get_sas_dev_by_hdl(adapter, hdl);
1157 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags);
1158 return sas_dev;
1159 }
1160
leapraid_sas_dev_remove(struct leapraid_adapter * adapter,struct leapraid_sas_dev * sas_dev)1161 void leapraid_sas_dev_remove(struct leapraid_adapter *adapter,
1162 struct leapraid_sas_dev *sas_dev)
1163 {
1164 unsigned long flags;
1165 bool del_from_list;
1166
1167 if (!sas_dev) {
1168 dev_warn(&adapter->pdev->dev,
1169 "%s: Invalid SAS device\n", __func__);
1170 return;
1171 }
1172
1173 del_from_list = false;
1174 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags);
1175 if (!list_empty(&sas_dev->list)) {
1176 list_del_init(&sas_dev->list);
1177 del_from_list = true;
1178 }
1179 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags);
1180
1181 if (del_from_list) {
1182 leapraid_clear_cached_boot_dev(adapter, sas_dev, 0);
1183 leapraid_sdev_put(sas_dev);
1184 }
1185 }
1186
leapraid_sas_dev_remove_by_hdl(struct leapraid_adapter * adapter,u16 hdl)1187 static void leapraid_sas_dev_remove_by_hdl(struct leapraid_adapter *adapter,
1188 u16 hdl)
1189 {
1190 struct leapraid_sas_dev *sas_dev;
1191 unsigned long flags;
1192 bool del_from_list;
1193
1194 if (adapter->access_ctrl.shost_recovering)
1195 return;
1196
1197 del_from_list = false;
1198 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags);
1199 sas_dev = leapraid_hold_lock_get_sas_dev_by_hdl(adapter, hdl);
1200 if (sas_dev && (!list_empty(&sas_dev->list))) {
1201 list_del_init(&sas_dev->list);
1202 del_from_list = true;
1203 leapraid_sdev_put(sas_dev);
1204 }
1205 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags);
1206
1207 if (del_from_list) {
1208 leapraid_remove_device(adapter, sas_dev);
1209 leapraid_sdev_put(sas_dev);
1210 }
1211 }
1212
leapraid_sas_dev_remove_by_sas_address(struct leapraid_adapter * adapter,u64 sas_address,struct leapraid_card_port * port)1213 void leapraid_sas_dev_remove_by_sas_address(struct leapraid_adapter *adapter,
1214 u64 sas_address,
1215 struct leapraid_card_port *port)
1216 {
1217 struct leapraid_sas_dev *sas_dev;
1218 unsigned long flags;
1219 bool del_from_list;
1220
1221 if (adapter->access_ctrl.shost_recovering)
1222 return;
1223
1224 del_from_list = false;
1225 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags);
1226 sas_dev = leapraid_hold_lock_get_sas_dev_by_addr(adapter, sas_address,
1227 port);
1228 if (sas_dev && (!list_empty(&sas_dev->list))) {
1229 list_del_init(&sas_dev->list);
1230 del_from_list = true;
1231 leapraid_sdev_put(sas_dev);
1232 }
1233 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags);
1234
1235 if (del_from_list) {
1236 leapraid_remove_device(adapter, sas_dev);
1237 leapraid_sdev_put(sas_dev);
1238 }
1239 }
1240
leapraid_raid_volume_find_by_id(struct leapraid_adapter * adapter,uint id,uint channel)1241 struct leapraid_raid_volume *leapraid_raid_volume_find_by_id(
1242 struct leapraid_adapter *adapter, uint id, uint channel)
1243 {
1244 struct leapraid_raid_volume *raid_volume;
1245 unsigned long flags;
1246
1247 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags);
1248 list_for_each_entry(raid_volume, &adapter->dev_topo.raid_volume_list,
1249 list) {
1250 if (raid_volume->id == id && raid_volume->channel == channel) {
1251 leapraid_raid_volume_get(raid_volume);
1252 spin_unlock_irqrestore(
1253 &adapter->dev_topo.raid_volume_lock, flags);
1254 return raid_volume;
1255 }
1256 }
1257 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, flags);
1258
1259 return NULL;
1260 }
1261
leapraid_raid_volume_find_by_hdl(struct leapraid_adapter * adapter,u16 hdl)1262 struct leapraid_raid_volume *leapraid_raid_volume_find_by_hdl(
1263 struct leapraid_adapter *adapter, u16 hdl)
1264 {
1265 struct leapraid_raid_volume *raid_volume;
1266 unsigned long flags;
1267
1268 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags);
1269 list_for_each_entry(raid_volume, &adapter->dev_topo.raid_volume_list,
1270 list) {
1271 if (raid_volume->hdl == hdl) {
1272 leapraid_raid_volume_get(raid_volume);
1273 spin_unlock_irqrestore(
1274 &adapter->dev_topo.raid_volume_lock, flags);
1275 return raid_volume;
1276 }
1277 }
1278 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, flags);
1279
1280 return NULL;
1281 }
1282
leapraid_raid_volume_find_by_wwid(struct leapraid_adapter * adapter,u64 wwid)1283 static struct leapraid_raid_volume *leapraid_raid_volume_find_by_wwid(
1284 struct leapraid_adapter *adapter, u64 wwid)
1285 {
1286 struct leapraid_raid_volume *raid_volume;
1287 unsigned long flags;
1288
1289 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags);
1290 list_for_each_entry(raid_volume, &adapter->dev_topo.raid_volume_list,
1291 list) {
1292 if (raid_volume->wwid == wwid) {
1293 leapraid_raid_volume_get(raid_volume);
1294 spin_unlock_irqrestore(
1295 &adapter->dev_topo.raid_volume_lock, flags);
1296 return raid_volume;
1297 }
1298 }
1299 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, flags);
1300
1301 return NULL;
1302 }
1303
leapraid_raid_volume_add(struct leapraid_adapter * adapter,struct leapraid_raid_volume * raid_volume)1304 static void leapraid_raid_volume_add(struct leapraid_adapter *adapter,
1305 struct leapraid_raid_volume *raid_volume)
1306 {
1307 unsigned long flags;
1308
1309 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags);
1310 leapraid_raid_volume_get(raid_volume);
1311 list_add_tail(&raid_volume->list, &adapter->dev_topo.raid_volume_list);
1312 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, flags);
1313 }
1314
leapraid_raid_volume_remove(struct leapraid_adapter * adapter,struct leapraid_raid_volume * raid_volume)1315 void leapraid_raid_volume_remove(struct leapraid_adapter *adapter,
1316 struct leapraid_raid_volume *raid_volume)
1317 {
1318 unsigned long flags;
1319 bool del_from_list = false;
1320
1321 if (!raid_volume) {
1322 dev_warn(&adapter->pdev->dev,
1323 "%s: Invalid RAID volume\n", __func__);
1324 return;
1325 }
1326
1327 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags);
1328 if (!list_empty(&raid_volume->list)) {
1329 list_del_init(&raid_volume->list);
1330 del_from_list = true;
1331 }
1332 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, flags);
1333
1334 leapraid_clear_cached_boot_dev(adapter, raid_volume, RAID_CHANNEL);
1335 if (del_from_list)
1336 leapraid_raid_volume_put(raid_volume);
1337 }
1338
leapraid_enc_find_by_hdl(struct leapraid_adapter * adapter,u16 hdl)1339 static struct leapraid_enc_node *leapraid_enc_find_by_hdl(
1340 struct leapraid_adapter *adapter, u16 hdl)
1341 {
1342 struct leapraid_enc_node *enc_dev;
1343
1344 list_for_each_entry(enc_dev, &adapter->dev_topo.enc_list, list)
1345 if (le16_to_cpu(enc_dev->pg0.enc_hdl) == hdl)
1346 return enc_dev;
1347
1348 return NULL;
1349 }
1350
leapraid_exp_find_by_sas_address(struct leapraid_adapter * adapter,u64 sas_address,struct leapraid_card_port * port)1351 struct leapraid_topo_node *leapraid_exp_find_by_sas_address(
1352 struct leapraid_adapter *adapter,
1353 u64 sas_address, struct leapraid_card_port *port)
1354 {
1355 struct leapraid_topo_node *sas_exp;
1356
1357 if (!port) {
1358 dev_warn(&adapter->pdev->dev, "%s: Invalid port\n", __func__);
1359 return NULL;
1360 }
1361
1362 list_for_each_entry(sas_exp, &adapter->dev_topo.exp_list, list)
1363 if (sas_exp->sas_address == sas_address &&
1364 sas_exp->card_port == port)
1365 return sas_exp;
1366
1367 dev_warn(&adapter->pdev->dev,
1368 "%s: No expander found for SAS addr=0x%016llx port=%p\n",
1369 __func__, (unsigned long long)sas_address, port);
1370 return NULL;
1371 }
1372
leapraid_scmd_find_by_tgt(struct leapraid_adapter * adapter,uint id,uint channel)1373 bool leapraid_scmd_find_by_tgt(struct leapraid_adapter *adapter, uint id,
1374 uint channel)
1375 {
1376 struct scsi_cmnd *scmd;
1377 int taskid;
1378
1379 for (taskid = 1; taskid <= adapter->shost->can_queue; taskid++) {
1380 scmd = leapraid_get_scmd_from_taskid(adapter, taskid);
1381 if (!scmd)
1382 continue;
1383
1384 if (scmd->device->id == id && scmd->device->channel == channel)
1385 return true;
1386 }
1387
1388 return false;
1389 }
1390
leapraid_scmd_find_by_lun(struct leapraid_adapter * adapter,uint id,unsigned int lun,uint channel)1391 bool leapraid_scmd_find_by_lun(struct leapraid_adapter *adapter, uint id,
1392 unsigned int lun, uint channel)
1393 {
1394 struct scsi_cmnd *scmd;
1395 int taskid;
1396
1397 for (taskid = 1; taskid <= adapter->shost->can_queue; taskid++) {
1398 scmd = leapraid_get_scmd_from_taskid(adapter, taskid);
1399 if (!scmd)
1400 continue;
1401
1402 if (scmd->device->id == id &&
1403 scmd->device->channel == channel &&
1404 scmd->device->lun == lun)
1405 return true;
1406 }
1407
1408 return false;
1409 }
1410
leapraid_exp_find_by_hdl(struct leapraid_adapter * adapter,u16 hdl)1411 static struct leapraid_topo_node *leapraid_exp_find_by_hdl(
1412 struct leapraid_adapter *adapter, u16 hdl)
1413 {
1414 struct leapraid_topo_node *sas_exp;
1415
1416 list_for_each_entry(sas_exp, &adapter->dev_topo.exp_list, list)
1417 if (sas_exp->hdl == hdl)
1418 return sas_exp;
1419
1420 return NULL;
1421 }
1422
leapraid_get_card_port_feature(struct leapraid_card_port * old_card_port,struct leapraid_card_port * card_port,struct leapraid_card_port_feature * feature)1423 static enum leapraid_card_port_checking_flg leapraid_get_card_port_feature(
1424 struct leapraid_card_port *old_card_port,
1425 struct leapraid_card_port *card_port,
1426 struct leapraid_card_port_feature *feature)
1427 {
1428 feature->dirty_flg =
1429 old_card_port->flg & LEAPRAID_CARD_PORT_FLG_DIRTY;
1430 feature->same_addr =
1431 old_card_port->sas_address == card_port->sas_address;
1432 feature->exact_phy =
1433 old_card_port->phy_mask == card_port->phy_mask;
1434 feature->phy_overlap =
1435 old_card_port->phy_mask & card_port->phy_mask;
1436 feature->same_port =
1437 old_card_port->port_id == card_port->port_id;
1438 feature->cur_chking_old_port = old_card_port;
1439
1440 if (!feature->dirty_flg || !feature->same_addr)
1441 return CARD_PORT_SKIP_CHECKING;
1442
1443 return CARD_PORT_FURTHER_CHECKING_NEEDED;
1444 }
1445
leapraid_process_card_port_feature(struct leapraid_card_port_feature * feature)1446 static bool leapraid_process_card_port_feature(
1447 struct leapraid_card_port_feature *feature)
1448 {
1449 struct leapraid_card_port *old_card_port;
1450
1451 old_card_port = feature->cur_chking_old_port;
1452 if (feature->exact_phy) {
1453 feature->checking_state = SAME_PORT_WITH_NOTHING_CHANGED;
1454 feature->expected_old_port = old_card_port;
1455 return true;
1456 }
1457
1458 if (feature->phy_overlap) {
1459 if (feature->same_port) {
1460 feature->checking_state =
1461 SAME_PORT_WITH_PARTIALLY_CHANGED_PHYS;
1462 feature->expected_old_port = old_card_port;
1463 } else if (feature->checking_state !=
1464 SAME_PORT_WITH_PARTIALLY_CHANGED_PHYS) {
1465 feature->checking_state =
1466 SAME_ADDR_WITH_PARTIALLY_CHANGED_PHYS;
1467 feature->expected_old_port = old_card_port;
1468 }
1469 } else if (feature->checking_state !=
1470 SAME_PORT_WITH_PARTIALLY_CHANGED_PHYS &&
1471 feature->checking_state !=
1472 SAME_ADDR_WITH_PARTIALLY_CHANGED_PHYS) {
1473 feature->checking_state = SAME_ADDR_ONLY;
1474 feature->expected_old_port = old_card_port;
1475 feature->same_addr_port_count++;
1476 }
1477
1478 return false;
1479 }
1480
leapraid_check_card_port(struct leapraid_adapter * adapter,struct leapraid_card_port * card_port,struct leapraid_card_port ** expected_card_port,int * count)1481 static int leapraid_check_card_port(
1482 struct leapraid_adapter *adapter,
1483 struct leapraid_card_port *card_port,
1484 struct leapraid_card_port **expected_card_port,
1485 int *count)
1486 {
1487 struct leapraid_card_port *old_card_port;
1488 struct leapraid_card_port_feature feature;
1489
1490 *expected_card_port = NULL;
1491 memset(&feature, 0, sizeof(struct leapraid_card_port_feature));
1492 feature.expected_old_port = NULL;
1493 feature.same_addr_port_count = 0;
1494 feature.checking_state = NEW_CARD_PORT;
1495
1496 list_for_each_entry(old_card_port, &adapter->dev_topo.card_port_list,
1497 list) {
1498 if (leapraid_get_card_port_feature(old_card_port, card_port,
1499 &feature))
1500 continue;
1501
1502 if (leapraid_process_card_port_feature(&feature))
1503 break;
1504 }
1505
1506 if (feature.checking_state == SAME_ADDR_ONLY)
1507 *count = feature.same_addr_port_count;
1508
1509 *expected_card_port = feature.expected_old_port;
1510 return feature.checking_state;
1511 }
1512
leapraid_del_phy_part_of_anther_port(struct leapraid_adapter * adapter,struct leapraid_card_port * card_port_table,int index,u8 port_count,int offset)1513 static void leapraid_del_phy_part_of_anther_port(
1514 struct leapraid_adapter *adapter,
1515 struct leapraid_card_port *card_port_table, int index,
1516 u8 port_count, int offset)
1517 {
1518 struct leapraid_topo_node *card_topo_node;
1519 bool found = false;
1520 int i;
1521
1522 card_topo_node = &adapter->dev_topo.card;
1523 for (i = 0; i < port_count; i++) {
1524 if (i == index)
1525 continue;
1526
1527 if (card_port_table[i].phy_mask & BIT(offset)) {
1528 leapraid_transport_detach_phy_to_port(
1529 adapter,
1530 card_topo_node,
1531 &card_topo_node->card_phy[offset]);
1532 found = true;
1533 break;
1534 }
1535 }
1536
1537 if (!found)
1538 card_port_table[index].phy_mask |= BIT(offset);
1539 }
1540
leapraid_add_or_del_phys_from_existing_port(struct leapraid_adapter * adapter,struct leapraid_card_port * card_port,struct leapraid_card_port * card_port_table,int index,u8 port_count)1541 static void leapraid_add_or_del_phys_from_existing_port(
1542 struct leapraid_adapter *adapter,
1543 struct leapraid_card_port *card_port,
1544 struct leapraid_card_port *card_port_table,
1545 int index, u8 port_count)
1546 {
1547 struct leapraid_topo_node *card_topo_node;
1548 u32 phy_mask_diff;
1549 u32 offset;
1550
1551 card_topo_node = &adapter->dev_topo.card;
1552 phy_mask_diff = card_port->phy_mask ^
1553 card_port_table[index].phy_mask;
1554 for (offset = 0; offset < adapter->dev_topo.card.phys_num; offset++) {
1555 if (!(phy_mask_diff & BIT(offset)))
1556 continue;
1557
1558 if (!(card_port_table[index].phy_mask & BIT(offset))) {
1559 leapraid_del_phy_part_of_anther_port(adapter,
1560 card_port_table,
1561 index, port_count,
1562 offset);
1563 continue;
1564 }
1565
1566 if (card_topo_node->card_phy[offset].phy_is_assigned)
1567 leapraid_transport_detach_phy_to_port(
1568 adapter,
1569 card_topo_node,
1570 &card_topo_node->card_phy[offset]);
1571
1572 leapraid_transport_attach_phy_to_port(
1573 adapter,
1574 card_topo_node,
1575 &card_topo_node->card_phy[offset],
1576 card_port->sas_address,
1577 card_port);
1578 }
1579 }
1580
leapraid_get_next_sas_dev_from_init_list(struct leapraid_adapter * adapter)1581 struct leapraid_sas_dev *leapraid_get_next_sas_dev_from_init_list(
1582 struct leapraid_adapter *adapter)
1583 {
1584 struct leapraid_sas_dev *sas_dev = NULL;
1585 unsigned long flags;
1586
1587 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags);
1588 if (!list_empty(&adapter->dev_topo.sas_dev_init_list)) {
1589 sas_dev = list_first_entry(&adapter->dev_topo.sas_dev_init_list,
1590 struct leapraid_sas_dev,
1591 list);
1592 leapraid_sdev_get(sas_dev);
1593 }
1594 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags);
1595 return sas_dev;
1596 }
1597
leapraid_check_boot_dev_internal(u64 sas_address,u64 dev_name,u64 enc_lid,u16 slot,struct leapraid_boot_dev * boot_dev,u8 form)1598 static bool leapraid_check_boot_dev_internal(u64 sas_address, u64 dev_name,
1599 u64 enc_lid, u16 slot,
1600 struct leapraid_boot_dev *boot_dev,
1601 u8 form)
1602 {
1603 struct leapraid_boot_dev_format_sas_wwid *wwid;
1604 struct leapraid_boot_dev_format_enc_slot *es;
1605 struct leapraid_boot_dev_format_dev_name *dn;
1606 void *pg_dev;
1607
1608 if (!boot_dev)
1609 return false;
1610
1611 pg_dev = boot_dev->pg_dev;
1612 switch (form & LEAPRAID_BOOTDEV_FORM_MASK) {
1613 case LEAPRAID_BOOTDEV_FORM_SAS_WWID:
1614 wwid = pg_dev;
1615
1616 if (!sas_address)
1617 return false;
1618
1619 return sas_address == le64_to_cpu(wwid->sas_addr);
1620 case LEAPRAID_BOOTDEV_FORM_ENC_SLOT:
1621 es = pg_dev;
1622
1623 if (!enc_lid)
1624 return false;
1625
1626 return (enc_lid == le64_to_cpu(es->enc_lid) &&
1627 slot == le16_to_cpu(es->slot_num));
1628 case LEAPRAID_BOOTDEV_FORM_DEV_NAME:
1629 dn = pg_dev;
1630
1631 if (!dev_name)
1632 return false;
1633
1634 return dev_name == le64_to_cpu(dn->dev_name);
1635 case LEAPRAID_BOOTDEV_FORM_NONE:
1636 default:
1637 return false;
1638 }
1639 }
1640
leapraid_boot_dev_get(void * dev,u32 chnl)1641 void leapraid_boot_dev_get(void *dev, u32 chnl)
1642 {
1643 if (!dev)
1644 return;
1645
1646 if (chnl == RAID_CHANNEL)
1647 leapraid_raid_volume_get((struct leapraid_raid_volume *)dev);
1648 else
1649 leapraid_sdev_get((struct leapraid_sas_dev *)dev);
1650 }
1651
leapraid_boot_dev_put(void * dev,u32 chnl)1652 void leapraid_boot_dev_put(void *dev, u32 chnl)
1653 {
1654 if (!dev)
1655 return;
1656
1657 if (chnl == RAID_CHANNEL)
1658 leapraid_raid_volume_put((struct leapraid_raid_volume *)dev);
1659 else
1660 leapraid_sdev_put((struct leapraid_sas_dev *)dev);
1661 }
1662
leapraid_try_set_boot_dev(struct leapraid_boot_dev * boot_dev,u64 sas_addr,u64 dev_name,u64 enc_lid,u16 slot,void * dev,u32 chnl)1663 static void leapraid_try_set_boot_dev(struct leapraid_boot_dev *boot_dev,
1664 u64 sas_addr, u64 dev_name,
1665 u64 enc_lid, u16 slot,
1666 void *dev, u32 chnl)
1667 {
1668 bool matched = false;
1669
1670 if (boot_dev->dev)
1671 return;
1672
1673 matched = leapraid_check_boot_dev_internal(sas_addr, dev_name, enc_lid,
1674 slot, boot_dev,
1675 boot_dev->form);
1676 if (matched) {
1677 leapraid_boot_dev_get(dev, chnl);
1678 boot_dev->dev = dev;
1679 boot_dev->chnl = chnl;
1680 }
1681 }
1682
leapraid_clear_boot_dev(struct leapraid_adapter * adapter,struct leapraid_boot_dev * boot_dev,void * dev,u32 chnl)1683 static void leapraid_clear_boot_dev(struct leapraid_adapter *adapter,
1684 struct leapraid_boot_dev *boot_dev,
1685 void *dev, u32 chnl)
1686 {
1687 void *cached_dev;
1688 u32 cached_chnl;
1689 unsigned long flags;
1690
1691 spin_lock_irqsave(&adapter->boot_devs.lock, flags);
1692 if (boot_dev->dev != dev || boot_dev->chnl != chnl)
1693 goto out_unlock;
1694
1695 cached_dev = boot_dev->dev;
1696 cached_chnl = boot_dev->chnl;
1697 boot_dev->dev = NULL;
1698 boot_dev->chnl = 0;
1699 spin_unlock_irqrestore(&adapter->boot_devs.lock, flags);
1700 leapraid_boot_dev_put(cached_dev, cached_chnl);
1701 return;
1702
1703 out_unlock:
1704 spin_unlock_irqrestore(&adapter->boot_devs.lock, flags);
1705 }
1706
leapraid_clear_cached_boot_dev(struct leapraid_adapter * adapter,void * dev,u32 chnl)1707 static void leapraid_clear_cached_boot_dev(struct leapraid_adapter *adapter,
1708 void *dev, u32 chnl)
1709 {
1710 leapraid_clear_boot_dev(adapter,
1711 &adapter->boot_devs.requested_boot_dev,
1712 dev, chnl);
1713 leapraid_clear_boot_dev(adapter,
1714 &adapter->boot_devs.requested_alt_boot_dev,
1715 dev, chnl);
1716 leapraid_clear_boot_dev(adapter,
1717 &adapter->boot_devs.current_boot_dev,
1718 dev, chnl);
1719 }
1720
leapraid_check_boot_dev(struct leapraid_adapter * adapter,void * dev,u32 chnl)1721 static void leapraid_check_boot_dev(struct leapraid_adapter *adapter,
1722 void *dev, u32 chnl)
1723 {
1724 struct leapraid_raid_volume *raid_volume;
1725 struct leapraid_sas_dev *sas_dev;
1726 u64 sas_addr;
1727 u64 dev_name = 0;
1728 u64 enc_lid = 0;
1729 u16 slot = 0;
1730
1731 if (!adapter->scan_dev_desc.driver_loading)
1732 return;
1733
1734 switch (chnl) {
1735 case RAID_CHANNEL:
1736 raid_volume = dev;
1737 sas_addr = raid_volume->wwid;
1738 break;
1739 default:
1740 sas_dev = dev;
1741 sas_addr = sas_dev->sas_addr;
1742 dev_name = sas_dev->dev_name;
1743 enc_lid = sas_dev->enc_lid;
1744 slot = sas_dev->slot;
1745 break;
1746 }
1747
1748 leapraid_try_set_boot_dev(&adapter->boot_devs.requested_boot_dev,
1749 sas_addr, dev_name, enc_lid,
1750 slot, dev, chnl);
1751 leapraid_try_set_boot_dev(&adapter->boot_devs.requested_alt_boot_dev,
1752 sas_addr, dev_name, enc_lid,
1753 slot, dev, chnl);
1754 leapraid_try_set_boot_dev(&adapter->boot_devs.current_boot_dev,
1755 sas_addr, dev_name, enc_lid,
1756 slot, dev, chnl);
1757 }
1758
leapraid_func_name(u8 func)1759 static const char *leapraid_func_name(u8 func)
1760 {
1761 switch (func) {
1762 case LEAPRAID_FUNC_SCSIIO:
1763 return "SCSIIO";
1764 case LEAPRAID_FUNC_SCSI_TMF:
1765 return "SCSI_TMF";
1766 case LEAPRAID_FUNC_ADAPTER_INIT:
1767 return "ADAPTER_INIT";
1768 case LEAPRAID_FUNC_GET_ADAPTER_FEATURES:
1769 return "GET_ADAPTER_FEATURES";
1770 case LEAPRAID_FUNC_CONFIG_OP:
1771 return "CONFIG_OP";
1772 case LEAPRAID_FUNC_SCAN_DEV:
1773 return "SCAN_DEV";
1774 case LEAPRAID_FUNC_EVENT_NOTIFY:
1775 return "EVENT_NOTIFY";
1776 case LEAPRAID_FUNC_FW_DOWNLOAD:
1777 return "FW_DOWNLOAD";
1778 case LEAPRAID_FUNC_FW_UPLOAD:
1779 return "FW_UPLOAD";
1780 case LEAPRAID_FUNC_SCSIIO_RAID_PASSTHROUGH:
1781 return "SCSIIO_RAID_PASSTHROUGH";
1782 case LEAPRAID_FUNC_SCSI_ENC_PROCESSOR:
1783 return "SCSI_ENC_PROCESSOR";
1784 case LEAPRAID_FUNC_SMP_PASSTHROUGH:
1785 return "SMP_PASSTHROUGH";
1786 case LEAPRAID_FUNC_SAS_IO_UNIT_CTRL:
1787 return "SAS_IO_UNIT_CTRL";
1788 case LEAPRAID_FUNC_SCSIIO_SATA_PASSTHROUGH:
1789 return "SCSIIO_SATA_PASSTHROUGH";
1790 case LEAPRAID_FUNC_ADAPTER_UNIT_RESET:
1791 return "ADAPTER_UNIT_RESET";
1792 case LEAPRAID_FUNC_HANDSHAKE:
1793 return "HANDSHAKE";
1794 case LEAPRAID_FUNC_LOGBUF_INIT:
1795 return "LOGBUF_INIT";
1796 default:
1797 return "UNKNOWN";
1798 }
1799 }
1800
leapraid_cfg_action_name(u8 action)1801 static const char *leapraid_cfg_action_name(u8 action)
1802 {
1803 switch (action) {
1804 case LEAPRAID_CFG_ACT_PAGE_HEADER:
1805 return "PAGE_HEADER";
1806 case LEAPRAID_CFG_ACT_PAGE_READ_CUR:
1807 return "PAGE_READ_CUR";
1808 case LEAPRAID_CFG_ACT_PAGE_WRITE_CUR:
1809 return "PAGE_WRITE_CUR";
1810 default:
1811 return "UNKNOWN";
1812 }
1813 }
1814
leapraid_cfg_page_type_name(u8 page_type)1815 static const char *leapraid_cfg_page_type_name(u8 page_type)
1816 {
1817 switch (page_type) {
1818 case LEAPRAID_CFG_PT_IO_UNIT:
1819 return "IO_UNIT";
1820 case LEAPRAID_CFG_PT_ADAPTER:
1821 return "ADAPTER";
1822 case LEAPRAID_CFG_PT_BIOS:
1823 return "BIOS";
1824 case LEAPRAID_CFG_PT_RAID_VOLUME:
1825 return "RAID_VOLUME";
1826 case LEAPRAID_CFG_PT_MANUFACTURING:
1827 return "MANUFACTURING";
1828 case LEAPRAID_CFG_PT_RAID_PHYSDISK:
1829 return "RAID_PHYSDISK";
1830 case LEAPRAID_CFG_PT_EXTENDED:
1831 return "EXTENDED";
1832 default:
1833 return "UNKNOWN";
1834 }
1835 }
1836
leapraid_cfg_ext_page_type_name(u8 ext_page_type)1837 static const char *leapraid_cfg_ext_page_type_name(u8 ext_page_type)
1838 {
1839 switch (ext_page_type) {
1840 case LEAPRAID_CFG_EXTPT_SAS_IO_UNIT:
1841 return "SAS_IO_UNIT";
1842 case LEAPRAID_CFG_EXTPT_SAS_EXP:
1843 return "SAS_EXPANDER";
1844 case LEAPRAID_CFG_EXTPT_SAS_DEV:
1845 return "SAS_DEVICE";
1846 case LEAPRAID_CFG_EXTPT_SAS_PHY:
1847 return "SAS_PHY";
1848 case LEAPRAID_CFG_EXTPT_ENC:
1849 return "ENCLOSURE";
1850 case LEAPRAID_CFG_EXTPT_RAID_CONFIG:
1851 return "RAID_CONFIG";
1852 default:
1853 return "UNKNOWN";
1854 }
1855 }
1856
leapraid_sep_action_name(u8 action)1857 static const char *leapraid_sep_action_name(u8 action)
1858 {
1859 switch (action) {
1860 case LEAPRAID_SEP_REQ_ACT_WRITE_STATUS:
1861 return "WRITE_STATUS";
1862 default:
1863 return "UNKNOWN";
1864 }
1865 }
1866
leapraid_sas_op_name(u8 op)1867 static const char *leapraid_sas_op_name(u8 op)
1868 {
1869 switch (op) {
1870 case LEAPRAID_SAS_OP_PHY_LINK_RESET:
1871 return "PHY_LINK_RESET";
1872 case LEAPRAID_SAS_OP_PHY_HARD_RESET:
1873 return "PHY_HARD_RESET";
1874 case LEAPRAID_SAS_OP_SET_PARAMETER:
1875 return "SET_PARAMETER";
1876 default:
1877 return "UNKNOWN";
1878 }
1879 }
1880
leapraid_tm_type_name(u8 task_type)1881 static const char *leapraid_tm_type_name(u8 task_type)
1882 {
1883 switch (task_type) {
1884 case LEAPRAID_TM_TASKTYPE_ABORT_TASK:
1885 return "ABORT_TASK";
1886 case LEAPRAID_TM_TASKTYPE_ABRT_TASK_SET:
1887 return "ABORT_TASK_SET";
1888 case LEAPRAID_TM_TASKTYPE_TARGET_RESET:
1889 return "TARGET_RESET";
1890 case LEAPRAID_TM_TASKTYPE_LOGICAL_UNIT_RESET:
1891 return "LOGICAL_UNIT_RESET";
1892 case LEAPRAID_TM_TASKTYPE_CLEAR_TASK_SET:
1893 return "CLEAR_TASK_SET";
1894 case LEAPRAID_TM_TASKTYPE_QUERY_TASK:
1895 return "QUERY_TASK";
1896 case LEAPRAID_TM_TASKTYPE_CLEAR_ACA:
1897 return "CLEAR_ACA";
1898 case LEAPRAID_TM_TASKTYPE_QUERY_TASK_SET:
1899 return "QUERY_TASK_SET";
1900 case LEAPRAID_TM_TASKTYPE_QUERY_ASYNC_EVENT:
1901 return "QUERY_ASYNC_EVENT";
1902 default:
1903 return "UNKNOWN";
1904 }
1905 }
1906
leapraid_log_req_context(struct leapraid_adapter * adapter,u16 smid,const void * req_data)1907 void leapraid_log_req_context(struct leapraid_adapter *adapter, u16 smid,
1908 const void *req_data)
1909 {
1910 const struct leapraid_req *req = req_data;
1911
1912 if (!adapter || !adapter->pdev || !req_data)
1913 return;
1914
1915 switch (req->func) {
1916 case LEAPRAID_FUNC_CONFIG_OP: {
1917 const struct leapraid_cfg_req *cfg_req = req_data;
1918
1919 dev_err(&adapter->pdev->dev,
1920 "cfg-req: smid=%u func=0x%02x(%s) action=0x%02x(%s)\n",
1921 smid, req->func, leapraid_func_name(req->func),
1922 cfg_req->action,
1923 leapraid_cfg_action_name(cfg_req->action));
1924 dev_err(&adapter->pdev->dev,
1925 "cfg-req: page_type=0x%02x(%s) page_num=%u\n",
1926 cfg_req->header.page_type,
1927 leapraid_cfg_page_type_name(cfg_req->header.page_type),
1928 cfg_req->header.page_num);
1929 if (cfg_req->header.page_type == LEAPRAID_CFG_PT_EXTENDED)
1930 dev_err(&adapter->pdev->dev,
1931 "cfg-req: ext_page_type=0x%02x(%s)\n",
1932 cfg_req->ext_page_type,
1933 leapraid_cfg_ext_page_type_name(
1934 cfg_req->ext_page_type));
1935 dev_err(&adapter->pdev->dev, "cfg-req: page_addr=0x%08x\n",
1936 le32_to_cpu(cfg_req->page_addr));
1937 break;
1938 }
1939 case LEAPRAID_FUNC_SCSI_TMF: {
1940 const struct leapraid_scsi_tm_req *tm_req = req_data;
1941
1942 dev_err(&adapter->pdev->dev,
1943 "scsi_tm:: smid=%u func=0x%02x(%s) task=0x%02x(%s)\n",
1944 smid, req->func, leapraid_func_name(req->func),
1945 tm_req->task_type,
1946 leapraid_tm_type_name(tm_req->task_type));
1947 dev_err(&adapter->pdev->dev,
1948 "scsi_tm:: dev_hdl=0x%04x task_mid=%u\n",
1949 le16_to_cpu(tm_req->dev_hdl),
1950 le16_to_cpu(tm_req->task_mid));
1951 break;
1952 }
1953 case LEAPRAID_FUNC_SCSI_ENC_PROCESSOR: {
1954 const struct leapraid_sep_req *sep_req = req_data;
1955
1956 dev_err(&adapter->pdev->dev,
1957 "sep: smid=%u func=0x%02x(%s) action=0x%02x(%s)\n",
1958 smid, req->func, leapraid_func_name(req->func),
1959 sep_req->act,
1960 leapraid_sep_action_name(sep_req->act));
1961 dev_err(&adapter->pdev->dev,
1962 "sep: dev_hdl=0x%04x slot=%u enc_hdl=0x%04x\n",
1963 le16_to_cpu(sep_req->dev_hdl),
1964 le16_to_cpu(sep_req->slot),
1965 le16_to_cpu(sep_req->enc_hdl));
1966 break;
1967 }
1968 case LEAPRAID_FUNC_SAS_IO_UNIT_CTRL: {
1969 const struct leapraid_io_unit_ctrl_req *io_req = req_data;
1970
1971 dev_err(&adapter->pdev->dev,
1972 "ctl_cmd: smid=%u func=0x%02x(%s) action=0x%02x(%s)\n",
1973 smid, req->func, leapraid_func_name(req->func),
1974 io_req->op, leapraid_sas_op_name(io_req->op));
1975 dev_err(&adapter->pdev->dev,
1976 "ctl_cmd: dev_hdl=0x%04x param=0x%02x\n",
1977 le16_to_cpu(io_req->dev_hdl),
1978 io_req->adapter_para);
1979 break;
1980 }
1981 case LEAPRAID_FUNC_SMP_PASSTHROUGH: {
1982 const struct leapraid_smp_passthrough_req *smp_req = req_data;
1983
1984 dev_err(&adapter->pdev->dev,
1985 "smp_cmd: smid=%u func=0x%02x(%s) action=0x%02x\n",
1986 smid, req->func, leapraid_func_name(req->func),
1987 smp_req->passthrough_flg);
1988 dev_err(&adapter->pdev->dev,
1989 "smp_cmd: port=%u req_len=%u\n",
1990 smp_req->physical_port,
1991 le16_to_cpu(smp_req->req_data_len));
1992 dev_err(&adapter->pdev->dev, "smp_cmd: sas_addr=0x%016llx\n",
1993 (unsigned long long)le64_to_cpu(smp_req->sas_address));
1994 break;
1995 }
1996 default:
1997 dev_err(&adapter->pdev->dev,
1998 "cmd: smid=%u func=0x%02x(%s)\n",
1999 smid, req->func, leapraid_func_name(req->func));
2000 break;
2001 }
2002 }
2003
leapraid_build_and_fire_cfg_req(struct leapraid_adapter * adapter,struct leapraid_cfg_req * leap_mpi_cfgp_req,struct leapraid_cfg_rep * leap_mpi_cfgp_rep)2004 static void leapraid_build_and_fire_cfg_req(
2005 struct leapraid_adapter *adapter,
2006 struct leapraid_cfg_req *leap_mpi_cfgp_req,
2007 struct leapraid_cfg_rep *leap_mpi_cfgp_rep)
2008 {
2009 struct leapraid_cfg_req *local_leap_cfg_req;
2010 u16 smid;
2011
2012 memset(leap_mpi_cfgp_rep, 0, sizeof(struct leapraid_cfg_rep));
2013 memset(&adapter->driver_cmds.cfg_op_cmd.reply, 0,
2014 sizeof(struct leapraid_cfg_rep));
2015 adapter->driver_cmds.cfg_op_cmd.status = LEAPRAID_CMD_PENDING;
2016 smid = adapter->driver_cmds.cfg_op_cmd.inter_taskid;
2017 local_leap_cfg_req = leapraid_get_task_desc(adapter, smid);
2018 memcpy(local_leap_cfg_req, leap_mpi_cfgp_req,
2019 sizeof(struct leapraid_cfg_req));
2020 init_completion(&adapter->driver_cmds.cfg_op_cmd.done);
2021 leapraid_fire_task(adapter, smid);
2022 wait_for_completion_timeout(&adapter->driver_cmds.cfg_op_cmd.done,
2023 LEAPRAID_CFG_OP_TIMEOUT * HZ);
2024 }
2025
leapraid_req_cfg_func(struct leapraid_adapter * adapter,struct leapraid_cfg_req * leap_mpi_cfgp_req,struct leapraid_cfg_rep * leap_mpi_cfgp_rep,void * target_cfg_pg,void * real_cfg_pg_addr,u16 target_real_cfg_pg_sz)2026 static int leapraid_req_cfg_func(struct leapraid_adapter *adapter,
2027 struct leapraid_cfg_req *leap_mpi_cfgp_req,
2028 struct leapraid_cfg_rep *leap_mpi_cfgp_rep,
2029 void *target_cfg_pg, void *real_cfg_pg_addr,
2030 u16 target_real_cfg_pg_sz)
2031 {
2032 u32 adapter_status = UINT_MAX;
2033 bool issue_reset = false;
2034 u16 smid;
2035 u8 retry_cnt;
2036 int rc;
2037
2038 retry_cnt = 0;
2039 mutex_lock(&adapter->driver_cmds.cfg_op_cmd.mutex);
2040 smid = adapter->driver_cmds.cfg_op_cmd.inter_taskid;
2041 retry:
2042 if (retry_cnt) {
2043 if (retry_cnt > LEAPRAID_CFG_REQ_RETRY_TIMES) {
2044 rc = -EFAULT;
2045 goto out_cleanup;
2046 }
2047 dev_warn(&adapter->pdev->dev,
2048 "cfg-req: Retry request, cnt=%u\n", retry_cnt);
2049 }
2050
2051 rc = leapraid_check_adapter_is_op(adapter, LEAPRAID_DB_WAIT_OP_SHORT,
2052 __func__);
2053 if (rc) {
2054 dev_err(&adapter->pdev->dev,
2055 "cfg-req: Adapter not operational\n");
2056 goto out_cleanup;
2057 }
2058
2059 leapraid_build_and_fire_cfg_req(adapter, leap_mpi_cfgp_req,
2060 leap_mpi_cfgp_rep);
2061 if (!(adapter->driver_cmds.cfg_op_cmd.status & LEAPRAID_CMD_DONE)) {
2062 retry_cnt++;
2063 if (adapter->driver_cmds.cfg_op_cmd.status &
2064 LEAPRAID_CMD_RESET) {
2065 dev_warn(&adapter->pdev->dev,
2066 "cfg-req: CMD fail due to hard reset\n");
2067 goto retry;
2068 }
2069
2070 if (adapter->access_ctrl.shost_recovering ||
2071 adapter->access_ctrl.pcie_recovering) {
2072 dev_err(&adapter->pdev->dev,
2073 "cfg-req: pending in %s, status=0x%x\n",
2074 adapter->access_ctrl.shost_recovering ?
2075 "shost recovery" : "pcie recovery",
2076 adapter->driver_cmds.cfg_op_cmd.status);
2077 leapraid_log_req_context(adapter, smid,
2078 leap_mpi_cfgp_req);
2079 issue_reset = false;
2080 rc = -EFAULT;
2081 } else {
2082 dev_err(&adapter->pdev->dev,
2083 "cfg-req: timeout, status=0x%x, reset\n",
2084 adapter->driver_cmds.cfg_op_cmd.status);
2085 leapraid_log_req_context(adapter, smid,
2086 leap_mpi_cfgp_req);
2087 issue_reset = true;
2088 }
2089
2090 goto out_cleanup;
2091 }
2092
2093 if (adapter->driver_cmds.cfg_op_cmd.status &
2094 LEAPRAID_CMD_REPLY_VALID) {
2095 memcpy(leap_mpi_cfgp_rep,
2096 &adapter->driver_cmds.cfg_op_cmd.reply,
2097 sizeof(struct leapraid_cfg_rep));
2098 adapter_status = le16_to_cpu(
2099 leap_mpi_cfgp_rep->adapter_status) &
2100 LEAPRAID_ADAPTER_STATUS_MASK;
2101 if (adapter_status == LEAPRAID_ADAPTER_STATUS_SUCCESS &&
2102 target_cfg_pg && real_cfg_pg_addr &&
2103 target_real_cfg_pg_sz &&
2104 leap_mpi_cfgp_req->action ==
2105 LEAPRAID_CFG_ACT_PAGE_READ_CUR)
2106 memcpy(target_cfg_pg, real_cfg_pg_addr,
2107 target_real_cfg_pg_sz);
2108 if (adapter_status != LEAPRAID_ADAPTER_STATUS_SUCCESS) {
2109 if (adapter_status !=
2110 LEAPRAID_ADAPTER_STATUS_CONFIG_INVALID_PAGE)
2111 dev_err(&adapter->pdev->dev,
2112 "cfg-rep: adapter_status=0x%x\n",
2113 adapter_status);
2114 rc = -EFAULT;
2115 }
2116 } else {
2117 dev_err(&adapter->pdev->dev, "cfg-rep: Reply invalid\n");
2118 rc = -EFAULT;
2119 }
2120
2121 out_cleanup:
2122 adapter->driver_cmds.cfg_op_cmd.status = LEAPRAID_CMD_NOT_USED;
2123 mutex_unlock(&adapter->driver_cmds.cfg_op_cmd.mutex);
2124 if (issue_reset) {
2125 if (adapter->scan_dev_desc.first_scan_dev_fired) {
2126 dev_warn(&adapter->pdev->dev,
2127 "%s:%d cfg-req: Failure, issuing reset\n",
2128 __func__, __LINE__);
2129 leapraid_hard_reset_handler(adapter, FULL_RESET);
2130 } else {
2131 dev_warn(&adapter->pdev->dev,
2132 "cfg-req: CMD fail in init, skip reset\n");
2133 }
2134 rc = -EFAULT;
2135 }
2136 return rc;
2137 }
2138
leapraid_request_cfg_pg_header(struct leapraid_adapter * adapter,struct leapraid_cfg_req * leap_mpi_cfgp_req,struct leapraid_cfg_rep * leap_mpi_cfgp_rep)2139 static int leapraid_request_cfg_pg_header(
2140 struct leapraid_adapter *adapter,
2141 struct leapraid_cfg_req *leap_mpi_cfgp_req,
2142 struct leapraid_cfg_rep *leap_mpi_cfgp_rep)
2143 {
2144 return leapraid_req_cfg_func(adapter, leap_mpi_cfgp_req,
2145 leap_mpi_cfgp_rep, NULL, NULL, 0);
2146 }
2147
leapraid_request_cfg_pg(struct leapraid_adapter * adapter,struct leapraid_cfg_req * leap_mpi_cfgp_req,struct leapraid_cfg_rep * leap_mpi_cfgp_rep,void * target_cfg_pg,void * real_cfg_pg_addr,u16 target_real_cfg_pg_sz)2148 static int leapraid_request_cfg_pg(struct leapraid_adapter *adapter,
2149 struct leapraid_cfg_req *leap_mpi_cfgp_req,
2150 struct leapraid_cfg_rep *leap_mpi_cfgp_rep,
2151 void *target_cfg_pg, void *real_cfg_pg_addr,
2152 u16 target_real_cfg_pg_sz)
2153 {
2154 return leapraid_req_cfg_func(adapter, leap_mpi_cfgp_req,
2155 leap_mpi_cfgp_rep, target_cfg_pg,
2156 real_cfg_pg_addr, target_real_cfg_pg_sz);
2157 }
2158
leapraid_op_config_page(struct leapraid_adapter * adapter,void * target_cfg_pg,union cfg_param_1 cfgp1,union cfg_param_2 cfgp2,enum config_page_action cfg_op)2159 int leapraid_op_config_page(struct leapraid_adapter *adapter,
2160 void *target_cfg_pg, union cfg_param_1 cfgp1,
2161 union cfg_param_2 cfgp2,
2162 enum config_page_action cfg_op)
2163 {
2164 struct leapraid_cfg_req leap_mpi_cfgp_req;
2165 struct leapraid_cfg_rep leap_mpi_cfgp_rep;
2166 u16 real_cfg_pg_sz;
2167 void *real_cfg_pg_addr;
2168 dma_addr_t real_cfg_pg_dma = 0;
2169 u32 __page_size;
2170 int rc;
2171
2172 memset(&leap_mpi_cfgp_req, 0, sizeof(struct leapraid_cfg_req));
2173 leap_mpi_cfgp_req.func = LEAPRAID_FUNC_CONFIG_OP;
2174 leap_mpi_cfgp_req.action = LEAPRAID_CFG_ACT_PAGE_HEADER;
2175
2176 switch (cfg_op) {
2177 case GET_BIOS_PG3:
2178 leap_mpi_cfgp_req.header.page_type = LEAPRAID_CFG_PT_BIOS;
2179 leap_mpi_cfgp_req.header.page_num =
2180 LEAPRAID_CFG_PAGE_NUM_BIOS3;
2181 __page_size = sizeof(struct leapraid_bios_page3);
2182 break;
2183 case GET_BIOS_PG2:
2184 leap_mpi_cfgp_req.header.page_type = LEAPRAID_CFG_PT_BIOS;
2185 leap_mpi_cfgp_req.header.page_num =
2186 LEAPRAID_CFG_PAGE_NUM_BIOS2;
2187 __page_size = sizeof(struct leapraid_bios_page2);
2188 break;
2189 case GET_MANUFACTURING_PG0:
2190 leap_mpi_cfgp_req.header.page_type =
2191 LEAPRAID_CFG_PT_MANUFACTURING;
2192 leap_mpi_cfgp_req.header.page_num =
2193 LEAPRAID_CFG_PAGE_NUM_MANU0;
2194 __page_size = sizeof(struct leapraid_manufacturing_p0);
2195 break;
2196 case GET_SAS_DEVICE_PG0:
2197 leap_mpi_cfgp_req.header.page_type = LEAPRAID_CFG_PT_EXTENDED;
2198 leap_mpi_cfgp_req.ext_page_type = LEAPRAID_CFG_EXTPT_SAS_DEV;
2199 leap_mpi_cfgp_req.header.page_num = LEAPRAID_CFG_PAGE_NUM_DEV0;
2200 __page_size = sizeof(struct leapraid_sas_dev_p0);
2201 break;
2202 case GET_SAS_IOUNIT_PG0:
2203 leap_mpi_cfgp_req.header.page_type = LEAPRAID_CFG_PT_EXTENDED;
2204 leap_mpi_cfgp_req.ext_page_type =
2205 LEAPRAID_CFG_EXTPT_SAS_IO_UNIT;
2206 leap_mpi_cfgp_req.header.page_num =
2207 LEAPRAID_CFG_PAGE_NUM_IOUNIT0;
2208 __page_size = cfgp1.size;
2209 break;
2210 case GET_SAS_IOUNIT_PG1:
2211 leap_mpi_cfgp_req.header.page_type = LEAPRAID_CFG_PT_EXTENDED;
2212 leap_mpi_cfgp_req.ext_page_type =
2213 LEAPRAID_CFG_EXTPT_SAS_IO_UNIT;
2214 leap_mpi_cfgp_req.header.page_num =
2215 LEAPRAID_CFG_PAGE_NUM_IOUNIT1;
2216 __page_size = cfgp1.size;
2217 break;
2218 case GET_SAS_EXPANDER_PG0:
2219 leap_mpi_cfgp_req.header.page_type = LEAPRAID_CFG_PT_EXTENDED;
2220 leap_mpi_cfgp_req.ext_page_type = LEAPRAID_CFG_EXTPT_SAS_EXP;
2221 leap_mpi_cfgp_req.header.page_num = LEAPRAID_CFG_PAGE_NUM_EXP0;
2222 __page_size = sizeof(struct leapraid_exp_p0);
2223 break;
2224 case GET_SAS_EXPANDER_PG1:
2225 leap_mpi_cfgp_req.header.page_type = LEAPRAID_CFG_PT_EXTENDED;
2226 leap_mpi_cfgp_req.ext_page_type = LEAPRAID_CFG_EXTPT_SAS_EXP;
2227 leap_mpi_cfgp_req.header.page_num = LEAPRAID_CFG_PAGE_NUM_EXP1;
2228 __page_size = sizeof(struct leapraid_exp_p1);
2229 break;
2230 case GET_SAS_ENCLOSURE_PG0:
2231 leap_mpi_cfgp_req.header.page_type = LEAPRAID_CFG_PT_EXTENDED;
2232 leap_mpi_cfgp_req.ext_page_type = LEAPRAID_CFG_EXTPT_ENC;
2233 leap_mpi_cfgp_req.header.page_num = LEAPRAID_CFG_PAGE_NUM_ENC0;
2234 __page_size = sizeof(struct leapraid_enc_p0);
2235 break;
2236 case GET_PHY_PG0:
2237 leap_mpi_cfgp_req.header.page_type = LEAPRAID_CFG_PT_EXTENDED;
2238 leap_mpi_cfgp_req.ext_page_type = LEAPRAID_CFG_EXTPT_SAS_PHY;
2239 leap_mpi_cfgp_req.header.page_num = LEAPRAID_CFG_PAGE_NUM_PHY0;
2240 __page_size = sizeof(struct leapraid_sas_phy_p0);
2241 break;
2242 case GET_RAID_VOLUME_PG0:
2243 leap_mpi_cfgp_req.header.page_type =
2244 LEAPRAID_CFG_PT_RAID_VOLUME;
2245 leap_mpi_cfgp_req.header.page_num = LEAPRAID_CFG_PAGE_NUM_VOL0;
2246 __page_size = cfgp1.size;
2247 break;
2248 case GET_RAID_VOLUME_PG1:
2249 leap_mpi_cfgp_req.header.page_type =
2250 LEAPRAID_CFG_PT_RAID_VOLUME;
2251 leap_mpi_cfgp_req.header.page_num = LEAPRAID_CFG_PAGE_NUM_VOL1;
2252 __page_size = sizeof(struct leapraid_raidvol_p1);
2253 break;
2254 case GET_PHY_DISK_PG0:
2255 leap_mpi_cfgp_req.header.page_type =
2256 LEAPRAID_CFG_PT_RAID_PHYSDISK;
2257 leap_mpi_cfgp_req.header.page_num = LEAPRAID_CFG_PAGE_NUM_PD0;
2258 __page_size = sizeof(struct leapraid_raidpd_p0);
2259 break;
2260 default:
2261 dev_err(&adapter->pdev->dev,
2262 "Unsupported config page action=%d!\n", cfg_op);
2263 return -EINVAL;
2264 }
2265
2266 leapraid_build_nodata_mpi_sg(adapter,
2267 &leap_mpi_cfgp_req.page_buf_sge);
2268 rc = leapraid_request_cfg_pg_header(adapter,
2269 &leap_mpi_cfgp_req,
2270 &leap_mpi_cfgp_rep);
2271 if (rc) {
2272 dev_err(&adapter->pdev->dev,
2273 "cfg-req: Header failed rc=%dn", rc);
2274 return rc;
2275 }
2276
2277 if (cfg_op == GET_SAS_DEVICE_PG0 ||
2278 cfg_op == GET_SAS_EXPANDER_PG0 ||
2279 cfg_op == GET_SAS_ENCLOSURE_PG0 ||
2280 cfg_op == GET_RAID_VOLUME_PG1)
2281 leap_mpi_cfgp_req.page_addr = cpu_to_le32(cfgp1.form |
2282 cfgp2.handle);
2283 else if (cfg_op == GET_PHY_DISK_PG0)
2284 leap_mpi_cfgp_req.page_addr = cpu_to_le32(cfgp1.form |
2285 cfgp2.form_specific);
2286 else if (cfg_op == GET_RAID_VOLUME_PG0)
2287 leap_mpi_cfgp_req.page_addr =
2288 cpu_to_le32(cfgp2.handle |
2289 LEAPRAID_RAID_VOL_CFG_PGAD_HDL);
2290 else if (cfg_op == GET_SAS_EXPANDER_PG1)
2291 leap_mpi_cfgp_req.page_addr =
2292 cpu_to_le32(cfgp2.handle |
2293 (cfgp1.phy_number <<
2294 LEAPRAID_SAS_EXP_CFG_PGAD_PHYNUM_SHIFT) |
2295 LEAPRAID_SAS_EXP_CFG_PGAD_HDL_PHY_NUM);
2296 else if (cfg_op == GET_PHY_PG0)
2297 leap_mpi_cfgp_req.page_addr = cpu_to_le32(cfgp1.phy_number |
2298 LEAPRAID_SAS_PHY_CFG_PGAD_PHY_NUMBER);
2299
2300 leap_mpi_cfgp_req.action = LEAPRAID_CFG_ACT_PAGE_READ_CUR;
2301
2302 leap_mpi_cfgp_req.header.page_num = leap_mpi_cfgp_rep.header.page_num;
2303 leap_mpi_cfgp_req.header.page_type =
2304 leap_mpi_cfgp_rep.header.page_type;
2305 leap_mpi_cfgp_req.header.page_len = leap_mpi_cfgp_rep.header.page_len;
2306 leap_mpi_cfgp_req.ext_page_len = leap_mpi_cfgp_rep.ext_page_len;
2307 leap_mpi_cfgp_req.ext_page_type = leap_mpi_cfgp_rep.ext_page_type;
2308
2309 real_cfg_pg_sz = (leap_mpi_cfgp_req.header.page_len) ?
2310 leap_mpi_cfgp_req.header.page_len * sizeof(u32) :
2311 le16_to_cpu(leap_mpi_cfgp_rep.ext_page_len) * sizeof(u32);
2312 real_cfg_pg_addr = dma_alloc_coherent(&adapter->pdev->dev,
2313 real_cfg_pg_sz,
2314 &real_cfg_pg_dma,
2315 GFP_KERNEL);
2316 if (!real_cfg_pg_addr)
2317 return -ENOMEM;
2318
2319 if (leap_mpi_cfgp_req.action == LEAPRAID_CFG_ACT_PAGE_WRITE_CUR) {
2320 leapraid_single_mpi_sg_append(adapter,
2321 &leap_mpi_cfgp_req.page_buf_sge,
2322 ((LEAPRAID_SGE_FLG_SIMPLE_ONE |
2323 LEAPRAID_SGE_FLG_LAST_ONE |
2324 LEAPRAID_SGE_FLG_EOB |
2325 LEAPRAID_SGE_FLG_EOL |
2326 LEAPRAID_SGE_FLG_H2C) <<
2327 LEAPRAID_SGE_FLG_SHIFT) |
2328 real_cfg_pg_sz,
2329 real_cfg_pg_dma);
2330 memcpy(real_cfg_pg_addr, target_cfg_pg,
2331 min_t(u16, real_cfg_pg_sz, __page_size));
2332 } else {
2333 memset(target_cfg_pg, 0, __page_size);
2334 leapraid_single_mpi_sg_append(adapter,
2335 &leap_mpi_cfgp_req.page_buf_sge,
2336 ((LEAPRAID_SGE_FLG_SIMPLE_ONE |
2337 LEAPRAID_SGE_FLG_LAST_ONE |
2338 LEAPRAID_SGE_FLG_EOB |
2339 LEAPRAID_SGE_FLG_EOL) <<
2340 LEAPRAID_SGE_FLG_SHIFT) |
2341 real_cfg_pg_sz,
2342 real_cfg_pg_dma);
2343 memset(real_cfg_pg_addr, 0,
2344 min_t(u16, real_cfg_pg_sz, __page_size));
2345 }
2346
2347 rc = leapraid_request_cfg_pg(adapter,
2348 &leap_mpi_cfgp_req,
2349 &leap_mpi_cfgp_rep,
2350 target_cfg_pg,
2351 real_cfg_pg_addr,
2352 min_t(u16, real_cfg_pg_sz, __page_size));
2353 if (rc) {
2354 u32 status;
2355
2356 status = le16_to_cpu(leap_mpi_cfgp_rep.adapter_status) &
2357 LEAPRAID_ADAPTER_STATUS_MASK;
2358 if (status != LEAPRAID_ADAPTER_STATUS_CONFIG_INVALID_PAGE)
2359 dev_err(&adapter->pdev->dev,
2360 "cfg-req: rc=%d, pg_info: 0x%x, 0x%x, %d\n",
2361 rc, leap_mpi_cfgp_req.header.page_type,
2362 leap_mpi_cfgp_req.ext_page_type,
2363 leap_mpi_cfgp_req.header.page_num);
2364 }
2365
2366 if (real_cfg_pg_addr)
2367 dma_free_coherent(&adapter->pdev->dev,
2368 real_cfg_pg_sz,
2369 real_cfg_pg_addr,
2370 real_cfg_pg_dma);
2371
2372 return rc;
2373 }
2374
leapraid_cfg_find_vol_in_page(struct leapraid_raid_cfg_p0 * raid_cfg_p0,u16 pd_hdl,u16 * vol_hdl)2375 static int leapraid_cfg_find_vol_in_page(
2376 struct leapraid_raid_cfg_p0 *raid_cfg_p0,
2377 u16 pd_hdl, u16 *vol_hdl)
2378 {
2379 u16 elements = raid_cfg_p0->elements_num;
2380 int i;
2381
2382 for (i = 0; i < elements; i++) {
2383 struct leapraid_raid_cfg_p0_element *elem;
2384 u16 type;
2385
2386 elem = &raid_cfg_p0->cfg_element[i];
2387
2388 type = le16_to_cpu(elem->element_flg) &
2389 LEAPRAID_RAIDCFG_P0_EFLG_MASK_ELEMENT_TYPE;
2390
2391 switch (type) {
2392 case LEAPRAID_RAIDCFG_P0_EFLG_VOL_PHYS_DISK_ELEMENT:
2393 case LEAPRAID_RAIDCFG_P0_EFLG_OCE_ELEMENT: {
2394 u16 phys_hdl;
2395
2396 phys_hdl = le16_to_cpu(elem->phys_disk_dev_hdl);
2397 if (phys_hdl == pd_hdl) {
2398 *vol_hdl = le16_to_cpu(elem->vol_dev_hdl);
2399 return 0;
2400 }
2401 break;
2402 }
2403 case LEAPRAID_RAIDCFG_P0_EFLG_HOT_SPARE_ELEMENT:
2404 *vol_hdl = 0;
2405 return 0;
2406
2407 default:
2408 break;
2409 }
2410 }
2411
2412 return -ENOENT;
2413 }
2414
leapraid_cfg_get_volume_hdl_dispatch(struct leapraid_adapter * adapter,struct leapraid_cfg_req * cfg_req,struct leapraid_cfg_rep * cfg_rep,struct leapraid_raid_cfg_p0 * raid_cfg_p0,void * real_cfg_pg_addr,u16 real_cfg_pg_sz,u16 raid_cfg_p0_sz,u16 pd_hdl,u16 * vol_hdl)2415 static int leapraid_cfg_get_volume_hdl_dispatch(
2416 struct leapraid_adapter *adapter,
2417 struct leapraid_cfg_req *cfg_req,
2418 struct leapraid_cfg_rep *cfg_rep,
2419 struct leapraid_raid_cfg_p0 *raid_cfg_p0,
2420 void *real_cfg_pg_addr,
2421 u16 real_cfg_pg_sz,
2422 u16 raid_cfg_p0_sz,
2423 u16 pd_hdl, u16 *vol_hdl)
2424 {
2425 u16 adapter_status;
2426 int config_num;
2427 int rc;
2428
2429 config_num = 0xFF;
2430 while (true) {
2431 cfg_req->page_addr =
2432 cpu_to_le32(config_num +
2433 LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP);
2434 rc = leapraid_request_cfg_pg(
2435 adapter, cfg_req, cfg_rep,
2436 raid_cfg_p0, real_cfg_pg_addr,
2437 min_t(u16, real_cfg_pg_sz, raid_cfg_p0_sz));
2438 adapter_status = le16_to_cpu(cfg_rep->adapter_status) &
2439 LEAPRAID_ADAPTER_STATUS_MASK;
2440 if (rc) {
2441 if (adapter_status ==
2442 LEAPRAID_ADAPTER_STATUS_CONFIG_INVALID_PAGE) {
2443 *vol_hdl = 0;
2444 return 0;
2445 }
2446 return rc;
2447 }
2448
2449 if (adapter_status != LEAPRAID_ADAPTER_STATUS_SUCCESS)
2450 return LEAPRAID_OPERATION_FAILED;
2451
2452 rc = leapraid_cfg_find_vol_in_page(raid_cfg_p0,
2453 pd_hdl,
2454 vol_hdl);
2455 if (rc != -ENOENT)
2456 return rc;
2457
2458 config_num = raid_cfg_p0->cfg_num;
2459 }
2460 return 0;
2461 }
2462
leapraid_cfg_get_volume_hdl(struct leapraid_adapter * adapter,u16 pd_hdl,u16 * vol_hdl)2463 int leapraid_cfg_get_volume_hdl(struct leapraid_adapter *adapter,
2464 u16 pd_hdl, u16 *vol_hdl)
2465 {
2466 struct leapraid_raid_cfg_p0 *raid_cfg_p0;
2467 struct leapraid_cfg_req cfg_req;
2468 struct leapraid_cfg_rep cfg_rep;
2469 dma_addr_t real_cfg_pg_dma = 0;
2470 void *real_cfg_pg_addr;
2471 u16 real_cfg_pg_sz;
2472 int rc, raid_cfg_p0_sz;
2473
2474 *vol_hdl = 0;
2475 memset(&cfg_req, 0, sizeof(struct leapraid_cfg_req));
2476 cfg_req.func = LEAPRAID_FUNC_CONFIG_OP;
2477 cfg_req.action = LEAPRAID_CFG_ACT_PAGE_HEADER;
2478 cfg_req.header.page_type = LEAPRAID_CFG_PT_EXTENDED;
2479 cfg_req.ext_page_type = LEAPRAID_CFG_EXTPT_RAID_CONFIG;
2480 cfg_req.header.page_num = LEAPRAID_CFG_PAGE_NUM_VOL0;
2481
2482 leapraid_build_nodata_mpi_sg(adapter, &cfg_req.page_buf_sge);
2483 rc = leapraid_request_cfg_pg_header(adapter, &cfg_req, &cfg_rep);
2484 if (rc)
2485 return rc;
2486
2487 cfg_req.action = LEAPRAID_CFG_ACT_PAGE_READ_CUR;
2488 raid_cfg_p0_sz = le16_to_cpu(cfg_rep.ext_page_len) *
2489 LEAPRAID_CFG_UNIT_SIZE;
2490 raid_cfg_p0 = kmalloc(raid_cfg_p0_sz, GFP_KERNEL);
2491 if (!raid_cfg_p0)
2492 return -ENOMEM;
2493
2494 real_cfg_pg_sz = (cfg_req.header.page_len) ?
2495 cfg_req.header.page_len * LEAPRAID_CFG_UNIT_SIZE :
2496 le16_to_cpu(cfg_rep.ext_page_len) * LEAPRAID_CFG_UNIT_SIZE;
2497
2498 real_cfg_pg_addr = dma_alloc_coherent(&adapter->pdev->dev,
2499 real_cfg_pg_sz, &real_cfg_pg_dma,
2500 GFP_KERNEL);
2501 if (!real_cfg_pg_addr) {
2502 rc = -ENOMEM;
2503 goto out_free;
2504 }
2505
2506 memset(raid_cfg_p0, 0, raid_cfg_p0_sz);
2507 leapraid_single_mpi_sg_append(adapter,
2508 &cfg_req.page_buf_sge,
2509 ((LEAPRAID_SGE_FLG_SIMPLE_ONE |
2510 LEAPRAID_SGE_FLG_LAST_ONE |
2511 LEAPRAID_SGE_FLG_EOB |
2512 LEAPRAID_SGE_FLG_EOL) <<
2513 LEAPRAID_SGE_FLG_SHIFT) |
2514 real_cfg_pg_sz,
2515 real_cfg_pg_dma);
2516 memset(real_cfg_pg_addr, 0,
2517 min_t(u16, real_cfg_pg_sz, raid_cfg_p0_sz));
2518
2519 rc = leapraid_cfg_get_volume_hdl_dispatch(adapter,
2520 &cfg_req, &cfg_rep,
2521 raid_cfg_p0,
2522 real_cfg_pg_addr,
2523 real_cfg_pg_sz,
2524 raid_cfg_p0_sz,
2525 pd_hdl, vol_hdl);
2526
2527 out_free:
2528 if (real_cfg_pg_addr)
2529 dma_free_coherent(&adapter->pdev->dev,
2530 real_cfg_pg_sz, real_cfg_pg_addr,
2531 real_cfg_pg_dma);
2532 kfree(raid_cfg_p0);
2533 return rc;
2534 }
2535
leapraid_get_adapter_phys(struct leapraid_adapter * adapter,u8 * nr_phys)2536 static int leapraid_get_adapter_phys(struct leapraid_adapter *adapter,
2537 u8 *nr_phys)
2538 {
2539 struct leapraid_sas_io_unit_p0 sas_io_unit_page0;
2540 union cfg_param_1 cfgp1 = {0};
2541 union cfg_param_2 cfgp2 = {0};
2542 int rc;
2543
2544 *nr_phys = 0;
2545 cfgp1.size = sizeof(struct leapraid_sas_io_unit_p0);
2546 rc = leapraid_op_config_page(adapter, &sas_io_unit_page0, cfgp1,
2547 cfgp2, GET_SAS_IOUNIT_PG0);
2548 if (rc)
2549 return rc;
2550
2551 *nr_phys = sas_io_unit_page0.phy_num;
2552
2553 return 0;
2554 }
2555
leapraid_cfg_get_number_pds(struct leapraid_adapter * adapter,u16 hdl,u8 * num_pds)2556 static int leapraid_cfg_get_number_pds(struct leapraid_adapter *adapter,
2557 u16 hdl, u8 *num_pds)
2558 {
2559 union cfg_param_1 cfgp1 = {0};
2560 union cfg_param_2 cfgp2 = {0};
2561 struct leapraid_raidvol_p0 raidvol_p0;
2562 int rc;
2563
2564 *num_pds = 0;
2565 cfgp1.size = sizeof(struct leapraid_raidvol_p0);
2566 cfgp2.handle = hdl;
2567 rc = leapraid_op_config_page(adapter, &raidvol_p0, cfgp1,
2568 cfgp2, GET_RAID_VOLUME_PG0);
2569 if (!rc)
2570 *num_pds = raidvol_p0.num_phys_disks;
2571
2572 return rc;
2573 }
2574
leapraid_cfg_get_volume_wwid(struct leapraid_adapter * adapter,u16 vol_hdl,u64 * wwid)2575 int leapraid_cfg_get_volume_wwid(struct leapraid_adapter *adapter,
2576 u16 vol_hdl, u64 *wwid)
2577 {
2578 union cfg_param_1 cfgp1 = {0};
2579 union cfg_param_2 cfgp2 = {0};
2580 struct leapraid_raidvol_p1 raidvol_p1;
2581 int rc;
2582
2583 *wwid = 0;
2584 cfgp1.form = LEAPRAID_RAID_VOL_CFG_PGAD_HDL;
2585 cfgp2.handle = vol_hdl;
2586 rc = leapraid_op_config_page(adapter, &raidvol_p1, cfgp1,
2587 cfgp2, GET_RAID_VOLUME_PG1);
2588 if (!rc)
2589 *wwid = le64_to_cpu(raidvol_p1.wwid);
2590
2591 return rc;
2592 }
2593
leapraid_get_sas_io_unit_page0(struct leapraid_adapter * adapter,struct leapraid_sas_io_unit_p0 * sas_io_unit_p0,u16 sas_iou_pg0_sz)2594 static int leapraid_get_sas_io_unit_page0(
2595 struct leapraid_adapter *adapter,
2596 struct leapraid_sas_io_unit_p0 *sas_io_unit_p0,
2597 u16 sas_iou_pg0_sz)
2598 {
2599 union cfg_param_1 cfgp1 = {0};
2600 union cfg_param_2 cfgp2 = {0};
2601
2602 cfgp1.size = sas_iou_pg0_sz;
2603 return leapraid_op_config_page(adapter, sas_io_unit_p0, cfgp1,
2604 cfgp2, GET_SAS_IOUNIT_PG0);
2605 }
2606
leapraid_get_sas_address(struct leapraid_adapter * adapter,u16 hdl,u64 * sas_address)2607 static int leapraid_get_sas_address(struct leapraid_adapter *adapter,
2608 u16 hdl, u64 *sas_address)
2609 {
2610 union cfg_param_1 cfgp1 = {0};
2611 union cfg_param_2 cfgp2 = {0};
2612 struct leapraid_sas_dev_p0 sas_dev_p0;
2613
2614 *sas_address = 0;
2615 cfgp1.form = LEAPRAID_SAS_DEV_CFG_PGAD_HDL;
2616 cfgp2.handle = hdl;
2617 if (leapraid_op_config_page(adapter, &sas_dev_p0, cfgp1,
2618 cfgp2, GET_SAS_DEVICE_PG0))
2619 return -ENXIO;
2620
2621 if (hdl <= adapter->dev_topo.card.phys_num &&
2622 (!(le32_to_cpu(sas_dev_p0.dev_info) & LEAPRAID_DEVTYP_SEP)))
2623 *sas_address = adapter->dev_topo.card.sas_address;
2624 else
2625 *sas_address = le64_to_cpu(sas_dev_p0.sas_address);
2626
2627 return 0;
2628 }
2629
leapraid_get_volume_cap(struct leapraid_adapter * adapter,struct leapraid_raid_volume * raid_volume)2630 int leapraid_get_volume_cap(struct leapraid_adapter *adapter,
2631 struct leapraid_raid_volume *raid_volume)
2632 {
2633 union cfg_param_1 cfgp1 = {0};
2634 union cfg_param_2 cfgp2 = {0};
2635 struct leapraid_raidvol_p0 *raidvol_p0;
2636 struct leapraid_sas_dev_p0 sas_dev_p0;
2637 struct leapraid_raidpd_p0 raidpd_p0;
2638 u8 num_pds;
2639 u16 sz;
2640 int rc = 0;
2641
2642 if (leapraid_cfg_get_number_pds(adapter, raid_volume->hdl,
2643 &num_pds) || !num_pds)
2644 return -EFAULT;
2645
2646 raid_volume->pd_num = num_pds;
2647 sz = offsetof(struct leapraid_raidvol_p0, phys_disk) +
2648 (num_pds * sizeof(struct leapraid_raidvol0_phys_disk));
2649 raidvol_p0 = kzalloc(sz, GFP_KERNEL);
2650 if (!raidvol_p0)
2651 return -ENOMEM;
2652
2653 cfgp1.size = sz;
2654 cfgp2.handle = raid_volume->hdl;
2655 if (leapraid_op_config_page(adapter, raidvol_p0, cfgp1, cfgp2,
2656 GET_RAID_VOLUME_PG0)) {
2657 rc = -EFAULT;
2658 goto out_cleanup;
2659 }
2660
2661 raid_volume->vol_type = raidvol_p0->volume_type;
2662 cfgp1.form = LEAPRAID_PHYSDISK_CFG_PGAD_PHYSDISKNUM;
2663 cfgp2.form_specific = raidvol_p0->phys_disk[0].phys_disk_num;
2664 if (!(leapraid_op_config_page(adapter, &raidpd_p0, cfgp1, cfgp2,
2665 GET_PHY_DISK_PG0))) {
2666 cfgp1.form = LEAPRAID_SAS_DEV_CFG_PGAD_HDL;
2667 cfgp2.handle = le16_to_cpu(raidpd_p0.dev_hdl);
2668 if (!(leapraid_op_config_page(adapter, &sas_dev_p0, cfgp1,
2669 cfgp2, GET_SAS_DEVICE_PG0)))
2670 raid_volume->dev_info =
2671 le32_to_cpu(sas_dev_p0.dev_info);
2672 }
2673
2674 out_cleanup:
2675 kfree(raidvol_p0);
2676 return rc;
2677 }
2678
leapraid_should_skip_poll_work(struct leapraid_adapter * adapter)2679 static bool leapraid_should_skip_poll_work(struct leapraid_adapter *adapter)
2680 {
2681 unsigned long flags;
2682 bool skip;
2683
2684 spin_lock_irqsave(&adapter->reset_desc.adapter_reset_lock, flags);
2685 skip = adapter->access_ctrl.shost_recovering ||
2686 adapter->access_ctrl.pcie_recovering ||
2687 adapter->access_ctrl.host_removing;
2688 spin_unlock_irqrestore(&adapter->reset_desc.adapter_reset_lock, flags);
2689
2690 return skip;
2691 }
2692
leapraid_fw_log_work(struct work_struct * work)2693 static void leapraid_fw_log_work(struct work_struct *work)
2694 {
2695 struct leapraid_adapter *adapter = container_of(work,
2696 struct leapraid_adapter, fw_log_desc.fw_log_work.work);
2697 struct leapraid_fw_log_info *infom;
2698 struct leapraid_reg_base __iomem *iomem_base;
2699 unsigned long flags;
2700
2701 if (leapraid_should_skip_poll_work(adapter))
2702 goto scheduled_timer;
2703
2704 infom = (struct leapraid_fw_log_info *)
2705 (adapter->fw_log_desc.fw_log_buffer +
2706 LEAPRAID_SYS_LOG_BUF_SIZE);
2707
2708 iomem_base = adapter->iomem_base;
2709 if (adapter->fw_log_desc.fw_log_init_flag == 0) {
2710 infom->user_position =
2711 leapraid_readl(&iomem_base->host_log_buf_pos);
2712 infom->adapter_position =
2713 leapraid_readl(&iomem_base->adapter_log_buf_pos);
2714 adapter->fw_log_desc.fw_log_init_flag++;
2715 }
2716
2717 writel(infom->user_position, &iomem_base->host_log_buf_pos);
2718 infom->adapter_position =
2719 leapraid_readl(&iomem_base->adapter_log_buf_pos);
2720
2721 scheduled_timer:
2722 spin_lock_irqsave(&adapter->reset_desc.adapter_reset_lock, flags);
2723 if (adapter->fw_log_desc.fw_log_wq)
2724 queue_delayed_work(
2725 adapter->fw_log_desc.fw_log_wq,
2726 &adapter->fw_log_desc.fw_log_work,
2727 msecs_to_jiffies(LEAPRAID_PCIE_LOG_POLLING_INTERVAL));
2728 spin_unlock_irqrestore(&adapter->reset_desc.adapter_reset_lock, flags);
2729 }
2730
leapraid_fw_log_stop(struct leapraid_adapter * adapter)2731 void leapraid_fw_log_stop(struct leapraid_adapter *adapter)
2732 {
2733 struct workqueue_struct *wq;
2734 unsigned long flags;
2735
2736 if (!adapter->fw_log_desc.open_pcie_trace)
2737 return;
2738
2739 spin_lock_irqsave(&adapter->reset_desc.adapter_reset_lock, flags);
2740 wq = adapter->fw_log_desc.fw_log_wq;
2741 adapter->fw_log_desc.fw_log_wq = NULL;
2742 spin_unlock_irqrestore(&adapter->reset_desc.adapter_reset_lock, flags);
2743 if (wq) {
2744 if (!cancel_delayed_work_sync(&adapter->fw_log_desc
2745 .fw_log_work))
2746 flush_workqueue(wq);
2747 destroy_workqueue(wq);
2748 }
2749 }
2750
leapraid_fw_log_start(struct leapraid_adapter * adapter)2751 void leapraid_fw_log_start(struct leapraid_adapter *adapter)
2752 {
2753 unsigned long flags;
2754
2755 if (!adapter->fw_log_desc.open_pcie_trace)
2756 return;
2757
2758 if (adapter->fw_log_desc.fw_log_wq)
2759 return;
2760
2761 INIT_DELAYED_WORK(&adapter->fw_log_desc.fw_log_work,
2762 leapraid_fw_log_work);
2763 snprintf(adapter->fw_log_desc.fw_log_wq_name,
2764 sizeof(adapter->fw_log_desc.fw_log_wq_name),
2765 "poll_%s%u_fw_log",
2766 LEAPRAID_DRIVER_NAME, adapter->adapter_attr.id);
2767 adapter->fw_log_desc.fw_log_wq =
2768 create_singlethread_workqueue(
2769 adapter->fw_log_desc.fw_log_wq_name);
2770 if (!adapter->fw_log_desc.fw_log_wq)
2771 return;
2772
2773 spin_lock_irqsave(&adapter->reset_desc.adapter_reset_lock, flags);
2774 if (adapter->fw_log_desc.fw_log_wq)
2775 queue_delayed_work(
2776 adapter->fw_log_desc.fw_log_wq,
2777 &adapter->fw_log_desc.fw_log_work,
2778 msecs_to_jiffies(LEAPRAID_PCIE_LOG_POLLING_INTERVAL));
2779 spin_unlock_irqrestore(&adapter->reset_desc.adapter_reset_lock, flags);
2780 }
2781
leapraid_check_scheduled_fault_work(struct work_struct * work)2782 static void leapraid_check_scheduled_fault_work(struct work_struct *work)
2783 {
2784 struct leapraid_adapter *adapter;
2785 unsigned long flags;
2786 u32 adapter_state;
2787 int rc;
2788
2789 adapter = container_of(work, struct leapraid_adapter,
2790 reset_desc.fault_reset_work.work);
2791
2792 if (leapraid_should_skip_poll_work(adapter))
2793 goto scheduled_timer;
2794
2795 adapter_state = leapraid_get_adapter_state(adapter);
2796 if (adapter_state != LEAPRAID_DB_OPERATIONAL) {
2797 dev_info(&adapter->pdev->dev, "%s:%d: call hard_reset 0x%x\n",
2798 __func__, __LINE__, adapter_state);
2799 rc = leapraid_hard_reset_handler(adapter, FULL_RESET);
2800 adapter_state = leapraid_get_adapter_state(adapter);
2801 if (rc && adapter_state != LEAPRAID_DB_OPERATIONAL) {
2802 dev_err(&adapter->pdev->dev,
2803 "%s: Hard reset failed, state=0x%x rc=%d\n",
2804 __func__, adapter_state, rc);
2805 return;
2806 }
2807 }
2808
2809 scheduled_timer:
2810 spin_lock_irqsave(&adapter->reset_desc.adapter_reset_lock, flags);
2811 if (adapter->reset_desc.fault_reset_wq)
2812 queue_delayed_work(
2813 adapter->reset_desc.fault_reset_wq,
2814 &adapter->reset_desc.fault_reset_work,
2815 msecs_to_jiffies(LEAPRAID_FAULT_POLLING_INTERVAL));
2816 spin_unlock_irqrestore(&adapter->reset_desc.adapter_reset_lock, flags);
2817 }
2818
leapraid_check_scheduled_fault_start(struct leapraid_adapter * adapter)2819 void leapraid_check_scheduled_fault_start(struct leapraid_adapter *adapter)
2820 {
2821 unsigned long flags;
2822
2823 if (adapter->reset_desc.fault_reset_wq)
2824 return;
2825
2826 INIT_DELAYED_WORK(&adapter->reset_desc.fault_reset_work,
2827 leapraid_check_scheduled_fault_work);
2828 snprintf(adapter->reset_desc.fault_reset_wq_name,
2829 sizeof(adapter->reset_desc.fault_reset_wq_name),
2830 "poll_%s%u_status",
2831 LEAPRAID_DRIVER_NAME, adapter->adapter_attr.id);
2832 adapter->reset_desc.fault_reset_wq =
2833 create_singlethread_workqueue(
2834 adapter->reset_desc.fault_reset_wq_name);
2835 if (!adapter->reset_desc.fault_reset_wq) {
2836 dev_err(&adapter->pdev->dev,
2837 "Create single thread workqueue failed!\n");
2838 return;
2839 }
2840
2841 spin_lock_irqsave(&adapter->reset_desc.adapter_reset_lock, flags);
2842 if (adapter->reset_desc.fault_reset_wq)
2843 queue_delayed_work(
2844 adapter->reset_desc.fault_reset_wq,
2845 &adapter->reset_desc.fault_reset_work,
2846 msecs_to_jiffies(LEAPRAID_FAULT_POLLING_INTERVAL));
2847 spin_unlock_irqrestore(&adapter->reset_desc.adapter_reset_lock, flags);
2848 }
2849
leapraid_check_scheduled_fault_stop(struct leapraid_adapter * adapter)2850 void leapraid_check_scheduled_fault_stop(struct leapraid_adapter *adapter)
2851 {
2852 struct workqueue_struct *wq;
2853 unsigned long flags;
2854
2855 spin_lock_irqsave(&adapter->reset_desc.adapter_reset_lock, flags);
2856 wq = adapter->reset_desc.fault_reset_wq;
2857 adapter->reset_desc.fault_reset_wq = NULL;
2858 spin_unlock_irqrestore(&adapter->reset_desc.adapter_reset_lock, flags);
2859
2860 if (!wq)
2861 return;
2862
2863 if (!cancel_delayed_work_sync(&adapter->reset_desc.fault_reset_work))
2864 flush_workqueue(wq);
2865 destroy_workqueue(wq);
2866 }
2867
leapraid_overheat_work(struct work_struct * work)2868 static void leapraid_overheat_work(struct work_struct *work)
2869 {
2870 struct leapraid_overheat_desc *desc;
2871 struct leapraid_adapter *adapter;
2872 struct workqueue_struct *wq;
2873 struct Scsi_Host *shost;
2874 struct pci_dev *pdev;
2875 unsigned long flags;
2876
2877 desc = container_of(work, struct leapraid_overheat_desc,
2878 fault_overheat_work);
2879 adapter = container_of(desc, struct leapraid_adapter, overheat_desc);
2880 pdev = adapter->pdev;
2881 shost = pci_get_drvdata(pdev);
2882
2883 if (!shost) {
2884 dev_err(&pdev->dev,
2885 "Overheat processing failed: invalid host/adapter\n");
2886 atomic_set(&adapter->overheat_desc.thermal_alert, 0);
2887 wake_up(&adapter->scan_dev_desc.wait_driver_loading);
2888 return;
2889 }
2890
2891 if (adapter->access_ctrl.host_removing) {
2892 atomic_set(&adapter->overheat_desc.thermal_alert, 0);
2893 wake_up(&adapter->scan_dev_desc.wait_driver_loading);
2894 return;
2895 }
2896
2897 adapter->access_ctrl.host_removing = 1;
2898 adapter->access_ctrl.shost_recover_async = 0;
2899 adapter->scan_dev_desc.scan_start = 0;
2900 adapter->scan_dev_desc.wait_scan_dev_done = 0;
2901 adapter->scan_dev_desc.driver_loading = 0;
2902 wake_up(&adapter->access_ctrl.shost_recover_wq);
2903 wake_up(&adapter->scan_dev_desc.wait_driver_loading);
2904
2905 leapraid_mask_int(adapter);
2906
2907 leapraid_check_scheduled_fault_stop(adapter);
2908 leapraid_fw_log_stop(adapter);
2909 leapraid_mq_polling_pause(adapter);
2910
2911 leapraid_clean_active_cmds(adapter);
2912 spin_lock_irqsave(&adapter->fw_evt_s.fw_evt_lock, flags);
2913 wq = adapter->fw_evt_s.fw_evt_thread;
2914 adapter->fw_evt_s.fw_evt_thread = NULL;
2915 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags);
2916 if (wq)
2917 destroy_workqueue(wq);
2918
2919 sas_remove_host(shost);
2920 leapraid_cleanup_lists(adapter);
2921 atomic_set(&adapter->overheat_desc.thermal_alert, 0);
2922 wake_up(&adapter->scan_dev_desc.wait_driver_loading);
2923 dev_err(&pdev->dev, "%s: Suspend adapter due to overheat\n", __func__);
2924 }
2925
leapraid_overheat_init(struct leapraid_adapter * adapter)2926 static void leapraid_overheat_init(struct leapraid_adapter *adapter)
2927 {
2928 if (adapter->overheat_desc.fault_overheat_wq)
2929 return;
2930
2931 atomic_set(&adapter->overheat_desc.thermal_alert, 0);
2932 snprintf(adapter->overheat_desc.fault_overheat_wq_name,
2933 sizeof(adapter->overheat_desc.fault_overheat_wq_name),
2934 "driver_%s%u_overheat",
2935 LEAPRAID_DRIVER_NAME,
2936 adapter->adapter_attr.id);
2937 adapter->overheat_desc.fault_overheat_wq =
2938 create_singlethread_workqueue(
2939 adapter->overheat_desc.fault_overheat_wq_name);
2940 if (!adapter->overheat_desc.fault_overheat_wq) {
2941 dev_err(&adapter->pdev->dev,
2942 "Failed to create overheat workqueue\n");
2943 return;
2944 }
2945
2946 INIT_WORK(&adapter->overheat_desc.fault_overheat_work,
2947 leapraid_overheat_work);
2948 }
2949
leapraid_overheat_cleanup(struct leapraid_adapter * adapter)2950 void leapraid_overheat_cleanup(struct leapraid_adapter *adapter)
2951 {
2952 struct workqueue_struct *wq;
2953
2954 wq = xchg(&adapter->overheat_desc.fault_overheat_wq, NULL);
2955 if (!wq)
2956 return;
2957
2958 cancel_work_sync(&adapter->overheat_desc.fault_overheat_work);
2959 destroy_workqueue(wq);
2960 }
2961
2962 static void leapraid_fw_work(struct leapraid_adapter *adapter,
2963 struct leapraid_fw_evt_work *fw_evt);
2964
leapraid_fw_evt_free(struct kref * r)2965 static void leapraid_fw_evt_free(struct kref *r)
2966 {
2967 struct leapraid_fw_evt_work *fw_evt;
2968
2969 fw_evt = container_of(r, struct leapraid_fw_evt_work, refcnt);
2970
2971 kfree(fw_evt->evt_data);
2972 kfree(fw_evt);
2973 }
2974
leapraid_fw_evt_get(struct leapraid_fw_evt_work * fw_evt)2975 static void leapraid_fw_evt_get(struct leapraid_fw_evt_work *fw_evt)
2976 {
2977 kref_get(&fw_evt->refcnt);
2978 }
2979
leapraid_fw_evt_put(struct leapraid_fw_evt_work * fw_work)2980 static void leapraid_fw_evt_put(struct leapraid_fw_evt_work *fw_work)
2981 {
2982 kref_put(&fw_work->refcnt, leapraid_fw_evt_free);
2983 }
2984
leapraid_alloc_fw_evt_work(void)2985 static struct leapraid_fw_evt_work *leapraid_alloc_fw_evt_work(void)
2986 {
2987 struct leapraid_fw_evt_work *fw_evt =
2988 kzalloc(sizeof(*fw_evt), GFP_ATOMIC);
2989
2990 if (fw_evt)
2991 kref_init(&fw_evt->refcnt);
2992
2993 return fw_evt;
2994 }
2995
leapraid_run_fw_evt_work(struct work_struct * work)2996 static void leapraid_run_fw_evt_work(struct work_struct *work)
2997 {
2998 struct leapraid_fw_evt_work *fw_evt =
2999 container_of(work, struct leapraid_fw_evt_work, work);
3000
3001 leapraid_fw_work(fw_evt->adapter, fw_evt);
3002 }
3003
leapraid_fw_evt_add(struct leapraid_adapter * adapter,struct leapraid_fw_evt_work * fw_evt)3004 static void leapraid_fw_evt_add(struct leapraid_adapter *adapter,
3005 struct leapraid_fw_evt_work *fw_evt)
3006 {
3007 unsigned long flags;
3008
3009 spin_lock_irqsave(&adapter->fw_evt_s.fw_evt_lock, flags);
3010 if (adapter->access_ctrl.host_removing ||
3011 adapter->access_ctrl.pcie_recovering ||
3012 !adapter->fw_evt_s.fw_evt_thread) {
3013 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags);
3014 return;
3015 }
3016
3017 leapraid_fw_evt_get(fw_evt);
3018 INIT_LIST_HEAD(&fw_evt->list);
3019 list_add_tail(&fw_evt->list, &adapter->fw_evt_s.fw_evt_list);
3020 INIT_WORK(&fw_evt->work, leapraid_run_fw_evt_work);
3021 leapraid_fw_evt_get(fw_evt);
3022 queue_work(adapter->fw_evt_s.fw_evt_thread, &fw_evt->work);
3023 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags);
3024 }
3025
leapraid_del_fw_evt_from_list(struct leapraid_adapter * adapter,struct leapraid_fw_evt_work * fw_evt)3026 static void leapraid_del_fw_evt_from_list(struct leapraid_adapter *adapter,
3027 struct leapraid_fw_evt_work *fw_evt)
3028 {
3029 unsigned long flags;
3030
3031 spin_lock_irqsave(&adapter->fw_evt_s.fw_evt_lock, flags);
3032 if (!list_empty(&fw_evt->list)) {
3033 list_del_init(&fw_evt->list);
3034 leapraid_fw_evt_put(fw_evt);
3035 }
3036 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags);
3037 }
3038
leapraid_next_fw_evt(struct leapraid_adapter * adapter)3039 static struct leapraid_fw_evt_work *leapraid_next_fw_evt(
3040 struct leapraid_adapter *adapter)
3041 {
3042 struct leapraid_fw_evt_work *fw_evt = NULL;
3043 unsigned long flags;
3044
3045 spin_lock_irqsave(&adapter->fw_evt_s.fw_evt_lock, flags);
3046 if (!list_empty(&adapter->fw_evt_s.fw_evt_list)) {
3047 fw_evt = list_first_entry(&adapter->fw_evt_s.fw_evt_list,
3048 struct leapraid_fw_evt_work, list);
3049 list_del_init(&fw_evt->list);
3050 }
3051 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags);
3052 return fw_evt;
3053 }
3054
leapraid_clean_active_fw_evt(struct leapraid_adapter * adapter)3055 void leapraid_clean_active_fw_evt(struct leapraid_adapter *adapter)
3056 {
3057 struct leapraid_fw_evt_work *fw_evt;
3058 unsigned long flags;
3059 bool in_fw_evt_context;
3060 bool rc;
3061
3062 if ((list_empty(&adapter->fw_evt_s.fw_evt_list) &&
3063 !adapter->fw_evt_s.cur_evt) || !adapter->fw_evt_s.fw_evt_thread)
3064 return;
3065
3066 adapter->fw_evt_s.fw_evt_cleanup = 1;
3067 if (adapter->access_ctrl.shost_recovering &&
3068 adapter->fw_evt_s.cur_evt)
3069 adapter->fw_evt_s.cur_evt->ignore = 1;
3070
3071 while ((fw_evt = leapraid_next_fw_evt(adapter))) {
3072 rc = cancel_work_sync(&fw_evt->work);
3073 if (rc)
3074 leapraid_fw_evt_put(fw_evt);
3075 leapraid_fw_evt_put(fw_evt);
3076 }
3077
3078 spin_lock_irqsave(&adapter->fw_evt_s.fw_evt_lock, flags);
3079 fw_evt = adapter->fw_evt_s.cur_evt;
3080 if (fw_evt) {
3081 in_fw_evt_context = adapter->fw_evt_s.cur_evt_task == current;
3082 leapraid_fw_evt_get(fw_evt);
3083 }
3084 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags);
3085 if (fw_evt) {
3086 if (!in_fw_evt_context)
3087 cancel_work_sync(&fw_evt->work);
3088 leapraid_fw_evt_put(fw_evt);
3089 }
3090
3091 adapter->fw_evt_s.fw_evt_cleanup = 0;
3092 }
3093
leapraid_internal_dev_ublk(struct scsi_device * sdev,struct leapraid_sdev_priv * sdev_priv)3094 static void leapraid_internal_dev_ublk(struct scsi_device *sdev,
3095 struct leapraid_sdev_priv *sdev_priv)
3096 {
3097 int rc;
3098
3099 sdev_printk(KERN_WARNING, sdev,
3100 "hdl 0x%04x: Now internal unblkg dev\n",
3101 sdev_priv->starget_priv->hdl);
3102 sdev_priv->block = 0;
3103 rc = scsi_internal_device_unblock_nowait(sdev, SDEV_RUNNING);
3104 if (rc == -EINVAL) {
3105 sdev_printk(KERN_WARNING, sdev,
3106 "hdl 0x%04x: unblkg failed, rc=%d\n",
3107 sdev_priv->starget_priv->hdl, rc);
3108 sdev_priv->block = 1;
3109 rc = scsi_internal_device_block_nowait(sdev);
3110 if (rc)
3111 sdev_printk(KERN_WARNING, sdev,
3112 "hdl 0x%04x: Earlier ublkg err, rc=%d\n",
3113 sdev_priv->starget_priv->hdl, rc);
3114
3115 sdev_priv->block = 0;
3116 rc = scsi_internal_device_unblock_nowait(sdev, SDEV_RUNNING);
3117 if (rc)
3118 sdev_printk(KERN_WARNING, sdev,
3119 "hdl 0x%04x: ublkg failed again, rc=%d\n",
3120 sdev_priv->starget_priv->hdl, rc);
3121 }
3122 }
3123
leapraid_ublk_io_dev(struct leapraid_adapter * adapter,u64 sas_addr,struct leapraid_card_port * card_port)3124 static void leapraid_ublk_io_dev(struct leapraid_adapter *adapter,
3125 u64 sas_addr,
3126 struct leapraid_card_port *card_port)
3127 {
3128 struct leapraid_sdev_priv *sdev_priv;
3129 struct scsi_device *sdev;
3130
3131 shost_for_each_device(sdev, adapter->shost) {
3132 sdev_priv = sdev->hostdata;
3133 if (!sdev_priv || !sdev_priv->starget_priv)
3134 continue;
3135
3136 if (sdev_priv->starget_priv->sas_address != sas_addr)
3137 continue;
3138
3139 if (sdev_priv->starget_priv->card_port != card_port)
3140 continue;
3141
3142 if (sdev_priv->block)
3143 leapraid_internal_dev_ublk(sdev, sdev_priv);
3144
3145 scsi_device_set_state(sdev, SDEV_OFFLINE);
3146 }
3147 }
3148
leapraid_ublk_io_all_dev(struct leapraid_adapter * adapter)3149 static void leapraid_ublk_io_all_dev(struct leapraid_adapter *adapter)
3150 {
3151 struct leapraid_sdev_priv *sdev_priv;
3152 struct leapraid_starget_priv *stgt_priv;
3153 struct scsi_device *sdev;
3154
3155 shost_for_each_device(sdev, adapter->shost) {
3156 sdev_priv = sdev->hostdata;
3157
3158 if (!sdev_priv)
3159 continue;
3160
3161 stgt_priv = sdev_priv->starget_priv;
3162 if (!stgt_priv || stgt_priv->deleted)
3163 continue;
3164
3165 if (!sdev_priv->block)
3166 continue;
3167
3168 sdev_printk(KERN_WARNING, sdev, "hdl 0x%04x: blkg...\n",
3169 sdev_priv->starget_priv->hdl);
3170 leapraid_internal_dev_ublk(sdev, sdev_priv);
3171 continue;
3172 }
3173 }
3174
leapraid_internal_dev_blk(struct scsi_device * sdev,struct leapraid_sdev_priv * sdev_priv)3175 static void leapraid_internal_dev_blk(
3176 struct scsi_device *sdev,
3177 struct leapraid_sdev_priv *sdev_priv)
3178 {
3179 int rc;
3180
3181 sdev_printk(KERN_INFO, sdev, "Internal blkg hdl 0x%04x\n",
3182 sdev_priv->starget_priv->hdl);
3183 sdev_priv->block = 1;
3184 rc = scsi_internal_device_block_nowait(sdev);
3185 if (rc == -EINVAL)
3186 sdev_printk(KERN_WARNING, sdev,
3187 "hdl 0x%04x: blkg failed, rc=%d\n",
3188 rc, sdev_priv->starget_priv->hdl);
3189 }
3190
leapraid_imm_blkio_to_end_dev(struct leapraid_adapter * adapter,struct leapraid_sas_port * sas_port)3191 static void leapraid_imm_blkio_to_end_dev(struct leapraid_adapter *adapter,
3192 struct leapraid_sas_port *sas_port)
3193 {
3194 struct leapraid_sdev_priv *sdev_priv;
3195 struct leapraid_sas_dev *sas_dev;
3196 struct scsi_device *sdev;
3197 unsigned long flags;
3198
3199 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags);
3200 sas_dev = leapraid_hold_lock_get_sas_dev_by_addr(
3201 adapter,
3202 sas_port->remote_identify.sas_address,
3203 sas_port->card_port);
3204
3205 if (sas_dev) {
3206 shost_for_each_device(sdev, adapter->shost) {
3207 sdev_priv = sdev->hostdata;
3208 if (!sdev_priv)
3209 continue;
3210
3211 if (sdev_priv->starget_priv->hdl != sas_dev->hdl)
3212 continue;
3213
3214 if (sdev_priv->block)
3215 continue;
3216
3217 if (sas_dev && sas_dev->pend_sas_rphy_add)
3218 continue;
3219
3220 if (sdev_priv->sep) {
3221 sdev_printk(KERN_INFO, sdev,
3222 "skip dev blk: sep hdl 0x%04x\n",
3223 sdev_priv->starget_priv->hdl);
3224 continue;
3225 }
3226
3227 leapraid_internal_dev_blk(sdev, sdev_priv);
3228 }
3229
3230 leapraid_sdev_put(sas_dev);
3231 }
3232 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags);
3233 }
3234
leapraid_imm_blkio_set_end_dev_blk_hdls(struct leapraid_adapter * adapter,struct leapraid_topo_node * topo_node_exp)3235 static void leapraid_imm_blkio_set_end_dev_blk_hdls(
3236 struct leapraid_adapter *adapter,
3237 struct leapraid_topo_node *topo_node_exp)
3238 {
3239 struct leapraid_sas_port *sas_port;
3240
3241 list_for_each_entry(sas_port,
3242 &topo_node_exp->sas_port_list, port_list) {
3243 if (sas_port->remote_identify.device_type == SAS_END_DEVICE)
3244 leapraid_imm_blkio_to_end_dev(adapter, sas_port);
3245 }
3246 }
3247
3248 static void leapraid_imm_blkio_to_kids_attchd_to_ex(
3249 struct leapraid_adapter *adapter,
3250 struct leapraid_topo_node *topo_node_exp);
3251
leapraid_imm_blkio_to_sib_exp(struct leapraid_adapter * adapter,struct leapraid_topo_node * topo_node_exp)3252 static void leapraid_imm_blkio_to_sib_exp(
3253 struct leapraid_adapter *adapter,
3254 struct leapraid_topo_node *topo_node_exp)
3255 {
3256 struct leapraid_topo_node *topo_node_exp_sib;
3257 struct leapraid_sas_port *sas_port;
3258
3259 list_for_each_entry(sas_port,
3260 &topo_node_exp->sas_port_list, port_list) {
3261 if (sas_port->remote_identify.device_type ==
3262 SAS_EDGE_EXPANDER_DEVICE ||
3263 sas_port->remote_identify.device_type ==
3264 SAS_FANOUT_EXPANDER_DEVICE) {
3265 topo_node_exp_sib =
3266 leapraid_exp_find_by_sas_address(
3267 adapter,
3268 sas_port->remote_identify.sas_address,
3269 sas_port->card_port);
3270 leapraid_imm_blkio_to_kids_attchd_to_ex(
3271 adapter,
3272 topo_node_exp_sib);
3273 }
3274 }
3275 }
3276
leapraid_imm_blkio_to_kids_attchd_to_ex(struct leapraid_adapter * adapter,struct leapraid_topo_node * topo_node_exp)3277 static void leapraid_imm_blkio_to_kids_attchd_to_ex(
3278 struct leapraid_adapter *adapter,
3279 struct leapraid_topo_node *topo_node_exp)
3280 {
3281 if (!topo_node_exp)
3282 return;
3283
3284 leapraid_imm_blkio_set_end_dev_blk_hdls(adapter, topo_node_exp);
3285
3286 leapraid_imm_blkio_to_sib_exp(adapter, topo_node_exp);
3287 }
3288
leapraid_report_sdev_directly(struct leapraid_adapter * adapter,struct leapraid_sas_dev * sas_dev)3289 static void leapraid_report_sdev_directly(struct leapraid_adapter *adapter,
3290 struct leapraid_sas_dev *sas_dev)
3291 {
3292 struct leapraid_sas_port *sas_port;
3293
3294 sas_port = leapraid_transport_port_add(adapter,
3295 sas_dev->hdl,
3296 sas_dev->parent_sas_addr,
3297 sas_dev->card_port);
3298 if (!sas_port) {
3299 leapraid_sas_dev_remove(adapter, sas_dev);
3300 return;
3301 }
3302
3303 if (!sas_dev->starget) {
3304 if (!adapter->scan_dev_desc.driver_loading) {
3305 leapraid_transport_port_remove(
3306 adapter,
3307 sas_dev->sas_addr,
3308 sas_dev->parent_sas_addr,
3309 sas_dev->card_port);
3310 leapraid_sas_dev_remove(adapter, sas_dev);
3311 }
3312 return;
3313 }
3314 }
3315
leapraid_init_sas_dev(struct leapraid_adapter * adapter,struct leapraid_sas_dev_p0 * sas_dev_pg0,struct leapraid_card_port * card_port,u16 hdl,u64 parent_sas_addr,u64 sas_addr,u32 dev_info)3316 static struct leapraid_sas_dev *leapraid_init_sas_dev(
3317 struct leapraid_adapter *adapter,
3318 struct leapraid_sas_dev_p0 *sas_dev_pg0,
3319 struct leapraid_card_port *card_port, u16 hdl,
3320 u64 parent_sas_addr, u64 sas_addr, u32 dev_info)
3321 {
3322 struct leapraid_sas_dev *sas_dev;
3323 struct leapraid_enc_node *enc_dev;
3324 unsigned long flags;
3325
3326 sas_dev = kzalloc_obj(*sas_dev);
3327 if (!sas_dev)
3328 return NULL;
3329
3330 kref_init(&sas_dev->refcnt);
3331 sas_dev->hdl = hdl;
3332 sas_dev->dev_info = dev_info;
3333 sas_dev->sas_addr = sas_addr;
3334 sas_dev->card_port = card_port;
3335 sas_dev->parent_sas_addr = parent_sas_addr;
3336 sas_dev->phy = sas_dev_pg0->phy_num;
3337 sas_dev->enc_hdl = le16_to_cpu(sas_dev_pg0->enc_hdl);
3338 sas_dev->dev_name = le64_to_cpu(sas_dev_pg0->dev_name);
3339 sas_dev->port_connection = sas_dev_pg0->max_port_connections;
3340 sas_dev->slot = sas_dev->enc_hdl ? le16_to_cpu(sas_dev_pg0->slot) : 0;
3341 if (le16_to_cpu(sas_dev_pg0->flg) &
3342 LEAPRAID_SAS_DEV_P0_FLG_ENC_LEVEL_VALID) {
3343 sas_dev->enc_level = sas_dev_pg0->enc_level;
3344 memcpy(sas_dev->connector_name,
3345 sas_dev_pg0->connector_name,
3346 LEAPRAID_SAS_DEV_P0_CON_NAME_LEN);
3347 sas_dev->connector_name[LEAPRAID_SAS_DEV_P0_CON_NAME_LEN] =
3348 '\0';
3349 } else {
3350 sas_dev->enc_level = 0;
3351 sas_dev->connector_name[0] = '\0';
3352 }
3353 if (sas_dev->enc_hdl) {
3354 spin_lock_irqsave(&adapter->dev_topo.enc_lock, flags);
3355 enc_dev = leapraid_enc_find_by_hdl(adapter, sas_dev->enc_hdl);
3356 if (enc_dev)
3357 sas_dev->enc_lid = le64_to_cpu(enc_dev->pg0.enc_lid);
3358 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, flags);
3359 }
3360 dev_info(&adapter->pdev->dev,
3361 "add dev: hdl=0x%x, SAS addr=0x%016llx, port connect=0x%x\n",
3362 hdl, sas_dev->sas_addr, sas_dev->port_connection);
3363
3364 return sas_dev;
3365 }
3366
leapraid_add_dev(struct leapraid_adapter * adapter,u16 hdl)3367 static void leapraid_add_dev(struct leapraid_adapter *adapter, u16 hdl)
3368 {
3369 union cfg_param_1 cfgp1 = {0};
3370 union cfg_param_2 cfgp2 = {0};
3371 struct leapraid_sas_dev_p0 sas_dev_pg0;
3372 struct leapraid_card_port *card_port;
3373 struct leapraid_sas_dev *sas_dev;
3374 unsigned long flags;
3375 u64 parent_sas_addr;
3376 u32 dev_info;
3377 u64 sas_addr;
3378 u8 port_id;
3379
3380 cfgp1.form = LEAPRAID_SAS_DEV_CFG_PGAD_HDL;
3381 cfgp2.handle = hdl;
3382 if (leapraid_op_config_page(adapter, &sas_dev_pg0,
3383 cfgp1, cfgp2, GET_SAS_DEVICE_PG0))
3384 return;
3385
3386 dev_info = le32_to_cpu(sas_dev_pg0.dev_info);
3387 if (!(leapraid_is_end_dev(dev_info)))
3388 return;
3389
3390 sas_addr = le64_to_cpu(sas_dev_pg0.sas_address);
3391 if (!(le16_to_cpu(sas_dev_pg0.flg) &
3392 LEAPRAID_SAS_DEV_P0_FLG_DEV_PRESENT))
3393 return;
3394
3395 port_id = sas_dev_pg0.physical_port;
3396 card_port = leapraid_get_port_by_id(adapter, port_id, false);
3397 if (!card_port)
3398 return;
3399
3400 sas_dev = leapraid_get_sas_dev_by_addr(adapter, sas_addr, card_port);
3401 if (sas_dev) {
3402 leapraid_sdev_put(sas_dev);
3403 return;
3404 }
3405
3406 if (leapraid_get_sas_address(adapter,
3407 le16_to_cpu(sas_dev_pg0.parent_dev_hdl),
3408 &parent_sas_addr))
3409 return;
3410
3411 sas_dev = leapraid_init_sas_dev(adapter, &sas_dev_pg0, card_port,
3412 hdl, parent_sas_addr, sas_addr,
3413 dev_info);
3414 if (!sas_dev)
3415 return;
3416
3417 if (adapter->scan_dev_desc.wait_scan_dev_done) {
3418 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags);
3419 leapraid_sdev_get(sas_dev);
3420 list_add_tail(&sas_dev->list,
3421 &adapter->dev_topo.sas_dev_init_list);
3422 leapraid_check_boot_dev(adapter, sas_dev, 0);
3423 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags);
3424 } else {
3425 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags);
3426 leapraid_sdev_get(sas_dev);
3427 list_add_tail(&sas_dev->list, &adapter->dev_topo.sas_dev_list);
3428 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags);
3429 leapraid_report_sdev_directly(adapter, sas_dev);
3430 }
3431 leapraid_sdev_put(sas_dev);
3432 }
3433
leapraid_remove_device(struct leapraid_adapter * adapter,struct leapraid_sas_dev * sas_dev)3434 static void leapraid_remove_device(struct leapraid_adapter *adapter,
3435 struct leapraid_sas_dev *sas_dev)
3436 {
3437 struct leapraid_starget_priv *starget_priv;
3438
3439 leapraid_clear_cached_boot_dev(adapter, sas_dev, 0);
3440 if (sas_dev->led_on) {
3441 leapraid_set_led(adapter, sas_dev, false);
3442 sas_dev->led_on = 0;
3443 }
3444
3445 if (sas_dev->starget && sas_dev->starget->hostdata) {
3446 starget_priv = sas_dev->starget->hostdata;
3447 starget_priv->deleted = 1;
3448 leapraid_ublk_io_dev(adapter,
3449 sas_dev->sas_addr, sas_dev->card_port);
3450 starget_priv->hdl = LEAPRAID_INVALID_DEV_HANDLE;
3451 }
3452
3453 leapraid_transport_port_remove(adapter,
3454 sas_dev->sas_addr,
3455 sas_dev->parent_sas_addr,
3456 sas_dev->card_port);
3457
3458 dev_info(&adapter->pdev->dev,
3459 "remove dev: hdl=0x%04x, SAS addr=0x%016llx\n",
3460 sas_dev->hdl, (unsigned long long)sas_dev->sas_addr);
3461 }
3462
leapraid_alloc_vphy(struct leapraid_adapter * adapter,u8 port_id,u8 phy_num)3463 static struct leapraid_vphy *leapraid_alloc_vphy(
3464 struct leapraid_adapter *adapter,
3465 u8 port_id, u8 phy_num)
3466 {
3467 struct leapraid_card_port *port;
3468 struct leapraid_vphy *vphy;
3469
3470 port = leapraid_get_port_by_id(adapter, port_id, false);
3471 if (!port)
3472 return NULL;
3473
3474 vphy = leapraid_get_vphy_by_phy(port, phy_num);
3475 if (vphy)
3476 return vphy;
3477 vphy = kzalloc_obj(*vphy);
3478 if (!vphy)
3479 return NULL;
3480
3481 if (!port->vphys_mask)
3482 INIT_LIST_HEAD(&port->vphys_list);
3483
3484 port->vphys_mask |= BIT(phy_num);
3485 vphy->phy_mask |= BIT(phy_num);
3486 list_add_tail(&vphy->list, &port->vphys_list);
3487 return vphy;
3488 }
3489
leapraid_add_port_to_card_port_list(struct leapraid_adapter * adapter,u8 port_id,bool refresh)3490 static int leapraid_add_port_to_card_port_list(
3491 struct leapraid_adapter *adapter,
3492 u8 port_id, bool refresh)
3493 {
3494 struct leapraid_card_port *card_port;
3495
3496 card_port = leapraid_get_port_by_id(adapter, port_id, false);
3497 if (card_port)
3498 return 0;
3499 card_port = kzalloc_obj(*card_port);
3500 if (!card_port)
3501 return -ENOMEM;
3502
3503 card_port->port_id = port_id;
3504 dev_dbg(&adapter->pdev->dev,
3505 "port: %d is added to card_port list\n",
3506 card_port->port_id);
3507
3508 if (refresh && adapter->access_ctrl.shost_recovering)
3509 card_port->flg = LEAPRAID_CARD_PORT_FLG_NEW;
3510 list_add_tail(&card_port->list, &adapter->dev_topo.card_port_list);
3511 return 0;
3512 }
3513
leapraid_add_card_phy(struct leapraid_adapter * adapter,struct leapraid_sas_io_unit_p0 * iou,int i)3514 static int leapraid_add_card_phy(struct leapraid_adapter *adapter,
3515 struct leapraid_sas_io_unit_p0 *iou,
3516 int i)
3517 {
3518 struct leapraid_sas_phy_p0 phy_pg0;
3519 union cfg_param_1 cfgp1 = {0};
3520 union cfg_param_2 cfgp2 = {0};
3521 struct leapraid_topo_node *card = &adapter->dev_topo.card;
3522 u8 port_id;
3523
3524 cfgp1.phy_number = i;
3525
3526 if (leapraid_op_config_page(adapter, &phy_pg0,
3527 cfgp1, cfgp2, GET_PHY_PG0))
3528 return -EINVAL;
3529
3530 port_id = iou->phy_info[i].port;
3531
3532 if (leapraid_add_port_to_card_port_list(adapter, port_id, false))
3533 return -EINVAL;
3534
3535 if ((le32_to_cpu(phy_pg0.phy_info) &
3536 LEAPRAID_SAS_PHYINFO_VPHY) &&
3537 ((phy_pg0.neg_link_rate >>
3538 LEAPRAID_SAS_NEG_LINK_RATE_SHIFT) >=
3539 LEAPRAID_SAS_NEG_LINK_RATE_1_5)) {
3540 if (!leapraid_alloc_vphy(adapter, port_id, i))
3541 return -ENOMEM;
3542
3543 card->card_phy[i].vphy = 1;
3544 }
3545
3546 card->card_phy[i].hdl = card->hdl;
3547 card->card_phy[i].phy_id = i;
3548 card->card_phy[i].card_port =
3549 leapraid_get_port_by_id(adapter, port_id, false);
3550
3551 leapraid_transport_add_card_phy(adapter,
3552 &card->card_phy[i],
3553 &phy_pg0,
3554 card->parent_dev);
3555
3556 return 0;
3557 }
3558
leapraid_refresh_card_phy(struct leapraid_adapter * adapter,struct leapraid_sas_io_unit_p0 * iou,int i)3559 static int leapraid_refresh_card_phy(struct leapraid_adapter *adapter,
3560 struct leapraid_sas_io_unit_p0 *iou,
3561 int i)
3562 {
3563 struct leapraid_topo_node *card = &adapter->dev_topo.card;
3564 struct leapraid_sas_phy_p0 phy_pg0;
3565 union cfg_param_1 cfgp1 = {0};
3566 union cfg_param_2 cfgp2 = {0};
3567 u16 attached_hdl;
3568 u32 dev_info;
3569 u8 link_rate;
3570 u8 port_id;
3571
3572 link_rate = iou->phy_info[i].neg_link_rate >>
3573 LEAPRAID_SAS_NEG_LINK_RATE_SHIFT;
3574 port_id = iou->phy_info[i].port;
3575 if (leapraid_add_port_to_card_port_list(adapter, port_id, true))
3576 return -EINVAL;
3577
3578 dev_info = le32_to_cpu(iou->phy_info[i].controller_phy_dev_info);
3579 if (dev_info & LEAPRAID_DEVTYP_SEP &&
3580 link_rate >= LEAPRAID_SAS_NEG_LINK_RATE_1_5) {
3581 cfgp1.phy_number = i;
3582
3583 if (leapraid_op_config_page(adapter, &phy_pg0,
3584 cfgp1, cfgp2, GET_PHY_PG0))
3585 return 0;
3586
3587 if (le32_to_cpu(phy_pg0.phy_info) &
3588 LEAPRAID_SAS_PHYINFO_VPHY) {
3589 if (!leapraid_alloc_vphy(adapter, port_id, i))
3590 return -ENOMEM;
3591 card->card_phy[i].vphy = 1;
3592 }
3593 }
3594
3595 card->card_phy[i].hdl = card->hdl;
3596
3597 attached_hdl = le16_to_cpu(iou->phy_info[i].attached_dev_hdl);
3598 if (attached_hdl && link_rate < LEAPRAID_SAS_NEG_LINK_RATE_1_5)
3599 link_rate = LEAPRAID_SAS_NEG_LINK_RATE_1_5;
3600
3601 card->card_phy[i].card_port =
3602 leapraid_get_port_by_id(adapter, port_id, false);
3603
3604 if (!card->card_phy[i].phy) {
3605 cfgp1.phy_number = i;
3606 if (leapraid_op_config_page(adapter, &phy_pg0,
3607 cfgp1, cfgp2, GET_PHY_PG0))
3608 return 0;
3609
3610 card->card_phy[i].phy_id = i;
3611
3612 leapraid_transport_add_card_phy(adapter,
3613 &card->card_phy[i],
3614 &phy_pg0,
3615 card->parent_dev);
3616 return 0;
3617 }
3618
3619 leapraid_transport_update_links(adapter,
3620 card->sas_address,
3621 attached_hdl,
3622 i,
3623 link_rate,
3624 card->card_phy[i].card_port);
3625
3626 return 0;
3627 }
3628
leapraid_sas_host_add(struct leapraid_adapter * adapter,bool refresh)3629 static void leapraid_sas_host_add(struct leapraid_adapter *adapter,
3630 bool refresh)
3631 {
3632 union cfg_param_1 cfgp1 = {0};
3633 union cfg_param_2 cfgp2 = {0};
3634 struct leapraid_sas_dev_p0 sas_dev_pg0;
3635 struct leapraid_enc_p0 enc_pg0;
3636 struct leapraid_sas_io_unit_p0 *sas_iou_pg0;
3637 u16 sas_iou_pg0_sz;
3638 u8 phys_num;
3639 int i;
3640 int rc;
3641
3642 if (!refresh) {
3643 if (leapraid_get_adapter_phys(adapter, &phys_num) || !phys_num)
3644 return;
3645
3646 adapter->dev_topo.card.card_phy =
3647 kcalloc(phys_num,
3648 sizeof(struct leapraid_card_phy), GFP_KERNEL);
3649 if (!adapter->dev_topo.card.card_phy)
3650 return;
3651
3652 adapter->dev_topo.card.phys_num = phys_num;
3653 }
3654
3655 sas_iou_pg0_sz =
3656 offsetof(struct leapraid_sas_io_unit_p0, phy_info) +
3657 (adapter->dev_topo.card.phys_num *
3658 sizeof(struct leapraid_sas_io_unit0_phy_info));
3659 sas_iou_pg0 = kzalloc(sas_iou_pg0_sz, GFP_KERNEL);
3660 if (!sas_iou_pg0)
3661 return;
3662
3663 if (leapraid_get_sas_io_unit_page0(adapter,
3664 sas_iou_pg0,
3665 sas_iou_pg0_sz))
3666 goto out_free;
3667
3668 adapter->dev_topo.card.parent_dev = &adapter->shost->shost_gendev;
3669 adapter->dev_topo.card.hdl =
3670 le16_to_cpu(sas_iou_pg0->phy_info[0].controller_dev_hdl);
3671 for (i = 0; i < adapter->dev_topo.card.phys_num; i++) {
3672 if (!refresh) /* add */
3673 rc = leapraid_add_card_phy(adapter, sas_iou_pg0, i);
3674 else /* refresh */
3675 rc = leapraid_refresh_card_phy(adapter,
3676 sas_iou_pg0,
3677 i);
3678 if (rc)
3679 goto out_free;
3680 }
3681
3682 if (!refresh) {
3683 cfgp1.form = LEAPRAID_SAS_DEV_CFG_PGAD_HDL;
3684 cfgp2.handle = adapter->dev_topo.card.hdl;
3685 if (leapraid_op_config_page(adapter, &sas_dev_pg0, cfgp1,
3686 cfgp2, GET_SAS_DEVICE_PG0))
3687 goto out_free;
3688
3689 adapter->dev_topo.card.enc_hdl =
3690 le16_to_cpu(sas_dev_pg0.enc_hdl);
3691 adapter->dev_topo.card.sas_address =
3692 le64_to_cpu(sas_dev_pg0.sas_address);
3693 dev_info(&adapter->pdev->dev,
3694 "add host: hdl=0x%04x, SAS addr=0x%016llx, phy=%d\n",
3695 adapter->dev_topo.card.hdl,
3696 (unsigned long long)adapter->dev_topo.card.sas_address,
3697 adapter->dev_topo.card.phys_num);
3698
3699 if (adapter->dev_topo.card.enc_hdl) {
3700 cfgp1.form = LEAPRAID_SAS_ENC_CFG_PGAD_HDL;
3701 cfgp2.handle = adapter->dev_topo.card.enc_hdl;
3702 if (!(leapraid_op_config_page(adapter, &enc_pg0,
3703 cfgp1, cfgp2,
3704 GET_SAS_ENCLOSURE_PG0)))
3705 adapter->dev_topo.card.enc_lid =
3706 le64_to_cpu(enc_pg0.enc_lid);
3707 }
3708 }
3709 out_free:
3710 kfree(sas_iou_pg0);
3711 }
3712
leapraid_internal_exp_add(struct leapraid_adapter * adapter,struct leapraid_exp_p0 * exp_pg0,union cfg_param_1 * cfgp1,union cfg_param_2 * cfgp2,u16 hdl)3713 static int leapraid_internal_exp_add(struct leapraid_adapter *adapter,
3714 struct leapraid_exp_p0 *exp_pg0,
3715 union cfg_param_1 *cfgp1,
3716 union cfg_param_2 *cfgp2,
3717 u16 hdl)
3718 {
3719 struct leapraid_topo_node *topo_node_exp;
3720 struct leapraid_sas_port *sas_port = NULL;
3721 struct leapraid_enc_node *enc_dev;
3722 struct leapraid_exp_p1 exp_pg1;
3723 int ret;
3724 int rc;
3725 unsigned long flags;
3726 u8 port_id;
3727 u16 parent_handle;
3728 u64 sas_addr_parent;
3729 int i;
3730
3731 port_id = exp_pg0->physical_port;
3732 parent_handle = le16_to_cpu(exp_pg0->parent_dev_hdl);
3733
3734 rc = leapraid_get_sas_address(adapter,
3735 parent_handle, &sas_addr_parent);
3736 if (rc)
3737 return rc;
3738 topo_node_exp = kzalloc_obj(*topo_node_exp);
3739 if (!topo_node_exp)
3740 return -ENOMEM;
3741
3742 topo_node_exp->hdl = hdl;
3743 topo_node_exp->phys_num = exp_pg0->phy_num;
3744 topo_node_exp->sas_address_parent = sas_addr_parent;
3745 topo_node_exp->sas_address = le64_to_cpu(exp_pg0->sas_address);
3746 topo_node_exp->card_port =
3747 leapraid_get_port_by_id(adapter, port_id, false);
3748 if (!topo_node_exp->card_port) {
3749 rc = -EPERM;
3750 goto out_fail;
3751 }
3752
3753 dev_info(&adapter->pdev->dev,
3754 "add exp: saddr=0x%016llx, hdl=0x%04x, phdl=0x%04x, phy=%d\n",
3755 (unsigned long long)topo_node_exp->sas_address,
3756 hdl, parent_handle,
3757 topo_node_exp->phys_num);
3758 if (!topo_node_exp->phys_num) {
3759 dev_err(&adapter->pdev->dev,
3760 "%s: Invalid PHY num from exp_pg0\n", __func__);
3761 rc = -EPERM;
3762 goto out_fail;
3763 }
3764
3765 topo_node_exp->card_phy =
3766 kcalloc(topo_node_exp->phys_num,
3767 sizeof(struct leapraid_card_phy), GFP_KERNEL);
3768 if (!topo_node_exp->card_phy) {
3769 dev_err(&adapter->pdev->dev,
3770 "%s: Failed to alloc expander phy array, count=%u\n",
3771 __func__, topo_node_exp->phys_num);
3772 rc = -EPERM;
3773 goto out_fail;
3774 }
3775
3776 INIT_LIST_HEAD(&topo_node_exp->sas_port_list);
3777 sas_port = leapraid_transport_port_add(adapter, hdl, sas_addr_parent,
3778 topo_node_exp->card_port);
3779 if (!sas_port) {
3780 rc = -EPERM;
3781 goto out_fail;
3782 }
3783
3784 topo_node_exp->parent_dev = &sas_port->rphy->dev;
3785 topo_node_exp->rphy = sas_port->rphy;
3786 for (i = 0; i < topo_node_exp->phys_num; i++) {
3787 cfgp1->phy_number = i;
3788 cfgp2->handle = hdl;
3789 if (leapraid_op_config_page(adapter, &exp_pg1, *cfgp1, *cfgp2,
3790 GET_SAS_EXPANDER_PG1)) {
3791 dev_err(&adapter->pdev->dev,
3792 "%s: Failed to get exp_pg1, phy=%d\n",
3793 __func__, i);
3794 rc = -EPERM;
3795 goto out_fail;
3796 }
3797
3798 topo_node_exp->card_phy[i].hdl = hdl;
3799 topo_node_exp->card_phy[i].phy_id = i;
3800 topo_node_exp->card_phy[i].card_port =
3801 leapraid_get_port_by_id(adapter, port_id, false);
3802 ret = leapraid_transport_add_exp_phy(
3803 adapter,
3804 &topo_node_exp->card_phy[i],
3805 &exp_pg1,
3806 topo_node_exp->parent_dev);
3807 if (ret) {
3808 rc = -EPERM;
3809 goto out_fail;
3810 }
3811 }
3812
3813 if (topo_node_exp->enc_hdl) {
3814 spin_lock_irqsave(&adapter->dev_topo.enc_lock, flags);
3815 enc_dev = leapraid_enc_find_by_hdl(adapter,
3816 topo_node_exp->enc_hdl);
3817 if (enc_dev)
3818 topo_node_exp->enc_lid =
3819 le64_to_cpu(enc_dev->pg0.enc_lid);
3820 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, flags);
3821 }
3822
3823 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags);
3824 list_add_tail(&topo_node_exp->list, &adapter->dev_topo.exp_list);
3825 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock, flags);
3826 return 0;
3827
3828 out_fail:
3829 if (sas_port)
3830 leapraid_transport_port_remove(adapter,
3831 topo_node_exp->sas_address,
3832 sas_addr_parent,
3833 topo_node_exp->card_port);
3834 kfree(topo_node_exp->card_phy);
3835 kfree(topo_node_exp);
3836 return rc;
3837 }
3838
leapraid_exp_add(struct leapraid_adapter * adapter,u16 hdl)3839 static int leapraid_exp_add(struct leapraid_adapter *adapter, u16 hdl)
3840 {
3841 union cfg_param_1 cfgp1 = {0};
3842 union cfg_param_2 cfgp2 = {0};
3843 struct leapraid_topo_node *topo_node_exp;
3844 struct leapraid_exp_p0 exp_pg0;
3845 u16 parent_handle;
3846 u64 sas_addr, sas_addr_parent;
3847 unsigned long flags;
3848 u8 port_id;
3849 int rc;
3850
3851 if (!hdl) {
3852 dev_warn(&adapter->pdev->dev, "%s: Invalid hdl\n", __func__);
3853 return -EPERM;
3854 }
3855
3856 if (adapter->access_ctrl.shost_recovering ||
3857 adapter->access_ctrl.pcie_recovering) {
3858 dev_warn(&adapter->pdev->dev,
3859 "%s: Failed, shost_recovering=%d pcie_recovering=%d\n",
3860 __func__, adapter->access_ctrl.shost_recovering,
3861 adapter->access_ctrl.pcie_recovering);
3862 return -EPERM;
3863 }
3864
3865 cfgp1.form = LEAPRAID_SAS_EXP_CFD_PGAD_HDL;
3866 cfgp2.handle = hdl;
3867 if (leapraid_op_config_page(adapter, &exp_pg0, cfgp1, cfgp2,
3868 GET_SAS_EXPANDER_PG0))
3869 return -EPERM;
3870
3871 parent_handle = le16_to_cpu(exp_pg0.parent_dev_hdl);
3872 if (leapraid_get_sas_address(adapter, parent_handle, &sas_addr_parent))
3873 return -EPERM;
3874
3875 port_id = exp_pg0.physical_port;
3876 if (sas_addr_parent != adapter->dev_topo.card.sas_address) {
3877 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags);
3878 topo_node_exp =
3879 leapraid_exp_find_by_sas_address(
3880 adapter,
3881 sas_addr_parent,
3882 leapraid_get_port_by_id(adapter,
3883 port_id,
3884 false));
3885 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock,
3886 flags);
3887 if (!topo_node_exp) {
3888 rc = leapraid_exp_add(adapter, parent_handle);
3889 if (rc != 0)
3890 return rc;
3891 }
3892 }
3893
3894 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags);
3895 sas_addr = le64_to_cpu(exp_pg0.sas_address);
3896 topo_node_exp =
3897 leapraid_exp_find_by_sas_address(
3898 adapter,
3899 sas_addr,
3900 leapraid_get_port_by_id(adapter, port_id, false));
3901 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock, flags);
3902
3903 if (topo_node_exp)
3904 return 0;
3905
3906 return leapraid_internal_exp_add(adapter, &exp_pg0, &cfgp1,
3907 &cfgp2, hdl);
3908 }
3909
leapraid_exp_node_rm(struct leapraid_adapter * adapter,struct leapraid_topo_node * topo_node_exp)3910 static void leapraid_exp_node_rm(struct leapraid_adapter *adapter,
3911 struct leapraid_topo_node *topo_node_exp)
3912 {
3913 struct leapraid_sas_port *sas_port, *sas_port_next;
3914 unsigned long flags;
3915 int port_id;
3916
3917 list_for_each_entry_safe(sas_port, sas_port_next,
3918 &topo_node_exp->sas_port_list,
3919 port_list) {
3920 if (adapter->access_ctrl.shost_recovering)
3921 return;
3922
3923 switch (sas_port->remote_identify.device_type) {
3924 case SAS_END_DEVICE:
3925 leapraid_sas_dev_remove_by_sas_address(
3926 adapter,
3927 sas_port->remote_identify.sas_address,
3928 sas_port->card_port);
3929 break;
3930 case SAS_EDGE_EXPANDER_DEVICE:
3931 case SAS_FANOUT_EXPANDER_DEVICE:
3932 leapraid_exp_rm(
3933 adapter,
3934 sas_port->remote_identify.sas_address,
3935 sas_port->card_port);
3936 break;
3937 default:
3938 break;
3939 }
3940 }
3941
3942 port_id = topo_node_exp->card_port->port_id;
3943 leapraid_transport_port_remove(adapter, topo_node_exp->sas_address,
3944 topo_node_exp->sas_address_parent,
3945 topo_node_exp->card_port);
3946 dev_info(&adapter->pdev->dev,
3947 "removing exp: port=%d, SAS addr=0x%016llx, hdl=0x%04x\n",
3948 port_id, (unsigned long long)topo_node_exp->sas_address,
3949 topo_node_exp->hdl);
3950 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags);
3951 list_del(&topo_node_exp->list);
3952 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock, flags);
3953 kfree(topo_node_exp->card_phy);
3954 kfree(topo_node_exp);
3955 }
3956
leapraid_exp_rm(struct leapraid_adapter * adapter,u64 sas_addr,struct leapraid_card_port * port)3957 void leapraid_exp_rm(struct leapraid_adapter *adapter, u64 sas_addr,
3958 struct leapraid_card_port *port)
3959 {
3960 struct leapraid_topo_node *topo_node_exp;
3961 unsigned long flags;
3962
3963 if (adapter->access_ctrl.shost_recovering)
3964 return;
3965
3966 if (!port)
3967 return;
3968
3969 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags);
3970 topo_node_exp = leapraid_exp_find_by_sas_address(adapter,
3971 sas_addr,
3972 port);
3973 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock, flags);
3974
3975 if (topo_node_exp)
3976 leapraid_exp_node_rm(adapter, topo_node_exp);
3977 }
3978
leapraid_internal_sas_topo_chg_evt(struct leapraid_adapter * adapter,struct leapraid_card_port * card_port,struct leapraid_topo_node * topo_node_exp,struct leapraid_fw_evt_work * fw_evt,u64 sas_addr,u8 max_phys)3979 static void leapraid_internal_sas_topo_chg_evt(
3980 struct leapraid_adapter *adapter,
3981 struct leapraid_card_port *card_port,
3982 struct leapraid_topo_node *topo_node_exp,
3983 struct leapraid_fw_evt_work *fw_evt,
3984 u64 sas_addr, u8 max_phys)
3985 {
3986 struct leapraid_evt_data_sas_topo_change_list *evt_data;
3987 u8 phy_number;
3988 u8 link_rate;
3989 u16 reason_code;
3990 u16 hdl;
3991 int i;
3992
3993 evt_data = fw_evt->evt_data;
3994 for (i = 0; i < evt_data->entry_num; i++) {
3995 if (fw_evt->ignore)
3996 return;
3997
3998 if (adapter->access_ctrl.host_removing ||
3999 adapter->access_ctrl.pcie_recovering)
4000 return;
4001
4002 phy_number = evt_data->start_phy_num + i;
4003 if (phy_number >= max_phys)
4004 continue;
4005
4006 reason_code = evt_data->phy[i].phy_status &
4007 LEAPRAID_EVT_SAS_TOPO_RC_MASK;
4008
4009 hdl = le16_to_cpu(evt_data->phy[i].attached_dev_hdl);
4010 if (!hdl ||
4011 hdl > adapter->adapter_attr.features.max_dev_handle) {
4012 dev_warn(&adapter->pdev->dev,
4013 "%s: Invalid device handle\n", __func__);
4014 continue;
4015 }
4016 link_rate = evt_data->phy[i].link_rate >>
4017 LEAPRAID_SAS_NEG_LINK_RATE_SHIFT;
4018 switch (reason_code) {
4019 case LEAPRAID_EVT_SAS_TOPO_RC_TARG_ADDED:
4020 if (adapter->access_ctrl.shost_recovering)
4021 break;
4022 leapraid_transport_update_links(adapter, sas_addr,
4023 hdl, phy_number,
4024 link_rate, card_port);
4025 if (link_rate < LEAPRAID_SAS_NEG_LINK_RATE_1_5)
4026 break;
4027 leapraid_add_dev(adapter, hdl);
4028 break;
4029 case LEAPRAID_EVT_SAS_TOPO_RC_TARG_NOT_RESPONDING:
4030 leapraid_sas_dev_remove_by_hdl(adapter, hdl);
4031 break;
4032 }
4033 }
4034
4035 if (evt_data->exp_status == LEAPRAID_EVT_SAS_TOPO_ES_NOT_RESPONDING &&
4036 topo_node_exp)
4037 leapraid_exp_rm(adapter, sas_addr, card_port);
4038 }
4039
leapraid_sas_topo_chg_evt(struct leapraid_adapter * adapter,struct leapraid_fw_evt_work * fw_evt)4040 static void leapraid_sas_topo_chg_evt(struct leapraid_adapter *adapter,
4041 struct leapraid_fw_evt_work *fw_evt)
4042 {
4043 struct leapraid_topo_node *topo_node_exp;
4044 struct leapraid_card_port *card_port;
4045 struct leapraid_evt_data_sas_topo_change_list *evt_data;
4046 u16 phdl;
4047 u8 max_phys;
4048 u64 sas_addr;
4049 unsigned long flags;
4050
4051 if (adapter->access_ctrl.shost_recovering ||
4052 adapter->access_ctrl.host_removing ||
4053 adapter->access_ctrl.pcie_recovering)
4054 return;
4055
4056 evt_data = fw_evt->evt_data;
4057 leapraid_sas_host_add(adapter, adapter->dev_topo.card.phys_num > 0);
4058
4059 if (fw_evt->ignore)
4060 return;
4061
4062 phdl = le16_to_cpu(evt_data->exp_dev_hdl);
4063 card_port = leapraid_get_port_by_id(adapter,
4064 evt_data->physical_port,
4065 false);
4066 if (evt_data->exp_status == LEAPRAID_EVT_SAS_TOPO_ES_ADDED &&
4067 leapraid_exp_add(adapter, phdl) != 0)
4068 return;
4069
4070 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags);
4071 topo_node_exp = leapraid_exp_find_by_hdl(adapter, phdl);
4072 if (topo_node_exp) {
4073 sas_addr = topo_node_exp->sas_address;
4074 max_phys = topo_node_exp->phys_num;
4075 card_port = topo_node_exp->card_port;
4076 } else if (phdl < adapter->dev_topo.card.phys_num) {
4077 sas_addr = adapter->dev_topo.card.sas_address;
4078 max_phys = adapter->dev_topo.card.phys_num;
4079 } else {
4080 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock,
4081 flags);
4082 return;
4083 }
4084 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock, flags);
4085
4086 leapraid_internal_sas_topo_chg_evt(adapter, card_port,
4087 topo_node_exp, fw_evt,
4088 sas_addr, max_phys);
4089 }
4090
leapraid_reprobe_lun(struct scsi_device * sdev,void * no_uld_attach)4091 static void leapraid_reprobe_lun(struct scsi_device *sdev, void *no_uld_attach)
4092 {
4093 sdev->no_uld_attach = no_uld_attach ? 1 : 0;
4094 sdev_printk(KERN_INFO, sdev,
4095 "%s RAID component to upper layer\n",
4096 sdev->no_uld_attach ? "hide" : "expose");
4097 WARN_ON(scsi_device_reprobe(sdev));
4098 }
4099
leapraid_sas_pd_add(struct leapraid_adapter * adapter,struct leapraid_evt_data_ir_change * evt_data)4100 static void leapraid_sas_pd_add(
4101 struct leapraid_adapter *adapter,
4102 struct leapraid_evt_data_ir_change *evt_data)
4103 {
4104 union cfg_param_1 cfgp1 = {0};
4105 union cfg_param_2 cfgp2 = {0};
4106 struct leapraid_sas_dev_p0 sas_dev_p0;
4107 struct leapraid_sas_dev *sas_dev;
4108 u64 sas_address;
4109 u16 parent_hdl;
4110 u16 hdl;
4111
4112 hdl = le16_to_cpu(evt_data->phys_disk_dev_hdl);
4113 if (!hdl || hdl > adapter->adapter_attr.features.max_dev_handle) {
4114 dev_warn(&adapter->pdev->dev,
4115 "%s: Invalid device handle\n", __func__);
4116 return;
4117 }
4118
4119 set_bit(hdl, adapter->dev_topo.pd_hdls);
4120 sas_dev = leapraid_get_sas_dev_by_hdl(adapter, hdl);
4121 if (sas_dev) {
4122 leapraid_sdev_put(sas_dev);
4123 dev_warn(&adapter->pdev->dev,
4124 "Dev handle 0x%x already exists\n", hdl);
4125 return;
4126 }
4127
4128 cfgp1.form = LEAPRAID_SAS_DEV_CFG_PGAD_HDL;
4129 cfgp2.handle = hdl;
4130 if (leapraid_op_config_page(adapter, &sas_dev_p0, cfgp1, cfgp2,
4131 GET_SAS_DEVICE_PG0)) {
4132 dev_warn(&adapter->pdev->dev, "Failed to read dev page0\n");
4133 return;
4134 }
4135
4136 parent_hdl = le16_to_cpu(sas_dev_p0.parent_dev_hdl);
4137 if (!leapraid_get_sas_address(adapter, parent_hdl, &sas_address))
4138 leapraid_transport_update_links(adapter, sas_address, hdl,
4139 sas_dev_p0.phy_num,
4140 LEAPRAID_SAS_NEG_LINK_RATE_1_5,
4141 leapraid_get_port_by_id(adapter,
4142 sas_dev_p0.physical_port,
4143 false));
4144 leapraid_add_dev(adapter, hdl);
4145 }
4146
leapraid_sas_pd_delete(struct leapraid_adapter * adapter,struct leapraid_evt_data_ir_change * evt_data)4147 static void leapraid_sas_pd_delete(
4148 struct leapraid_adapter *adapter,
4149 struct leapraid_evt_data_ir_change *evt_data)
4150 {
4151 u16 hdl;
4152
4153 hdl = le16_to_cpu(evt_data->phys_disk_dev_hdl);
4154 leapraid_sas_dev_remove_by_hdl(adapter, hdl);
4155 }
4156
leapraid_sas_pd_hide(struct leapraid_adapter * adapter,struct leapraid_evt_data_ir_change * evt_data)4157 static void leapraid_sas_pd_hide(
4158 struct leapraid_adapter *adapter,
4159 struct leapraid_evt_data_ir_change *evt_data)
4160 {
4161 struct leapraid_starget_priv *starget_priv;
4162 struct scsi_target *starget = NULL;
4163 struct leapraid_sas_dev *sas_dev;
4164 unsigned long flags;
4165 u64 volume_wwid = 0;
4166 u16 volume_hdl;
4167 u16 hdl;
4168
4169 hdl = le16_to_cpu(evt_data->phys_disk_dev_hdl);
4170 if (!hdl || hdl > adapter->adapter_attr.features.max_dev_handle) {
4171 dev_warn(&adapter->pdev->dev,
4172 "%s: Invalid device handle\n", __func__);
4173 return;
4174 }
4175 leapraid_cfg_get_volume_hdl(adapter, hdl, &volume_hdl);
4176 if (volume_hdl)
4177 leapraid_cfg_get_volume_wwid(adapter,
4178 volume_hdl,
4179 &volume_wwid);
4180
4181 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags);
4182 sas_dev = leapraid_hold_lock_get_sas_dev_by_hdl(adapter, hdl);
4183 if (!sas_dev) {
4184 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags);
4185 return;
4186 }
4187
4188 set_bit(hdl, adapter->dev_topo.pd_hdls);
4189 if (sas_dev->starget && sas_dev->starget->hostdata) {
4190 starget = sas_dev->starget;
4191 starget_priv = starget->hostdata;
4192 starget_priv->flg |= LEAPRAID_TGT_FLG_RAID_MEMBER;
4193 sas_dev->volume_hdl = volume_hdl;
4194 sas_dev->volume_wwid = volume_wwid;
4195 }
4196 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags);
4197 if (starget) {
4198 starget_for_each_device(starget,
4199 (void *)LEAPRAID_NO_ULD_ATTACH_FLAG,
4200 leapraid_reprobe_lun);
4201 }
4202
4203 leapraid_sdev_put(sas_dev);
4204 }
4205
leapraid_sas_pd_expose(struct leapraid_adapter * adapter,struct leapraid_evt_data_ir_change * evt_data)4206 static void leapraid_sas_pd_expose(
4207 struct leapraid_adapter *adapter,
4208 struct leapraid_evt_data_ir_change *evt_data)
4209 {
4210 struct leapraid_starget_priv *starget_priv;
4211 struct scsi_target *starget = NULL;
4212 struct leapraid_sas_dev *sas_dev;
4213 unsigned long flags;
4214 u16 hdl;
4215
4216 hdl = le16_to_cpu(evt_data->phys_disk_dev_hdl);
4217 if (!hdl || hdl > adapter->adapter_attr.features.max_dev_handle) {
4218 dev_warn(&adapter->pdev->dev,
4219 "%s: Invalid device handle\n", __func__);
4220 return;
4221 }
4222
4223 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags);
4224 sas_dev = leapraid_hold_lock_get_sas_dev_by_hdl(adapter, hdl);
4225 if (!sas_dev) {
4226 dev_warn(&adapter->pdev->dev,
4227 "%s:%d: sas_dev not found, hdl=0x%x\n",
4228 __func__, __LINE__, hdl);
4229 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags);
4230 return;
4231 }
4232
4233 sas_dev->volume_hdl = 0;
4234 sas_dev->volume_wwid = 0;
4235 clear_bit(hdl, adapter->dev_topo.pd_hdls);
4236 if (sas_dev->starget && sas_dev->starget->hostdata) {
4237 starget = sas_dev->starget;
4238 starget_priv = starget->hostdata;
4239 starget_priv->flg &= ~LEAPRAID_TGT_FLG_RAID_MEMBER;
4240 sas_dev->led_on = 0;
4241 }
4242 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags);
4243
4244 if (starget) {
4245 starget_for_each_device(starget,
4246 NULL,
4247 leapraid_reprobe_lun);
4248 }
4249
4250 leapraid_sdev_put(sas_dev);
4251 }
4252
leapraid_sas_vol_visibility(struct leapraid_adapter * adapter,struct leapraid_evt_data_ir_change * evt_data)4253 static void leapraid_sas_vol_visibility(
4254 struct leapraid_adapter *adapter,
4255 struct leapraid_evt_data_ir_change *evt_data)
4256 {
4257 struct leapraid_raid_volume *raid_volume;
4258 struct scsi_device *sdev;
4259 bool reprobe_flg = false;
4260 bool sdev_held = false;
4261 unsigned long flags;
4262 u16 hdl;
4263 u8 rc;
4264
4265 hdl = le16_to_cpu(evt_data->vol_dev_hdl);
4266 rc = evt_data->reason_code;
4267 raid_volume = leapraid_raid_volume_find_by_hdl(adapter, hdl);
4268 if (!raid_volume) {
4269 dev_warn(&adapter->pdev->dev,
4270 "%s:%d: Volume handle 0x%x not found\n",
4271 __func__, __LINE__, hdl);
4272 return;
4273 }
4274
4275 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags);
4276 sdev = raid_volume->sdev;
4277 if (!sdev) {
4278 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock,
4279 flags);
4280 leapraid_raid_volume_put(raid_volume);
4281 dev_warn(&adapter->pdev->dev,
4282 "%s:%d: Volume handle 0x%x has no sdev\n",
4283 __func__, __LINE__, hdl);
4284 return;
4285 }
4286
4287 if (sdev->no_uld_attach &&
4288 rc == LEAPRAID_EVT_IR_RC_VOLUME_UNHIDE) {
4289 sdev->no_uld_attach = 0;
4290 reprobe_flg = true;
4291 } else if (!sdev->no_uld_attach &&
4292 rc == LEAPRAID_EVT_IR_RC_VOLUME_HIDE) {
4293 sdev->no_uld_attach = 1;
4294 reprobe_flg = true;
4295 }
4296
4297 if (reprobe_flg && !scsi_device_get(sdev))
4298 sdev_held = true;
4299 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, flags);
4300 leapraid_raid_volume_put(raid_volume);
4301
4302 if (!reprobe_flg) {
4303 dev_warn(&adapter->pdev->dev,
4304 "%s:rc(0x%x): Request matches, skipping\n",
4305 __func__, rc);
4306 return;
4307 }
4308
4309 if (!sdev_held) {
4310 dev_warn(&adapter->pdev->dev,
4311 "%s: Failed to hold sdev for reprobe, hdl=0x%x\n",
4312 __func__, hdl);
4313 return;
4314 }
4315
4316 if (sdev->no_uld_attach)
4317 sdev_printk(KERN_INFO, sdev, "hide vol\n");
4318 else
4319 sdev_printk(KERN_INFO, sdev, "unhide vol\n");
4320
4321 WARN_ON(scsi_device_reprobe(sdev));
4322 scsi_device_put(sdev);
4323 }
4324
leapraid_sas_volume_add(struct leapraid_adapter * adapter,struct leapraid_evt_data_ir_change * evt_data)4325 static void leapraid_sas_volume_add(
4326 struct leapraid_adapter *adapter,
4327 struct leapraid_evt_data_ir_change *evt_data)
4328 {
4329 struct leapraid_raid_volume *raid_volume;
4330 unsigned long flags;
4331 u64 wwid;
4332 u16 hdl;
4333
4334 hdl = le16_to_cpu(evt_data->vol_dev_hdl);
4335
4336 if (leapraid_cfg_get_volume_wwid(adapter, hdl, &wwid)) {
4337 dev_warn(&adapter->pdev->dev, "Failed to read volume page1\n");
4338 return;
4339 }
4340
4341 if (!wwid) {
4342 dev_warn(&adapter->pdev->dev, "Invalid WWID(handle=0x%x)\n",
4343 hdl);
4344 return;
4345 }
4346
4347 raid_volume = leapraid_raid_volume_find_by_wwid(adapter, wwid);
4348 if (raid_volume) {
4349 dev_warn(&adapter->pdev->dev,
4350 "Volume handle 0x%x already exists\n", hdl);
4351 leapraid_raid_volume_put(raid_volume);
4352 return;
4353 }
4354
4355 raid_volume = kzalloc(sizeof(*raid_volume), GFP_KERNEL);
4356 if (!raid_volume)
4357 return;
4358
4359 INIT_LIST_HEAD(&raid_volume->list);
4360 kref_init(&raid_volume->refcnt);
4361 raid_volume->id = adapter->dev_topo.sas_id++;
4362 raid_volume->channel = RAID_CHANNEL;
4363 raid_volume->hdl = hdl;
4364 raid_volume->wwid = wwid;
4365 leapraid_raid_volume_add(adapter, raid_volume);
4366 if (!adapter->scan_dev_desc.wait_scan_dev_done) {
4367 if (scsi_add_device(adapter->shost, RAID_CHANNEL,
4368 raid_volume->id, 0))
4369 leapraid_raid_volume_remove(adapter, raid_volume);
4370 dev_info(&adapter->pdev->dev,
4371 "add RAID volume: hdl=0x%x, wwid=0x%llx\n", hdl, wwid);
4372 } else {
4373 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags);
4374 leapraid_check_boot_dev(adapter, raid_volume, RAID_CHANNEL);
4375 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock,
4376 flags);
4377 }
4378 leapraid_raid_volume_put(raid_volume);
4379 }
4380
leapraid_sas_volume_delete_by_ptr(struct leapraid_adapter * adapter,struct leapraid_raid_volume * raid_volume)4381 static void leapraid_sas_volume_delete_by_ptr(
4382 struct leapraid_adapter *adapter,
4383 struct leapraid_raid_volume *raid_volume)
4384 {
4385 struct leapraid_starget_priv *starget_priv;
4386 struct scsi_target *starget = NULL;
4387 unsigned long flags;
4388 bool in_list;
4389
4390 if (!raid_volume)
4391 return;
4392
4393 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags);
4394 in_list = !list_empty(&raid_volume->list);
4395 if (in_list && raid_volume->starget) {
4396 starget = raid_volume->starget;
4397 starget_priv = starget->hostdata;
4398 if (starget_priv)
4399 starget_priv->deleted = 1;
4400 }
4401 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, flags);
4402
4403 if (!in_list)
4404 return;
4405
4406 dev_info(&adapter->pdev->dev,
4407 "delete RAID volume: hdl=0x%x, wwid=0x%llx\n",
4408 raid_volume->hdl, raid_volume->wwid);
4409 leapraid_raid_volume_remove(adapter, raid_volume);
4410
4411 if (starget)
4412 scsi_remove_target(&starget->dev);
4413 }
4414
leapraid_sas_volume_delete(struct leapraid_adapter * adapter,u16 hdl)4415 static void leapraid_sas_volume_delete(struct leapraid_adapter *adapter,
4416 u16 hdl)
4417 {
4418 struct leapraid_raid_volume *raid_volume;
4419
4420 raid_volume = leapraid_raid_volume_find_by_hdl(adapter, hdl);
4421 if (!raid_volume) {
4422 dev_warn(&adapter->pdev->dev,
4423 "%s:%d: Volume handle 0x%x not found\n",
4424 __func__, __LINE__, hdl);
4425 return;
4426 }
4427
4428 leapraid_sas_volume_delete_by_ptr(adapter, raid_volume);
4429 leapraid_raid_volume_put(raid_volume);
4430 }
4431
leapraid_sas_ir_chg_evt(struct leapraid_adapter * adapter,struct leapraid_fw_evt_work * fw_evt)4432 static void leapraid_sas_ir_chg_evt(struct leapraid_adapter *adapter,
4433 struct leapraid_fw_evt_work *fw_evt)
4434 {
4435 struct leapraid_evt_data_ir_change *evt_data;
4436
4437 evt_data = fw_evt->evt_data;
4438
4439 switch (evt_data->reason_code) {
4440 case LEAPRAID_EVT_IR_RC_VOLUME_ADD:
4441 leapraid_sas_volume_add(adapter, evt_data);
4442 break;
4443 case LEAPRAID_EVT_IR_RC_VOLUME_DELETE:
4444 leapraid_sas_volume_delete(adapter,
4445 le16_to_cpu(evt_data->vol_dev_hdl));
4446 break;
4447 case LEAPRAID_EVT_IR_RC_PD_HIDDEN_TO_ADD:
4448 leapraid_sas_pd_add(adapter, evt_data);
4449 break;
4450 case LEAPRAID_EVT_IR_RC_PD_UNHIDDEN_TO_DELETE:
4451 leapraid_sas_pd_delete(adapter, evt_data);
4452 break;
4453 case LEAPRAID_EVT_IR_RC_PD_CREATED_TO_HIDE:
4454 leapraid_sas_pd_hide(adapter, evt_data);
4455 break;
4456 case LEAPRAID_EVT_IR_RC_PD_DELETED_TO_EXPOSE:
4457 leapraid_sas_pd_expose(adapter, evt_data);
4458 break;
4459 case LEAPRAID_EVT_IR_RC_VOLUME_HIDE:
4460 case LEAPRAID_EVT_IR_RC_VOLUME_UNHIDE:
4461 leapraid_sas_vol_visibility(adapter, evt_data);
4462 break;
4463 default:
4464 break;
4465 }
4466 }
4467
leapraid_sas_enc_dev_stat_add_node(struct leapraid_adapter * adapter,u16 hdl)4468 static void leapraid_sas_enc_dev_stat_add_node(
4469 struct leapraid_adapter *adapter, u16 hdl)
4470 {
4471 union cfg_param_1 cfgp1 = {0};
4472 union cfg_param_2 cfgp2 = {0};
4473 struct leapraid_enc_node *enc_node;
4474 struct leapraid_enc_node *enc_exist;
4475 unsigned long flags;
4476 int rc;
4477
4478 enc_node = kzalloc_obj(*enc_node);
4479 if (!enc_node)
4480 return;
4481
4482 cfgp1.form = LEAPRAID_SAS_ENC_CFG_PGAD_HDL;
4483 cfgp2.handle = hdl;
4484 rc = leapraid_op_config_page(adapter, &enc_node->pg0, cfgp1, cfgp2,
4485 GET_SAS_ENCLOSURE_PG0);
4486 if (rc) {
4487 kfree(enc_node);
4488 return;
4489 }
4490
4491 spin_lock_irqsave(&adapter->dev_topo.enc_lock, flags);
4492 enc_exist = leapraid_enc_find_by_hdl(adapter, hdl);
4493 if (enc_exist) {
4494 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, flags);
4495 kfree(enc_node);
4496 return;
4497 }
4498 list_add_tail(&enc_node->list, &adapter->dev_topo.enc_list);
4499 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, flags);
4500 }
4501
leapraid_sas_enc_dev_stat_del_node(struct leapraid_adapter * adapter,u16 hdl)4502 static void leapraid_sas_enc_dev_stat_del_node(
4503 struct leapraid_adapter *adapter, u16 hdl)
4504 {
4505 struct leapraid_enc_node *enc_node;
4506 unsigned long flags;
4507
4508 if (!hdl)
4509 return;
4510
4511 spin_lock_irqsave(&adapter->dev_topo.enc_lock, flags);
4512 enc_node = leapraid_enc_find_by_hdl(adapter, hdl);
4513 if (enc_node)
4514 list_del(&enc_node->list);
4515 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, flags);
4516
4517 kfree(enc_node);
4518 }
4519
leapraid_sas_enc_dev_stat_chg_evt(struct leapraid_adapter * adapter,struct leapraid_fw_evt_work * fw_evt)4520 static void leapraid_sas_enc_dev_stat_chg_evt(
4521 struct leapraid_adapter *adapter,
4522 struct leapraid_fw_evt_work *fw_evt)
4523 {
4524 struct leapraid_evt_data_sas_enc_dev_status_change *evt_data;
4525 u16 enc_hdl;
4526
4527 if (adapter->access_ctrl.shost_recovering)
4528 return;
4529
4530 evt_data = fw_evt->evt_data;
4531 enc_hdl = le16_to_cpu(evt_data->enc_hdl);
4532 switch (evt_data->reason_code) {
4533 case LEAPRAID_EVT_SAS_ENCL_RC_ADDED:
4534 if (enc_hdl)
4535 leapraid_sas_enc_dev_stat_add_node(adapter, enc_hdl);
4536 break;
4537 case LEAPRAID_EVT_SAS_ENCL_RC_NOT_RESPONDING:
4538 leapraid_sas_enc_dev_stat_del_node(adapter, enc_hdl);
4539 break;
4540 default:
4541 break;
4542 }
4543 }
4544
leapraid_remove_unresp_sas_end_dev(struct leapraid_adapter * adapter)4545 static void leapraid_remove_unresp_sas_end_dev(
4546 struct leapraid_adapter *adapter)
4547 {
4548 struct leapraid_sas_dev *sas_dev, *sas_dev_next;
4549 unsigned long flags;
4550 LIST_HEAD(head);
4551
4552 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags);
4553 list_for_each_entry_safe(sas_dev, sas_dev_next,
4554 &adapter->dev_topo.sas_dev_init_list, list) {
4555 if (sas_dev->rphy || sas_dev->pend_sas_rphy_add)
4556 continue;
4557
4558 list_del_init(&sas_dev->list);
4559 leapraid_clear_cached_boot_dev(adapter, sas_dev, 0);
4560 leapraid_sdev_put(sas_dev);
4561 }
4562 list_for_each_entry_safe(sas_dev, sas_dev_next,
4563 &adapter->dev_topo.sas_dev_list, list) {
4564 if (!sas_dev->resp)
4565 list_move_tail(&sas_dev->list, &head);
4566 else
4567 sas_dev->resp = 0;
4568 }
4569 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags);
4570
4571 list_for_each_entry_safe(sas_dev, sas_dev_next, &head, list) {
4572 leapraid_remove_device(adapter, sas_dev);
4573 list_del_init(&sas_dev->list);
4574 leapraid_sdev_put(sas_dev);
4575 }
4576
4577 dev_warn(&adapter->pdev->dev,
4578 "Unresponsive SAS end devices removed\n");
4579 }
4580
leapraid_remove_unresp_raid_volumes(struct leapraid_adapter * adapter)4581 static void leapraid_remove_unresp_raid_volumes(
4582 struct leapraid_adapter *adapter)
4583 {
4584 unsigned long flags;
4585 struct leapraid_raid_volume *raid_volume, *raid_volume_next;
4586 LIST_HEAD(head);
4587
4588 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags);
4589 list_for_each_entry_safe(raid_volume, raid_volume_next,
4590 &adapter->dev_topo.raid_volume_list, list) {
4591 if (!raid_volume->resp)
4592 list_move_tail(&raid_volume->list, &head);
4593 else
4594 raid_volume->resp = 0;
4595 }
4596 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, flags);
4597
4598 list_for_each_entry_safe(raid_volume, raid_volume_next, &head, list) {
4599 leapraid_sas_volume_delete_by_ptr(adapter, raid_volume);
4600 }
4601
4602 dev_warn(&adapter->pdev->dev,
4603 "Unresponsive RAID volumes removed\n");
4604 }
4605
leapraid_remove_unresp_sas_exp(struct leapraid_adapter * adapter)4606 static void leapraid_remove_unresp_sas_exp(struct leapraid_adapter *adapter)
4607 {
4608 struct leapraid_topo_node *topo_node_exp, *topo_node_exp_next;
4609 unsigned long flags;
4610 LIST_HEAD(head);
4611
4612 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags);
4613 list_for_each_entry_safe(topo_node_exp, topo_node_exp_next,
4614 &adapter->dev_topo.exp_list, list) {
4615 if (!topo_node_exp->resp)
4616 list_move_tail(&topo_node_exp->list, &head);
4617 else
4618 topo_node_exp->resp = 0;
4619 }
4620 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock, flags);
4621
4622 list_for_each_entry_safe(topo_node_exp, topo_node_exp_next,
4623 &head, list)
4624 leapraid_exp_node_rm(adapter, topo_node_exp);
4625
4626 dev_warn(&adapter->pdev->dev,
4627 "Unresponsive SAS expanders removed\n");
4628 }
4629
leapraid_remove_unresp_dev(struct leapraid_adapter * adapter)4630 static void leapraid_remove_unresp_dev(struct leapraid_adapter *adapter)
4631 {
4632 leapraid_remove_unresp_sas_end_dev(adapter);
4633 if (adapter->adapter_attr.raid_support)
4634 leapraid_remove_unresp_raid_volumes(adapter);
4635 leapraid_remove_unresp_sas_exp(adapter);
4636 leapraid_ublk_io_all_dev(adapter);
4637 }
4638
leapraid_del_dirty_vphy(struct leapraid_adapter * adapter)4639 static void leapraid_del_dirty_vphy(struct leapraid_adapter *adapter)
4640 {
4641 struct leapraid_card_port *card_port, *card_port_next;
4642 struct leapraid_vphy *vphy, *vphy_next;
4643
4644 list_for_each_entry_safe(card_port, card_port_next,
4645 &adapter->dev_topo.card_port_list, list) {
4646 if (!card_port->vphys_mask)
4647 continue;
4648
4649 list_for_each_entry_safe(vphy, vphy_next,
4650 &card_port->vphys_list, list) {
4651 if (!(vphy->flg & LEAPRAID_VPHY_FLG_DIRTY))
4652 continue;
4653
4654 card_port->vphys_mask &= ~vphy->phy_mask;
4655 list_del(&vphy->list);
4656 kfree(vphy);
4657 }
4658
4659 if (!card_port->vphys_mask && !card_port->sas_address)
4660 card_port->flg |= LEAPRAID_CARD_PORT_FLG_DIRTY;
4661 }
4662 }
4663
leapraid_del_dirty_card_port(struct leapraid_adapter * adapter)4664 static void leapraid_del_dirty_card_port(struct leapraid_adapter *adapter)
4665 {
4666 struct leapraid_card_port *card_port, *card_port_next;
4667
4668 list_for_each_entry_safe(card_port, card_port_next,
4669 &adapter->dev_topo.card_port_list, list) {
4670 if (!(card_port->flg & LEAPRAID_CARD_PORT_FLG_DIRTY) ||
4671 card_port->flg & LEAPRAID_CARD_PORT_FLG_NEW)
4672 continue;
4673
4674 list_del(&card_port->list);
4675 kfree(card_port);
4676 }
4677 }
4678
leapraid_update_dev_qdepth(struct leapraid_adapter * adapter)4679 static void leapraid_update_dev_qdepth(struct leapraid_adapter *adapter)
4680 {
4681 struct leapraid_sdev_priv *sdev_priv;
4682 struct leapraid_sas_dev *sas_dev;
4683 struct leapraid_adapter_attr *attr;
4684 struct scsi_device *sdev;
4685 u16 qdepth;
4686
4687 attr = &adapter->adapter_attr;
4688 shost_for_each_device(sdev, adapter->shost) {
4689 sdev_priv = sdev->hostdata;
4690 if (!sdev_priv || !sdev_priv->starget_priv)
4691 continue;
4692 sas_dev = sdev_priv->starget_priv->sas_dev;
4693 if (sas_dev && sas_dev->dev_info & LEAPRAID_DEVTYP_SSP_TGT)
4694 qdepth = (sas_dev->port_connection > 1) ?
4695 attr->wideport_max_queue_depth :
4696 attr->narrowport_max_queue_depth;
4697 else if (sas_dev && sas_dev->dev_info &
4698 LEAPRAID_DEVTYP_SATA_DEV)
4699 qdepth = attr->sata_max_queue_depth;
4700 else
4701 continue;
4702
4703 leapraid_change_queue_depth(sdev, qdepth);
4704 }
4705 }
4706
leapraid_update_exp_links(struct leapraid_adapter * adapter,struct leapraid_topo_node * topo_node_exp,u16 hdl)4707 static void leapraid_update_exp_links(struct leapraid_adapter *adapter,
4708 struct leapraid_topo_node *topo_node_exp,
4709 u16 hdl)
4710 {
4711 union cfg_param_1 cfgp1 = {0};
4712 union cfg_param_2 cfgp2 = {0};
4713 struct leapraid_exp_p1 exp_p1;
4714 int i;
4715
4716 cfgp2.handle = hdl;
4717 for (i = 0; i < topo_node_exp->phys_num; i++) {
4718 cfgp1.phy_number = i;
4719 if (leapraid_op_config_page(adapter, &exp_p1, cfgp1, cfgp2,
4720 GET_SAS_EXPANDER_PG1))
4721 return;
4722
4723 leapraid_transport_update_links(
4724 adapter,
4725 topo_node_exp->sas_address,
4726 le16_to_cpu(exp_p1.attached_dev_hdl),
4727 i,
4728 exp_p1.neg_link_rate >>
4729 LEAPRAID_SAS_NEG_LINK_RATE_SHIFT,
4730 topo_node_exp->card_port);
4731 }
4732 }
4733
leapraid_scan_exp_after_reset(struct leapraid_adapter * adapter)4734 static void leapraid_scan_exp_after_reset(struct leapraid_adapter *adapter)
4735 {
4736 union cfg_param_1 cfgp1 = {0};
4737 union cfg_param_2 cfgp2 = {0};
4738 struct leapraid_topo_node *topo_node_exp;
4739 struct leapraid_exp_p0 exp_p0;
4740 unsigned long flags;
4741 u16 hdl;
4742 u8 port_id;
4743
4744 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP;
4745 for (hdl = 0xFFFF, cfgp2.handle = hdl;
4746 !leapraid_op_config_page(adapter, &exp_p0, cfgp1, cfgp2,
4747 GET_SAS_EXPANDER_PG0);
4748 cfgp2.handle = hdl) {
4749 hdl = le16_to_cpu(exp_p0.dev_hdl);
4750 port_id = exp_p0.physical_port;
4751 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags);
4752 topo_node_exp =
4753 leapraid_exp_find_by_sas_address(
4754 adapter,
4755 le64_to_cpu(exp_p0.sas_address),
4756 leapraid_get_port_by_id(adapter,
4757 port_id,
4758 false));
4759 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock,
4760 flags);
4761
4762 if (topo_node_exp) {
4763 leapraid_update_exp_links(adapter, topo_node_exp, hdl);
4764 } else {
4765 leapraid_exp_add(adapter, hdl);
4766
4767 dev_info(&adapter->pdev->dev,
4768 "add exp: hdl=0x%04x, SAS addr=0x%016llx\n",
4769 hdl,
4770 (unsigned long long)le64_to_cpu(
4771 exp_p0.sas_address));
4772 }
4773 }
4774 }
4775
leapraid_scan_phy_disks_after_reset(struct leapraid_adapter * adapter)4776 static void leapraid_scan_phy_disks_after_reset(
4777 struct leapraid_adapter *adapter)
4778 {
4779 union cfg_param_1 cfgp1 = {0};
4780 union cfg_param_2 cfgp2 = {0};
4781 union cfg_param_1 cfgp1_extra = {0};
4782 union cfg_param_2 cfgp2_extra = {0};
4783 struct leapraid_sas_dev_p0 sas_dev_p0;
4784 struct leapraid_raidpd_p0 raidpd_p0;
4785 struct leapraid_sas_dev *sas_dev;
4786 u8 phys_disk_num, port_id;
4787 u16 hdl, parent_hdl;
4788 u64 sas_addr;
4789
4790 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP;
4791 for (phys_disk_num = 0xFF, cfgp2.form_specific = phys_disk_num;
4792 !leapraid_op_config_page(adapter, &raidpd_p0,
4793 cfgp1, cfgp2, GET_PHY_DISK_PG0);
4794 cfgp2.form_specific = phys_disk_num) {
4795 phys_disk_num = raidpd_p0.phys_disk_num;
4796 hdl = le16_to_cpu(raidpd_p0.dev_hdl);
4797 sas_dev = leapraid_get_sas_dev_by_hdl(adapter, hdl);
4798 if (sas_dev) {
4799 leapraid_sdev_put(sas_dev);
4800 continue;
4801 }
4802
4803 cfgp1_extra.form = LEAPRAID_SAS_DEV_CFG_PGAD_HDL;
4804 cfgp2_extra.handle = hdl;
4805 if (leapraid_op_config_page(adapter, &sas_dev_p0, cfgp1_extra,
4806 cfgp2_extra, GET_SAS_DEVICE_PG0) !=
4807 0)
4808 continue;
4809
4810 parent_hdl = le16_to_cpu(sas_dev_p0.parent_dev_hdl);
4811 if (!leapraid_get_sas_address(adapter,
4812 parent_hdl,
4813 &sas_addr)) {
4814 port_id = sas_dev_p0.physical_port;
4815 leapraid_transport_update_links(
4816 adapter, sas_addr, hdl,
4817 sas_dev_p0.phy_num,
4818 LEAPRAID_SAS_NEG_LINK_RATE_1_5,
4819 leapraid_get_port_by_id(
4820 adapter, port_id, false));
4821 if (!hdl || hdl >
4822 adapter->adapter_attr.features.max_dev_handle) {
4823 dev_warn(&adapter->pdev->dev,
4824 "%s: Invalid device handle\n",
4825 __func__);
4826 } else {
4827 set_bit(hdl, adapter->dev_topo.pd_hdls);
4828 leapraid_add_dev(adapter, hdl);
4829
4830 dev_info(&adapter->pdev->dev,
4831 "add pd hdl=0x%04x saddr=0x%016llx\n",
4832 hdl,
4833 (unsigned long long)le64_to_cpu(
4834 sas_dev_p0.sas_address));
4835 }
4836 }
4837 }
4838 }
4839
leapraid_scan_vol_after_reset(struct leapraid_adapter * adapter)4840 static void leapraid_scan_vol_after_reset(struct leapraid_adapter *adapter)
4841 {
4842 union cfg_param_1 cfgp1 = {0};
4843 union cfg_param_2 cfgp2 = {0};
4844 union cfg_param_1 cfgp1_extra = {0};
4845 union cfg_param_2 cfgp2_extra = {0};
4846 struct leapraid_evt_data_ir_change evt_data;
4847 struct leapraid_raid_volume *raid_volume;
4848 struct leapraid_raidvol_p1 *vol_p1;
4849 struct leapraid_raidvol_p0 *vol_p0;
4850 u16 hdl;
4851
4852 vol_p0 = kzalloc_obj(*vol_p0);
4853 if (!vol_p0)
4854 return;
4855
4856 vol_p1 = kzalloc_obj(*vol_p1);
4857 if (!vol_p1) {
4858 kfree(vol_p0);
4859 return;
4860 }
4861
4862 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP;
4863 for (hdl = 0xFFFF, cfgp2.handle = hdl;
4864 !leapraid_op_config_page(adapter, vol_p1, cfgp1,
4865 cfgp2, GET_RAID_VOLUME_PG1);
4866 cfgp2.handle = hdl) {
4867 hdl = le16_to_cpu(vol_p1->dev_hdl);
4868 raid_volume = leapraid_raid_volume_find_by_wwid(
4869 adapter,
4870 le64_to_cpu(vol_p1->wwid));
4871 if (raid_volume) {
4872 leapraid_raid_volume_put(raid_volume);
4873 continue;
4874 }
4875
4876 cfgp1_extra.size = sizeof(struct leapraid_raidvol_p0);
4877 cfgp2_extra.handle = hdl;
4878 if (leapraid_op_config_page(adapter, vol_p0, cfgp1_extra,
4879 cfgp2_extra, GET_RAID_VOLUME_PG0))
4880 continue;
4881
4882 if (vol_p0->volume_state == LEAPRAID_VOL_STATE_OPTIMAL ||
4883 vol_p0->volume_state == LEAPRAID_VOL_STATE_ONLINE ||
4884 vol_p0->volume_state == LEAPRAID_VOL_STATE_DEGRADED) {
4885 memset(&evt_data, 0,
4886 sizeof(struct leapraid_evt_data_ir_change));
4887 evt_data.reason_code = LEAPRAID_EVT_IR_RC_VOLUME_ADD;
4888 evt_data.vol_dev_hdl = vol_p1->dev_hdl;
4889 leapraid_sas_volume_add(adapter, &evt_data);
4890 dev_info(&adapter->pdev->dev,
4891 "add volume: hdl=0x%04x\n",
4892 vol_p1->dev_hdl);
4893 }
4894 }
4895
4896 kfree(vol_p0);
4897 kfree(vol_p1);
4898 }
4899
leapraid_scan_sas_dev_after_reset(struct leapraid_adapter * adapter)4900 static void leapraid_scan_sas_dev_after_reset(struct leapraid_adapter *adapter)
4901 {
4902 union cfg_param_1 cfgp1 = {0};
4903 union cfg_param_2 cfgp2 = {0};
4904 struct leapraid_sas_dev_p0 sas_dev_p0;
4905 struct leapraid_sas_dev *sas_dev;
4906 u16 hdl, parent_hdl;
4907 u64 sas_address;
4908 u8 port_id;
4909
4910 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP;
4911 for (hdl = 0xFFFF, cfgp2.handle = hdl;
4912 !leapraid_op_config_page(adapter, &sas_dev_p0, cfgp1, cfgp2,
4913 GET_SAS_DEVICE_PG0);
4914 cfgp2.handle = hdl) {
4915 hdl = le16_to_cpu(sas_dev_p0.dev_hdl);
4916 if (!hdl ||
4917 hdl > adapter->adapter_attr.features.max_dev_handle) {
4918 dev_warn(&adapter->pdev->dev,
4919 "%s: Invalid device handle\n", __func__);
4920 continue;
4921 }
4922
4923 if (!(leapraid_is_end_dev(le32_to_cpu(sas_dev_p0.dev_info))))
4924 continue;
4925
4926 port_id = sas_dev_p0.physical_port;
4927 sas_dev = leapraid_get_sas_dev_by_addr(
4928 adapter,
4929 le64_to_cpu(sas_dev_p0.sas_address),
4930 leapraid_get_port_by_id(
4931 adapter,
4932 port_id,
4933 false));
4934 if (sas_dev) {
4935 leapraid_sdev_put(sas_dev);
4936 continue;
4937 }
4938
4939 parent_hdl = le16_to_cpu(sas_dev_p0.parent_dev_hdl);
4940 if (!leapraid_get_sas_address(adapter, parent_hdl,
4941 &sas_address)) {
4942 leapraid_transport_update_links(
4943 adapter,
4944 sas_address,
4945 hdl,
4946 sas_dev_p0.phy_num,
4947 LEAPRAID_SAS_NEG_LINK_RATE_1_5,
4948 leapraid_get_port_by_id(adapter,
4949 port_id,
4950 false));
4951 leapraid_add_dev(adapter, hdl);
4952 dev_info(&adapter->pdev->dev,
4953 "Add SAS dev: hdl=0x%04x, saddr=0x%016llx\n",
4954 hdl,
4955 (unsigned long long)le64_to_cpu(
4956 sas_dev_p0.sas_address));
4957 }
4958 }
4959 }
4960
leapraid_scan_all_dev_after_reset(struct leapraid_adapter * adapter)4961 static void leapraid_scan_all_dev_after_reset(struct leapraid_adapter *adapter)
4962 {
4963 leapraid_sas_host_add(adapter, adapter->dev_topo.card.phys_num > 0);
4964 leapraid_scan_exp_after_reset(adapter);
4965 if (adapter->adapter_attr.raid_support) {
4966 leapraid_scan_phy_disks_after_reset(adapter);
4967 leapraid_scan_vol_after_reset(adapter);
4968 }
4969 leapraid_scan_sas_dev_after_reset(adapter);
4970 }
4971
leapraid_hardreset_async_logic(struct leapraid_adapter * adapter)4972 static void leapraid_hardreset_async_logic(struct leapraid_adapter *adapter)
4973 {
4974 unsigned long flags;
4975
4976 leapraid_remove_unresp_dev(adapter);
4977 leapraid_del_dirty_vphy(adapter);
4978 leapraid_del_dirty_card_port(adapter);
4979 leapraid_update_dev_qdepth(adapter);
4980 leapraid_scan_all_dev_after_reset(adapter);
4981
4982 if (adapter->scan_dev_desc.driver_loading)
4983 leapraid_scan_dev_done(adapter);
4984 spin_lock_irqsave(&adapter->reset_desc.adapter_reset_lock, flags);
4985 adapter->access_ctrl.shost_recover_async = 0;
4986 spin_unlock_irqrestore(&adapter->reset_desc.adapter_reset_lock, flags);
4987 wake_up(&adapter->access_ctrl.shost_recover_wq);
4988 }
4989
leapraid_send_enc_cmd(struct leapraid_adapter * adapter,struct leapraid_sep_rep * sep_rep,struct leapraid_sep_req * sep_req)4990 static int leapraid_send_enc_cmd(struct leapraid_adapter *adapter,
4991 struct leapraid_sep_rep *sep_rep,
4992 struct leapraid_sep_req *sep_req)
4993 {
4994 void *req;
4995 bool reset_flg = false;
4996 int rc;
4997 u16 smid;
4998
4999 mutex_lock(&adapter->driver_cmds.enc_cmd.mutex);
5000 rc = leapraid_check_adapter_is_op(adapter, LEAPRAID_DB_WAIT_OP_SHORT,
5001 __func__);
5002 if (rc)
5003 goto unlock;
5004
5005 adapter->driver_cmds.enc_cmd.status = LEAPRAID_CMD_PENDING;
5006 smid = adapter->driver_cmds.enc_cmd.inter_taskid;
5007 req = leapraid_get_task_desc(adapter, smid);
5008 memset(req, 0, LEAPRAID_REQUEST_SIZE);
5009 memcpy(req, sep_req, sizeof(struct leapraid_sep_req));
5010 init_completion(&adapter->driver_cmds.enc_cmd.done);
5011 leapraid_fire_task(adapter, smid);
5012 wait_for_completion_timeout(&adapter->driver_cmds.enc_cmd.done,
5013 LEAPRAID_ENC_CMD_TIMEOUT * HZ);
5014 if (!(adapter->driver_cmds.enc_cmd.status & LEAPRAID_CMD_DONE)) {
5015 dev_err(&adapter->pdev->dev,
5016 "%s: SEP command timeout, status=0x%x\n",
5017 __func__, adapter->driver_cmds.enc_cmd.status);
5018 leapraid_log_req_context(adapter, smid, sep_req);
5019 reset_flg =
5020 leapraid_check_reset(
5021 adapter->driver_cmds.enc_cmd.status);
5022 rc = -EFAULT;
5023 goto do_hard_reset;
5024 }
5025
5026 if (adapter->driver_cmds.enc_cmd.status & LEAPRAID_CMD_REPLY_VALID)
5027 memcpy(sep_rep, &adapter->driver_cmds.enc_cmd.reply,
5028 sizeof(struct leapraid_sep_rep));
5029 do_hard_reset:
5030 if (reset_flg) {
5031 dev_info(&adapter->pdev->dev, "%s:%d: call hard_reset\n",
5032 __func__, __LINE__);
5033 leapraid_hard_reset_handler(adapter, FULL_RESET);
5034 }
5035
5036 adapter->driver_cmds.enc_cmd.status = LEAPRAID_CMD_NOT_USED;
5037 unlock:
5038 mutex_unlock(&adapter->driver_cmds.enc_cmd.mutex);
5039 return rc;
5040 }
5041
leapraid_set_led(struct leapraid_adapter * adapter,struct leapraid_sas_dev * sas_dev,bool on)5042 static void leapraid_set_led(struct leapraid_adapter *adapter,
5043 struct leapraid_sas_dev *sas_dev, bool on)
5044 {
5045 struct leapraid_sep_rep sep_rep;
5046 struct leapraid_sep_req sep_req;
5047
5048 if (!sas_dev)
5049 return;
5050
5051 memset(&sep_req, 0, sizeof(struct leapraid_sep_req));
5052 memset(&sep_rep, 0, sizeof(struct leapraid_sep_rep));
5053 sep_req.func = LEAPRAID_FUNC_SCSI_ENC_PROCESSOR;
5054 sep_req.act = LEAPRAID_SEP_REQ_ACT_WRITE_STATUS;
5055 if (on) {
5056 u32 status = LEAPRAID_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT;
5057
5058 sep_req.slot_status = cpu_to_le32(status);
5059 sep_req.dev_hdl = cpu_to_le16(sas_dev->hdl);
5060 sep_req.flg = LEAPRAID_SEP_REQ_FLG_DEVHDL_ADDRESS;
5061 if (leapraid_send_enc_cmd(adapter, &sep_rep, &sep_req)) {
5062 leapraid_sdev_put(sas_dev);
5063 return;
5064 }
5065
5066 sas_dev->led_on = 1;
5067 leapraid_sdev_put(sas_dev);
5068 } else {
5069 sep_req.slot_status = 0;
5070 sep_req.slot = cpu_to_le16(sas_dev->slot);
5071 sep_req.dev_hdl = 0;
5072 sep_req.enc_hdl = cpu_to_le16(sas_dev->enc_hdl);
5073 sep_req.flg = LEAPRAID_SEP_REQ_FLG_ENCLOSURE_SLOT_ADDRESS;
5074 leapraid_send_enc_cmd(adapter, &sep_rep, &sep_req);
5075 }
5076 }
5077
leapraid_wait_adapter_recovery(struct leapraid_adapter * adapter)5078 static int leapraid_wait_adapter_recovery(struct leapraid_adapter *adapter)
5079 {
5080 unsigned long flags;
5081
5082 while (leapraid_shost_in_recovery(adapter->shost) ||
5083 READ_ONCE(adapter->access_ctrl.shost_recovering)) {
5084 if (READ_ONCE(adapter->access_ctrl.host_removing) ||
5085 READ_ONCE(adapter->fw_evt_s.fw_evt_cleanup)) {
5086 spin_lock_irqsave(
5087 &adapter->reset_desc.adapter_reset_lock,
5088 flags);
5089 adapter->access_ctrl.shost_recover_async = 0;
5090 spin_unlock_irqrestore(
5091 &adapter->reset_desc.adapter_reset_lock,
5092 flags);
5093
5094 wake_up(&adapter->access_ctrl.shost_recover_wq);
5095
5096 dev_warn(&adapter->pdev->dev,
5097 "%s: Failed, shost %d, host %d\n",
5098 __func__,
5099 adapter->access_ctrl.shost_recovering,
5100 adapter->access_ctrl.host_removing);
5101
5102 return -EFAULT;
5103 }
5104
5105 wait_event_timeout(
5106 adapter->access_ctrl.recovery_waitq,
5107 (!leapraid_shost_in_recovery(adapter->shost) &&
5108 !READ_ONCE(adapter->access_ctrl.shost_recovering)),
5109 msecs_to_jiffies(1000));
5110 }
5111
5112 return 0;
5113 }
5114
leapraid_fw_work(struct leapraid_adapter * adapter,struct leapraid_fw_evt_work * fw_evt)5115 static void leapraid_fw_work(struct leapraid_adapter *adapter,
5116 struct leapraid_fw_evt_work *fw_evt)
5117 {
5118 struct leapraid_sas_dev *sas_dev;
5119 unsigned long flags;
5120
5121 spin_lock_irqsave(&adapter->fw_evt_s.fw_evt_lock, flags);
5122 adapter->fw_evt_s.cur_evt = fw_evt;
5123 adapter->fw_evt_s.cur_evt_task = current;
5124 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags);
5125 leapraid_del_fw_evt_from_list(adapter, fw_evt);
5126 if (adapter->access_ctrl.host_removing ||
5127 adapter->access_ctrl.pcie_recovering) {
5128 spin_lock_irqsave(&adapter->fw_evt_s.fw_evt_lock, flags);
5129 leapraid_fw_evt_put(fw_evt);
5130 adapter->fw_evt_s.cur_evt = NULL;
5131 adapter->fw_evt_s.cur_evt_task = NULL;
5132 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags);
5133 return;
5134 }
5135 switch (fw_evt->evt_type) {
5136 case LEAPRAID_EVT_SAS_TOPO_CHANGE_LIST:
5137 leapraid_sas_topo_chg_evt(adapter, fw_evt);
5138 break;
5139 case LEAPRAID_EVT_IR_CHANGE:
5140 leapraid_sas_ir_chg_evt(adapter, fw_evt);
5141 break;
5142 case LEAPRAID_EVT_SAS_ENCL_DEV_STATUS_CHANGE:
5143 leapraid_sas_enc_dev_stat_chg_evt(adapter, fw_evt);
5144 break;
5145 case LEAPRAID_EVT_REMOVE_DEAD_DEV:
5146 if (leapraid_wait_adapter_recovery(adapter))
5147 goto out_cleanup;
5148
5149 leapraid_hardreset_async_logic(adapter);
5150 break;
5151 case LEAPRAID_EVT_TURN_ON_PFA_LED:
5152 sas_dev = leapraid_get_sas_dev_by_hdl(adapter,
5153 fw_evt->dev_handle);
5154 leapraid_set_led(adapter, sas_dev, true);
5155 break;
5156 case LEAPRAID_EVT_SCAN_DEV_DONE:
5157 adapter->scan_dev_desc.scan_start = 0;
5158 break;
5159 default:
5160 break;
5161 }
5162 out_cleanup:
5163 spin_lock_irqsave(&adapter->fw_evt_s.fw_evt_lock, flags);
5164 leapraid_fw_evt_put(fw_evt);
5165 adapter->fw_evt_s.cur_evt = NULL;
5166 adapter->fw_evt_s.cur_evt_task = NULL;
5167 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags);
5168 }
5169
leapraid_sas_dev_stat_chg_evt(struct leapraid_adapter * adapter,struct leapraid_evt_data_sas_dev_status_change * event_data)5170 static void leapraid_sas_dev_stat_chg_evt(
5171 struct leapraid_adapter *adapter,
5172 struct leapraid_evt_data_sas_dev_status_change *event_data)
5173 {
5174 struct leapraid_starget_priv *starget_priv;
5175 struct leapraid_sas_dev *sas_dev;
5176 u64 sas_address;
5177 unsigned long flags;
5178
5179 switch (event_data->reason_code) {
5180 case LEAPRAID_EVT_SAS_DEV_STAT_RC_INTERNAL_DEV_RESET:
5181 case LEAPRAID_EVT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET:
5182 break;
5183 default:
5184 return;
5185 }
5186
5187 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags);
5188
5189 sas_address = le64_to_cpu(event_data->sas_address);
5190 sas_dev = leapraid_hold_lock_get_sas_dev_by_addr(
5191 adapter,
5192 sas_address,
5193 leapraid_get_port_by_id(adapter,
5194 event_data->physical_port,
5195 false));
5196 if (!sas_dev || !sas_dev->starget)
5197 goto out_unlock;
5198
5199 starget_priv = sas_dev->starget->hostdata;
5200 if (starget_priv) {
5201 switch (event_data->reason_code) {
5202 case LEAPRAID_EVT_SAS_DEV_STAT_RC_INTERNAL_DEV_RESET:
5203 starget_priv->tm_busy = 1;
5204 break;
5205 case LEAPRAID_EVT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET:
5206 starget_priv->tm_busy = 0;
5207 break;
5208 }
5209 }
5210
5211 out_unlock:
5212 if (sas_dev)
5213 leapraid_sdev_put(sas_dev);
5214 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags);
5215 }
5216
leapraid_set_volume_delete_flag(struct leapraid_adapter * adapter,u16 handle)5217 static void leapraid_set_volume_delete_flag(struct leapraid_adapter *adapter,
5218 u16 handle)
5219 {
5220 struct leapraid_raid_volume *raid_volume;
5221 struct leapraid_starget_priv *sas_target_priv_data;
5222 unsigned long flags;
5223
5224 raid_volume = leapraid_raid_volume_find_by_hdl(adapter, handle);
5225 if (raid_volume) {
5226 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags);
5227 if (raid_volume->starget &&
5228 raid_volume->starget->hostdata) {
5229 sas_target_priv_data = raid_volume->starget->hostdata;
5230 sas_target_priv_data->deleted = 1;
5231 }
5232 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock,
5233 flags);
5234 leapraid_raid_volume_put(raid_volume);
5235 }
5236 }
5237
leapraid_check_ir_change_evt(struct leapraid_adapter * adapter,struct leapraid_evt_data_ir_change * evt_data)5238 static void leapraid_check_ir_change_evt(
5239 struct leapraid_adapter *adapter,
5240 struct leapraid_evt_data_ir_change *evt_data)
5241 {
5242 u16 phys_disk_dev_hdl;
5243
5244 switch (evt_data->reason_code) {
5245 case LEAPRAID_EVT_IR_RC_VOLUME_DELETE:
5246 leapraid_set_volume_delete_flag(
5247 adapter,
5248 le16_to_cpu(evt_data->vol_dev_hdl));
5249 break;
5250 case LEAPRAID_EVT_IR_RC_PD_UNHIDDEN_TO_DELETE:
5251 phys_disk_dev_hdl =
5252 le16_to_cpu(evt_data->phys_disk_dev_hdl);
5253 if (!phys_disk_dev_hdl ||
5254 phys_disk_dev_hdl >
5255 adapter->adapter_attr.features.max_dev_handle) {
5256 dev_warn(&adapter->pdev->dev,
5257 "%s: Invalid device handle\n", __func__);
5258 } else {
5259 clear_bit(phys_disk_dev_hdl,
5260 adapter->dev_topo.pd_hdls);
5261 leapraid_tgt_rst_send(adapter, phys_disk_dev_hdl);
5262 }
5263 break;
5264 }
5265 }
5266
leapraid_topo_del_evts_process_exp_status(struct leapraid_adapter * adapter,struct leapraid_evt_data_sas_topo_change_list * evt_data)5267 static void leapraid_topo_del_evts_process_exp_status(
5268 struct leapraid_adapter *adapter,
5269 struct leapraid_evt_data_sas_topo_change_list *evt_data)
5270 {
5271 struct leapraid_fw_evt_work *fw_evt = NULL;
5272 struct leapraid_evt_data_sas_topo_change_list *loc_evt_data;
5273 unsigned long flags;
5274 u16 exp_hdl;
5275
5276 exp_hdl = le16_to_cpu(evt_data->exp_dev_hdl);
5277
5278 switch (evt_data->exp_status) {
5279 case LEAPRAID_EVT_SAS_TOPO_ES_NOT_RESPONDING:
5280 spin_lock_irqsave(&adapter->fw_evt_s.fw_evt_lock, flags);
5281 list_for_each_entry(fw_evt,
5282 &adapter->fw_evt_s.fw_evt_list, list) {
5283 if (fw_evt->evt_type !=
5284 LEAPRAID_EVT_SAS_TOPO_CHANGE_LIST ||
5285 fw_evt->ignore)
5286 continue;
5287
5288 loc_evt_data = fw_evt->evt_data;
5289 if ((loc_evt_data->exp_status ==
5290 LEAPRAID_EVT_SAS_TOPO_ES_ADDED ||
5291 loc_evt_data->exp_status ==
5292 LEAPRAID_EVT_SAS_TOPO_ES_RESPONDING) &&
5293 le16_to_cpu(loc_evt_data->exp_dev_hdl) == exp_hdl)
5294 fw_evt->ignore = 1;
5295 }
5296 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags);
5297 break;
5298 default:
5299 break;
5300 }
5301 }
5302
leapraid_check_topo_del_evts(struct leapraid_adapter * adapter,struct leapraid_evt_data_sas_topo_change_list * evt_data)5303 static void leapraid_check_topo_del_evts(
5304 struct leapraid_adapter *adapter,
5305 struct leapraid_evt_data_sas_topo_change_list *evt_data)
5306 {
5307 int reason_code;
5308 u16 hdl;
5309 int i;
5310
5311 for (i = 0; i < evt_data->entry_num; i++) {
5312 hdl = le16_to_cpu(evt_data->phy[i].attached_dev_hdl);
5313 if (!hdl)
5314 continue;
5315
5316 reason_code = evt_data->phy[i].phy_status &
5317 LEAPRAID_EVT_SAS_TOPO_RC_MASK;
5318 if (reason_code ==
5319 LEAPRAID_EVT_SAS_TOPO_RC_TARG_NOT_RESPONDING)
5320 leapraid_tgt_not_responding(adapter, hdl);
5321 }
5322 leapraid_topo_del_evts_process_exp_status(adapter, evt_data);
5323 }
5324
leapraid_async_evt_validate(struct leapraid_adapter * adapter,struct leapraid_evt_notify_rep * event_notify_rep)5325 static bool leapraid_async_evt_validate(
5326 struct leapraid_adapter *adapter,
5327 struct leapraid_evt_notify_rep *event_notify_rep)
5328 {
5329 size_t msg_len;
5330 size_t evt_sz;
5331 size_t evt_avail;
5332 u16 evt;
5333
5334 msg_len = event_notify_rep->msg_len * sizeof(u32);
5335 if (msg_len > LEAPRAID_REPLY_SIZE ||
5336 msg_len < offsetof(struct leapraid_evt_notify_rep, evt_data)) {
5337 dev_warn(&adapter->pdev->dev,
5338 "%s: Invalid async event msg_len=%zu\n",
5339 __func__, msg_len);
5340 return false;
5341 }
5342
5343 evt_sz = le16_to_cpu(event_notify_rep->evt_data_len) * sizeof(u32);
5344 evt_avail = msg_len -
5345 offsetof(struct leapraid_evt_notify_rep, evt_data);
5346 if (evt_sz > evt_avail) {
5347 dev_warn(&adapter->pdev->dev,
5348 "%s: Invalid async event evt_data_len=%zu\n",
5349 __func__, evt_sz);
5350 return false;
5351 }
5352
5353 evt = le16_to_cpu(event_notify_rep->evt);
5354 switch (evt) {
5355 case LEAPRAID_EVT_SAS_DEV_STATUS_CHANGE:
5356 if (evt_sz <
5357 sizeof(struct leapraid_evt_data_sas_dev_status_change))
5358 goto invalid_evt_sz;
5359 break;
5360 case LEAPRAID_EVT_IR_CHANGE:
5361 if (evt_sz < sizeof(struct leapraid_evt_data_ir_change))
5362 goto invalid_evt_sz;
5363 break;
5364 case LEAPRAID_EVT_SAS_TOPO_CHANGE_LIST:
5365 {
5366 struct leapraid_evt_data_sas_topo_change_list *evt_data =
5367 (void *)event_notify_rep->evt_data;
5368 size_t hdr_sz;
5369
5370 hdr_sz =
5371 offsetof(struct leapraid_evt_data_sas_topo_change_list,
5372 phy);
5373 if (evt_sz < hdr_sz)
5374 goto invalid_evt_sz;
5375
5376 if (evt_data->entry_num >
5377 (evt_sz - hdr_sz) / sizeof(evt_data->phy[0]))
5378 goto invalid_evt_sz;
5379 break;
5380 }
5381 case LEAPRAID_EVT_SAS_ENCL_DEV_STATUS_CHANGE:
5382 if (evt_sz <
5383 sizeof(struct leapraid_evt_data_sas_enc_dev_status_change))
5384 goto invalid_evt_sz;
5385 break;
5386 default:
5387 break;
5388 }
5389
5390 return true;
5391
5392 invalid_evt_sz:
5393 dev_warn(&adapter->pdev->dev,
5394 "%s: Invalid async event size=%zu for evt=0x%x\n",
5395 __func__, evt_sz, evt);
5396 return false;
5397 }
5398
leapraid_async_process_evt(struct leapraid_adapter * adapter,struct leapraid_evt_notify_rep * event_notify_rep)5399 static bool leapraid_async_process_evt(
5400 struct leapraid_adapter *adapter,
5401 struct leapraid_evt_notify_rep *event_notify_rep)
5402 {
5403 u16 evt = le16_to_cpu(event_notify_rep->evt);
5404 bool exit_flag = false;
5405
5406 if (adapter->access_ctrl.host_removing ||
5407 adapter->access_ctrl.pcie_recovering)
5408 return true;
5409
5410 switch (evt) {
5411 case LEAPRAID_EVT_SAS_DEV_STATUS_CHANGE:
5412 leapraid_sas_dev_stat_chg_evt(
5413 adapter,
5414 (struct leapraid_evt_data_sas_dev_status_change
5415 *)event_notify_rep->evt_data);
5416 break;
5417 case LEAPRAID_EVT_IR_CHANGE:
5418 leapraid_check_ir_change_evt(
5419 adapter,
5420 (struct leapraid_evt_data_ir_change
5421 *)event_notify_rep->evt_data);
5422 break;
5423 case LEAPRAID_EVT_SAS_TOPO_CHANGE_LIST:
5424 leapraid_check_topo_del_evts(
5425 adapter,
5426 (struct leapraid_evt_data_sas_topo_change_list
5427 *)event_notify_rep->evt_data);
5428 if (adapter->access_ctrl.shost_recovering) {
5429 exit_flag = true;
5430 return exit_flag;
5431 }
5432 break;
5433 case LEAPRAID_EVT_SAS_ENCL_DEV_STATUS_CHANGE:
5434 break;
5435 default:
5436 exit_flag = true;
5437 return exit_flag;
5438 }
5439
5440 return exit_flag;
5441 }
5442
leapraid_async_evt_cb_enqueue(struct leapraid_adapter * adapter,struct leapraid_evt_notify_rep * evt_notify_rep)5443 static void leapraid_async_evt_cb_enqueue(
5444 struct leapraid_adapter *adapter,
5445 struct leapraid_evt_notify_rep *evt_notify_rep)
5446 {
5447 struct leapraid_fw_evt_work *fw_evt;
5448 u16 evt_sz;
5449
5450 fw_evt = leapraid_alloc_fw_evt_work();
5451 if (!fw_evt)
5452 return;
5453
5454 evt_sz = le16_to_cpu(evt_notify_rep->evt_data_len) * sizeof(u32);
5455 fw_evt->evt_data = kmemdup(evt_notify_rep->evt_data,
5456 evt_sz, GFP_ATOMIC);
5457 if (!fw_evt->evt_data) {
5458 leapraid_fw_evt_put(fw_evt);
5459 return;
5460 }
5461 fw_evt->adapter = adapter;
5462 fw_evt->evt_type = le16_to_cpu(evt_notify_rep->evt);
5463 leapraid_fw_evt_add(adapter, fw_evt);
5464 leapraid_fw_evt_put(fw_evt);
5465 }
5466
leapraid_async_evt_cb(struct leapraid_adapter * adapter,u8 msix_index,u32 rep_paddr)5467 static void leapraid_async_evt_cb(struct leapraid_adapter *adapter,
5468 u8 msix_index, u32 rep_paddr)
5469 {
5470 struct leapraid_evt_notify_rep *evt_notify_rep;
5471
5472 if (adapter->access_ctrl.host_removing ||
5473 adapter->access_ctrl.pcie_recovering)
5474 return;
5475
5476 evt_notify_rep = leapraid_get_reply_vaddr(adapter, rep_paddr);
5477 if (unlikely(!evt_notify_rep))
5478 return;
5479
5480 if (!leapraid_async_evt_validate(adapter, evt_notify_rep))
5481 return;
5482
5483 if (leapraid_async_process_evt(adapter, evt_notify_rep))
5484 return;
5485
5486 leapraid_async_evt_cb_enqueue(adapter, evt_notify_rep);
5487 }
5488
leapraid_handle_async_event(struct leapraid_adapter * adapter,u8 msix_index,u32 reply)5489 static void leapraid_handle_async_event(struct leapraid_adapter *adapter,
5490 u8 msix_index, u32 reply)
5491 {
5492 struct leapraid_evt_notify_rep *leap_mpi_rep =
5493 leapraid_get_reply_vaddr(adapter, reply);
5494
5495 if (!leap_mpi_rep)
5496 return;
5497
5498 if (leap_mpi_rep->func != LEAPRAID_FUNC_EVENT_NOTIFY)
5499 return;
5500
5501 leapraid_async_evt_cb(adapter, msix_index, reply);
5502 }
5503
leapraid_async_turn_on_led(struct leapraid_adapter * adapter,u16 handle)5504 void leapraid_async_turn_on_led(struct leapraid_adapter *adapter, u16 handle)
5505 {
5506 struct leapraid_fw_evt_work *fw_event;
5507
5508 fw_event = leapraid_alloc_fw_evt_work();
5509 if (!fw_event)
5510 return;
5511
5512 fw_event->dev_handle = handle;
5513 fw_event->adapter = adapter;
5514 fw_event->evt_type = LEAPRAID_EVT_TURN_ON_PFA_LED;
5515 leapraid_fw_evt_add(adapter, fw_event);
5516 leapraid_fw_evt_put(fw_event);
5517 }
5518
leapraid_hardreset_barrier(struct leapraid_adapter * adapter)5519 static void leapraid_hardreset_barrier(struct leapraid_adapter *adapter)
5520 {
5521 struct leapraid_fw_evt_work *fw_event;
5522
5523 fw_event = leapraid_alloc_fw_evt_work();
5524 if (!fw_event)
5525 return;
5526
5527 fw_event->adapter = adapter;
5528 fw_event->evt_type = LEAPRAID_EVT_REMOVE_DEAD_DEV;
5529 leapraid_fw_evt_add(adapter, fw_event);
5530 leapraid_fw_evt_put(fw_event);
5531 }
5532
leapraid_scan_dev_complete(struct leapraid_adapter * adapter)5533 static void leapraid_scan_dev_complete(struct leapraid_adapter *adapter)
5534 {
5535 struct leapraid_fw_evt_work *fw_evt;
5536
5537 fw_evt = leapraid_alloc_fw_evt_work();
5538 if (!fw_evt)
5539 return;
5540
5541 fw_evt->evt_type = LEAPRAID_EVT_SCAN_DEV_DONE;
5542 fw_evt->adapter = adapter;
5543 leapraid_fw_evt_add(adapter, fw_evt);
5544 leapraid_fw_evt_put(fw_evt);
5545 }
5546
leapraid_handle_scan_cb(struct leapraid_adapter * adapter,struct leapraid_driver_cmd * cmd,struct leapraid_rep * rep)5547 static void leapraid_handle_scan_cb(struct leapraid_adapter *adapter,
5548 struct leapraid_driver_cmd *cmd,
5549 struct leapraid_rep *rep)
5550 {
5551 u16 status;
5552
5553 cmd->status &= ~LEAPRAID_CMD_PENDING;
5554
5555 status = le16_to_cpu(rep->adapter_status) &
5556 LEAPRAID_ADAPTER_STATUS_MASK;
5557 if (status != LEAPRAID_ADAPTER_STATUS_SUCCESS)
5558 adapter->scan_dev_desc.scan_dev_failed = 1;
5559
5560 if (!cmd->async_scan_dev) {
5561 complete(&cmd->done);
5562 return;
5563 }
5564
5565 if (status == LEAPRAID_ADAPTER_STATUS_SUCCESS)
5566 leapraid_scan_dev_complete(adapter);
5567 else
5568 adapter->scan_dev_desc.scan_start_failed = status;
5569 }
5570
leapraid_handle_ctl_cb(struct leapraid_adapter * adapter,struct leapraid_rep * rep,u16 taskid)5571 static void leapraid_handle_ctl_cb(struct leapraid_adapter *adapter,
5572 struct leapraid_rep *rep,
5573 u16 taskid)
5574 {
5575 struct leapraid_scsiio_rep *scsiio_reply;
5576
5577 if (rep->function != LEAPRAID_FUNC_SCSIIO &&
5578 rep->function != LEAPRAID_FUNC_SCSIIO_RAID_PASSTHROUGH)
5579 return;
5580
5581 scsiio_reply = (struct leapraid_scsiio_rep *)rep;
5582 if (!(scsiio_reply->scsi_state &
5583 LEAPRAID_SCSI_STATE_AUTOSENSE_VALID))
5584 return;
5585
5586 memcpy(&adapter->driver_cmds.ctl_cmd.sense,
5587 leapraid_get_sense_buffer(adapter, taskid),
5588 min_t(u32, SCSI_SENSE_BUFFERSIZE,
5589 le32_to_cpu(scsiio_reply->sense_count)));
5590 }
5591
leapraid_driver_cmds_done(struct leapraid_adapter * adapter,u16 taskid,u8 msix_index,u32 rep_paddr,u8 cb_idx)5592 static bool leapraid_driver_cmds_done(struct leapraid_adapter *adapter,
5593 u16 taskid, u8 msix_index,
5594 u32 rep_paddr, u8 cb_idx)
5595 {
5596 struct leapraid_rep *leap_mpi_rep =
5597 leapraid_get_reply_vaddr(adapter, rep_paddr);
5598 struct leapraid_driver_cmd *sp_cmd, *_sp_cmd = NULL;
5599 u8 reply_len;
5600
5601 list_for_each_entry(sp_cmd, &adapter->driver_cmds.special_cmd_list,
5602 list)
5603 if (cb_idx == sp_cmd->cb_idx) {
5604 _sp_cmd = sp_cmd;
5605 break;
5606 }
5607
5608 if (WARN_ON(!_sp_cmd))
5609 return true;
5610 if (WARN_ON(_sp_cmd->status == LEAPRAID_CMD_NOT_USED))
5611 return true;
5612 if (WARN_ON(taskid != _sp_cmd->hp_taskid &&
5613 taskid != _sp_cmd->taskid &&
5614 taskid != _sp_cmd->inter_taskid))
5615 return true;
5616 _sp_cmd->status |= LEAPRAID_CMD_DONE;
5617 if (leap_mpi_rep) {
5618 reply_len = leap_mpi_rep->msg_len * sizeof(u32);
5619 if (reply_len > LEAPRAID_REPLY_SIZE)
5620 reply_len = LEAPRAID_REPLY_SIZE;
5621 memcpy(&_sp_cmd->reply, leap_mpi_rep, reply_len);
5622 _sp_cmd->status |= LEAPRAID_CMD_REPLY_VALID;
5623
5624 if (_sp_cmd->cb_idx == LEAPRAID_SCAN_DEV_CB_IDX) {
5625 leapraid_handle_scan_cb(adapter, _sp_cmd,
5626 leap_mpi_rep);
5627 return true;
5628 }
5629
5630 if (_sp_cmd->cb_idx == LEAPRAID_CTL_CB_IDX)
5631 leapraid_handle_ctl_cb(adapter, leap_mpi_rep, taskid);
5632 }
5633
5634 _sp_cmd->status &= ~LEAPRAID_CMD_PENDING;
5635 complete(&_sp_cmd->done);
5636
5637 return true;
5638 }
5639
leapraid_complete_task(struct leapraid_adapter * adapter,u16 taskid,u8 msix_idx,u32 rep)5640 static void leapraid_complete_task(struct leapraid_adapter *adapter,
5641 u16 taskid, u8 msix_idx, u32 rep)
5642 {
5643 bool scsiio_task = taskid <= adapter->shost->can_queue;
5644
5645 if (scsiio_task) {
5646 if (leapraid_scsiio_done(adapter, taskid, msix_idx, rep))
5647 leapraid_free_taskid(adapter, taskid);
5648 return;
5649 }
5650
5651 if (leapraid_driver_cmds_done(adapter, taskid, msix_idx, rep,
5652 leapraid_get_cb_idx(adapter, taskid)))
5653 leapraid_free_taskid(adapter, taskid);
5654 }
5655
leapraid_request_descript_handler(struct leapraid_adapter * adapter,union leapraid_rep_desc_union * rpf,u8 req_desc_type,u8 msix_idx)5656 static void leapraid_request_descript_handler(
5657 struct leapraid_adapter *adapter,
5658 union leapraid_rep_desc_union *rpf,
5659 u8 req_desc_type, u8 msix_idx)
5660 {
5661 u32 rep;
5662 u16 taskid;
5663
5664 rep = 0;
5665 taskid = le16_to_cpu(rpf->dflt_rep.taskid);
5666 switch (req_desc_type) {
5667 case LEAPRAID_RPY_DESC_FLG_FP_SCSI_IO_SUCCESS:
5668 case LEAPRAID_RPY_DESC_FLG_SCSI_IO_SUCCESS:
5669 leapraid_complete_task(adapter, taskid, msix_idx, 0);
5670 break;
5671 case LEAPRAID_RPY_DESC_FLG_ADDRESS_REPLY:
5672 rep = le32_to_cpu(rpf->addr_rep.rep_frame_addr);
5673 if (rep > (u32)adapter->mem_desc.rep_msg_dma +
5674 adapter->adapter_attr.rep_msg_qd *
5675 LEAPRAID_REPLY_SIZE ||
5676 rep < (u32)adapter->mem_desc.rep_msg_dma)
5677 rep = 0;
5678
5679 if (taskid)
5680 leapraid_complete_task(adapter, taskid, msix_idx, rep);
5681 else
5682 leapraid_handle_async_event(adapter, msix_idx, rep);
5683
5684 if (!rep)
5685 return;
5686
5687 adapter->rep_msg_host_idx =
5688 (adapter->rep_msg_host_idx ==
5689 (adapter->adapter_attr.rep_msg_qd - 1)) ?
5690 0 : adapter->rep_msg_host_idx + 1;
5691 adapter->mem_desc.rep_msg_addr[adapter->rep_msg_host_idx] =
5692 cpu_to_le32(rep);
5693 wmb(); /* Make sure that all write ops are in order */
5694 writel(adapter->rep_msg_host_idx,
5695 &adapter->iomem_base->rep_msg_host_idx);
5696
5697 break;
5698 default:
5699 break;
5700 }
5701 }
5702
leapraid_rep_queue_handler(struct leapraid_rq * rq)5703 int leapraid_rep_queue_handler(struct leapraid_rq *rq)
5704 {
5705 struct leapraid_adapter *adapter = rq->adapter;
5706 union leapraid_rep_desc_union *rep_desc;
5707 u8 req_desc_type;
5708 u64 finish_cmds;
5709 u8 msix_idx;
5710
5711 msix_idx = rq->msix_idx;
5712 finish_cmds = 0;
5713 if (!atomic_add_unless(&rq->busy, LEAPRAID_BUSY_LIMIT,
5714 LEAPRAID_BUSY_LIMIT))
5715 return finish_cmds;
5716
5717 rep_desc = &rq->rep_desc[rq->rep_post_host_idx];
5718 req_desc_type = rep_desc->dflt_rep.rep_flg &
5719 LEAPRAID_RPY_DESC_FLG_TYPE_MASK;
5720 if (req_desc_type == LEAPRAID_RPY_DESC_FLG_UNUSED) {
5721 atomic_dec(&rq->busy);
5722 return finish_cmds;
5723 }
5724
5725 for (;;) {
5726 if (rep_desc->u.low == UINT_MAX ||
5727 rep_desc->u.high == UINT_MAX)
5728 break;
5729
5730 leapraid_request_descript_handler(adapter, rep_desc,
5731 req_desc_type, msix_idx);
5732 dev_dbg(&adapter->pdev->dev,
5733 "LEAPRAID_SCSIIO: Handled Desc taskid %d, msix %d\n",
5734 rep_desc->dflt_rep.taskid, msix_idx);
5735 rep_desc->words = cpu_to_le64(ULLONG_MAX);
5736 rq->rep_post_host_idx =
5737 (rq->rep_post_host_idx ==
5738 (adapter->adapter_attr.rep_desc_qd -
5739 LEAPRAID_BUSY_LIMIT)) ?
5740 0 : rq->rep_post_host_idx + 1;
5741 req_desc_type =
5742 rq->rep_desc[rq->rep_post_host_idx].dflt_rep.rep_flg &
5743 LEAPRAID_RPY_DESC_FLG_TYPE_MASK;
5744 finish_cmds++;
5745 if (req_desc_type == LEAPRAID_RPY_DESC_FLG_UNUSED)
5746 break;
5747 rep_desc = rq->rep_desc + rq->rep_post_host_idx;
5748 }
5749
5750 if (!finish_cmds) {
5751 atomic_dec(&rq->busy);
5752 return finish_cmds;
5753 }
5754
5755 wmb(); /* Make sure that all write ops are in order */
5756 writel(rq->rep_post_host_idx | ((msix_idx & LEAPRAID_MSIX_GROUP_MASK) <<
5757 LEAPRAID_RPHI_MSIX_IDX_SHIFT),
5758 &adapter->iomem_base->rep_post_reg_idx[
5759 msix_idx / LEAPRAID_MSIX_GROUP_SIZE].idx);
5760 atomic_dec(&rq->busy);
5761 return finish_cmds;
5762 }
5763
leapraid_irq_handler(int irq,void * bus_id)5764 static irqreturn_t leapraid_irq_handler(int irq, void *bus_id)
5765 {
5766 struct leapraid_rq *rq = bus_id;
5767 struct leapraid_adapter *adapter = rq->adapter;
5768
5769 dev_dbg(&adapter->pdev->dev,
5770 "LEAPRAID_SCSIIO: Receive a interrupt, irq %d msix %d\n",
5771 irq, rq->msix_idx);
5772
5773 if (adapter->mask_int)
5774 return IRQ_NONE;
5775
5776 return (leapraid_rep_queue_handler(rq) > 0 ?
5777 IRQ_HANDLED : IRQ_NONE);
5778 }
5779
leapraid_sync_irqs(struct leapraid_adapter * adapter,bool poll)5780 void leapraid_sync_irqs(struct leapraid_adapter *adapter, bool poll)
5781 {
5782 struct leapraid_int_rq *int_rq;
5783 struct leapraid_blk_mq_poll_rq *blk_mq_poll_rq;
5784 unsigned int i;
5785
5786 if (!adapter->notification_desc.msix_enable)
5787 return;
5788
5789 if (adapter->access_ctrl.shost_recovering ||
5790 adapter->access_ctrl.host_removing ||
5791 adapter->access_ctrl.pcie_recovering)
5792 return;
5793
5794 for (i = 0; i < adapter->notification_desc.iopoll_qdex; i++) {
5795 int_rq = &adapter->notification_desc.int_rqs[i];
5796 if (adapter->access_ctrl.shost_recovering ||
5797 adapter->access_ctrl.host_removing ||
5798 adapter->access_ctrl.pcie_recovering)
5799 return;
5800
5801 if (int_rq->rq.msix_idx == 0)
5802 continue;
5803
5804 synchronize_irq(pci_irq_vector(adapter->pdev,
5805 int_rq->rq.msix_idx));
5806 if (poll)
5807 leapraid_rep_queue_handler(&int_rq->rq);
5808 }
5809
5810 for (i = 0; i < adapter->notification_desc.iopoll_qcnt; i++) {
5811 blk_mq_poll_rq =
5812 &adapter->notification_desc.blk_mq_poll_rqs[i];
5813 if (adapter->access_ctrl.shost_recovering ||
5814 adapter->access_ctrl.host_removing ||
5815 adapter->access_ctrl.pcie_recovering)
5816 return;
5817
5818 if (blk_mq_poll_rq->rq.msix_idx == 0)
5819 continue;
5820
5821 leapraid_rep_queue_handler(&blk_mq_poll_rq->rq);
5822 }
5823 }
5824
leapraid_sync_irqs_for_cleanup(struct leapraid_adapter * adapter)5825 static void leapraid_sync_irqs_for_cleanup(struct leapraid_adapter *adapter)
5826 {
5827 struct leapraid_notification_desc *desc = &adapter->notification_desc;
5828 struct leapraid_int_rq *int_rq;
5829 unsigned int i;
5830
5831 if (!adapter->mask_int && leapraid_pci_active(adapter))
5832 leapraid_mask_int(adapter);
5833
5834 for (i = 0; i < desc->int_rqs_allocated; i++) {
5835 int_rq = &desc->int_rqs[i];
5836 synchronize_irq(pci_irq_vector(adapter->pdev,
5837 int_rq->rq.msix_idx));
5838 }
5839 }
5840
leapraid_mq_polling_pause(struct leapraid_adapter * adapter)5841 void leapraid_mq_polling_pause(struct leapraid_adapter *adapter)
5842 {
5843 struct leapraid_notification_desc *desc;
5844 int iopoll_q_count;
5845 int qid;
5846
5847 desc = &adapter->notification_desc;
5848 iopoll_q_count = adapter->adapter_attr.rq_cnt - desc->iopoll_qdex;
5849
5850 for (qid = 0; qid < iopoll_q_count; qid++)
5851 atomic_set(&desc->blk_mq_poll_rqs[qid].pause, 1);
5852
5853 for (qid = 0; qid < iopoll_q_count; qid++) {
5854 while (atomic_read(&desc->blk_mq_poll_rqs[qid].busy)) {
5855 cpu_relax();
5856 udelay(LEAPRAID_IO_POLL_DELAY_US);
5857 }
5858 }
5859 }
5860
leapraid_mq_polling_resume(struct leapraid_adapter * adapter)5861 void leapraid_mq_polling_resume(struct leapraid_adapter *adapter)
5862 {
5863 struct leapraid_notification_desc *desc;
5864 int iopoll_q_count;
5865 int qid;
5866
5867 desc = &adapter->notification_desc;
5868 iopoll_q_count = adapter->adapter_attr.rq_cnt - desc->iopoll_qdex;
5869
5870 for (qid = 0; qid < iopoll_q_count; qid++)
5871 atomic_set(&desc->blk_mq_poll_rqs[qid].pause, 0);
5872 }
5873
leapraid_unlock_host_diag(struct leapraid_adapter * adapter,u32 * host_diag)5874 static int leapraid_unlock_host_diag(struct leapraid_adapter *adapter,
5875 u32 *host_diag)
5876 {
5877 const u32 unlock_seq[] = {
5878 LEAPRAID_WRSEQ_FLUSH_KEY_VALUE,
5879 LEAPRAID_WRSEQ_1ST_KEY_VALUE,
5880 LEAPRAID_WRSEQ_2ND_KEY_VALUE,
5881 LEAPRAID_WRSEQ_3RD_KEY_VALUE,
5882 LEAPRAID_WRSEQ_4TH_KEY_VALUE,
5883 LEAPRAID_WRSEQ_5TH_KEY_VALUE,
5884 LEAPRAID_WRSEQ_6TH_KEY_VALUE
5885 };
5886
5887 const int max_retries = LEAPRAID_UNLOCK_RETRY_LIMIT;
5888 int retry = 0;
5889 unsigned int i;
5890
5891 *host_diag = 0;
5892 while (retry++ <= max_retries) {
5893 for (i = 0; i < ARRAY_SIZE(unlock_seq); i++)
5894 writel(unlock_seq[i], &adapter->iomem_base->ws);
5895
5896 msleep(LEAPRAID_UNLOCK_SLEEP_MS);
5897
5898 *host_diag = leapraid_readl(&adapter->iomem_base->host_diag);
5899 if (*host_diag & LEAPRAID_DIAG_WRITE_ENABLE)
5900 return 0;
5901 }
5902
5903 dev_err(&adapter->pdev->dev, "Try host reset timeout!\n");
5904 return -EFAULT;
5905 }
5906
leapraid_host_diag_reset(struct leapraid_adapter * adapter)5907 static int leapraid_host_diag_reset(struct leapraid_adapter *adapter)
5908 {
5909 u32 host_diag;
5910
5911 pci_cfg_access_lock(adapter->pdev);
5912
5913 mutex_lock(&adapter->reset_desc.host_diag_mutex);
5914 if (leapraid_unlock_host_diag(adapter, &host_diag))
5915 goto out_cleanup;
5916
5917 writel(host_diag | LEAPRAID_DIAG_RESET,
5918 &adapter->iomem_base->host_diag);
5919
5920 msleep(LEAPRAID_MSLEEP_EXTRA_LONG_MS);
5921 msleep(LEAPRAID_MSLEEP_NORMAL_MS);
5922
5923 host_diag = leapraid_readl(&adapter->iomem_base->host_diag);
5924 if (host_diag == LEAPRAID_INVALID_HOST_DIAG_VAL ||
5925 host_diag & LEAPRAID_DIAG_RESET)
5926 goto out_cleanup;
5927
5928 writel(0x0, &adapter->iomem_base->ws);
5929 mutex_unlock(&adapter->reset_desc.host_diag_mutex);
5930 if (!leapraid_wait_adapter_ready(adapter))
5931 goto out_failed;
5932
5933 pci_cfg_access_unlock(adapter->pdev);
5934 return 0;
5935
5936 out_cleanup:
5937 mutex_unlock(&adapter->reset_desc.host_diag_mutex);
5938 out_failed:
5939 pci_cfg_access_unlock(adapter->pdev);
5940 dev_err(&adapter->pdev->dev, "Host diag failed\n");
5941 return -EFAULT;
5942 }
5943
leapraid_find_matching_port(struct leapraid_card_port * card_port_table,u8 count,u8 port_id,u64 sas_addr)5944 static int leapraid_find_matching_port(
5945 struct leapraid_card_port *card_port_table,
5946 u8 count, u8 port_id, u64 sas_addr)
5947 {
5948 int i;
5949
5950 for (i = 0; i < count; i++)
5951 if (card_port_table[i].port_id == port_id &&
5952 card_port_table[i].sas_address == sas_addr)
5953 return i;
5954
5955 return LEAPRAID_INVALID_INDEX;
5956 }
5957
leapraid_fill_card_port_table(struct leapraid_adapter * adapter,struct leapraid_sas_io_unit_p0 * sas_iounit_p0,struct leapraid_card_port * new_card_port_table)5958 static u8 leapraid_fill_card_port_table(
5959 struct leapraid_adapter *adapter,
5960 struct leapraid_sas_io_unit_p0 *sas_iounit_p0,
5961 struct leapraid_card_port *new_card_port_table)
5962 {
5963 u8 port_entry_num = 0, port_id;
5964 u16 attached_hdl;
5965 u64 attached_sas_addr;
5966 int i, idx;
5967
5968 for (i = 0; i < adapter->dev_topo.card.phys_num; i++) {
5969 if (sas_iounit_p0->phy_info[i].neg_link_rate >>
5970 LEAPRAID_SAS_NEG_LINK_RATE_SHIFT <
5971 LEAPRAID_SAS_NEG_LINK_RATE_1_5)
5972 continue;
5973
5974 attached_hdl = le16_to_cpu(sas_iounit_p0->phy_info[i]
5975 .attached_dev_hdl);
5976 if (leapraid_get_sas_address(adapter,
5977 attached_hdl,
5978 &attached_sas_addr) != 0)
5979 continue;
5980
5981 port_id = sas_iounit_p0->phy_info[i].port;
5982
5983 idx = leapraid_find_matching_port(new_card_port_table,
5984 port_entry_num,
5985 port_id,
5986 attached_sas_addr);
5987 if (idx >= 0) {
5988 new_card_port_table[idx].phy_mask |= BIT(i);
5989 } else {
5990 new_card_port_table[port_entry_num].port_id = port_id;
5991 new_card_port_table[port_entry_num].phy_mask = BIT(i);
5992 new_card_port_table[port_entry_num].sas_address =
5993 attached_sas_addr;
5994 port_entry_num++;
5995 }
5996 }
5997
5998 return port_entry_num;
5999 }
6000
leapraid_set_new_card_port_table_after_reset(struct leapraid_adapter * adapter,struct leapraid_card_port * new_card_port_table)6001 static u8 leapraid_set_new_card_port_table_after_reset(
6002 struct leapraid_adapter *adapter,
6003 struct leapraid_card_port *new_card_port_table)
6004 {
6005 union cfg_param_1 cfgp1 = {0};
6006 union cfg_param_2 cfgp2 = {0};
6007 struct leapraid_sas_io_unit_p0 *sas_iounit_p0;
6008 u8 port_entry_num = 0;
6009 u16 sz;
6010
6011 sz = offsetof(struct leapraid_sas_io_unit_p0, phy_info) +
6012 (adapter->dev_topo.card.phys_num *
6013 sizeof(struct leapraid_sas_io_unit0_phy_info));
6014 sas_iounit_p0 = kzalloc(sz, GFP_KERNEL);
6015 if (!sas_iounit_p0)
6016 return port_entry_num;
6017
6018 cfgp1.size = sz;
6019 if (leapraid_op_config_page(adapter, sas_iounit_p0, cfgp1, cfgp2,
6020 GET_SAS_IOUNIT_PG0) != 0)
6021 goto out_free;
6022
6023 port_entry_num = leapraid_fill_card_port_table(adapter,
6024 sas_iounit_p0,
6025 new_card_port_table);
6026 out_free:
6027 kfree(sas_iounit_p0);
6028 return port_entry_num;
6029 }
6030
leapraid_update_existing_port(struct leapraid_adapter * adapter,struct leapraid_card_port * new_table,int entry_idx,int port_entry_num)6031 static void leapraid_update_existing_port(struct leapraid_adapter *adapter,
6032 struct leapraid_card_port *new_table,
6033 int entry_idx, int port_entry_num)
6034 {
6035 struct leapraid_card_port *matched_card_port;
6036 int matched_code;
6037 int count, lcount = 0;
6038 u64 sas_addr;
6039 int i;
6040
6041 matched_code = leapraid_check_card_port(adapter,
6042 &new_table[entry_idx],
6043 &matched_card_port,
6044 &count);
6045
6046 if (!matched_card_port)
6047 return;
6048
6049 if (matched_code == SAME_PORT_WITH_PARTIALLY_CHANGED_PHYS ||
6050 matched_code == SAME_ADDR_WITH_PARTIALLY_CHANGED_PHYS) {
6051 leapraid_add_or_del_phys_from_existing_port(adapter,
6052 matched_card_port,
6053 new_table,
6054 entry_idx,
6055 port_entry_num);
6056 } else if (matched_code == SAME_ADDR_ONLY) {
6057 sas_addr = new_table[entry_idx].sas_address;
6058 for (i = 0; i < port_entry_num; i++)
6059 if (new_table[i].sas_address == sas_addr)
6060 lcount++;
6061
6062 if (count > 1 || lcount > 1)
6063 return;
6064
6065 leapraid_add_or_del_phys_from_existing_port(adapter,
6066 matched_card_port,
6067 new_table,
6068 entry_idx,
6069 port_entry_num);
6070 }
6071
6072 if (matched_card_port->port_id != new_table[entry_idx].port_id)
6073 matched_card_port->port_id = new_table[entry_idx].port_id;
6074
6075 matched_card_port->flg &= ~LEAPRAID_CARD_PORT_FLG_DIRTY;
6076 matched_card_port->phy_mask = new_table[entry_idx].phy_mask;
6077 }
6078
leapraid_update_card_port_after_reset(struct leapraid_adapter * adapter)6079 static void leapraid_update_card_port_after_reset(
6080 struct leapraid_adapter *adapter)
6081 {
6082 struct leapraid_card_port *new_card_port_table;
6083 struct leapraid_card_port *matched_card_port;
6084 u8 port_entry_num;
6085 u8 nr_phys;
6086 int i;
6087
6088 if (leapraid_get_adapter_phys(adapter, &nr_phys) || !nr_phys)
6089 return;
6090
6091 if (!adapter->dev_topo.card.card_phy) {
6092 adapter->dev_topo.card.card_phy =
6093 kcalloc(nr_phys, sizeof(struct leapraid_card_phy),
6094 GFP_KERNEL);
6095 if (!adapter->dev_topo.card.card_phy)
6096 return;
6097 }
6098
6099 adapter->dev_topo.card.phys_num = nr_phys;
6100
6101 new_card_port_table = kcalloc(adapter->dev_topo.card.phys_num,
6102 sizeof(struct leapraid_card_port),
6103 GFP_KERNEL);
6104 if (!new_card_port_table)
6105 return;
6106
6107 port_entry_num =
6108 leapraid_set_new_card_port_table_after_reset(
6109 adapter,
6110 new_card_port_table);
6111 if (!port_entry_num)
6112 goto out_free_port_table;
6113
6114 list_for_each_entry(matched_card_port,
6115 &adapter->dev_topo.card_port_list, list)
6116 matched_card_port->flg |= LEAPRAID_CARD_PORT_FLG_DIRTY;
6117
6118 matched_card_port = NULL;
6119 for (i = 0; i < port_entry_num; i++)
6120 leapraid_update_existing_port(adapter,
6121 new_card_port_table,
6122 i, port_entry_num);
6123 out_free_port_table:
6124 kfree(new_card_port_table);
6125 }
6126
leapraid_is_valid_vphy(struct leapraid_adapter * adapter,struct leapraid_sas_io_unit_p0 * sas_io_unit_p0,int phy_index)6127 static bool leapraid_is_valid_vphy(
6128 struct leapraid_adapter *adapter,
6129 struct leapraid_sas_io_unit_p0 *sas_io_unit_p0,
6130 int phy_index)
6131 {
6132 union cfg_param_1 cfgp1 = {0};
6133 union cfg_param_2 cfgp2 = {0};
6134 struct leapraid_sas_phy_p0 phy_p0;
6135 u32 dev_info;
6136
6137 if (sas_io_unit_p0->phy_info[phy_index].neg_link_rate >>
6138 LEAPRAID_SAS_NEG_LINK_RATE_SHIFT <
6139 LEAPRAID_SAS_NEG_LINK_RATE_1_5)
6140 return false;
6141
6142 dev_info = le32_to_cpu(sas_io_unit_p0->phy_info[phy_index]
6143 .controller_phy_dev_info);
6144 if (!(dev_info & LEAPRAID_DEVTYP_SEP))
6145 return false;
6146
6147 cfgp1.phy_number = phy_index;
6148 if (leapraid_op_config_page(adapter, &phy_p0, cfgp1, cfgp2,
6149 GET_PHY_PG0))
6150 return false;
6151
6152 if (!(le32_to_cpu(phy_p0.phy_info) & LEAPRAID_SAS_PHYINFO_VPHY))
6153 return false;
6154
6155 return true;
6156 }
6157
leapraid_update_vphy_binding(struct leapraid_adapter * adapter,struct leapraid_card_port * card_port,struct leapraid_vphy * vphy,int phy_index,u8 may_new_port_id,u64 attached_sas_addr)6158 static void leapraid_update_vphy_binding(struct leapraid_adapter *adapter,
6159 struct leapraid_card_port *card_port,
6160 struct leapraid_vphy *vphy,
6161 int phy_index, u8 may_new_port_id,
6162 u64 attached_sas_addr)
6163 {
6164 struct leapraid_card_port *may_new_card_port;
6165 struct leapraid_sas_dev *sas_dev;
6166
6167 may_new_card_port = leapraid_get_port_by_id(adapter,
6168 may_new_port_id,
6169 true);
6170 if (!may_new_card_port) {
6171 may_new_card_port = kzalloc_obj(*may_new_card_port);
6172 if (!may_new_card_port)
6173 return;
6174 may_new_card_port->port_id = may_new_port_id;
6175 dev_err(&adapter->pdev->dev,
6176 "%s: New card port %p added, port=%d\n",
6177 __func__, may_new_card_port, may_new_port_id);
6178 list_add_tail(&may_new_card_port->list,
6179 &adapter->dev_topo.card_port_list);
6180 }
6181
6182 if (card_port != may_new_card_port) {
6183 if (!may_new_card_port->vphys_mask)
6184 INIT_LIST_HEAD(&may_new_card_port->vphys_list);
6185 may_new_card_port->vphys_mask |= BIT(phy_index);
6186 card_port->vphys_mask &= ~BIT(phy_index);
6187 list_move(&vphy->list, &may_new_card_port->vphys_list);
6188
6189 sas_dev = leapraid_get_sas_dev_by_addr(adapter,
6190 attached_sas_addr,
6191 card_port);
6192 if (sas_dev) {
6193 sas_dev->card_port = may_new_card_port;
6194 leapraid_sdev_put(sas_dev);
6195 }
6196 }
6197
6198 if (may_new_card_port->flg & LEAPRAID_CARD_PORT_FLG_DIRTY) {
6199 may_new_card_port->sas_address = 0;
6200 may_new_card_port->phy_mask = 0;
6201 may_new_card_port->flg &= ~LEAPRAID_CARD_PORT_FLG_DIRTY;
6202 }
6203 vphy->flg &= ~LEAPRAID_VPHY_FLG_DIRTY;
6204 }
6205
leapraid_update_vphys_after_reset(struct leapraid_adapter * adapter)6206 static void leapraid_update_vphys_after_reset(struct leapraid_adapter *adapter)
6207 {
6208 union cfg_param_1 cfgp1 = {0};
6209 union cfg_param_2 cfgp2 = {0};
6210 struct leapraid_sas_io_unit_p0 *sas_iounit_p0;
6211 struct leapraid_card_port *card_port, *card_port_next;
6212 struct leapraid_vphy *vphy, *vphy_next;
6213 u64 attached_sas_addr;
6214 u16 sz;
6215 u16 attached_hdl;
6216 bool found = false;
6217 u8 port_id;
6218 int i;
6219
6220 list_for_each_entry_safe(card_port, card_port_next,
6221 &adapter->dev_topo.card_port_list, list) {
6222 if (!card_port->vphys_mask)
6223 continue;
6224
6225 list_for_each_entry_safe(vphy, vphy_next,
6226 &card_port->vphys_list, list)
6227 vphy->flg |= LEAPRAID_VPHY_FLG_DIRTY;
6228 }
6229
6230 sz = offsetof(struct leapraid_sas_io_unit_p0, phy_info) +
6231 (adapter->dev_topo.card.phys_num *
6232 sizeof(struct leapraid_sas_io_unit0_phy_info));
6233 sas_iounit_p0 = kzalloc(sz, GFP_KERNEL);
6234 if (!sas_iounit_p0)
6235 return;
6236
6237 cfgp1.size = sz;
6238 if (leapraid_op_config_page(adapter, sas_iounit_p0, cfgp1, cfgp2,
6239 GET_SAS_IOUNIT_PG0) != 0)
6240 goto out_free;
6241
6242 for (i = 0; i < adapter->dev_topo.card.phys_num; i++) {
6243 if (!leapraid_is_valid_vphy(adapter, sas_iounit_p0, i))
6244 continue;
6245
6246 attached_hdl =
6247 le16_to_cpu(sas_iounit_p0->phy_info[i]
6248 .attached_dev_hdl);
6249 if (leapraid_get_sas_address(adapter, attached_hdl,
6250 &attached_sas_addr) != 0)
6251 continue;
6252
6253 found = false;
6254 card_port = NULL;
6255 card_port_next = NULL;
6256 list_for_each_entry_safe(card_port, card_port_next,
6257 &adapter->dev_topo.card_port_list,
6258 list) {
6259 if (!card_port->vphys_mask)
6260 continue;
6261
6262 list_for_each_entry_safe(vphy, vphy_next,
6263 &card_port->vphys_list,
6264 list) {
6265 if (!(vphy->flg & LEAPRAID_VPHY_FLG_DIRTY))
6266 continue;
6267
6268 if (vphy->sas_address != attached_sas_addr)
6269 continue;
6270
6271 if (!(vphy->phy_mask & BIT(i)))
6272 vphy->phy_mask = BIT(i);
6273
6274 port_id = sas_iounit_p0->phy_info[i].port;
6275
6276 leapraid_update_vphy_binding(adapter,
6277 card_port,
6278 vphy,
6279 i,
6280 port_id,
6281 attached_sas_addr);
6282
6283 found = true;
6284 break;
6285 }
6286 if (found)
6287 break;
6288 }
6289 }
6290 out_free:
6291 kfree(sas_iounit_p0);
6292 }
6293
leapraid_mark_all_dev_deleted(struct leapraid_adapter * adapter)6294 static void leapraid_mark_all_dev_deleted(struct leapraid_adapter *adapter)
6295 {
6296 struct leapraid_sdev_priv *sdev_priv;
6297 struct scsi_device *sdev;
6298
6299 shost_for_each_device(sdev, adapter->shost) {
6300 sdev_priv = sdev->hostdata;
6301 if (sdev_priv && sdev_priv->starget_priv)
6302 sdev_priv->starget_priv->deleted = 1;
6303 }
6304 }
6305
leapraid_free_enc_list(struct leapraid_adapter * adapter)6306 static void leapraid_free_enc_list(struct leapraid_adapter *adapter)
6307 {
6308 struct leapraid_enc_node *enc_dev, *enc_dev_next;
6309 LIST_HEAD(free_list);
6310 unsigned long flags;
6311
6312 spin_lock_irqsave(&adapter->dev_topo.enc_lock, flags);
6313 list_splice_init(&adapter->dev_topo.enc_list, &free_list);
6314 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, flags);
6315
6316 list_for_each_entry_safe(enc_dev, enc_dev_next, &free_list, list) {
6317 list_del(&enc_dev->list);
6318 kfree(enc_dev);
6319 }
6320 }
6321
leapraid_rebuild_enc_list_after_reset(struct leapraid_adapter * adapter)6322 static void leapraid_rebuild_enc_list_after_reset(
6323 struct leapraid_adapter *adapter)
6324 {
6325 union cfg_param_1 cfgp1 = {0};
6326 union cfg_param_2 cfgp2 = {0};
6327 struct leapraid_enc_node *enc_node;
6328 u16 enc_hdl;
6329 unsigned long flags;
6330 int rc;
6331
6332 leapraid_free_enc_list(adapter);
6333
6334 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP;
6335 for (enc_hdl = 0xFFFF; ; enc_hdl = le16_to_cpu(enc_node->pg0.enc_hdl)) {
6336 enc_node = kzalloc_obj(*enc_node);
6337 if (!enc_node)
6338 return;
6339
6340 cfgp2.handle = enc_hdl;
6341 rc = leapraid_op_config_page(adapter, &enc_node->pg0, cfgp1,
6342 cfgp2, GET_SAS_ENCLOSURE_PG0);
6343 if (rc) {
6344 kfree(enc_node);
6345 return;
6346 }
6347
6348 spin_lock_irqsave(&adapter->dev_topo.enc_lock, flags);
6349 list_add_tail(&enc_node->list, &adapter->dev_topo.enc_list);
6350 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, flags);
6351 }
6352 }
6353
leapraid_mark_resp_sas_dev(struct leapraid_adapter * adapter,struct leapraid_sas_dev_p0 * sas_dev_p0)6354 static void leapraid_mark_resp_sas_dev(struct leapraid_adapter *adapter,
6355 struct leapraid_sas_dev_p0 *sas_dev_p0)
6356 {
6357 struct leapraid_starget_priv *starget_priv;
6358 struct leapraid_enc_node *enc_node = NULL;
6359 struct leapraid_card_port *card_port;
6360 struct leapraid_sas_dev *sas_dev;
6361 struct scsi_target *starget;
6362 unsigned long flags;
6363 unsigned long enc_flags = 0;
6364 u16 enc_hdl;
6365 u64 enc_lid = 0;
6366
6367 card_port = leapraid_get_port_by_id(adapter, sas_dev_p0->physical_port,
6368 false);
6369 enc_hdl = le16_to_cpu(sas_dev_p0->enc_hdl);
6370 if (enc_hdl) {
6371 spin_lock_irqsave(&adapter->dev_topo.enc_lock, enc_flags);
6372 enc_node = leapraid_enc_find_by_hdl(adapter, enc_hdl);
6373 if (enc_node)
6374 enc_lid = le64_to_cpu(enc_node->pg0.enc_lid);
6375 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, enc_flags);
6376 if (!enc_node)
6377 dev_info(&adapter->pdev->dev,
6378 "enc hdl 0x%04x has no matched enc dev\n",
6379 enc_hdl);
6380 }
6381
6382 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags);
6383 list_for_each_entry(sas_dev, &adapter->dev_topo.sas_dev_list, list) {
6384 if (sas_dev->sas_addr != le64_to_cpu(sas_dev_p0->sas_address) ||
6385 sas_dev->slot != le16_to_cpu(sas_dev_p0->slot) ||
6386 sas_dev->card_port != card_port)
6387 continue;
6388
6389 sas_dev->resp = 1;
6390 starget = sas_dev->starget;
6391 if (starget && starget->hostdata) {
6392 starget_priv = starget->hostdata;
6393 starget_priv->tm_busy = 0;
6394 starget_priv->deleted = 0;
6395 } else {
6396 starget_priv = NULL;
6397 }
6398
6399 if (starget) {
6400 starget_printk(
6401 KERN_INFO, starget,
6402 "dev: hdl=0x%04x saddr=0x%016llx port_id=%d\n",
6403 sas_dev->hdl,
6404 (unsigned long long)sas_dev->sas_addr,
6405 sas_dev->card_port->port_id);
6406 if (sas_dev->enc_hdl != 0)
6407 starget_printk(
6408 KERN_INFO,
6409 starget,
6410 "enc info: enc_lid=0x%016llx slot=%d\n",
6411 (unsigned long long)sas_dev->enc_lid,
6412 sas_dev->slot);
6413 }
6414
6415 if (le16_to_cpu(sas_dev_p0->flg) &
6416 LEAPRAID_SAS_DEV_P0_FLG_ENC_LEVEL_VALID) {
6417 sas_dev->enc_level = sas_dev_p0->enc_level;
6418 memcpy(sas_dev->connector_name,
6419 sas_dev_p0->connector_name,
6420 LEAPRAID_SAS_DEV_P0_CON_NAME_LEN);
6421 sas_dev->connector_name[
6422 LEAPRAID_SAS_DEV_P0_CON_NAME_LEN] = '\0';
6423 } else {
6424 sas_dev->enc_level = 0;
6425 sas_dev->connector_name[0] = '\0';
6426 }
6427
6428 sas_dev->enc_hdl = enc_hdl;
6429 sas_dev->enc_lid = enc_lid;
6430
6431 if (sas_dev->hdl == le16_to_cpu(sas_dev_p0->dev_hdl))
6432 goto unlock;
6433
6434 dev_info(&adapter->pdev->dev,
6435 "hdl changed: 0x%04x -> 0x%04x\n",
6436 sas_dev->hdl, sas_dev_p0->dev_hdl);
6437 sas_dev->hdl = le16_to_cpu(sas_dev_p0->dev_hdl);
6438 if (starget_priv)
6439 starget_priv->hdl = le16_to_cpu(sas_dev_p0->dev_hdl);
6440
6441 goto unlock;
6442 }
6443 unlock:
6444 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags);
6445 }
6446
leapraid_search_resp_sas_dev(struct leapraid_adapter * adapter)6447 static void leapraid_search_resp_sas_dev(struct leapraid_adapter *adapter)
6448 {
6449 union cfg_param_1 cfgp1 = {0};
6450 union cfg_param_2 cfgp2 = {0};
6451 struct leapraid_sas_dev_p0 sas_dev_p0;
6452 u32 device_info;
6453
6454 if (list_empty(&adapter->dev_topo.sas_dev_list))
6455 return;
6456
6457 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP;
6458 for (cfgp2.handle = 0xFFFF;
6459 !leapraid_op_config_page(adapter, &sas_dev_p0,
6460 cfgp1, cfgp2, GET_SAS_DEVICE_PG0);
6461 cfgp2.handle = le16_to_cpu(sas_dev_p0.dev_hdl)) {
6462 device_info = le32_to_cpu(sas_dev_p0.dev_info);
6463 if (!(leapraid_is_end_dev(device_info)))
6464 continue;
6465
6466 leapraid_mark_resp_sas_dev(adapter, &sas_dev_p0);
6467 }
6468 }
6469
leapraid_mark_resp_raid_volume(struct leapraid_adapter * adapter,u64 wwid,u16 hdl)6470 static void leapraid_mark_resp_raid_volume(struct leapraid_adapter *adapter,
6471 u64 wwid, u16 hdl)
6472 {
6473 struct leapraid_raid_volume *raid_volume;
6474 struct leapraid_starget_priv *starget_priv = NULL;
6475 struct scsi_target *starget;
6476 unsigned long flags;
6477 u64 volume_wwid;
6478 u16 old_hdl;
6479
6480 raid_volume = leapraid_raid_volume_find_by_wwid(adapter, wwid);
6481 if (!raid_volume)
6482 return;
6483
6484 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags);
6485 if (!raid_volume->starget) {
6486 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock,
6487 flags);
6488 leapraid_raid_volume_put(raid_volume);
6489 return;
6490 }
6491
6492 starget = raid_volume->starget;
6493 if (starget->hostdata) {
6494 starget_priv = starget->hostdata;
6495 starget_priv->deleted = 0;
6496 }
6497
6498 raid_volume->resp = 1;
6499 volume_wwid = raid_volume->wwid;
6500 old_hdl = raid_volume->hdl;
6501 if (old_hdl != hdl) {
6502 raid_volume->hdl = hdl;
6503 if (starget_priv)
6504 starget_priv->hdl = hdl;
6505 }
6506 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, flags);
6507
6508 starget_printk(KERN_INFO, starget,
6509 "raid volume: hdl=0x%04x, wwid=0x%016llx\n",
6510 hdl, (unsigned long long)volume_wwid);
6511 if (old_hdl != hdl)
6512 dev_info(&adapter->pdev->dev,
6513 "hdl changed: 0x%04x -> 0x%04x\n",
6514 old_hdl, hdl);
6515
6516 leapraid_raid_volume_put(raid_volume);
6517 }
6518
leapraid_search_resp_raid_volume(struct leapraid_adapter * adapter)6519 static void leapraid_search_resp_raid_volume(struct leapraid_adapter *adapter)
6520 {
6521 union cfg_param_1 cfgp1 = {0};
6522 union cfg_param_1 cfgp1_extra = {0};
6523 union cfg_param_2 cfgp2 = {0};
6524 union cfg_param_2 cfgp2_extra = {0};
6525 struct leapraid_raidvol_p1 raidvol_p1;
6526 struct leapraid_raidvol_p0 raidvol_p0;
6527 struct leapraid_raidpd_p0 raidpd_p0;
6528 unsigned long flags;
6529 u16 hdl;
6530 u8 phys_disk_num;
6531 bool is_empty;
6532
6533 if (!adapter->adapter_attr.raid_support)
6534 return;
6535
6536 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags);
6537 is_empty = list_empty(&adapter->dev_topo.raid_volume_list);
6538 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, flags);
6539 if (is_empty)
6540 return;
6541
6542 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP;
6543 for (hdl = 0xFFFF, cfgp2.handle = hdl;
6544 !leapraid_op_config_page(adapter, &raidvol_p1, cfgp1, cfgp2,
6545 GET_RAID_VOLUME_PG1);
6546 cfgp2.handle = hdl) {
6547 hdl = le16_to_cpu(raidvol_p1.dev_hdl);
6548 cfgp1_extra.size = sizeof(struct leapraid_raidvol_p0);
6549 cfgp2_extra.handle = hdl;
6550 if (leapraid_op_config_page(adapter, &raidvol_p0, cfgp1_extra,
6551 cfgp2_extra, GET_RAID_VOLUME_PG0))
6552 continue;
6553
6554 if (raidvol_p0.volume_state == LEAPRAID_VOL_STATE_OPTIMAL ||
6555 raidvol_p0.volume_state == LEAPRAID_VOL_STATE_ONLINE ||
6556 raidvol_p0.volume_state == LEAPRAID_VOL_STATE_DEGRADED)
6557 leapraid_mark_resp_raid_volume(
6558 adapter,
6559 le64_to_cpu(raidvol_p1.wwid),
6560 hdl);
6561 }
6562
6563 memset(adapter->dev_topo.pd_hdls, 0, adapter->dev_topo.pd_hdls_sz);
6564 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP;
6565 for (phys_disk_num = 0xFF, cfgp2.form_specific = phys_disk_num;
6566 !leapraid_op_config_page(adapter, &raidpd_p0, cfgp1, cfgp2,
6567 GET_PHY_DISK_PG0);
6568 cfgp2.form_specific = phys_disk_num) {
6569 phys_disk_num = raidpd_p0.phys_disk_num;
6570 hdl = le16_to_cpu(raidpd_p0.dev_hdl);
6571 if (!hdl ||
6572 hdl > adapter->adapter_attr.features.max_dev_handle)
6573 dev_warn(&adapter->pdev->dev,
6574 "%s: Invalid device handle\n", __func__);
6575 else
6576 set_bit(hdl, adapter->dev_topo.pd_hdls);
6577 }
6578 }
6579
leapraid_mark_resp_exp(struct leapraid_adapter * adapter,struct leapraid_exp_p0 * exp_pg0)6580 static void leapraid_mark_resp_exp(struct leapraid_adapter *adapter,
6581 struct leapraid_exp_p0 *exp_pg0)
6582 {
6583 struct leapraid_enc_node *enc_node = NULL;
6584 struct leapraid_topo_node *topo_node_exp;
6585 u16 enc_hdl = le16_to_cpu(exp_pg0->enc_hdl);
6586 u64 sas_address = le64_to_cpu(exp_pg0->sas_address);
6587 u16 hdl = le16_to_cpu(exp_pg0->dev_hdl);
6588 u8 port_id = exp_pg0->physical_port;
6589 struct leapraid_card_port *card_port = leapraid_get_port_by_id(adapter,
6590 port_id,
6591 false);
6592 unsigned long flags;
6593 unsigned long enc_flags = 0;
6594 u64 enc_lid = 0;
6595 int i;
6596
6597 if (enc_hdl) {
6598 spin_lock_irqsave(&adapter->dev_topo.enc_lock, enc_flags);
6599 enc_node = leapraid_enc_find_by_hdl(adapter, enc_hdl);
6600 if (enc_node)
6601 enc_lid = le64_to_cpu(enc_node->pg0.enc_lid);
6602 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, enc_flags);
6603 }
6604
6605 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags);
6606 list_for_each_entry(topo_node_exp, &adapter->dev_topo.exp_list, list) {
6607 if (topo_node_exp->sas_address != sas_address ||
6608 topo_node_exp->card_port != card_port)
6609 continue;
6610
6611 topo_node_exp->resp = 1;
6612 topo_node_exp->enc_hdl = enc_hdl;
6613 topo_node_exp->enc_lid = enc_lid;
6614 if (topo_node_exp->hdl == hdl)
6615 goto unlock;
6616
6617 dev_info(&adapter->pdev->dev,
6618 "hdl changed: 0x%04x -> 0x%04x\n",
6619 topo_node_exp->hdl, hdl);
6620 topo_node_exp->hdl = hdl;
6621 for (i = 0; i < topo_node_exp->phys_num; i++)
6622 topo_node_exp->card_phy[i].hdl = hdl;
6623 goto unlock;
6624 }
6625 unlock:
6626 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock, flags);
6627 }
6628
leapraid_search_resp_exp(struct leapraid_adapter * adapter)6629 static void leapraid_search_resp_exp(struct leapraid_adapter *adapter)
6630 {
6631 union cfg_param_1 cfgp1 = {0};
6632 union cfg_param_2 cfgp2 = {0};
6633 struct leapraid_exp_p0 exp_p0;
6634 u64 sas_address;
6635 u16 hdl;
6636 u8 port;
6637
6638 if (list_empty(&adapter->dev_topo.exp_list))
6639 return;
6640
6641 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP;
6642 for (hdl = 0xFFFF, cfgp2.handle = hdl;
6643 !leapraid_op_config_page(adapter, &exp_p0, cfgp1, cfgp2,
6644 GET_SAS_EXPANDER_PG0);
6645 cfgp2.handle = hdl) {
6646 hdl = le16_to_cpu(exp_p0.dev_hdl);
6647 sas_address = le64_to_cpu(exp_p0.sas_address);
6648 port = exp_p0.physical_port;
6649
6650 dev_dbg(&adapter->pdev->dev,
6651 "exp detected: hdl=0x%04x, sas=0x%016llx, port=%u",
6652 hdl, (unsigned long long)sas_address,
6653 adapter->adapter_attr.enable_mp ? port :
6654 LEAPRAID_DISABLE_MP_PORT_ID);
6655 leapraid_mark_resp_exp(adapter, &exp_p0);
6656 }
6657 }
6658
leapraid_wait_cmds_done(struct leapraid_adapter * adapter)6659 void leapraid_wait_cmds_done(struct leapraid_adapter *adapter)
6660 {
6661 struct leapraid_io_req_tracker *io_req_tracker;
6662 unsigned long flags;
6663 u16 i;
6664
6665 adapter->reset_desc.pending_io_cnt = 0;
6666 if (!leapraid_pci_active(adapter)) {
6667 dev_err(&adapter->pdev->dev,
6668 "%s %s: PCI error, device reset or unplugged!\n",
6669 adapter->adapter_attr.name, __func__);
6670 return;
6671 }
6672
6673 if (leapraid_get_adapter_state(adapter) != LEAPRAID_DB_OPERATIONAL)
6674 return;
6675
6676 spin_lock_irqsave(&adapter->dynamic_task_desc.task_lock, flags);
6677 for (i = 1; i <= adapter->shost->can_queue; i++) {
6678 io_req_tracker = leapraid_get_io_tracker_from_taskid(adapter,
6679 i);
6680 if (io_req_tracker && io_req_tracker->taskid != 0 &&
6681 io_req_tracker->scmd)
6682 adapter->reset_desc.pending_io_cnt++;
6683 }
6684 spin_unlock_irqrestore(&adapter->dynamic_task_desc.task_lock, flags);
6685
6686 if (!adapter->reset_desc.pending_io_cnt)
6687 return;
6688
6689 wait_event_timeout(adapter->reset_desc.reset_wait_queue,
6690 adapter->reset_desc.pending_io_cnt == 0,
6691 LEAPRAID_IO_CMD_TIMEOUT * HZ);
6692 }
6693
leapraid_hard_reset_handler(struct leapraid_adapter * adapter,enum reset_type type)6694 int leapraid_hard_reset_handler(struct leapraid_adapter *adapter,
6695 enum reset_type type)
6696 {
6697 unsigned long flags;
6698 bool wake = false;
6699 int rc;
6700
6701 mutex_lock(&adapter->reset_desc.adapter_reset_mutex);
6702
6703 if (adapter->access_ctrl.shost_recover_async) {
6704 rc = adapter->reset_desc.adapter_reset_results;
6705 dev_info(&adapter->pdev->dev,
6706 "Skip nested hard reset, async evt running, rc=%d\n",
6707 rc);
6708 mutex_unlock(&adapter->reset_desc.adapter_reset_mutex);
6709 return rc;
6710 }
6711
6712 if (!leapraid_pci_active(adapter)) {
6713 if (leapraid_pci_removed(adapter)) {
6714 dev_info(&adapter->pdev->dev,
6715 "pci_dev removed, pause poll, clean cmds\n");
6716 leapraid_mq_polling_pause(adapter);
6717 leapraid_clean_active_scsi_cmds(adapter);
6718 leapraid_mq_polling_resume(adapter);
6719 }
6720 dev_err(&adapter->pdev->dev, "PCIe unavailable!\n");
6721 mutex_unlock(&adapter->reset_desc.adapter_reset_mutex);
6722 return -ENXIO;
6723 }
6724
6725 dev_info(&adapter->pdev->dev, "Starting hard reset\n");
6726
6727 spin_lock_irqsave(&adapter->reset_desc.adapter_reset_lock, flags);
6728 adapter->access_ctrl.shost_recovering = 1;
6729 adapter->access_ctrl.shost_recover_async = 1;
6730 spin_unlock_irqrestore(&adapter->reset_desc.adapter_reset_lock, flags);
6731
6732 leapraid_wait_cmds_done(adapter);
6733 leapraid_mask_int(adapter);
6734 leapraid_mq_polling_pause(adapter);
6735 rc = leapraid_make_adapter_ready(adapter, type);
6736 if (rc) {
6737 dev_err(&adapter->pdev->dev,
6738 "Failed to make adapter ready, rc=%d\n", rc);
6739 goto out_cleanup;
6740 }
6741
6742 rc = leapraid_fw_log_init(adapter);
6743 if (rc) {
6744 dev_err(&adapter->pdev->dev, "Firmware log init failed\n");
6745 goto out_cleanup;
6746 }
6747
6748 leapraid_clean_active_cmds(adapter);
6749 if (adapter->scan_dev_desc.driver_loading &&
6750 adapter->scan_dev_desc.scan_dev_failed) {
6751 dev_err(&adapter->pdev->dev,
6752 "Previous device scan failed or driver loading\n");
6753 adapter->access_ctrl.host_removing = 1;
6754 rc = -EFAULT;
6755 goto out_cleanup;
6756 }
6757
6758 rc = leapraid_make_adapter_available(adapter);
6759 if (!rc) {
6760 dev_info(&adapter->pdev->dev,
6761 "Adapter is now available, rebuilding topology\n");
6762 if (adapter->adapter_attr.enable_mp) {
6763 leapraid_update_card_port_after_reset(adapter);
6764 leapraid_update_vphys_after_reset(adapter);
6765 }
6766 leapraid_mark_all_dev_deleted(adapter);
6767 leapraid_rebuild_enc_list_after_reset(adapter);
6768 leapraid_search_resp_sas_dev(adapter);
6769 leapraid_search_resp_raid_volume(adapter);
6770 leapraid_search_resp_exp(adapter);
6771 leapraid_hardreset_barrier(adapter);
6772 }
6773 out_cleanup:
6774 if (rc)
6775 dev_err(&adapter->pdev->dev, "Hard reset failed\n");
6776
6777 spin_lock_irqsave(&adapter->reset_desc.adapter_reset_lock, flags);
6778 adapter->reset_desc.adapter_reset_results = rc;
6779 adapter->access_ctrl.shost_recovering = 0;
6780 wake_up(&adapter->access_ctrl.recovery_waitq);
6781 if (rc) {
6782 adapter->access_ctrl.shost_recover_async = 0;
6783 wake = true;
6784 }
6785 spin_unlock_irqrestore(&adapter->reset_desc.adapter_reset_lock, flags);
6786 if (wake)
6787 wake_up(&adapter->access_ctrl.shost_recover_wq);
6788
6789 adapter->reset_desc.reset_cnt++;
6790 mutex_unlock(&adapter->reset_desc.adapter_reset_mutex);
6791
6792 if (rc)
6793 leapraid_clean_active_scsi_cmds(adapter);
6794 leapraid_mq_polling_resume(adapter);
6795
6796 return rc;
6797 }
6798
leapraid_get_adapter_features(struct leapraid_adapter * adapter)6799 static int leapraid_get_adapter_features(struct leapraid_adapter *adapter)
6800 {
6801 struct leapraid_adapter_features_req leap_mpi_req;
6802 struct leapraid_adapter_features_rep leap_mpi_rep;
6803 u8 fw_major, fw_minor, fw_build, fw_release;
6804 u32 req_sz;
6805 u32 rep_sz;
6806 u32 db;
6807 int r;
6808
6809 db = leapraid_readl(&adapter->iomem_base->db);
6810 if (db & LEAPRAID_DB_USED ||
6811 (db & LEAPRAID_DB_MASK) == LEAPRAID_DB_FAULT) {
6812 dev_err(&adapter->pdev->dev,
6813 "%s: Doorbell used or fault\n", __func__);
6814 return -EFAULT;
6815 }
6816
6817 if ((db & LEAPRAID_DB_MASK) != LEAPRAID_DB_READY &&
6818 (db & LEAPRAID_DB_MASK) != LEAPRAID_DB_OPERATIONAL &&
6819 !leapraid_wait_adapter_ready(adapter)) {
6820 dev_err(&adapter->pdev->dev,
6821 "%s: adapter not ready\n", __func__);
6822 return -EFAULT;
6823 }
6824
6825 req_sz = sizeof(struct leapraid_adapter_features_req);
6826 rep_sz = sizeof(struct leapraid_adapter_features_rep);
6827 memset(&leap_mpi_req, 0, req_sz);
6828 memset(&leap_mpi_rep, 0, rep_sz);
6829 leap_mpi_req.func = LEAPRAID_FUNC_GET_ADAPTER_FEATURES;
6830 r = leapraid_handshake_func(adapter,
6831 req_sz,
6832 (u32 *)&leap_mpi_req,
6833 rep_sz,
6834 (u16 *)&leap_mpi_rep);
6835 if (r) {
6836 dev_err(&adapter->pdev->dev,
6837 "%s %s: Handshake failed, r=%d\n",
6838 adapter->adapter_attr.name, __func__, r);
6839 return r;
6840 }
6841
6842 memset(&adapter->adapter_attr.features, 0,
6843 sizeof(struct leapraid_adapter_features));
6844 adapter->adapter_attr.features.req_slot =
6845 le16_to_cpu(leap_mpi_rep.req_slot);
6846 adapter->adapter_attr.features.hp_slot =
6847 le16_to_cpu(leap_mpi_rep.hp_slot);
6848 adapter->adapter_attr.features.adapter_caps =
6849 le32_to_cpu(leap_mpi_rep.adapter_caps);
6850 adapter->adapter_attr.features.max_msix_vectors =
6851 leap_mpi_rep.max_msix_vectors;
6852 adapter->adapter_attr.features.max_volumes =
6853 leap_mpi_rep.max_volumes;
6854 if (!adapter->adapter_attr.features.max_volumes)
6855 adapter->adapter_attr.features.max_volumes =
6856 LEAPRAID_MAX_VOLUMES_DEFAULT;
6857 adapter->adapter_attr.features.max_dev_handle =
6858 le16_to_cpu(leap_mpi_rep.max_dev_hdl);
6859 if (!adapter->adapter_attr.features.max_dev_handle)
6860 adapter->adapter_attr.features.max_dev_handle =
6861 LEAPRAID_MAX_DEV_HANDLE_DEFAULT;
6862 adapter->adapter_attr.features.min_dev_handle =
6863 le16_to_cpu(leap_mpi_rep.min_dev_hdl);
6864 if (adapter->adapter_attr.features.adapter_caps &
6865 LEAPRAID_ADAPTER_FEATURES_CAP_INTEGRATED_RAID)
6866 adapter->adapter_attr.raid_support = 1;
6867 adapter->adapter_attr.wideport_max_queue_depth =
6868 le16_to_cpu(leap_mpi_rep.sas_wide_max_qdepth) ?
6869 le16_to_cpu(leap_mpi_rep.sas_wide_max_qdepth) :
6870 LEAPRAID_SAS_QUEUE_DEPTH;
6871 adapter->adapter_attr.narrowport_max_queue_depth =
6872 le16_to_cpu(leap_mpi_rep.sas_narrow_max_qdepth) ?
6873 le16_to_cpu(leap_mpi_rep.sas_narrow_max_qdepth) :
6874 LEAPRAID_SAS_QUEUE_DEPTH;
6875 adapter->adapter_attr.sata_max_queue_depth =
6876 leap_mpi_rep.sata_max_qdepth ?
6877 leap_mpi_rep.sata_max_qdepth :
6878 LEAPRAID_SATA_QUEUE_DEPTH;
6879 adapter->adapter_attr.raid_volume_max_queue_depth =
6880 LEAPRAID_RAID_QUEUE_DEPTH;
6881 dev_info(&adapter->pdev->dev,
6882 "max: wp qd=%d, np qd=%d, SATA qd=%d, raid qd=%d\n",
6883 adapter->adapter_attr.wideport_max_queue_depth,
6884 adapter->adapter_attr.narrowport_max_queue_depth,
6885 adapter->adapter_attr.sata_max_queue_depth,
6886 adapter->adapter_attr.raid_volume_max_queue_depth);
6887 if (WARN_ON(!(adapter->adapter_attr.features.adapter_caps &
6888 LEAPRAID_ADAPTER_FEATURES_CAP_ATOMIC_REQ)))
6889 return -EFAULT;
6890 adapter->adapter_attr.features.fw_version =
6891 le32_to_cpu(leap_mpi_rep.fw_version);
6892
6893 fw_major = (adapter->adapter_attr.features.fw_version >>
6894 LEAPRAID_VER_MAJOR_SHIFT) & LEAPRAID_VER_MASK;
6895 fw_minor = (adapter->adapter_attr.features.fw_version >>
6896 LEAPRAID_VER_MINOR_SHIFT) & LEAPRAID_VER_MASK;
6897 fw_build = (adapter->adapter_attr.features.fw_version >>
6898 LEAPRAID_VER_BUILD_SHIFT) & LEAPRAID_VER_MASK;
6899 fw_release =
6900 adapter->adapter_attr.features.fw_version & LEAPRAID_VER_MASK;
6901
6902 dev_info(&adapter->pdev->dev,
6903 "Firmware version: %u.%u.%u.%u (0x%08x)\n",
6904 fw_major, fw_minor, fw_build, fw_release,
6905 adapter->adapter_attr.features.fw_version);
6906
6907 adapter->adapter_attr.features.msg_ver =
6908 le16_to_cpu(leap_mpi_rep.msg_ver);
6909 adapter->adapter_attr.features.product_id =
6910 le16_to_cpu(leap_mpi_rep.product_id);
6911 dev_info(&adapter->pdev->dev,
6912 "message version: 0x%x, product id 0x%x\n",
6913 adapter->adapter_attr.features.msg_ver,
6914 adapter->adapter_attr.features.product_id);
6915
6916 if (adapter->adapter_attr.features.msg_ver < 0x1000) {
6917 dev_err(&adapter->pdev->dev, "Device not supported\n");
6918 return -EFAULT;
6919 }
6920 adapter->shost->max_id = LEAPRAID_INVALID_INITIAL_VALUE;
6921
6922 return 0;
6923 }
6924
leapraid_disable_pcie(struct leapraid_adapter * adapter)6925 static inline void leapraid_disable_pcie(struct leapraid_adapter *adapter)
6926 {
6927 mutex_lock(&adapter->access_ctrl.pci_access_lock);
6928 if (adapter->iomem_base) {
6929 iounmap(adapter->iomem_base);
6930 adapter->iomem_base = NULL;
6931 }
6932 if (pci_is_enabled(adapter->pdev)) {
6933 pci_release_regions(adapter->pdev);
6934 pci_disable_device(adapter->pdev);
6935 }
6936 mutex_unlock(&adapter->access_ctrl.pci_access_lock);
6937 }
6938
leapraid_enable_pcie(struct leapraid_adapter * adapter)6939 static int leapraid_enable_pcie(struct leapraid_adapter *adapter)
6940 {
6941 u64 dma_mask;
6942 int rc;
6943
6944 rc = pci_enable_device(adapter->pdev);
6945 if (rc) {
6946 dev_err(&adapter->pdev->dev, "Failed to enable PCI device\n");
6947 return rc;
6948 }
6949
6950 rc = pci_request_regions(adapter->pdev, LEAPRAID_DRIVER_NAME);
6951 if (rc) {
6952 dev_err(&adapter->pdev->dev,
6953 "Failed to obtain PCI resources\n");
6954 return rc;
6955 }
6956
6957 if (sizeof(dma_addr_t) > 4) {
6958 dma_mask = DMA_BIT_MASK(DMA_64_BITS);
6959 adapter->adapter_attr.use_32_dma_mask = 0;
6960 } else {
6961 dma_mask = DMA_BIT_MASK(DMA_32_BITS);
6962 adapter->adapter_attr.use_32_dma_mask = 1;
6963 }
6964
6965 rc = dma_set_mask_and_coherent(&adapter->pdev->dev, dma_mask);
6966 if (rc) {
6967 dev_err(&adapter->pdev->dev,
6968 "Failed to set %lld DMA mask\n", dma_mask);
6969 return rc;
6970 }
6971 adapter->iomem_base = ioremap(pci_resource_start(adapter->pdev, 0),
6972 sizeof(struct leapraid_reg_base));
6973 if (!adapter->iomem_base) {
6974 dev_err(&adapter->pdev->dev,
6975 "Failed to map memory for controller registers\n");
6976 return -ENOMEM;
6977 }
6978
6979 pci_set_master(adapter->pdev);
6980
6981 return 0;
6982 }
6983
leapraid_cpus_on_irq(struct leapraid_adapter * adapter)6984 static void leapraid_cpus_on_irq(struct leapraid_adapter *adapter)
6985 {
6986 struct leapraid_int_rq *int_rq;
6987 unsigned int i, base_group, this_group;
6988 unsigned int cpu, nr_cpus, total_msix, index;
6989
6990 total_msix = adapter->notification_desc.iopoll_qdex;
6991 nr_cpus = num_online_cpus();
6992
6993 if (!nr_cpus || !total_msix)
6994 return;
6995 base_group = nr_cpus / total_msix;
6996
6997 cpu = cpumask_first(cpu_online_mask);
6998 for (index = 0; index < adapter->notification_desc.iopoll_qdex;
6999 index++) {
7000 int_rq = &adapter->notification_desc.int_rqs[index];
7001
7002 if (cpu >= adapter->notification_desc.msix_cpu_map_sz)
7003 break;
7004
7005 this_group = base_group +
7006 (index < (nr_cpus % total_msix) ? 1 : 0);
7007
7008 for (i = 0 ; i < this_group ; i++) {
7009 if (cpu >= adapter->notification_desc.msix_cpu_map_sz)
7010 break;
7011
7012 adapter->notification_desc.msix_cpu_map[cpu] =
7013 int_rq->rq.msix_idx;
7014 cpu = cpumask_next(cpu, cpu_online_mask);
7015 }
7016 }
7017 }
7018
leapraid_map_msix_to_cpu(struct leapraid_adapter * adapter)7019 static void leapraid_map_msix_to_cpu(struct leapraid_adapter *adapter)
7020 {
7021 struct leapraid_int_rq *int_rq;
7022 const cpumask_t *affinity_mask;
7023 int cpu;
7024 u32 i;
7025
7026 if (!adapter->adapter_attr.rq_cnt)
7027 return;
7028
7029 for (i = 0; i < adapter->notification_desc.iopoll_qdex; i++) {
7030 int_rq = &adapter->notification_desc.int_rqs[i];
7031 affinity_mask = pci_irq_get_affinity(adapter->pdev,
7032 int_rq->rq.msix_idx);
7033 if (!affinity_mask) {
7034 dev_warn(&adapter->pdev->dev,
7035 "%s: IRQ affinity NULL, msix_idx=%d\n",
7036 __func__, int_rq->rq.msix_idx);
7037 goto out_apply_irq_affinity;
7038 }
7039
7040 for_each_cpu_and(cpu, affinity_mask, cpu_online_mask) {
7041 if (cpu >= adapter->notification_desc.msix_cpu_map_sz)
7042 continue;
7043
7044 adapter->notification_desc.msix_cpu_map[cpu] =
7045 int_rq->rq.msix_idx;
7046 }
7047 }
7048 return;
7049 out_apply_irq_affinity:
7050 leapraid_cpus_on_irq(adapter);
7051 }
7052
leapraid_alloc_msix_cpu_map(struct leapraid_adapter * adapter)7053 static int leapraid_alloc_msix_cpu_map(struct leapraid_adapter *adapter)
7054 {
7055 adapter->notification_desc.msix_cpu_map_sz = nr_cpu_ids;
7056 adapter->notification_desc.msix_cpu_map =
7057 kzalloc(adapter->notification_desc.msix_cpu_map_sz,
7058 GFP_KERNEL);
7059 if (!adapter->notification_desc.msix_cpu_map)
7060 return -ENOMEM;
7061
7062 return 0;
7063 }
7064
leapraid_configure_reply_queue_affinity(struct leapraid_adapter * adapter)7065 static void leapraid_configure_reply_queue_affinity(
7066 struct leapraid_adapter *adapter)
7067 {
7068 if (!adapter || !adapter->notification_desc.msix_enable)
7069 return;
7070
7071 leapraid_map_msix_to_cpu(adapter);
7072 }
7073
leapraid_free_irq(struct leapraid_adapter * adapter)7074 static void leapraid_free_irq(struct leapraid_adapter *adapter)
7075 {
7076 struct leapraid_int_rq *int_rq;
7077 unsigned int i;
7078 int irq;
7079
7080 for (i = 0; adapter->notification_desc.int_rqs &&
7081 i < adapter->notification_desc.int_rqs_allocated; i++) {
7082 int_rq = &adapter->notification_desc.int_rqs[i];
7083 if (!int_rq)
7084 continue;
7085
7086 irq = pci_irq_vector(adapter->pdev, int_rq->rq.msix_idx);
7087 irq_set_affinity_hint(irq, NULL);
7088 free_irq(irq, &int_rq->rq);
7089 }
7090 adapter->notification_desc.int_rqs_allocated = 0;
7091
7092 if (adapter->notification_desc.irq_vectors_allocated) {
7093 pci_free_irq_vectors(adapter->pdev);
7094 adapter->notification_desc.irq_vectors_allocated = 0;
7095 }
7096
7097 adapter->notification_desc.msix_enable = 0;
7098
7099 kfree(adapter->notification_desc.blk_mq_poll_rqs);
7100 adapter->notification_desc.blk_mq_poll_rqs = NULL;
7101
7102 kfree(adapter->notification_desc.int_rqs);
7103 adapter->notification_desc.int_rqs = NULL;
7104
7105 kfree(adapter->notification_desc.msix_cpu_map);
7106 adapter->notification_desc.msix_cpu_map = NULL;
7107 adapter->notification_desc.msix_cpu_map_sz = 0;
7108 adapter->notification_desc.iopoll_qdex = 0;
7109 adapter->notification_desc.iopoll_qcnt = 0;
7110 }
7111
leapraid_setup_irqs(struct leapraid_adapter * adapter)7112 static int leapraid_setup_irqs(struct leapraid_adapter *adapter)
7113 {
7114 int irq_mode = adapter->notification_desc.irq_mode;
7115 unsigned int i;
7116 int rc = 0;
7117
7118 if (irq_mode == LEAPRAID_INTERRUPT_MODE_MSIX) {
7119 rc = pci_alloc_irq_vectors_affinity(
7120 adapter->pdev,
7121 adapter->notification_desc.iopoll_qdex,
7122 adapter->notification_desc.iopoll_qdex,
7123 PCI_IRQ_MSIX | PCI_IRQ_AFFINITY, NULL);
7124 if (rc < 0) {
7125 dev_err(&adapter->pdev->dev,
7126 "%d MSI/MSIX vectors allocated failed!\n",
7127 adapter->notification_desc.iopoll_qdex);
7128 return rc;
7129 }
7130
7131 adapter->notification_desc.irq_vectors_allocated = 1;
7132 }
7133
7134 for (i = 0; i < adapter->notification_desc.iopoll_qdex; i++) {
7135 adapter->notification_desc.int_rqs[i].rq.adapter = adapter;
7136 adapter->notification_desc.int_rqs[i].rq.msix_idx = i;
7137 atomic_set(&adapter->notification_desc.int_rqs[i].rq.busy, 0);
7138 if (irq_mode == LEAPRAID_INTERRUPT_MODE_MSIX)
7139 snprintf(adapter->notification_desc.int_rqs[i].rq.name,
7140 LEAPRAID_NAME_LENGTH, "%s%u-MSIx%u",
7141 LEAPRAID_DRIVER_NAME,
7142 adapter->adapter_attr.id, i);
7143 else if (irq_mode == LEAPRAID_INTERRUPT_MODE_MSI)
7144 snprintf(adapter->notification_desc.int_rqs[i].rq.name,
7145 LEAPRAID_NAME_LENGTH, "%s%u-MSI%u",
7146 LEAPRAID_DRIVER_NAME,
7147 adapter->adapter_attr.id, i);
7148
7149 rc = request_irq(pci_irq_vector(adapter->pdev, i),
7150 leapraid_irq_handler,
7151 IRQF_SHARED,
7152 adapter->notification_desc.int_rqs[i].rq.name,
7153 &adapter->notification_desc.int_rqs[i].rq);
7154 if (rc) {
7155 dev_err(&adapter->pdev->dev,
7156 "MSI/MSIx: request_irq %s failed!\n",
7157 adapter->notification_desc.int_rqs[i].rq.name);
7158 return rc;
7159 }
7160 adapter->notification_desc.int_rqs_allocated++;
7161 }
7162
7163 return 0;
7164 }
7165
leapraid_setup_legacy_int(struct leapraid_adapter * adapter)7166 static int leapraid_setup_legacy_int(struct leapraid_adapter *adapter)
7167 {
7168 int rc;
7169
7170 adapter->notification_desc.int_rqs[0].rq.adapter = adapter;
7171 adapter->notification_desc.int_rqs[0].rq.msix_idx = 0;
7172 atomic_set(&adapter->notification_desc.int_rqs[0].rq.busy, 0);
7173 snprintf(adapter->notification_desc.int_rqs[0].rq.name,
7174 LEAPRAID_NAME_LENGTH, "%s%d-LegacyInt",
7175 LEAPRAID_DRIVER_NAME, adapter->adapter_attr.id);
7176
7177 rc = pci_alloc_irq_vectors_affinity(
7178 adapter->pdev,
7179 adapter->notification_desc.iopoll_qdex,
7180 adapter->notification_desc.iopoll_qdex,
7181 PCI_IRQ_INTX | PCI_IRQ_AFFINITY,
7182 NULL);
7183 if (rc < 0) {
7184 dev_err(&adapter->pdev->dev,
7185 "Legacy irq allocated failed!\n");
7186 return rc;
7187 }
7188
7189 adapter->notification_desc.irq_vectors_allocated = 1;
7190 adapter->notification_desc.irq_mode = LEAPRAID_INTERRUPT_MODE_LEGACY;
7191 rc = request_irq(pci_irq_vector(adapter->pdev, 0),
7192 leapraid_irq_handler,
7193 IRQF_SHARED,
7194 adapter->notification_desc.int_rqs[0].rq.name,
7195 &adapter->notification_desc.int_rqs[0].rq);
7196 if (rc) {
7197 irq_set_affinity_hint(pci_irq_vector(adapter->pdev, 0), NULL);
7198 pci_free_irq_vectors(adapter->pdev);
7199 adapter->notification_desc.irq_vectors_allocated = 0;
7200 dev_err(&adapter->pdev->dev,
7201 "Legacy Int: request_irq %s failed!\n",
7202 adapter->notification_desc.int_rqs[0].rq.name);
7203 return -EBUSY;
7204 }
7205 adapter->notification_desc.int_rqs_allocated = 1;
7206 return rc;
7207 }
7208
leapraid_set_legacy_int(struct leapraid_adapter * adapter)7209 static int leapraid_set_legacy_int(struct leapraid_adapter *adapter)
7210 {
7211 int rc;
7212
7213 rc = leapraid_alloc_msix_cpu_map(adapter);
7214 if (rc)
7215 return rc;
7216
7217 adapter->adapter_attr.rq_cnt = 1;
7218 adapter->notification_desc.iopoll_qdex =
7219 adapter->adapter_attr.rq_cnt;
7220 adapter->notification_desc.iopoll_qcnt = 0;
7221 dev_info(&adapter->pdev->dev,
7222 "Legacy Intr: req queue cnt=%d intr=%d/poll=%d rep queues!\n",
7223 adapter->adapter_attr.rq_cnt,
7224 adapter->notification_desc.iopoll_qdex,
7225 adapter->notification_desc.iopoll_qcnt);
7226 adapter->notification_desc.int_rqs =
7227 kcalloc(adapter->notification_desc.iopoll_qdex,
7228 sizeof(struct leapraid_int_rq), GFP_KERNEL);
7229 if (!adapter->notification_desc.int_rqs)
7230 return -ENOMEM;
7231
7232 return leapraid_setup_legacy_int(adapter);
7233 }
7234
leapraid_set_msix(struct leapraid_adapter * adapter)7235 static int leapraid_set_msix(struct leapraid_adapter *adapter)
7236 {
7237 int iopoll_qcnt = 0;
7238 unsigned int i;
7239 int rc, msix_cnt;
7240
7241 msix_cnt = pci_msix_vec_count(adapter->pdev);
7242 if (msix_cnt <= 0 ||
7243 adapter->adapter_attr.features.max_msix_vectors == 0) {
7244 dev_info(&adapter->pdev->dev, "MSIX unsupported!\n");
7245 return -EOPNOTSUPP;
7246 }
7247
7248 msix_cnt = min_t(int, msix_cnt,
7249 adapter->adapter_attr.features.max_msix_vectors);
7250
7251 if (reset_devices)
7252 adapter->adapter_attr.rq_cnt = 1;
7253 else
7254 adapter->adapter_attr.rq_cnt = min_t(int,
7255 num_online_cpus(),
7256 msix_cnt);
7257
7258 if (max_msix_vectors > 0)
7259 adapter->adapter_attr.rq_cnt = min_t(
7260 int, max_msix_vectors, adapter->adapter_attr.rq_cnt);
7261
7262 if (adapter->adapter_attr.rq_cnt <= 1)
7263 adapter->shost->host_tagset = 0;
7264 if (adapter->shost->host_tagset) {
7265 iopoll_qcnt = poll_queues;
7266 if (iopoll_qcnt >= adapter->adapter_attr.rq_cnt)
7267 iopoll_qcnt = 0;
7268 }
7269 if (iopoll_qcnt) {
7270 adapter->notification_desc.blk_mq_poll_rqs =
7271 kcalloc(iopoll_qcnt,
7272 sizeof(struct leapraid_blk_mq_poll_rq),
7273 GFP_KERNEL);
7274 if (!adapter->notification_desc.blk_mq_poll_rqs)
7275 return -ENOMEM;
7276 adapter->adapter_attr.rq_cnt =
7277 min(adapter->adapter_attr.rq_cnt + iopoll_qcnt,
7278 msix_cnt);
7279 }
7280
7281 adapter->notification_desc.iopoll_qdex =
7282 adapter->adapter_attr.rq_cnt - iopoll_qcnt;
7283
7284 adapter->notification_desc.iopoll_qcnt = iopoll_qcnt;
7285 dev_info(&adapter->pdev->dev,
7286 "MSIx: req queue cnt=%d, intr=%d/poll=%d rep queues!\n",
7287 adapter->adapter_attr.rq_cnt,
7288 adapter->notification_desc.iopoll_qdex,
7289 adapter->notification_desc.iopoll_qcnt);
7290
7291 adapter->notification_desc.int_rqs =
7292 kcalloc(adapter->notification_desc.iopoll_qdex,
7293 sizeof(struct leapraid_int_rq), GFP_KERNEL);
7294 if (!adapter->notification_desc.int_rqs)
7295 return -ENOMEM;
7296
7297 for (i = 0; i < adapter->notification_desc.iopoll_qcnt; i++) {
7298 adapter->notification_desc.blk_mq_poll_rqs[i].rq.adapter =
7299 adapter;
7300 adapter->notification_desc.blk_mq_poll_rqs[i].rq.msix_idx =
7301 i + adapter->notification_desc.iopoll_qdex;
7302 atomic_set(
7303 &adapter->notification_desc.blk_mq_poll_rqs[i].rq.busy,
7304 0);
7305 snprintf(adapter->notification_desc.blk_mq_poll_rqs[i].rq.name,
7306 LEAPRAID_NAME_LENGTH,
7307 "%s%u-MQ-Poll%u", LEAPRAID_DRIVER_NAME,
7308 adapter->adapter_attr.id, i);
7309 atomic_set(&adapter->notification_desc.blk_mq_poll_rqs[i].busy,
7310 0);
7311 atomic_set(&adapter->notification_desc.blk_mq_poll_rqs[i].pause,
7312 0);
7313 }
7314
7315 rc = leapraid_alloc_msix_cpu_map(adapter);
7316 if (rc)
7317 return rc;
7318
7319 adapter->notification_desc.irq_mode = LEAPRAID_INTERRUPT_MODE_MSIX;
7320 adapter->notification_desc.msix_enable = 1;
7321 rc = leapraid_setup_irqs(adapter);
7322 if (rc) {
7323 leapraid_free_irq(adapter);
7324 adapter->notification_desc.msix_enable = 0;
7325 return rc;
7326 }
7327
7328 return 0;
7329 }
7330
leapraid_set_msi(struct leapraid_adapter * adapter)7331 static int leapraid_set_msi(struct leapraid_adapter *adapter)
7332 {
7333 int iopoll_qcnt = 0;
7334 unsigned int i;
7335 int rc, msi_cnt;
7336
7337 msi_cnt = pci_msi_vec_count(adapter->pdev);
7338 if (msi_cnt <= 0 ||
7339 adapter->adapter_attr.features.max_msix_vectors == 0) {
7340 dev_info(&adapter->pdev->dev, "MSI unsupported!\n");
7341 return -EOPNOTSUPP;
7342 }
7343
7344 msi_cnt = min_t(int, msi_cnt,
7345 adapter->adapter_attr.features.max_msix_vectors);
7346
7347 if (reset_devices)
7348 adapter->adapter_attr.rq_cnt = 1;
7349 else
7350 adapter->adapter_attr.rq_cnt = min_t(int,
7351 num_online_cpus(),
7352 msi_cnt);
7353
7354 if (max_msix_vectors > 0)
7355 adapter->adapter_attr.rq_cnt = min_t(
7356 int, max_msix_vectors, adapter->adapter_attr.rq_cnt);
7357
7358 if (adapter->adapter_attr.rq_cnt <= 1)
7359 adapter->shost->host_tagset = 0;
7360 if (adapter->shost->host_tagset) {
7361 iopoll_qcnt = poll_queues;
7362 if (iopoll_qcnt >= adapter->adapter_attr.rq_cnt)
7363 iopoll_qcnt = 0;
7364 }
7365
7366 if (iopoll_qcnt) {
7367 adapter->notification_desc.blk_mq_poll_rqs =
7368 kcalloc(iopoll_qcnt,
7369 sizeof(struct leapraid_blk_mq_poll_rq),
7370 GFP_KERNEL);
7371 if (!adapter->notification_desc.blk_mq_poll_rqs)
7372 return -ENOMEM;
7373
7374 adapter->adapter_attr.rq_cnt =
7375 min(adapter->adapter_attr.rq_cnt + iopoll_qcnt,
7376 msi_cnt);
7377 }
7378
7379 adapter->notification_desc.iopoll_qdex =
7380 adapter->adapter_attr.rq_cnt - iopoll_qcnt;
7381 rc = pci_alloc_irq_vectors_affinity(
7382 adapter->pdev,
7383 1,
7384 adapter->notification_desc.iopoll_qdex,
7385 PCI_IRQ_MSI | PCI_IRQ_AFFINITY, NULL);
7386 if (rc < 0) {
7387 dev_err(&adapter->pdev->dev,
7388 "%d MSI vectors allocated failed!\n",
7389 adapter->notification_desc.iopoll_qdex);
7390 leapraid_free_irq(adapter);
7391 return rc;
7392 }
7393 adapter->notification_desc.irq_vectors_allocated = 1;
7394 if (rc != adapter->notification_desc.iopoll_qdex) {
7395 adapter->notification_desc.iopoll_qdex = rc;
7396 adapter->adapter_attr.rq_cnt =
7397 adapter->notification_desc.iopoll_qdex + iopoll_qcnt;
7398 }
7399 adapter->notification_desc.iopoll_qcnt = iopoll_qcnt;
7400 dev_info(&adapter->pdev->dev,
7401 "MSI: req queue cnt=%d, intr=%d/poll=%d rep queues!\n",
7402 adapter->adapter_attr.rq_cnt,
7403 adapter->notification_desc.iopoll_qdex,
7404 adapter->notification_desc.iopoll_qcnt);
7405
7406 adapter->notification_desc.int_rqs =
7407 kcalloc(adapter->notification_desc.iopoll_qdex,
7408 sizeof(struct leapraid_int_rq),
7409 GFP_KERNEL);
7410 if (!adapter->notification_desc.int_rqs)
7411 return -ENOMEM;
7412
7413 for (i = 0; i < adapter->notification_desc.iopoll_qcnt; i++) {
7414 adapter->notification_desc.blk_mq_poll_rqs[i].rq.adapter =
7415 adapter;
7416 adapter->notification_desc.blk_mq_poll_rqs[i].rq.msix_idx =
7417 i + adapter->notification_desc.iopoll_qdex;
7418 atomic_set(
7419 &adapter->notification_desc.blk_mq_poll_rqs[i].rq.busy,
7420 0);
7421 snprintf(adapter->notification_desc.blk_mq_poll_rqs[i].rq.name,
7422 LEAPRAID_NAME_LENGTH,
7423 "%s%u-MQ-Poll%u", LEAPRAID_DRIVER_NAME,
7424 adapter->adapter_attr.id, i);
7425 atomic_set(
7426 &adapter->notification_desc.blk_mq_poll_rqs[i].busy,
7427 0);
7428 atomic_set(
7429 &adapter->notification_desc.blk_mq_poll_rqs[i].pause,
7430 0);
7431 }
7432
7433 rc = leapraid_alloc_msix_cpu_map(adapter);
7434 if (rc)
7435 return rc;
7436
7437 adapter->notification_desc.irq_mode = LEAPRAID_INTERRUPT_MODE_MSI;
7438 adapter->notification_desc.msix_enable = 1;
7439 rc = leapraid_setup_irqs(adapter);
7440 if (rc) {
7441 leapraid_free_irq(adapter);
7442 adapter->notification_desc.msix_enable = 0;
7443 return rc;
7444 }
7445
7446 return 0;
7447 }
7448
leapraid_set_notification_auto(struct leapraid_adapter * adapter)7449 static int leapraid_set_notification_auto(struct leapraid_adapter *adapter)
7450 {
7451 int rc;
7452
7453 rc = leapraid_set_msix(adapter);
7454 if (!rc)
7455 return 0;
7456
7457 leapraid_free_irq(adapter);
7458 dev_info(&adapter->pdev->dev,
7459 "MSI-X setup failed (%d), trying MSI\n", rc);
7460
7461 rc = leapraid_set_msi(adapter);
7462 if (!rc)
7463 return 0;
7464
7465 leapraid_free_irq(adapter);
7466 dev_info(&adapter->pdev->dev,
7467 "MSI setup failed (%d), back to legacy INTx\n", rc);
7468
7469 rc = leapraid_set_legacy_int(adapter);
7470 if (rc)
7471 dev_err(&adapter->pdev->dev,
7472 "%s: Enable legacy irq failed!\n", __func__);
7473
7474 return rc;
7475 }
7476
leapraid_set_pcie_and_notification(struct leapraid_adapter * adapter)7477 int leapraid_set_pcie_and_notification(struct leapraid_adapter *adapter)
7478 {
7479 int rc;
7480
7481 rc = leapraid_enable_pcie(adapter);
7482 if (rc)
7483 goto out_fail;
7484
7485 leapraid_mask_int(adapter);
7486
7487 rc = leapraid_make_adapter_ready(adapter, PART_RESET);
7488 if (rc) {
7489 dev_err(&adapter->pdev->dev, "Make adapter ready failure\n");
7490 goto out_fail;
7491 }
7492
7493 rc = leapraid_get_adapter_features(adapter);
7494 if (rc) {
7495 dev_err(&adapter->pdev->dev, "Get adapter feature failure\n");
7496 goto out_fail;
7497 }
7498
7499 rc = leapraid_set_notification_auto(adapter);
7500 if (rc)
7501 goto out_fail;
7502
7503 pci_save_state(adapter->pdev);
7504
7505 return 0;
7506
7507 out_fail:
7508 leapraid_free_irq(adapter);
7509 leapraid_disable_pcie(adapter);
7510 return rc;
7511 }
7512
leapraid_disable_controller(struct leapraid_adapter * adapter)7513 void leapraid_disable_controller(struct leapraid_adapter *adapter)
7514 {
7515 if (!adapter->iomem_base)
7516 return;
7517
7518 leapraid_mask_int(adapter);
7519
7520 adapter->access_ctrl.shost_recovering = 1;
7521 leapraid_make_adapter_ready(adapter, PART_RESET);
7522 adapter->access_ctrl.shost_recovering = 0;
7523 wake_up(&adapter->access_ctrl.recovery_waitq);
7524
7525 leapraid_free_irq(adapter);
7526 leapraid_disable_pcie(adapter);
7527 }
7528
leapraid_adapter_unit_reset(struct leapraid_adapter * adapter)7529 static int leapraid_adapter_unit_reset(struct leapraid_adapter *adapter)
7530 {
7531 int rc = 0;
7532
7533 writel(LEAPRAID_FUNC_ADAPTER_UNIT_RESET << LEAPRAID_DB_FUNC_SHIFT,
7534 &adapter->iomem_base->db);
7535 if (leapraid_db_wait_ack_and_clear_int(adapter))
7536 rc = -EFAULT;
7537
7538 if (!leapraid_wait_adapter_ready(adapter)) {
7539 dev_err(&adapter->pdev->dev, "unit reset failed\n");
7540 return -EFAULT;
7541 }
7542
7543 return rc;
7544 }
7545
leapraid_make_adapter_ready(struct leapraid_adapter * adapter,enum reset_type type)7546 static int leapraid_make_adapter_ready(struct leapraid_adapter *adapter,
7547 enum reset_type type)
7548 {
7549 u32 db;
7550 int count;
7551
7552 if (!leapraid_pci_active(adapter))
7553 return 0;
7554
7555 count = 0;
7556 db = leapraid_readl(&adapter->iomem_base->db);
7557 if ((db & LEAPRAID_DB_MASK) == LEAPRAID_DB_RESET) {
7558 while ((db & LEAPRAID_DB_MASK) != LEAPRAID_DB_READY) {
7559 if (count++ == LEAPRAID_DB_RETRY_COUNT_MAX) {
7560 dev_err(&adapter->pdev->dev,
7561 "Wait adapter ready timeout\n");
7562 return -EFAULT;
7563 }
7564 ssleep(1);
7565 db = leapraid_readl(&adapter->iomem_base->db);
7566 dev_info(&adapter->pdev->dev,
7567 "Wait adapter ready, count=%d, db=0x%x\n",
7568 count, db);
7569 }
7570 }
7571 if ((db & LEAPRAID_DB_MASK) == LEAPRAID_DB_READY)
7572 return 0;
7573
7574 if (db & LEAPRAID_DB_USED)
7575 goto full_reset;
7576
7577 if ((db & LEAPRAID_DB_MASK) == LEAPRAID_DB_FAULT)
7578 goto full_reset;
7579
7580 if (type == FULL_RESET)
7581 goto full_reset;
7582
7583 if ((db & LEAPRAID_DB_MASK) == LEAPRAID_DB_OPERATIONAL &&
7584 !leapraid_adapter_unit_reset(adapter))
7585 return 0;
7586
7587 full_reset:
7588 return leapraid_host_diag_reset(adapter);
7589 }
7590
leapraid_fw_log_exit(struct leapraid_adapter * adapter)7591 static void leapraid_fw_log_exit(struct leapraid_adapter *adapter)
7592 {
7593 if (!adapter->fw_log_desc.open_pcie_trace)
7594 return;
7595
7596 if (adapter->fw_log_desc.fw_log_buffer) {
7597 wait_event(adapter->fw_log_desc.mmap_waitq,
7598 !atomic_read(&adapter->fw_log_desc.mmap_refcnt));
7599 dma_free_coherent(&adapter->pdev->dev,
7600 (LEAPRAID_SYS_LOG_BUF_SIZE +
7601 LEAPRAID_SYS_LOG_BUF_RESERVE),
7602 adapter->fw_log_desc.fw_log_buffer,
7603 adapter->fw_log_desc.fw_log_buffer_dma);
7604 adapter->fw_log_desc.fw_log_buffer = NULL;
7605 }
7606 }
7607
leapraid_fw_log_init(struct leapraid_adapter * adapter)7608 static int leapraid_fw_log_init(struct leapraid_adapter *adapter)
7609 {
7610 struct leapraid_adapter_log_req adapter_log_req;
7611 struct leapraid_adapter_log_rep adapter_log_rep;
7612 u16 adapter_status;
7613 u64 buf_addr;
7614 u32 rc;
7615
7616 if (!adapter->fw_log_desc.open_pcie_trace)
7617 return 0;
7618
7619 if (!adapter->fw_log_desc.fw_log_buffer) {
7620 adapter->fw_log_desc.fw_log_buffer =
7621 dma_alloc_coherent(
7622 &adapter->pdev->dev,
7623 (LEAPRAID_SYS_LOG_BUF_SIZE +
7624 LEAPRAID_SYS_LOG_BUF_RESERVE),
7625 &adapter->fw_log_desc.fw_log_buffer_dma,
7626 GFP_KERNEL);
7627 if (!adapter->fw_log_desc.fw_log_buffer)
7628 return -ENOMEM;
7629 }
7630
7631 memset(&adapter_log_req, 0, sizeof(struct leapraid_adapter_log_req));
7632 adapter_log_req.func = LEAPRAID_FUNC_LOGBUF_INIT;
7633 buf_addr = adapter->fw_log_desc.fw_log_buffer_dma;
7634
7635 adapter_log_req.mbox.w[0] =
7636 cpu_to_le32((u32)(buf_addr & 0xFFFFFFFF));
7637 adapter_log_req.mbox.w[1] =
7638 cpu_to_le32((u32)((buf_addr >> 32) & 0xFFFFFFFF));
7639 adapter_log_req.mbox.w[2] =
7640 cpu_to_le32(LEAPRAID_SYS_LOG_BUF_SIZE);
7641 rc = leapraid_handshake_func(adapter,
7642 sizeof(struct leapraid_adapter_log_req),
7643 (u32 *)&adapter_log_req,
7644 sizeof(struct leapraid_adapter_log_rep),
7645 (u16 *)&adapter_log_rep);
7646 if (rc != 0) {
7647 dev_err(&adapter->pdev->dev, "%s: Handshake failed, rc=%d\n",
7648 __func__, rc);
7649 return rc;
7650 }
7651
7652 adapter_status = le16_to_cpu(adapter_log_rep.adapter_status) &
7653 LEAPRAID_ADAPTER_STATUS_MASK;
7654 if (adapter_status != LEAPRAID_ADAPTER_STATUS_SUCCESS) {
7655 dev_err(&adapter->pdev->dev, "%s: failed!\n", __func__);
7656 rc = -EIO;
7657 }
7658
7659 return rc;
7660 }
7661
leapraid_free_host_memory(struct leapraid_adapter * adapter)7662 static void leapraid_free_host_memory(struct leapraid_adapter *adapter)
7663 {
7664 unsigned int i;
7665
7666 if (adapter->mem_desc.task_desc) {
7667 dma_free_coherent(&adapter->pdev->dev,
7668 adapter->adapter_attr.task_desc_dma_size,
7669 adapter->mem_desc.task_desc,
7670 adapter->mem_desc.task_desc_dma);
7671 adapter->mem_desc.task_desc = NULL;
7672 }
7673
7674 if (adapter->mem_desc.sense_data) {
7675 dma_free_coherent(
7676 &adapter->pdev->dev,
7677 adapter->adapter_attr.io_qd * SCSI_SENSE_BUFFERSIZE,
7678 adapter->mem_desc.sense_data,
7679 adapter->mem_desc.sense_data_dma);
7680 adapter->mem_desc.sense_data = NULL;
7681 }
7682
7683 if (adapter->mem_desc.rep_msg) {
7684 dma_free_coherent(
7685 &adapter->pdev->dev,
7686 adapter->adapter_attr.rep_msg_qd * LEAPRAID_REPLY_SIZE,
7687 adapter->mem_desc.rep_msg,
7688 adapter->mem_desc.rep_msg_dma);
7689 adapter->mem_desc.rep_msg = NULL;
7690 }
7691
7692 if (adapter->mem_desc.rep_msg_addr) {
7693 dma_free_coherent(&adapter->pdev->dev,
7694 adapter->adapter_attr.rep_msg_qd *
7695 LEAPRAID_REP_MSG_ADDR_SIZE,
7696 adapter->mem_desc.rep_msg_addr,
7697 adapter->mem_desc.rep_msg_addr_dma);
7698 adapter->mem_desc.rep_msg_addr = NULL;
7699 }
7700
7701 if (adapter->mem_desc.rep_desc_seg_maint) {
7702 for (i = 0; i < adapter->adapter_attr.rep_desc_q_seg_cnt;
7703 i++) {
7704 if (adapter->mem_desc.rep_desc_seg_maint[i]
7705 .rep_desc_seg) {
7706 dma_free_coherent(
7707 &adapter->pdev->dev,
7708 (adapter->adapter_attr.rep_desc_qd *
7709 LEAPRAID_REP_DESC_ENTRY_SIZE) *
7710 LEAPRAID_REP_DESC_CHUNK_SIZE,
7711 adapter->mem_desc.rep_desc_seg_maint[i]
7712 .rep_desc_seg,
7713 adapter->mem_desc.rep_desc_seg_maint[i]
7714 .rep_desc_seg_dma);
7715 adapter->mem_desc.rep_desc_seg_maint[i]
7716 .rep_desc_seg = NULL;
7717 }
7718 }
7719
7720 if (adapter->mem_desc.rep_desc_q_arr) {
7721 dma_free_coherent(
7722 &adapter->pdev->dev,
7723 adapter->adapter_attr.rq_cnt *
7724 LEAPRAID_REP_RQ_CNT_SIZE,
7725 adapter->mem_desc.rep_desc_q_arr,
7726 adapter->mem_desc.rep_desc_q_arr_dma);
7727 adapter->mem_desc.rep_desc_q_arr = NULL;
7728 }
7729
7730 for (i = 0; i < adapter->adapter_attr.rep_desc_q_seg_cnt; i++) {
7731 struct leapraid_mem_desc *mem_desc =
7732 &adapter->mem_desc;
7733 kfree(adapter->mem_desc.rep_desc_seg_maint[i]
7734 .rep_desc_maint);
7735 mem_desc->rep_desc_seg_maint[i].rep_desc_maint = NULL;
7736 }
7737 kfree(adapter->mem_desc.rep_desc_seg_maint);
7738 adapter->mem_desc.rep_desc_seg_maint = NULL;
7739 }
7740
7741 kfree(adapter->mem_desc.taskid_to_uniq_tag);
7742 adapter->mem_desc.taskid_to_uniq_tag = NULL;
7743
7744 dma_pool_destroy(adapter->mem_desc.sg_chain_pool);
7745 adapter->mem_desc.sg_chain_pool = NULL;
7746 }
7747
leapraid_is_in_same_4g_seg(dma_addr_t start,u32 size)7748 static inline bool leapraid_is_in_same_4g_seg(dma_addr_t start, u32 size)
7749 {
7750 return upper_32_bits(start) == upper_32_bits(start + size - 1);
7751 }
7752
leapraid_internal_init_cmd_priv(struct leapraid_adapter * adapter,struct leapraid_io_req_tracker * io_tracker)7753 int leapraid_internal_init_cmd_priv(struct leapraid_adapter *adapter,
7754 struct leapraid_io_req_tracker *io_tracker)
7755 {
7756 io_tracker->chain =
7757 dma_pool_alloc(adapter->mem_desc.sg_chain_pool,
7758 GFP_KERNEL,
7759 &io_tracker->chain_dma);
7760
7761 if (!io_tracker->chain)
7762 return -ENOMEM;
7763
7764 return 0;
7765 }
7766
leapraid_internal_exit_cmd_priv(struct leapraid_adapter * adapter,struct leapraid_io_req_tracker * io_tracker)7767 void leapraid_internal_exit_cmd_priv(struct leapraid_adapter *adapter,
7768 struct leapraid_io_req_tracker *io_tracker)
7769 {
7770 if (io_tracker && io_tracker->chain)
7771 dma_pool_free(adapter->mem_desc.sg_chain_pool,
7772 io_tracker->chain,
7773 io_tracker->chain_dma);
7774 }
7775
leapraid_request_host_memory(struct leapraid_adapter * adapter)7776 static int leapraid_request_host_memory(struct leapraid_adapter *adapter)
7777 {
7778 struct leapraid_adapter_features *facts =
7779 &adapter->adapter_attr.features;
7780 u16 rep_desc_q_cnt_allocated;
7781 unsigned int i, j;
7782 int rc;
7783
7784 /* Scatter-gather table size. */
7785 adapter->shost->sg_tablesize = LEAPRAID_SG_DEPTH;
7786 if (reset_devices)
7787 adapter->shost->sg_tablesize =
7788 LEAPRAID_KDUMP_MIN_PHYS_SEGMENTS;
7789 /* High-priority commands queue depth. */
7790 adapter->dynamic_task_desc.hp_cmd_qd = LEAPRAID_FIXED_HP_CMDS;
7791 /* Internal commands queue depth. */
7792 adapter->dynamic_task_desc.inter_cmd_qd = LEAPRAID_FIXED_INTER_CMDS;
7793 /* Adapter commands total queue depth. */
7794 if (reset_devices)
7795 adapter->adapter_attr.adapter_total_qd =
7796 LEAPRAID_DEFAULT_CMD_QD_OFFSET +
7797 adapter->dynamic_task_desc.inter_cmd_qd +
7798 adapter->dynamic_task_desc.hp_cmd_qd;
7799 else
7800 adapter->adapter_attr.adapter_total_qd = facts->req_slot +
7801 adapter->dynamic_task_desc.hp_cmd_qd;
7802 /* Reply message queue depth. */
7803 adapter->adapter_attr.rep_msg_qd =
7804 adapter->adapter_attr.adapter_total_qd +
7805 LEAPRAID_DEFAULT_CMD_QD_OFFSET;
7806 /* Reply descriptor queue depth. */
7807 adapter->adapter_attr.rep_desc_qd =
7808 round_up(adapter->adapter_attr.adapter_total_qd +
7809 adapter->adapter_attr.rep_msg_qd +
7810 LEAPRAID_TASKID_OFFSET_CTRL_CMD,
7811 LEAPRAID_REPLY_QD_ALIGNMENT);
7812 /* SCSI command I/O depth. */
7813 adapter->adapter_attr.io_qd =
7814 adapter->adapter_attr.adapter_total_qd -
7815 adapter->dynamic_task_desc.hp_cmd_qd -
7816 adapter->dynamic_task_desc.inter_cmd_qd;
7817 /* SCSI host can queue. */
7818 adapter->shost->can_queue = adapter->adapter_attr.io_qd -
7819 LEAPRAID_TASKID_OFFSET_CTRL_CMD;
7820 adapter->driver_cmds.ctl_cmd.taskid = adapter->shost->can_queue +
7821 LEAPRAID_TASKID_OFFSET_CTRL_CMD;
7822
7823 /* Allocate task descriptor. */
7824 try_again:
7825 adapter->adapter_attr.task_desc_dma_size =
7826 (adapter->adapter_attr.adapter_total_qd +
7827 LEAPRAID_TASKID_OFFSET_CTRL_CMD) *
7828 LEAPRAID_REQUEST_SIZE;
7829 adapter->mem_desc.task_desc =
7830 dma_alloc_coherent(&adapter->pdev->dev,
7831 adapter->adapter_attr.task_desc_dma_size,
7832 &adapter->mem_desc.task_desc_dma,
7833 GFP_KERNEL);
7834 if (!adapter->mem_desc.task_desc)
7835 return -ENOMEM;
7836
7837 /* Allocate chain message pool. */
7838 adapter->mem_desc.sg_chain_pool_size =
7839 LEAPRAID_DEFAULT_CHAINS_PER_IO * LEAPRAID_CHAIN_SEG_SIZE;
7840 adapter->mem_desc.sg_chain_pool =
7841 dma_pool_create("leapraid chain pool",
7842 &adapter->pdev->dev,
7843 adapter->mem_desc.sg_chain_pool_size,
7844 LEAPRAID_DMA_ALIGN, 0);
7845 if (!adapter->mem_desc.sg_chain_pool)
7846 return -ENOMEM;
7847
7848 /* Allocate I/O tracker to SCSI I/O. */
7849 adapter->mem_desc.taskid_to_uniq_tag =
7850 kcalloc(adapter->shost->can_queue, sizeof(u16), GFP_KERNEL);
7851 if (!adapter->mem_desc.taskid_to_uniq_tag)
7852 return -ENOMEM;
7853
7854 adapter->dynamic_task_desc.hp_taskid =
7855 adapter->adapter_attr.io_qd +
7856 LEAPRAID_HP_TASKID_OFFSET_CTL_CMD;
7857 /* Allocate static high-priority task ID. */
7858 adapter->driver_cmds.ctl_cmd.hp_taskid =
7859 adapter->dynamic_task_desc.hp_taskid;
7860 adapter->driver_cmds.tm_cmd.hp_taskid =
7861 adapter->dynamic_task_desc.hp_taskid +
7862 LEAPRAID_HP_TASKID_OFFSET_TM_CMD;
7863
7864 adapter->dynamic_task_desc.inter_taskid =
7865 adapter->dynamic_task_desc.hp_taskid +
7866 adapter->dynamic_task_desc.hp_cmd_qd;
7867 adapter->driver_cmds.scan_dev_cmd.inter_taskid =
7868 adapter->dynamic_task_desc.inter_taskid;
7869 adapter->driver_cmds.cfg_op_cmd.inter_taskid =
7870 adapter->dynamic_task_desc.inter_taskid +
7871 LEAPRAID_TASKID_OFFSET_CFG_OP_CMD;
7872 adapter->driver_cmds.transport_cmd.inter_taskid =
7873 adapter->dynamic_task_desc.inter_taskid +
7874 LEAPRAID_TASKID_OFFSET_TRANSPORT_CMD;
7875 adapter->driver_cmds.enc_cmd.inter_taskid =
7876 adapter->dynamic_task_desc.inter_taskid +
7877 LEAPRAID_TASKID_OFFSET_ENC_CMD;
7878 adapter->driver_cmds.notify_event_cmd.inter_taskid =
7879 adapter->dynamic_task_desc.inter_taskid +
7880 LEAPRAID_TASKID_OFFSET_NOTIFY_EVENT_CMD;
7881 dev_info(&adapter->pdev->dev, "queue depth:\n");
7882 dev_info(&adapter->pdev->dev, " host->can_queue: %d\n",
7883 adapter->shost->can_queue);
7884 dev_info(&adapter->pdev->dev, " io_qd: %d\n",
7885 adapter->adapter_attr.io_qd);
7886 dev_info(&adapter->pdev->dev, " hpr_cmd_qd: %d\n",
7887 adapter->dynamic_task_desc.hp_cmd_qd);
7888 dev_info(&adapter->pdev->dev, " inter_cmd_qd: %d\n",
7889 adapter->dynamic_task_desc.inter_cmd_qd);
7890 dev_info(&adapter->pdev->dev, " adapter_total_qd: %d\n",
7891 adapter->adapter_attr.adapter_total_qd);
7892
7893 dev_info(&adapter->pdev->dev, "taskid range:\n");
7894 dev_info(&adapter->pdev->dev,
7895 " adapter->dynamic_task_desc.hp_taskid: %d\n",
7896 adapter->dynamic_task_desc.hp_taskid);
7897 dev_info(&adapter->pdev->dev,
7898 " adapter->dynamic_task_desc.inter_taskid: %d\n",
7899 adapter->dynamic_task_desc.inter_taskid);
7900
7901 /*
7902 * Allocate sense data DMA buffer.
7903 * Constraint: Must reside within the same 4GB segment
7904 * (driver-maintained).
7905 */
7906 adapter->mem_desc.sense_data =
7907 dma_alloc_coherent(
7908 &adapter->pdev->dev,
7909 adapter->adapter_attr.io_qd * SCSI_SENSE_BUFFERSIZE,
7910 &adapter->mem_desc.sense_data_dma,
7911 GFP_KERNEL);
7912 if (!adapter->mem_desc.sense_data)
7913 return -ENOMEM;
7914
7915 if (!leapraid_is_in_same_4g_seg(adapter->mem_desc.sense_data_dma,
7916 adapter->adapter_attr.io_qd *
7917 SCSI_SENSE_BUFFERSIZE)) {
7918 dev_warn(&adapter->pdev->dev,
7919 "Try 32bit DMA: Sense not in same 4G\n");
7920 rc = -EAGAIN;
7921 goto out_fail;
7922 }
7923
7924 /*
7925 * Allocate reply frame buffer.
7926 * Constraint: Must reside in the same 4GB segment as the sense DMA.
7927 */
7928 adapter->mem_desc.rep_msg =
7929 dma_alloc_coherent(&adapter->pdev->dev,
7930 adapter->adapter_attr.rep_msg_qd *
7931 LEAPRAID_REPLY_SIZE,
7932 &adapter->mem_desc.rep_msg_dma,
7933 GFP_KERNEL);
7934 if (!adapter->mem_desc.rep_msg) {
7935 rc = -ENOMEM;
7936 goto out_fail;
7937 }
7938
7939 if (!leapraid_is_in_same_4g_seg(adapter->mem_desc.rep_msg_dma,
7940 adapter->adapter_attr.rep_msg_qd *
7941 LEAPRAID_REPLY_SIZE)) {
7942 dev_warn(&adapter->pdev->dev,
7943 "Use 32 bit DMA due to rep msg is not in same 4g!\n");
7944 rc = -EAGAIN;
7945 goto out_fail;
7946 }
7947
7948 /* Address of reply frame. */
7949 adapter->mem_desc.rep_msg_addr =
7950 dma_alloc_coherent(&adapter->pdev->dev,
7951 adapter->adapter_attr.rep_msg_qd *
7952 LEAPRAID_REP_MSG_ADDR_SIZE,
7953 &adapter->mem_desc.rep_msg_addr_dma,
7954 GFP_KERNEL);
7955 if (!adapter->mem_desc.rep_msg_addr)
7956 return -ENOMEM;
7957 adapter->adapter_attr.rep_desc_q_seg_cnt =
7958 DIV_ROUND_UP(adapter->adapter_attr.rq_cnt,
7959 LEAPRAID_REP_DESC_CHUNK_SIZE);
7960 adapter->mem_desc.rep_desc_seg_maint =
7961 kcalloc(adapter->adapter_attr.rep_desc_q_seg_cnt,
7962 sizeof(struct leapraid_rep_desc_seg_maint),
7963 GFP_KERNEL);
7964 if (!adapter->mem_desc.rep_desc_seg_maint)
7965 return -ENOMEM;
7966
7967 rep_desc_q_cnt_allocated = 0;
7968 for (i = 0; i < adapter->adapter_attr.rep_desc_q_seg_cnt; i++) {
7969 adapter->mem_desc.rep_desc_seg_maint[i].rep_desc_maint =
7970 kcalloc(LEAPRAID_REP_DESC_CHUNK_SIZE,
7971 sizeof(struct leapraid_rep_desc_maint),
7972 GFP_KERNEL);
7973 if (!adapter->mem_desc.rep_desc_seg_maint[i].rep_desc_maint)
7974 return -ENOMEM;
7975
7976 adapter->mem_desc.rep_desc_seg_maint[i].rep_desc_seg =
7977 dma_alloc_coherent(
7978 &adapter->pdev->dev,
7979 (adapter->adapter_attr.rep_desc_qd *
7980 LEAPRAID_REP_DESC_ENTRY_SIZE) *
7981 LEAPRAID_REP_DESC_CHUNK_SIZE,
7982 &adapter->mem_desc.rep_desc_seg_maint[i]
7983 .rep_desc_seg_dma,
7984 GFP_KERNEL);
7985 if (!adapter->mem_desc.rep_desc_seg_maint[i].rep_desc_seg)
7986 return -ENOMEM;
7987
7988 for (j = 0; j < LEAPRAID_REP_DESC_CHUNK_SIZE; j++) {
7989 if (rep_desc_q_cnt_allocated >=
7990 adapter->adapter_attr.rq_cnt)
7991 break;
7992 adapter->mem_desc
7993 .rep_desc_seg_maint[i]
7994 .rep_desc_maint[j]
7995 .rep_desc =
7996 (void *)((u8 *)(
7997 adapter->mem_desc
7998 .rep_desc_seg_maint[i]
7999 .rep_desc_seg) +
8000 j *
8001 (adapter->adapter_attr.rep_desc_qd *
8002 LEAPRAID_REP_DESC_ENTRY_SIZE));
8003 adapter->mem_desc
8004 .rep_desc_seg_maint[i]
8005 .rep_desc_maint[j]
8006 .rep_desc_dma =
8007 adapter->mem_desc
8008 .rep_desc_seg_maint[i]
8009 .rep_desc_seg_dma +
8010 j *
8011 (adapter->adapter_attr.rep_desc_qd *
8012 LEAPRAID_REP_DESC_ENTRY_SIZE);
8013 rep_desc_q_cnt_allocated++;
8014 }
8015 }
8016
8017 if (!reset_devices) {
8018 adapter->mem_desc.rep_desc_q_arr =
8019 dma_alloc_coherent(
8020 &adapter->pdev->dev,
8021 adapter->adapter_attr.rq_cnt *
8022 LEAPRAID_REP_RQ_CNT_SIZE,
8023 &adapter->mem_desc.rep_desc_q_arr_dma,
8024 GFP_KERNEL);
8025 if (!adapter->mem_desc.rep_desc_q_arr)
8026 return -ENOMEM;
8027 }
8028
8029 return 0;
8030 out_fail:
8031 if (rc == -EAGAIN) {
8032 leapraid_free_host_memory(adapter);
8033 adapter->adapter_attr.use_32_dma_mask = 1;
8034 rc = dma_set_mask_and_coherent(&adapter->pdev->dev,
8035 DMA_BIT_MASK(DMA_32_BITS));
8036 if (rc) {
8037 dev_err(&adapter->pdev->dev,
8038 "Failed to set 32 DMA mask\n");
8039 return rc;
8040 }
8041 goto try_again;
8042 }
8043 return rc;
8044 }
8045
leapraid_alloc_dev_topo_bitmaps(struct leapraid_adapter * adapter)8046 static int leapraid_alloc_dev_topo_bitmaps(struct leapraid_adapter *adapter)
8047 {
8048 u16 pd_hdls_sz;
8049
8050 pd_hdls_sz =
8051 BITS_TO_LONGS(
8052 adapter->adapter_attr.features.max_dev_handle + 1) *
8053 sizeof(unsigned long);
8054
8055 adapter->dev_topo.pd_hdls_sz = pd_hdls_sz;
8056 adapter->dev_topo.pd_hdls =
8057 kzalloc(adapter->dev_topo.pd_hdls_sz, GFP_KERNEL);
8058 if (!adapter->dev_topo.pd_hdls)
8059 return -ENOMEM;
8060
8061 adapter->dev_topo.blocking_hdls =
8062 kzalloc(adapter->dev_topo.pd_hdls_sz, GFP_KERNEL);
8063 if (!adapter->dev_topo.blocking_hdls)
8064 return -ENOMEM;
8065
8066 return 0;
8067 }
8068
leapraid_free_dev_topo_bitmaps(struct leapraid_adapter * adapter)8069 static void leapraid_free_dev_topo_bitmaps(struct leapraid_adapter *adapter)
8070 {
8071 kfree(adapter->dev_topo.pd_hdls);
8072 kfree(adapter->dev_topo.blocking_hdls);
8073 }
8074
leapraid_init_driver_cmds(struct leapraid_adapter * adapter)8075 static int leapraid_init_driver_cmds(struct leapraid_adapter *adapter)
8076 {
8077 INIT_LIST_HEAD(&adapter->driver_cmds.special_cmd_list);
8078
8079 adapter->driver_cmds.scan_dev_cmd.status = LEAPRAID_CMD_NOT_USED;
8080 adapter->driver_cmds.scan_dev_cmd.cb_idx = LEAPRAID_SCAN_DEV_CB_IDX;
8081 list_add_tail(&adapter->driver_cmds.scan_dev_cmd.list,
8082 &adapter->driver_cmds.special_cmd_list);
8083
8084 adapter->driver_cmds.cfg_op_cmd.status = LEAPRAID_CMD_NOT_USED;
8085 adapter->driver_cmds.cfg_op_cmd.cb_idx = LEAPRAID_CONFIG_CB_IDX;
8086 mutex_init(&adapter->driver_cmds.cfg_op_cmd.mutex);
8087 list_add_tail(&adapter->driver_cmds.cfg_op_cmd.list,
8088 &adapter->driver_cmds.special_cmd_list);
8089
8090 adapter->driver_cmds.transport_cmd.status = LEAPRAID_CMD_NOT_USED;
8091 adapter->driver_cmds.transport_cmd.cb_idx = LEAPRAID_TRANSPORT_CB_IDX;
8092 mutex_init(&adapter->driver_cmds.transport_cmd.mutex);
8093 list_add_tail(&adapter->driver_cmds.transport_cmd.list,
8094 &adapter->driver_cmds.special_cmd_list);
8095
8096 adapter->driver_cmds.enc_cmd.status = LEAPRAID_CMD_NOT_USED;
8097 adapter->driver_cmds.enc_cmd.cb_idx = LEAPRAID_ENC_CB_IDX;
8098 mutex_init(&adapter->driver_cmds.enc_cmd.mutex);
8099 list_add_tail(&adapter->driver_cmds.enc_cmd.list,
8100 &adapter->driver_cmds.special_cmd_list);
8101
8102 adapter->driver_cmds.notify_event_cmd.status = LEAPRAID_CMD_NOT_USED;
8103 adapter->driver_cmds.notify_event_cmd.cb_idx =
8104 LEAPRAID_NOTIFY_EVENT_CB_IDX;
8105 mutex_init(&adapter->driver_cmds.notify_event_cmd.mutex);
8106 list_add_tail(&adapter->driver_cmds.notify_event_cmd.list,
8107 &adapter->driver_cmds.special_cmd_list);
8108
8109 adapter->driver_cmds.ctl_cmd.status = LEAPRAID_CMD_NOT_USED;
8110 adapter->driver_cmds.ctl_cmd.cb_idx = LEAPRAID_CTL_CB_IDX;
8111 mutex_init(&adapter->driver_cmds.ctl_cmd.mutex);
8112 list_add_tail(&adapter->driver_cmds.ctl_cmd.list,
8113 &adapter->driver_cmds.special_cmd_list);
8114
8115 adapter->driver_cmds.tm_cmd.status = LEAPRAID_CMD_NOT_USED;
8116 adapter->driver_cmds.tm_cmd.cb_idx = LEAPRAID_TM_CB_IDX;
8117 mutex_init(&adapter->driver_cmds.tm_cmd.mutex);
8118 list_add_tail(&adapter->driver_cmds.tm_cmd.list,
8119 &adapter->driver_cmds.special_cmd_list);
8120
8121 return 0;
8122 }
8123
leapraid_unmask_evts(struct leapraid_adapter * adapter,u16 evt)8124 static void leapraid_unmask_evts(struct leapraid_adapter *adapter, u16 evt)
8125 {
8126 if (evt >= LEAPRAID_MAX_EVENT_NUM)
8127 return;
8128
8129 clear_bit(evt, (unsigned long *)adapter->fw_evt_s.leapraid_evt_masks);
8130 }
8131
leapraid_init_event_mask(struct leapraid_adapter * adapter)8132 static void leapraid_init_event_mask(struct leapraid_adapter *adapter)
8133 {
8134 int i;
8135
8136 for (i = 0; i < LEAPRAID_EVT_MASK_COUNT; i++)
8137 adapter->fw_evt_s.leapraid_evt_masks[i] =
8138 LEAPRAID_INVALID_INITIAL_VALUE;
8139
8140 leapraid_unmask_evts(adapter, LEAPRAID_EVT_SAS_TOPO_CHANGE_LIST);
8141 leapraid_unmask_evts(adapter, LEAPRAID_EVT_SAS_ENCL_DEV_STATUS_CHANGE);
8142 leapraid_unmask_evts(adapter, LEAPRAID_EVT_SAS_DEV_STATUS_CHANGE);
8143 leapraid_unmask_evts(adapter, LEAPRAID_EVT_IR_CHANGE);
8144 }
8145
leapraid_prepare_adapter_init_req(struct leapraid_adapter * adapter,struct leapraid_adapter_init_req * init_req)8146 static void leapraid_prepare_adapter_init_req(
8147 struct leapraid_adapter *adapter,
8148 struct leapraid_adapter_init_req *init_req)
8149 {
8150 ktime_t cur_time;
8151 int i, chunk;
8152 u32 reply_post_free_ary_sz;
8153
8154 memset(init_req, 0, sizeof(struct leapraid_adapter_init_req));
8155 init_req->func = LEAPRAID_FUNC_ADAPTER_INIT;
8156 init_req->who_init = LEAPRAID_WHOINIT_LINUX_DRIVER;
8157 init_req->msg_ver = cpu_to_le16(LEAPRAID_MSG_VERSION);
8158 init_req->header_ver = cpu_to_le16(LEAPRAID_HEADER_VERSION);
8159 init_req->driver_ver =
8160 cpu_to_le32((LEAPRAID_MAJOR_VERSION <<
8161 LEAPRAID_VER_MAJOR_SHIFT) |
8162 (LEAPRAID_MINOR_VERSION << LEAPRAID_VER_MINOR_SHIFT) |
8163 (LEAPRAID_BUILD_VERSION << LEAPRAID_VER_BUILD_SHIFT) |
8164 LEAPRAID_RELEASE_VERSION);
8165 if (adapter->notification_desc.msix_enable)
8166 init_req->host_msix_vectors = adapter->adapter_attr.rq_cnt;
8167
8168 init_req->req_frame_size =
8169 cpu_to_le16(LEAPRAID_REQUEST_SIZE / LEAPRAID_DWORDS_BYTE_SIZE);
8170 init_req->rep_desc_qd =
8171 cpu_to_le16(adapter->adapter_attr.rep_desc_qd);
8172 init_req->rep_msg_qd =
8173 cpu_to_le16(adapter->adapter_attr.rep_msg_qd);
8174 init_req->sense_buffer_add_high =
8175 cpu_to_le32((u64)adapter->mem_desc.sense_data_dma >> 32);
8176 init_req->rep_msg_dma_high =
8177 cpu_to_le32((u64)adapter->mem_desc.rep_msg_dma >> 32);
8178 init_req->task_desc_base_addr =
8179 cpu_to_le64((u64)adapter->mem_desc.task_desc_dma);
8180 init_req->rep_msg_addr_dma =
8181 cpu_to_le64((u64)adapter->mem_desc.rep_msg_addr_dma);
8182 if (!reset_devices) {
8183 reply_post_free_ary_sz =
8184 adapter->adapter_attr.rq_cnt * LEAPRAID_REP_RQ_CNT_SIZE;
8185 memset(adapter->mem_desc.rep_desc_q_arr, 0,
8186 reply_post_free_ary_sz);
8187
8188 chunk = LEAPRAID_REP_DESC_CHUNK_SIZE;
8189 for (i = 0; i < adapter->adapter_attr.rq_cnt; i++)
8190 adapter->mem_desc.rep_desc_q_arr[i].rep_desc_base_addr =
8191 cpu_to_le64 ((u64)adapter->mem_desc
8192 .rep_desc_seg_maint[i / chunk]
8193 .rep_desc_maint[i % chunk]
8194 .rep_desc_dma);
8195
8196 init_req->msg_flg =
8197 LEAPRAID_ADAPTER_INIT_MSGFLG_RDPQ_ARRAY_MODE;
8198 init_req->rep_desc_q_arr_addr =
8199 cpu_to_le64((u64)adapter->mem_desc.rep_desc_q_arr_dma);
8200 } else {
8201 init_req->rep_desc_q_arr_addr =
8202 cpu_to_le64((u64)adapter->mem_desc
8203 .rep_desc_seg_maint[0]
8204 .rep_desc_maint[0]
8205 .rep_desc_dma);
8206 }
8207 cur_time = ktime_get_real();
8208 init_req->time_stamp = cpu_to_le64(ktime_to_ms(cur_time));
8209 }
8210
leapraid_send_adapter_init(struct leapraid_adapter * adapter)8211 static int leapraid_send_adapter_init(struct leapraid_adapter *adapter)
8212 {
8213 struct leapraid_adapter_init_req init_req;
8214 struct leapraid_adapter_init_rep init_rep;
8215 u16 adapter_status;
8216 int rc;
8217
8218 leapraid_prepare_adapter_init_req(adapter, &init_req);
8219
8220 rc = leapraid_handshake_func(adapter,
8221 sizeof(struct leapraid_adapter_init_req),
8222 (u32 *)&init_req,
8223 sizeof(struct leapraid_adapter_init_rep),
8224 (u16 *)&init_rep);
8225 if (rc != 0) {
8226 dev_err(&adapter->pdev->dev, "%s: Handshake failed, rc=%d\n",
8227 __func__, rc);
8228 return rc;
8229 }
8230
8231 adapter_status =
8232 le16_to_cpu(init_rep.adapter_status) &
8233 LEAPRAID_ADAPTER_STATUS_MASK;
8234 if (adapter_status != LEAPRAID_ADAPTER_STATUS_SUCCESS) {
8235 dev_err(&adapter->pdev->dev, "%s: failed\n", __func__);
8236 rc = -EIO;
8237 }
8238
8239 return rc;
8240 }
8241
leapraid_cfg_pages(struct leapraid_adapter * adapter)8242 static int leapraid_cfg_pages(struct leapraid_adapter *adapter)
8243 {
8244 union cfg_param_1 cfgp1 = {0};
8245 union cfg_param_2 cfgp2 = {0};
8246 union {
8247 struct leapraid_manufacturing_p0 manufacturing_page0;
8248 struct leapraid_bios_page3 bios_page3;
8249 struct leapraid_bios_page2 bios_page2;
8250 } cfg_page;
8251 int rc;
8252
8253 rc = leapraid_op_config_page(adapter, &cfg_page.bios_page3, cfgp1,
8254 cfgp2, GET_BIOS_PG3);
8255 if (rc)
8256 return rc;
8257
8258 adapter->adapter_attr.bios_version =
8259 le32_to_cpu(cfg_page.bios_page3.bios_version);
8260
8261 rc = leapraid_op_config_page(adapter, &cfg_page.bios_page2, cfgp1,
8262 cfgp2, GET_BIOS_PG2);
8263 if (rc)
8264 return rc;
8265
8266 adapter->boot_devs.requested_boot_dev.form =
8267 cfg_page.bios_page2.requested_boot_dev_form;
8268 memcpy(adapter->boot_devs.requested_boot_dev.pg_dev,
8269 &cfg_page.bios_page2.requested_boot_dev,
8270 LEAPRAID_BOOT_DEV_SIZE);
8271 adapter->boot_devs.requested_alt_boot_dev.form =
8272 cfg_page.bios_page2.requested_alt_boot_dev_form;
8273 memcpy(adapter->boot_devs.requested_alt_boot_dev.pg_dev,
8274 &cfg_page.bios_page2.requested_alt_boot_dev,
8275 LEAPRAID_BOOT_DEV_SIZE);
8276 adapter->boot_devs.current_boot_dev.form =
8277 cfg_page.bios_page2.current_boot_dev_form;
8278 memcpy(adapter->boot_devs.current_boot_dev.pg_dev,
8279 &cfg_page.bios_page2.current_boot_dev,
8280 LEAPRAID_BOOT_DEV_SIZE);
8281
8282 rc = leapraid_op_config_page(adapter, &cfg_page.manufacturing_page0,
8283 cfgp1, cfgp2, GET_MANUFACTURING_PG0);
8284 if (rc)
8285 return rc;
8286
8287 snprintf(adapter->adapter_attr.board_name,
8288 sizeof(adapter->adapter_attr.board_name),
8289 "%.*s",
8290 (int)sizeof(cfg_page.manufacturing_page0.board_name),
8291 cfg_page.manufacturing_page0.board_name);
8292 return rc;
8293 }
8294
leapraid_evt_notify(struct leapraid_adapter * adapter)8295 static int leapraid_evt_notify(struct leapraid_adapter *adapter)
8296 {
8297 struct leapraid_evt_notify_req *evt_notify_req;
8298 struct leapraid_evt_notify_rep *evt_notify_rep;
8299 u16 adapter_status;
8300 int rc = 0;
8301 int i;
8302
8303 mutex_lock(&adapter->driver_cmds.notify_event_cmd.mutex);
8304 adapter->driver_cmds.notify_event_cmd.status = LEAPRAID_CMD_PENDING;
8305 evt_notify_req =
8306 leapraid_get_task_desc(
8307 adapter,
8308 adapter->driver_cmds.notify_event_cmd.inter_taskid);
8309 memset(evt_notify_req, 0, sizeof(struct leapraid_evt_notify_req));
8310 evt_notify_req->func = LEAPRAID_FUNC_EVENT_NOTIFY;
8311 for (i = 0; i < LEAPRAID_EVT_MASK_COUNT; i++)
8312 evt_notify_req->evt_masks[i] =
8313 cpu_to_le32(adapter->fw_evt_s.leapraid_evt_masks[i]);
8314 init_completion(&adapter->driver_cmds.notify_event_cmd.done);
8315 leapraid_fire_task(adapter,
8316 adapter->driver_cmds.notify_event_cmd.inter_taskid);
8317 wait_for_completion_timeout(
8318 &adapter->driver_cmds.notify_event_cmd.done,
8319 LEAPRAID_NOTIFY_EVENT_CMD_TIMEOUT * HZ);
8320
8321 if (!(adapter->driver_cmds.notify_event_cmd.status &
8322 LEAPRAID_CMD_DONE)) {
8323 rc = -EFAULT;
8324 goto out_cleanup;
8325 }
8326
8327 if (!(adapter->driver_cmds.notify_event_cmd.status &
8328 LEAPRAID_CMD_REPLY_VALID)) {
8329 rc = -EFAULT;
8330 goto out_cleanup;
8331 }
8332
8333 evt_notify_rep = (void *)&adapter->driver_cmds.notify_event_cmd.reply;
8334 adapter_status = le16_to_cpu(evt_notify_rep->adapter_status) &
8335 LEAPRAID_ADAPTER_STATUS_MASK;
8336 if (adapter_status != LEAPRAID_ADAPTER_STATUS_SUCCESS)
8337 rc = -EFAULT;
8338
8339 out_cleanup:
8340 adapter->driver_cmds.notify_event_cmd.status = LEAPRAID_CMD_NOT_USED;
8341 mutex_unlock(&adapter->driver_cmds.notify_event_cmd.mutex);
8342
8343 return rc;
8344 }
8345
leapraid_scan_dev(struct leapraid_adapter * adapter,bool async_scan_dev)8346 int leapraid_scan_dev(struct leapraid_adapter *adapter, bool async_scan_dev)
8347 {
8348 struct leapraid_scan_dev_req *scan_dev_req;
8349 struct leapraid_scan_dev_rep *scan_dev_rep;
8350 u16 adapter_status;
8351 int rc = 0;
8352
8353 dev_info(&adapter->pdev->dev,
8354 "Send device scan, async_scan_dev=%d!\n", async_scan_dev);
8355
8356 adapter->driver_cmds.scan_dev_cmd.status = LEAPRAID_CMD_PENDING;
8357 adapter->driver_cmds.scan_dev_cmd.async_scan_dev = async_scan_dev;
8358 scan_dev_req =
8359 leapraid_get_task_desc(
8360 adapter,
8361 adapter->driver_cmds.scan_dev_cmd.inter_taskid);
8362 memset(scan_dev_req, 0, sizeof(struct leapraid_scan_dev_req));
8363 scan_dev_req->func = LEAPRAID_FUNC_SCAN_DEV;
8364
8365 if (async_scan_dev) {
8366 adapter->scan_dev_desc.first_scan_dev_fired = 1;
8367 leapraid_fire_task(
8368 adapter,
8369 adapter->driver_cmds.scan_dev_cmd.inter_taskid);
8370 return 0;
8371 }
8372
8373 init_completion(&adapter->driver_cmds.scan_dev_cmd.done);
8374 leapraid_fire_task(adapter,
8375 adapter->driver_cmds.scan_dev_cmd.inter_taskid);
8376 wait_for_completion_timeout(&adapter->driver_cmds.scan_dev_cmd.done,
8377 LEAPRAID_SCAN_DEV_CMD_TIMEOUT * HZ);
8378 if (!(adapter->driver_cmds.scan_dev_cmd.status & LEAPRAID_CMD_DONE)) {
8379 dev_err(&adapter->pdev->dev, "Device scan timeout!\n");
8380 if (adapter->driver_cmds.scan_dev_cmd.status &
8381 LEAPRAID_CMD_RESET)
8382 rc = -EFAULT;
8383 else
8384 rc = -ETIME;
8385 goto out_cleanup;
8386 }
8387
8388 scan_dev_rep = (void *)&adapter->driver_cmds.scan_dev_cmd.reply;
8389 adapter_status =
8390 le16_to_cpu(scan_dev_rep->adapter_status) &
8391 LEAPRAID_ADAPTER_STATUS_MASK;
8392 if (adapter_status != LEAPRAID_ADAPTER_STATUS_SUCCESS) {
8393 dev_err(&adapter->pdev->dev, "Device scan failure!\n");
8394 rc = -EFAULT;
8395 goto out_cleanup;
8396 }
8397
8398 out_cleanup:
8399 adapter->driver_cmds.scan_dev_cmd.status = LEAPRAID_CMD_NOT_USED;
8400 return rc;
8401 }
8402
leapraid_init_task_tracker(struct leapraid_adapter * adapter)8403 static void leapraid_init_task_tracker(struct leapraid_adapter *adapter)
8404 {
8405 unsigned long flags;
8406
8407 spin_lock_irqsave(&adapter->dynamic_task_desc.task_lock, flags);
8408
8409 spin_unlock_irqrestore(&adapter->dynamic_task_desc.task_lock, flags);
8410 }
8411
leapraid_init_rep_msg_addr(struct leapraid_adapter * adapter)8412 static void leapraid_init_rep_msg_addr(struct leapraid_adapter *adapter)
8413 {
8414 u32 reply_address;
8415 unsigned int i;
8416
8417 for (i = 0, reply_address = (u32)adapter->mem_desc.rep_msg_dma;
8418 i < adapter->adapter_attr.rep_msg_qd;
8419 i++, reply_address += LEAPRAID_REPLY_SIZE)
8420 adapter->mem_desc.rep_msg_addr[i] = cpu_to_le32(reply_address);
8421 }
8422
init_rep_desc(struct leapraid_rq * rq,int index,union leapraid_rep_desc_union * reply_post_free_contig)8423 static void init_rep_desc(
8424 struct leapraid_rq *rq,
8425 int index,
8426 union leapraid_rep_desc_union *reply_post_free_contig)
8427 {
8428 struct leapraid_adapter *adapter = rq->adapter;
8429 unsigned int i;
8430
8431 if (!reset_devices)
8432 rq->rep_desc =
8433 adapter->mem_desc
8434 .rep_desc_seg_maint[index /
8435 LEAPRAID_REP_DESC_CHUNK_SIZE]
8436 .rep_desc_maint[index %
8437 LEAPRAID_REP_DESC_CHUNK_SIZE]
8438 .rep_desc;
8439 else
8440 rq->rep_desc = reply_post_free_contig;
8441
8442 rq->rep_post_host_idx = 0;
8443 for (i = 0; i < adapter->adapter_attr.rep_desc_qd; i++)
8444 rq->rep_desc[i].words = cpu_to_le64(ULLONG_MAX);
8445 }
8446
leapraid_init_rep_desc(struct leapraid_adapter * adapter)8447 static void leapraid_init_rep_desc(struct leapraid_adapter *adapter)
8448 {
8449 union leapraid_rep_desc_union *reply_post_free_contig;
8450 struct leapraid_int_rq *int_rq;
8451 struct leapraid_blk_mq_poll_rq *blk_mq_poll_rq;
8452 unsigned int i;
8453 int index;
8454
8455 index = 0;
8456 reply_post_free_contig = adapter->mem_desc
8457 .rep_desc_seg_maint[0]
8458 .rep_desc_maint[0]
8459 .rep_desc;
8460
8461 for (i = 0; i < adapter->notification_desc.iopoll_qdex; i++) {
8462 int_rq = &adapter->notification_desc.int_rqs[i];
8463 init_rep_desc(&int_rq->rq, index, reply_post_free_contig);
8464 if (!reset_devices)
8465 index++;
8466 else
8467 reply_post_free_contig +=
8468 adapter->adapter_attr.rep_desc_qd;
8469 }
8470
8471 for (i = 0; i < adapter->notification_desc.iopoll_qcnt; i++) {
8472 blk_mq_poll_rq = &adapter->notification_desc.blk_mq_poll_rqs[i];
8473 init_rep_desc(&blk_mq_poll_rq->rq,
8474 index, reply_post_free_contig);
8475 if (!reset_devices)
8476 index++;
8477 else
8478 reply_post_free_contig +=
8479 adapter->adapter_attr.rep_desc_qd;
8480 }
8481 }
8482
leapraid_init_bar_idx_regs(struct leapraid_adapter * adapter)8483 static void leapraid_init_bar_idx_regs(struct leapraid_adapter *adapter)
8484 {
8485 struct leapraid_int_rq *int_rq;
8486 struct leapraid_blk_mq_poll_rq *blk_mq_poll_rq;
8487 unsigned int i, j;
8488
8489 adapter->rep_msg_host_idx = adapter->adapter_attr.rep_msg_qd - 1;
8490 writel(adapter->rep_msg_host_idx,
8491 &adapter->iomem_base->rep_msg_host_idx);
8492
8493 for (i = 0; i < adapter->notification_desc.iopoll_qdex; i++) {
8494 int_rq = &adapter->notification_desc.int_rqs[i];
8495 for (j = 0; j < REP_POST_HOST_IDX_REG_CNT; j++)
8496 writel((int_rq->rq.msix_idx & 7) <<
8497 LEAPRAID_RPHI_MSIX_IDX_SHIFT,
8498 &adapter->iomem_base->rep_post_reg_idx[j].idx);
8499 }
8500
8501 for (i = 0; i < adapter->notification_desc.iopoll_qcnt; i++) {
8502 blk_mq_poll_rq =
8503 &adapter->notification_desc.blk_mq_poll_rqs[i];
8504 for (j = 0; j < REP_POST_HOST_IDX_REG_CNT; j++)
8505 writel((blk_mq_poll_rq->rq.msix_idx & 7) <<
8506 LEAPRAID_RPHI_MSIX_IDX_SHIFT,
8507 &adapter->iomem_base->rep_post_reg_idx[j].idx);
8508 }
8509 }
8510
leapraid_make_adapter_available(struct leapraid_adapter * adapter)8511 static int leapraid_make_adapter_available(struct leapraid_adapter *adapter)
8512 {
8513 int rc;
8514
8515 leapraid_init_task_tracker(adapter);
8516 leapraid_init_rep_msg_addr(adapter);
8517
8518 if (adapter->scan_dev_desc.driver_loading)
8519 leapraid_configure_reply_queue_affinity(adapter);
8520
8521 leapraid_init_rep_desc(adapter);
8522 rc = leapraid_send_adapter_init(adapter);
8523 if (rc)
8524 return rc;
8525
8526 leapraid_init_bar_idx_regs(adapter);
8527 leapraid_unmask_int(adapter);
8528 rc = leapraid_cfg_pages(adapter);
8529 if (rc)
8530 return rc;
8531
8532 rc = leapraid_evt_notify(adapter);
8533 if (rc)
8534 return rc;
8535
8536 if (!adapter->access_ctrl.shost_recovering) {
8537 adapter->scan_dev_desc.wait_scan_dev_done = 1;
8538 return 0;
8539 }
8540
8541 return leapraid_scan_dev(adapter, false);
8542 }
8543
leapraid_ctrl_init(struct leapraid_adapter * adapter)8544 int leapraid_ctrl_init(struct leapraid_adapter *adapter)
8545 {
8546 u32 cap;
8547 int rc;
8548
8549 rc = leapraid_init_driver_cmds(adapter);
8550 if (rc) {
8551 dev_err(&adapter->pdev->dev, "Init driver cmds failure\n");
8552 goto out_free;
8553 }
8554
8555 rc = leapraid_set_pcie_and_notification(adapter);
8556 if (rc)
8557 goto out_free;
8558
8559 pci_set_drvdata(adapter->pdev, adapter->shost);
8560
8561 pcie_capability_read_dword(adapter->pdev, PCI_EXP_DEVCAP, &cap);
8562
8563 if (cap & PCI_EXP_DEVCAP_EXT_TAG)
8564 pcie_capability_set_word(adapter->pdev, PCI_EXP_DEVCTL,
8565 PCI_EXP_DEVCTL_EXT_TAG);
8566
8567 rc = leapraid_fw_log_init(adapter);
8568 if (rc) {
8569 dev_err(&adapter->pdev->dev, "FW log init failure\n");
8570 goto out_free;
8571 }
8572
8573 rc = leapraid_request_host_memory(adapter);
8574 if (rc) {
8575 dev_err(&adapter->pdev->dev, "Request host memory failure\n");
8576 goto out_free;
8577 }
8578
8579 init_waitqueue_head(&adapter->reset_desc.reset_wait_queue);
8580 init_waitqueue_head(&adapter->access_ctrl.shost_recover_wq);
8581
8582 rc = leapraid_alloc_dev_topo_bitmaps(adapter);
8583 if (rc) {
8584 dev_err(&adapter->pdev->dev, "Alloc topo bitmaps failure\n");
8585 goto out_free;
8586 }
8587
8588 leapraid_init_event_mask(adapter);
8589
8590 rc = leapraid_make_adapter_available(adapter);
8591 if (rc) {
8592 dev_err(&adapter->pdev->dev,
8593 "Make adapter available failure\n");
8594 goto out_free;
8595 }
8596
8597 leapraid_overheat_init(adapter);
8598 if (!adapter->overheat_desc.fault_overheat_wq) {
8599 rc = -ENOMEM;
8600 goto out_free;
8601 }
8602
8603 return 0;
8604
8605 out_free:
8606 adapter->access_ctrl.host_removing = 1;
8607 leapraid_fw_log_exit(adapter);
8608 leapraid_disable_controller(adapter);
8609 leapraid_free_host_memory(adapter);
8610 leapraid_free_dev_topo_bitmaps(adapter);
8611 pci_set_drvdata(adapter->pdev, NULL);
8612 return rc;
8613 }
8614
leapraid_remove_ctrl(struct leapraid_adapter * adapter)8615 void leapraid_remove_ctrl(struct leapraid_adapter *adapter)
8616 {
8617 leapraid_overheat_cleanup(adapter);
8618 leapraid_check_scheduled_fault_stop(adapter);
8619 leapraid_fw_log_stop(adapter);
8620 leapraid_fw_log_exit(adapter);
8621 leapraid_disable_controller(adapter);
8622 leapraid_free_host_memory(adapter);
8623 leapraid_free_dev_topo_bitmaps(adapter);
8624 leapraid_free_enc_list(adapter);
8625 pci_set_drvdata(adapter->pdev, NULL);
8626 }
8627