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 = kzalloc_obj(*fw_evt, GFP_ATOMIC);
2988
2989 if (fw_evt)
2990 kref_init(&fw_evt->refcnt);
2991
2992 return fw_evt;
2993 }
2994
leapraid_run_fw_evt_work(struct work_struct * work)2995 static void leapraid_run_fw_evt_work(struct work_struct *work)
2996 {
2997 struct leapraid_fw_evt_work *fw_evt =
2998 container_of(work, struct leapraid_fw_evt_work, work);
2999
3000 leapraid_fw_work(fw_evt->adapter, fw_evt);
3001 }
3002
leapraid_fw_evt_add(struct leapraid_adapter * adapter,struct leapraid_fw_evt_work * fw_evt)3003 static void leapraid_fw_evt_add(struct leapraid_adapter *adapter,
3004 struct leapraid_fw_evt_work *fw_evt)
3005 {
3006 unsigned long flags;
3007
3008 spin_lock_irqsave(&adapter->fw_evt_s.fw_evt_lock, flags);
3009 if (adapter->access_ctrl.host_removing ||
3010 adapter->access_ctrl.pcie_recovering ||
3011 !adapter->fw_evt_s.fw_evt_thread) {
3012 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags);
3013 return;
3014 }
3015
3016 leapraid_fw_evt_get(fw_evt);
3017 INIT_LIST_HEAD(&fw_evt->list);
3018 list_add_tail(&fw_evt->list, &adapter->fw_evt_s.fw_evt_list);
3019 INIT_WORK(&fw_evt->work, leapraid_run_fw_evt_work);
3020 leapraid_fw_evt_get(fw_evt);
3021 queue_work(adapter->fw_evt_s.fw_evt_thread, &fw_evt->work);
3022 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags);
3023 }
3024
leapraid_del_fw_evt_from_list(struct leapraid_adapter * adapter,struct leapraid_fw_evt_work * fw_evt)3025 static void leapraid_del_fw_evt_from_list(struct leapraid_adapter *adapter,
3026 struct leapraid_fw_evt_work *fw_evt)
3027 {
3028 unsigned long flags;
3029
3030 spin_lock_irqsave(&adapter->fw_evt_s.fw_evt_lock, flags);
3031 if (!list_empty(&fw_evt->list)) {
3032 list_del_init(&fw_evt->list);
3033 leapraid_fw_evt_put(fw_evt);
3034 }
3035 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags);
3036 }
3037
leapraid_next_fw_evt(struct leapraid_adapter * adapter)3038 static struct leapraid_fw_evt_work *leapraid_next_fw_evt(
3039 struct leapraid_adapter *adapter)
3040 {
3041 struct leapraid_fw_evt_work *fw_evt = NULL;
3042 unsigned long flags;
3043
3044 spin_lock_irqsave(&adapter->fw_evt_s.fw_evt_lock, flags);
3045 if (!list_empty(&adapter->fw_evt_s.fw_evt_list)) {
3046 fw_evt = list_first_entry(&adapter->fw_evt_s.fw_evt_list,
3047 struct leapraid_fw_evt_work, list);
3048 list_del_init(&fw_evt->list);
3049 }
3050 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags);
3051 return fw_evt;
3052 }
3053
leapraid_clean_active_fw_evt(struct leapraid_adapter * adapter)3054 void leapraid_clean_active_fw_evt(struct leapraid_adapter *adapter)
3055 {
3056 struct leapraid_fw_evt_work *fw_evt;
3057 unsigned long flags;
3058 bool in_fw_evt_context;
3059 bool rc;
3060
3061 if ((list_empty(&adapter->fw_evt_s.fw_evt_list) &&
3062 !adapter->fw_evt_s.cur_evt) || !adapter->fw_evt_s.fw_evt_thread)
3063 return;
3064
3065 adapter->fw_evt_s.fw_evt_cleanup = 1;
3066 if (adapter->access_ctrl.shost_recovering &&
3067 adapter->fw_evt_s.cur_evt)
3068 adapter->fw_evt_s.cur_evt->ignore = 1;
3069
3070 while ((fw_evt = leapraid_next_fw_evt(adapter))) {
3071 rc = cancel_work_sync(&fw_evt->work);
3072 if (rc)
3073 leapraid_fw_evt_put(fw_evt);
3074 leapraid_fw_evt_put(fw_evt);
3075 }
3076
3077 spin_lock_irqsave(&adapter->fw_evt_s.fw_evt_lock, flags);
3078 fw_evt = adapter->fw_evt_s.cur_evt;
3079 if (fw_evt) {
3080 in_fw_evt_context = adapter->fw_evt_s.cur_evt_task == current;
3081 leapraid_fw_evt_get(fw_evt);
3082 }
3083 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags);
3084 if (fw_evt) {
3085 if (!in_fw_evt_context)
3086 cancel_work_sync(&fw_evt->work);
3087 leapraid_fw_evt_put(fw_evt);
3088 }
3089
3090 adapter->fw_evt_s.fw_evt_cleanup = 0;
3091 }
3092
leapraid_internal_dev_ublk(struct scsi_device * sdev,struct leapraid_sdev_priv * sdev_priv)3093 static void leapraid_internal_dev_ublk(struct scsi_device *sdev,
3094 struct leapraid_sdev_priv *sdev_priv)
3095 {
3096 int rc;
3097
3098 sdev_printk(KERN_WARNING, sdev,
3099 "hdl 0x%04x: Now internal unblkg dev\n",
3100 sdev_priv->starget_priv->hdl);
3101 sdev_priv->block = 0;
3102 rc = scsi_internal_device_unblock_nowait(sdev, SDEV_RUNNING);
3103 if (rc == -EINVAL) {
3104 sdev_printk(KERN_WARNING, sdev,
3105 "hdl 0x%04x: unblkg failed, rc=%d\n",
3106 sdev_priv->starget_priv->hdl, rc);
3107 sdev_priv->block = 1;
3108 rc = scsi_internal_device_block_nowait(sdev);
3109 if (rc)
3110 sdev_printk(KERN_WARNING, sdev,
3111 "hdl 0x%04x: Earlier ublkg err, rc=%d\n",
3112 sdev_priv->starget_priv->hdl, rc);
3113
3114 sdev_priv->block = 0;
3115 rc = scsi_internal_device_unblock_nowait(sdev, SDEV_RUNNING);
3116 if (rc)
3117 sdev_printk(KERN_WARNING, sdev,
3118 "hdl 0x%04x: ublkg failed again, rc=%d\n",
3119 sdev_priv->starget_priv->hdl, rc);
3120 }
3121 }
3122
leapraid_ublk_io_dev(struct leapraid_adapter * adapter,u64 sas_addr,struct leapraid_card_port * card_port)3123 static void leapraid_ublk_io_dev(struct leapraid_adapter *adapter,
3124 u64 sas_addr,
3125 struct leapraid_card_port *card_port)
3126 {
3127 struct leapraid_sdev_priv *sdev_priv;
3128 struct scsi_device *sdev;
3129
3130 shost_for_each_device(sdev, adapter->shost) {
3131 sdev_priv = sdev->hostdata;
3132 if (!sdev_priv || !sdev_priv->starget_priv)
3133 continue;
3134
3135 if (sdev_priv->starget_priv->sas_address != sas_addr)
3136 continue;
3137
3138 if (sdev_priv->starget_priv->card_port != card_port)
3139 continue;
3140
3141 if (sdev_priv->block)
3142 leapraid_internal_dev_ublk(sdev, sdev_priv);
3143
3144 scsi_device_set_state(sdev, SDEV_OFFLINE);
3145 }
3146 }
3147
leapraid_ublk_io_all_dev(struct leapraid_adapter * adapter)3148 static void leapraid_ublk_io_all_dev(struct leapraid_adapter *adapter)
3149 {
3150 struct leapraid_sdev_priv *sdev_priv;
3151 struct leapraid_starget_priv *stgt_priv;
3152 struct scsi_device *sdev;
3153
3154 shost_for_each_device(sdev, adapter->shost) {
3155 sdev_priv = sdev->hostdata;
3156
3157 if (!sdev_priv)
3158 continue;
3159
3160 stgt_priv = sdev_priv->starget_priv;
3161 if (!stgt_priv || stgt_priv->deleted)
3162 continue;
3163
3164 if (!sdev_priv->block)
3165 continue;
3166
3167 sdev_printk(KERN_WARNING, sdev, "hdl 0x%04x: blkg...\n",
3168 sdev_priv->starget_priv->hdl);
3169 leapraid_internal_dev_ublk(sdev, sdev_priv);
3170 continue;
3171 }
3172 }
3173
leapraid_internal_dev_blk(struct scsi_device * sdev,struct leapraid_sdev_priv * sdev_priv)3174 static void leapraid_internal_dev_blk(
3175 struct scsi_device *sdev,
3176 struct leapraid_sdev_priv *sdev_priv)
3177 {
3178 int rc;
3179
3180 sdev_printk(KERN_INFO, sdev, "Internal blkg hdl 0x%04x\n",
3181 sdev_priv->starget_priv->hdl);
3182 sdev_priv->block = 1;
3183 rc = scsi_internal_device_block_nowait(sdev);
3184 if (rc == -EINVAL)
3185 sdev_printk(KERN_WARNING, sdev,
3186 "hdl 0x%04x: blkg failed, rc=%d\n",
3187 rc, sdev_priv->starget_priv->hdl);
3188 }
3189
leapraid_imm_blkio_to_end_dev(struct leapraid_adapter * adapter,struct leapraid_sas_port * sas_port)3190 static void leapraid_imm_blkio_to_end_dev(struct leapraid_adapter *adapter,
3191 struct leapraid_sas_port *sas_port)
3192 {
3193 struct leapraid_sdev_priv *sdev_priv;
3194 struct leapraid_sas_dev *sas_dev;
3195 struct scsi_device *sdev;
3196 unsigned long flags;
3197
3198 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags);
3199 sas_dev = leapraid_hold_lock_get_sas_dev_by_addr(
3200 adapter,
3201 sas_port->remote_identify.sas_address,
3202 sas_port->card_port);
3203
3204 if (sas_dev) {
3205 shost_for_each_device(sdev, adapter->shost) {
3206 sdev_priv = sdev->hostdata;
3207 if (!sdev_priv)
3208 continue;
3209
3210 if (sdev_priv->starget_priv->hdl != sas_dev->hdl)
3211 continue;
3212
3213 if (sdev_priv->block)
3214 continue;
3215
3216 if (sas_dev && sas_dev->pend_sas_rphy_add)
3217 continue;
3218
3219 if (sdev_priv->sep) {
3220 sdev_printk(KERN_INFO, sdev,
3221 "skip dev blk: sep hdl 0x%04x\n",
3222 sdev_priv->starget_priv->hdl);
3223 continue;
3224 }
3225
3226 leapraid_internal_dev_blk(sdev, sdev_priv);
3227 }
3228
3229 leapraid_sdev_put(sas_dev);
3230 }
3231 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags);
3232 }
3233
leapraid_imm_blkio_set_end_dev_blk_hdls(struct leapraid_adapter * adapter,struct leapraid_topo_node * topo_node_exp)3234 static void leapraid_imm_blkio_set_end_dev_blk_hdls(
3235 struct leapraid_adapter *adapter,
3236 struct leapraid_topo_node *topo_node_exp)
3237 {
3238 struct leapraid_sas_port *sas_port;
3239
3240 list_for_each_entry(sas_port,
3241 &topo_node_exp->sas_port_list, port_list) {
3242 if (sas_port->remote_identify.device_type == SAS_END_DEVICE)
3243 leapraid_imm_blkio_to_end_dev(adapter, sas_port);
3244 }
3245 }
3246
3247 static void leapraid_imm_blkio_to_kids_attchd_to_ex(
3248 struct leapraid_adapter *adapter,
3249 struct leapraid_topo_node *topo_node_exp);
3250
leapraid_imm_blkio_to_sib_exp(struct leapraid_adapter * adapter,struct leapraid_topo_node * topo_node_exp)3251 static void leapraid_imm_blkio_to_sib_exp(
3252 struct leapraid_adapter *adapter,
3253 struct leapraid_topo_node *topo_node_exp)
3254 {
3255 struct leapraid_topo_node *topo_node_exp_sib;
3256 struct leapraid_sas_port *sas_port;
3257
3258 list_for_each_entry(sas_port,
3259 &topo_node_exp->sas_port_list, port_list) {
3260 if (sas_port->remote_identify.device_type ==
3261 SAS_EDGE_EXPANDER_DEVICE ||
3262 sas_port->remote_identify.device_type ==
3263 SAS_FANOUT_EXPANDER_DEVICE) {
3264 topo_node_exp_sib =
3265 leapraid_exp_find_by_sas_address(
3266 adapter,
3267 sas_port->remote_identify.sas_address,
3268 sas_port->card_port);
3269 leapraid_imm_blkio_to_kids_attchd_to_ex(
3270 adapter,
3271 topo_node_exp_sib);
3272 }
3273 }
3274 }
3275
leapraid_imm_blkio_to_kids_attchd_to_ex(struct leapraid_adapter * adapter,struct leapraid_topo_node * topo_node_exp)3276 static void leapraid_imm_blkio_to_kids_attchd_to_ex(
3277 struct leapraid_adapter *adapter,
3278 struct leapraid_topo_node *topo_node_exp)
3279 {
3280 if (!topo_node_exp)
3281 return;
3282
3283 leapraid_imm_blkio_set_end_dev_blk_hdls(adapter, topo_node_exp);
3284
3285 leapraid_imm_blkio_to_sib_exp(adapter, topo_node_exp);
3286 }
3287
leapraid_report_sdev_directly(struct leapraid_adapter * adapter,struct leapraid_sas_dev * sas_dev)3288 static void leapraid_report_sdev_directly(struct leapraid_adapter *adapter,
3289 struct leapraid_sas_dev *sas_dev)
3290 {
3291 struct leapraid_sas_port *sas_port;
3292
3293 sas_port = leapraid_transport_port_add(adapter,
3294 sas_dev->hdl,
3295 sas_dev->parent_sas_addr,
3296 sas_dev->card_port);
3297 if (!sas_port) {
3298 leapraid_sas_dev_remove(adapter, sas_dev);
3299 return;
3300 }
3301
3302 if (!sas_dev->starget) {
3303 if (!adapter->scan_dev_desc.driver_loading) {
3304 leapraid_transport_port_remove(
3305 adapter,
3306 sas_dev->sas_addr,
3307 sas_dev->parent_sas_addr,
3308 sas_dev->card_port);
3309 leapraid_sas_dev_remove(adapter, sas_dev);
3310 }
3311 return;
3312 }
3313 }
3314
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)3315 static struct leapraid_sas_dev *leapraid_init_sas_dev(
3316 struct leapraid_adapter *adapter,
3317 struct leapraid_sas_dev_p0 *sas_dev_pg0,
3318 struct leapraid_card_port *card_port, u16 hdl,
3319 u64 parent_sas_addr, u64 sas_addr, u32 dev_info)
3320 {
3321 struct leapraid_sas_dev *sas_dev;
3322 struct leapraid_enc_node *enc_dev;
3323 unsigned long flags;
3324
3325 sas_dev = kzalloc_obj(*sas_dev);
3326 if (!sas_dev)
3327 return NULL;
3328
3329 kref_init(&sas_dev->refcnt);
3330 sas_dev->hdl = hdl;
3331 sas_dev->dev_info = dev_info;
3332 sas_dev->sas_addr = sas_addr;
3333 sas_dev->card_port = card_port;
3334 sas_dev->parent_sas_addr = parent_sas_addr;
3335 sas_dev->phy = sas_dev_pg0->phy_num;
3336 sas_dev->enc_hdl = le16_to_cpu(sas_dev_pg0->enc_hdl);
3337 sas_dev->dev_name = le64_to_cpu(sas_dev_pg0->dev_name);
3338 sas_dev->port_connection = sas_dev_pg0->max_port_connections;
3339 sas_dev->slot = sas_dev->enc_hdl ? le16_to_cpu(sas_dev_pg0->slot) : 0;
3340 if (le16_to_cpu(sas_dev_pg0->flg) &
3341 LEAPRAID_SAS_DEV_P0_FLG_ENC_LEVEL_VALID) {
3342 sas_dev->enc_level = sas_dev_pg0->enc_level;
3343 memcpy(sas_dev->connector_name,
3344 sas_dev_pg0->connector_name,
3345 LEAPRAID_SAS_DEV_P0_CON_NAME_LEN);
3346 sas_dev->connector_name[LEAPRAID_SAS_DEV_P0_CON_NAME_LEN] =
3347 '\0';
3348 } else {
3349 sas_dev->enc_level = 0;
3350 sas_dev->connector_name[0] = '\0';
3351 }
3352 if (sas_dev->enc_hdl) {
3353 spin_lock_irqsave(&adapter->dev_topo.enc_lock, flags);
3354 enc_dev = leapraid_enc_find_by_hdl(adapter, sas_dev->enc_hdl);
3355 if (enc_dev)
3356 sas_dev->enc_lid = le64_to_cpu(enc_dev->pg0.enc_lid);
3357 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, flags);
3358 }
3359 dev_info(&adapter->pdev->dev,
3360 "add dev: hdl=0x%x, SAS addr=0x%016llx, port connect=0x%x\n",
3361 hdl, sas_dev->sas_addr, sas_dev->port_connection);
3362
3363 return sas_dev;
3364 }
3365
leapraid_add_dev(struct leapraid_adapter * adapter,u16 hdl)3366 static void leapraid_add_dev(struct leapraid_adapter *adapter, u16 hdl)
3367 {
3368 union cfg_param_1 cfgp1 = {0};
3369 union cfg_param_2 cfgp2 = {0};
3370 struct leapraid_sas_dev_p0 sas_dev_pg0;
3371 struct leapraid_card_port *card_port;
3372 struct leapraid_sas_dev *sas_dev;
3373 unsigned long flags;
3374 u64 parent_sas_addr;
3375 u32 dev_info;
3376 u64 sas_addr;
3377 u8 port_id;
3378
3379 cfgp1.form = LEAPRAID_SAS_DEV_CFG_PGAD_HDL;
3380 cfgp2.handle = hdl;
3381 if (leapraid_op_config_page(adapter, &sas_dev_pg0,
3382 cfgp1, cfgp2, GET_SAS_DEVICE_PG0))
3383 return;
3384
3385 dev_info = le32_to_cpu(sas_dev_pg0.dev_info);
3386 if (!(leapraid_is_end_dev(dev_info)))
3387 return;
3388
3389 sas_addr = le64_to_cpu(sas_dev_pg0.sas_address);
3390 if (!(le16_to_cpu(sas_dev_pg0.flg) &
3391 LEAPRAID_SAS_DEV_P0_FLG_DEV_PRESENT))
3392 return;
3393
3394 port_id = sas_dev_pg0.physical_port;
3395 card_port = leapraid_get_port_by_id(adapter, port_id, false);
3396 if (!card_port)
3397 return;
3398
3399 sas_dev = leapraid_get_sas_dev_by_addr(adapter, sas_addr, card_port);
3400 if (sas_dev) {
3401 leapraid_sdev_put(sas_dev);
3402 return;
3403 }
3404
3405 if (leapraid_get_sas_address(adapter,
3406 le16_to_cpu(sas_dev_pg0.parent_dev_hdl),
3407 &parent_sas_addr))
3408 return;
3409
3410 sas_dev = leapraid_init_sas_dev(adapter, &sas_dev_pg0, card_port,
3411 hdl, parent_sas_addr, sas_addr,
3412 dev_info);
3413 if (!sas_dev)
3414 return;
3415
3416 if (adapter->scan_dev_desc.wait_scan_dev_done) {
3417 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags);
3418 leapraid_sdev_get(sas_dev);
3419 list_add_tail(&sas_dev->list,
3420 &adapter->dev_topo.sas_dev_init_list);
3421 leapraid_check_boot_dev(adapter, sas_dev, 0);
3422 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags);
3423 } else {
3424 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags);
3425 leapraid_sdev_get(sas_dev);
3426 list_add_tail(&sas_dev->list, &adapter->dev_topo.sas_dev_list);
3427 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags);
3428 leapraid_report_sdev_directly(adapter, sas_dev);
3429 }
3430 leapraid_sdev_put(sas_dev);
3431 }
3432
leapraid_remove_device(struct leapraid_adapter * adapter,struct leapraid_sas_dev * sas_dev)3433 static void leapraid_remove_device(struct leapraid_adapter *adapter,
3434 struct leapraid_sas_dev *sas_dev)
3435 {
3436 struct leapraid_starget_priv *starget_priv;
3437
3438 leapraid_clear_cached_boot_dev(adapter, sas_dev, 0);
3439 if (sas_dev->led_on) {
3440 leapraid_set_led(adapter, sas_dev, false);
3441 sas_dev->led_on = 0;
3442 }
3443
3444 if (sas_dev->starget && sas_dev->starget->hostdata) {
3445 starget_priv = sas_dev->starget->hostdata;
3446 starget_priv->deleted = 1;
3447 leapraid_ublk_io_dev(adapter,
3448 sas_dev->sas_addr, sas_dev->card_port);
3449 starget_priv->hdl = LEAPRAID_INVALID_DEV_HANDLE;
3450 }
3451
3452 leapraid_transport_port_remove(adapter,
3453 sas_dev->sas_addr,
3454 sas_dev->parent_sas_addr,
3455 sas_dev->card_port);
3456
3457 dev_info(&adapter->pdev->dev,
3458 "remove dev: hdl=0x%04x, SAS addr=0x%016llx\n",
3459 sas_dev->hdl, (unsigned long long)sas_dev->sas_addr);
3460 }
3461
leapraid_alloc_vphy(struct leapraid_adapter * adapter,u8 port_id,u8 phy_num)3462 static struct leapraid_vphy *leapraid_alloc_vphy(
3463 struct leapraid_adapter *adapter,
3464 u8 port_id, u8 phy_num)
3465 {
3466 struct leapraid_card_port *port;
3467 struct leapraid_vphy *vphy;
3468
3469 port = leapraid_get_port_by_id(adapter, port_id, false);
3470 if (!port)
3471 return NULL;
3472
3473 vphy = leapraid_get_vphy_by_phy(port, phy_num);
3474 if (vphy)
3475 return vphy;
3476 vphy = kzalloc_obj(*vphy);
3477 if (!vphy)
3478 return NULL;
3479
3480 if (!port->vphys_mask)
3481 INIT_LIST_HEAD(&port->vphys_list);
3482
3483 port->vphys_mask |= BIT(phy_num);
3484 vphy->phy_mask |= BIT(phy_num);
3485 list_add_tail(&vphy->list, &port->vphys_list);
3486 return vphy;
3487 }
3488
leapraid_add_port_to_card_port_list(struct leapraid_adapter * adapter,u8 port_id,bool refresh)3489 static int leapraid_add_port_to_card_port_list(
3490 struct leapraid_adapter *adapter,
3491 u8 port_id, bool refresh)
3492 {
3493 struct leapraid_card_port *card_port;
3494
3495 card_port = leapraid_get_port_by_id(adapter, port_id, false);
3496 if (card_port)
3497 return 0;
3498 card_port = kzalloc_obj(*card_port);
3499 if (!card_port)
3500 return -ENOMEM;
3501
3502 card_port->port_id = port_id;
3503 dev_dbg(&adapter->pdev->dev,
3504 "port: %d is added to card_port list\n",
3505 card_port->port_id);
3506
3507 if (refresh && adapter->access_ctrl.shost_recovering)
3508 card_port->flg = LEAPRAID_CARD_PORT_FLG_NEW;
3509 list_add_tail(&card_port->list, &adapter->dev_topo.card_port_list);
3510 return 0;
3511 }
3512
leapraid_add_card_phy(struct leapraid_adapter * adapter,struct leapraid_sas_io_unit_p0 * iou,int i)3513 static int leapraid_add_card_phy(struct leapraid_adapter *adapter,
3514 struct leapraid_sas_io_unit_p0 *iou,
3515 int i)
3516 {
3517 struct leapraid_sas_phy_p0 phy_pg0;
3518 union cfg_param_1 cfgp1 = {0};
3519 union cfg_param_2 cfgp2 = {0};
3520 struct leapraid_topo_node *card = &adapter->dev_topo.card;
3521 u8 port_id;
3522
3523 cfgp1.phy_number = i;
3524
3525 if (leapraid_op_config_page(adapter, &phy_pg0,
3526 cfgp1, cfgp2, GET_PHY_PG0))
3527 return -EINVAL;
3528
3529 port_id = iou->phy_info[i].port;
3530
3531 if (leapraid_add_port_to_card_port_list(adapter, port_id, false))
3532 return -EINVAL;
3533
3534 if ((le32_to_cpu(phy_pg0.phy_info) &
3535 LEAPRAID_SAS_PHYINFO_VPHY) &&
3536 ((phy_pg0.neg_link_rate >>
3537 LEAPRAID_SAS_NEG_LINK_RATE_SHIFT) >=
3538 LEAPRAID_SAS_NEG_LINK_RATE_1_5)) {
3539 if (!leapraid_alloc_vphy(adapter, port_id, i))
3540 return -ENOMEM;
3541
3542 card->card_phy[i].vphy = 1;
3543 }
3544
3545 card->card_phy[i].hdl = card->hdl;
3546 card->card_phy[i].phy_id = i;
3547 card->card_phy[i].card_port =
3548 leapraid_get_port_by_id(adapter, port_id, false);
3549
3550 leapraid_transport_add_card_phy(adapter,
3551 &card->card_phy[i],
3552 &phy_pg0,
3553 card->parent_dev);
3554
3555 return 0;
3556 }
3557
leapraid_refresh_card_phy(struct leapraid_adapter * adapter,struct leapraid_sas_io_unit_p0 * iou,int i)3558 static int leapraid_refresh_card_phy(struct leapraid_adapter *adapter,
3559 struct leapraid_sas_io_unit_p0 *iou,
3560 int i)
3561 {
3562 struct leapraid_topo_node *card = &adapter->dev_topo.card;
3563 struct leapraid_sas_phy_p0 phy_pg0;
3564 union cfg_param_1 cfgp1 = {0};
3565 union cfg_param_2 cfgp2 = {0};
3566 u16 attached_hdl;
3567 u32 dev_info;
3568 u8 link_rate;
3569 u8 port_id;
3570
3571 link_rate = iou->phy_info[i].neg_link_rate >>
3572 LEAPRAID_SAS_NEG_LINK_RATE_SHIFT;
3573 port_id = iou->phy_info[i].port;
3574 if (leapraid_add_port_to_card_port_list(adapter, port_id, true))
3575 return -EINVAL;
3576
3577 dev_info = le32_to_cpu(iou->phy_info[i].controller_phy_dev_info);
3578 if (dev_info & LEAPRAID_DEVTYP_SEP &&
3579 link_rate >= LEAPRAID_SAS_NEG_LINK_RATE_1_5) {
3580 cfgp1.phy_number = i;
3581
3582 if (leapraid_op_config_page(adapter, &phy_pg0,
3583 cfgp1, cfgp2, GET_PHY_PG0))
3584 return 0;
3585
3586 if (le32_to_cpu(phy_pg0.phy_info) &
3587 LEAPRAID_SAS_PHYINFO_VPHY) {
3588 if (!leapraid_alloc_vphy(adapter, port_id, i))
3589 return -ENOMEM;
3590 card->card_phy[i].vphy = 1;
3591 }
3592 }
3593
3594 card->card_phy[i].hdl = card->hdl;
3595
3596 attached_hdl = le16_to_cpu(iou->phy_info[i].attached_dev_hdl);
3597 if (attached_hdl && link_rate < LEAPRAID_SAS_NEG_LINK_RATE_1_5)
3598 link_rate = LEAPRAID_SAS_NEG_LINK_RATE_1_5;
3599
3600 card->card_phy[i].card_port =
3601 leapraid_get_port_by_id(adapter, port_id, false);
3602
3603 if (!card->card_phy[i].phy) {
3604 cfgp1.phy_number = i;
3605 if (leapraid_op_config_page(adapter, &phy_pg0,
3606 cfgp1, cfgp2, GET_PHY_PG0))
3607 return 0;
3608
3609 card->card_phy[i].phy_id = i;
3610
3611 leapraid_transport_add_card_phy(adapter,
3612 &card->card_phy[i],
3613 &phy_pg0,
3614 card->parent_dev);
3615 return 0;
3616 }
3617
3618 leapraid_transport_update_links(adapter,
3619 card->sas_address,
3620 attached_hdl,
3621 i,
3622 link_rate,
3623 card->card_phy[i].card_port);
3624
3625 return 0;
3626 }
3627
leapraid_sas_host_add(struct leapraid_adapter * adapter,bool refresh)3628 static void leapraid_sas_host_add(struct leapraid_adapter *adapter,
3629 bool refresh)
3630 {
3631 union cfg_param_1 cfgp1 = {0};
3632 union cfg_param_2 cfgp2 = {0};
3633 struct leapraid_sas_dev_p0 sas_dev_pg0;
3634 struct leapraid_enc_p0 enc_pg0;
3635 struct leapraid_sas_io_unit_p0 *sas_iou_pg0;
3636 u16 sas_iou_pg0_sz;
3637 u8 phys_num;
3638 int i;
3639 int rc;
3640
3641 if (!refresh) {
3642 if (leapraid_get_adapter_phys(adapter, &phys_num) || !phys_num)
3643 return;
3644
3645 adapter->dev_topo.card.card_phy =
3646 kzalloc_objs(struct leapraid_card_phy, phys_num);
3647 if (!adapter->dev_topo.card.card_phy)
3648 return;
3649
3650 adapter->dev_topo.card.phys_num = phys_num;
3651 }
3652
3653 sas_iou_pg0_sz =
3654 offsetof(struct leapraid_sas_io_unit_p0, phy_info) +
3655 (adapter->dev_topo.card.phys_num *
3656 sizeof(struct leapraid_sas_io_unit0_phy_info));
3657 sas_iou_pg0 = kzalloc(sas_iou_pg0_sz, GFP_KERNEL);
3658 if (!sas_iou_pg0)
3659 return;
3660
3661 if (leapraid_get_sas_io_unit_page0(adapter,
3662 sas_iou_pg0,
3663 sas_iou_pg0_sz))
3664 goto out_free;
3665
3666 adapter->dev_topo.card.parent_dev = &adapter->shost->shost_gendev;
3667 adapter->dev_topo.card.hdl =
3668 le16_to_cpu(sas_iou_pg0->phy_info[0].controller_dev_hdl);
3669 for (i = 0; i < adapter->dev_topo.card.phys_num; i++) {
3670 if (!refresh) /* add */
3671 rc = leapraid_add_card_phy(adapter, sas_iou_pg0, i);
3672 else /* refresh */
3673 rc = leapraid_refresh_card_phy(adapter,
3674 sas_iou_pg0,
3675 i);
3676 if (rc)
3677 goto out_free;
3678 }
3679
3680 if (!refresh) {
3681 cfgp1.form = LEAPRAID_SAS_DEV_CFG_PGAD_HDL;
3682 cfgp2.handle = adapter->dev_topo.card.hdl;
3683 if (leapraid_op_config_page(adapter, &sas_dev_pg0, cfgp1,
3684 cfgp2, GET_SAS_DEVICE_PG0))
3685 goto out_free;
3686
3687 adapter->dev_topo.card.enc_hdl =
3688 le16_to_cpu(sas_dev_pg0.enc_hdl);
3689 adapter->dev_topo.card.sas_address =
3690 le64_to_cpu(sas_dev_pg0.sas_address);
3691 dev_info(&adapter->pdev->dev,
3692 "add host: hdl=0x%04x, SAS addr=0x%016llx, phy=%d\n",
3693 adapter->dev_topo.card.hdl,
3694 (unsigned long long)adapter->dev_topo.card.sas_address,
3695 adapter->dev_topo.card.phys_num);
3696
3697 if (adapter->dev_topo.card.enc_hdl) {
3698 cfgp1.form = LEAPRAID_SAS_ENC_CFG_PGAD_HDL;
3699 cfgp2.handle = adapter->dev_topo.card.enc_hdl;
3700 if (!(leapraid_op_config_page(adapter, &enc_pg0,
3701 cfgp1, cfgp2,
3702 GET_SAS_ENCLOSURE_PG0)))
3703 adapter->dev_topo.card.enc_lid =
3704 le64_to_cpu(enc_pg0.enc_lid);
3705 }
3706 }
3707 out_free:
3708 kfree(sas_iou_pg0);
3709 }
3710
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)3711 static int leapraid_internal_exp_add(struct leapraid_adapter *adapter,
3712 struct leapraid_exp_p0 *exp_pg0,
3713 union cfg_param_1 *cfgp1,
3714 union cfg_param_2 *cfgp2,
3715 u16 hdl)
3716 {
3717 struct leapraid_topo_node *topo_node_exp;
3718 struct leapraid_sas_port *sas_port = NULL;
3719 struct leapraid_enc_node *enc_dev;
3720 struct leapraid_exp_p1 exp_pg1;
3721 int ret;
3722 int rc;
3723 unsigned long flags;
3724 u8 port_id;
3725 u16 parent_handle;
3726 u64 sas_addr_parent;
3727 int i;
3728
3729 port_id = exp_pg0->physical_port;
3730 parent_handle = le16_to_cpu(exp_pg0->parent_dev_hdl);
3731
3732 rc = leapraid_get_sas_address(adapter,
3733 parent_handle, &sas_addr_parent);
3734 if (rc)
3735 return rc;
3736 topo_node_exp = kzalloc_obj(*topo_node_exp);
3737 if (!topo_node_exp)
3738 return -ENOMEM;
3739
3740 topo_node_exp->hdl = hdl;
3741 topo_node_exp->phys_num = exp_pg0->phy_num;
3742 topo_node_exp->sas_address_parent = sas_addr_parent;
3743 topo_node_exp->sas_address = le64_to_cpu(exp_pg0->sas_address);
3744 topo_node_exp->card_port =
3745 leapraid_get_port_by_id(adapter, port_id, false);
3746 if (!topo_node_exp->card_port) {
3747 rc = -EPERM;
3748 goto out_fail;
3749 }
3750
3751 dev_info(&adapter->pdev->dev,
3752 "add exp: saddr=0x%016llx, hdl=0x%04x, phdl=0x%04x, phy=%d\n",
3753 (unsigned long long)topo_node_exp->sas_address,
3754 hdl, parent_handle,
3755 topo_node_exp->phys_num);
3756 if (!topo_node_exp->phys_num) {
3757 dev_err(&adapter->pdev->dev,
3758 "%s: Invalid PHY num from exp_pg0\n", __func__);
3759 rc = -EPERM;
3760 goto out_fail;
3761 }
3762
3763 topo_node_exp->card_phy =
3764 kzalloc_objs(struct leapraid_card_phy, topo_node_exp->phys_num);
3765 if (!topo_node_exp->card_phy) {
3766 dev_err(&adapter->pdev->dev,
3767 "%s: Failed to alloc expander phy array, count=%u\n",
3768 __func__, topo_node_exp->phys_num);
3769 rc = -EPERM;
3770 goto out_fail;
3771 }
3772
3773 INIT_LIST_HEAD(&topo_node_exp->sas_port_list);
3774 sas_port = leapraid_transport_port_add(adapter, hdl, sas_addr_parent,
3775 topo_node_exp->card_port);
3776 if (!sas_port) {
3777 rc = -EPERM;
3778 goto out_fail;
3779 }
3780
3781 topo_node_exp->parent_dev = &sas_port->rphy->dev;
3782 topo_node_exp->rphy = sas_port->rphy;
3783 for (i = 0; i < topo_node_exp->phys_num; i++) {
3784 cfgp1->phy_number = i;
3785 cfgp2->handle = hdl;
3786 if (leapraid_op_config_page(adapter, &exp_pg1, *cfgp1, *cfgp2,
3787 GET_SAS_EXPANDER_PG1)) {
3788 dev_err(&adapter->pdev->dev,
3789 "%s: Failed to get exp_pg1, phy=%d\n",
3790 __func__, i);
3791 rc = -EPERM;
3792 goto out_fail;
3793 }
3794
3795 topo_node_exp->card_phy[i].hdl = hdl;
3796 topo_node_exp->card_phy[i].phy_id = i;
3797 topo_node_exp->card_phy[i].card_port =
3798 leapraid_get_port_by_id(adapter, port_id, false);
3799 ret = leapraid_transport_add_exp_phy(
3800 adapter,
3801 &topo_node_exp->card_phy[i],
3802 &exp_pg1,
3803 topo_node_exp->parent_dev);
3804 if (ret) {
3805 rc = -EPERM;
3806 goto out_fail;
3807 }
3808 }
3809
3810 if (topo_node_exp->enc_hdl) {
3811 spin_lock_irqsave(&adapter->dev_topo.enc_lock, flags);
3812 enc_dev = leapraid_enc_find_by_hdl(adapter,
3813 topo_node_exp->enc_hdl);
3814 if (enc_dev)
3815 topo_node_exp->enc_lid =
3816 le64_to_cpu(enc_dev->pg0.enc_lid);
3817 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, flags);
3818 }
3819
3820 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags);
3821 list_add_tail(&topo_node_exp->list, &adapter->dev_topo.exp_list);
3822 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock, flags);
3823 return 0;
3824
3825 out_fail:
3826 if (sas_port)
3827 leapraid_transport_port_remove(adapter,
3828 topo_node_exp->sas_address,
3829 sas_addr_parent,
3830 topo_node_exp->card_port);
3831 kfree(topo_node_exp->card_phy);
3832 kfree(topo_node_exp);
3833 return rc;
3834 }
3835
leapraid_exp_add(struct leapraid_adapter * adapter,u16 hdl)3836 static int leapraid_exp_add(struct leapraid_adapter *adapter, u16 hdl)
3837 {
3838 union cfg_param_1 cfgp1 = {0};
3839 union cfg_param_2 cfgp2 = {0};
3840 struct leapraid_topo_node *topo_node_exp;
3841 struct leapraid_exp_p0 exp_pg0;
3842 u16 parent_handle;
3843 u64 sas_addr, sas_addr_parent;
3844 unsigned long flags;
3845 u8 port_id;
3846 int rc;
3847
3848 if (!hdl) {
3849 dev_warn(&adapter->pdev->dev, "%s: Invalid hdl\n", __func__);
3850 return -EPERM;
3851 }
3852
3853 if (adapter->access_ctrl.shost_recovering ||
3854 adapter->access_ctrl.pcie_recovering) {
3855 dev_warn(&adapter->pdev->dev,
3856 "%s: Failed, shost_recovering=%d pcie_recovering=%d\n",
3857 __func__, adapter->access_ctrl.shost_recovering,
3858 adapter->access_ctrl.pcie_recovering);
3859 return -EPERM;
3860 }
3861
3862 cfgp1.form = LEAPRAID_SAS_EXP_CFD_PGAD_HDL;
3863 cfgp2.handle = hdl;
3864 if (leapraid_op_config_page(adapter, &exp_pg0, cfgp1, cfgp2,
3865 GET_SAS_EXPANDER_PG0))
3866 return -EPERM;
3867
3868 parent_handle = le16_to_cpu(exp_pg0.parent_dev_hdl);
3869 if (leapraid_get_sas_address(adapter, parent_handle, &sas_addr_parent))
3870 return -EPERM;
3871
3872 port_id = exp_pg0.physical_port;
3873 if (sas_addr_parent != adapter->dev_topo.card.sas_address) {
3874 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags);
3875 topo_node_exp =
3876 leapraid_exp_find_by_sas_address(
3877 adapter,
3878 sas_addr_parent,
3879 leapraid_get_port_by_id(adapter,
3880 port_id,
3881 false));
3882 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock,
3883 flags);
3884 if (!topo_node_exp) {
3885 rc = leapraid_exp_add(adapter, parent_handle);
3886 if (rc != 0)
3887 return rc;
3888 }
3889 }
3890
3891 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags);
3892 sas_addr = le64_to_cpu(exp_pg0.sas_address);
3893 topo_node_exp =
3894 leapraid_exp_find_by_sas_address(
3895 adapter,
3896 sas_addr,
3897 leapraid_get_port_by_id(adapter, port_id, false));
3898 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock, flags);
3899
3900 if (topo_node_exp)
3901 return 0;
3902
3903 return leapraid_internal_exp_add(adapter, &exp_pg0, &cfgp1,
3904 &cfgp2, hdl);
3905 }
3906
leapraid_exp_node_rm(struct leapraid_adapter * adapter,struct leapraid_topo_node * topo_node_exp)3907 static void leapraid_exp_node_rm(struct leapraid_adapter *adapter,
3908 struct leapraid_topo_node *topo_node_exp)
3909 {
3910 struct leapraid_sas_port *sas_port, *sas_port_next;
3911 unsigned long flags;
3912 int port_id;
3913
3914 list_for_each_entry_safe(sas_port, sas_port_next,
3915 &topo_node_exp->sas_port_list,
3916 port_list) {
3917 if (adapter->access_ctrl.shost_recovering)
3918 return;
3919
3920 switch (sas_port->remote_identify.device_type) {
3921 case SAS_END_DEVICE:
3922 leapraid_sas_dev_remove_by_sas_address(
3923 adapter,
3924 sas_port->remote_identify.sas_address,
3925 sas_port->card_port);
3926 break;
3927 case SAS_EDGE_EXPANDER_DEVICE:
3928 case SAS_FANOUT_EXPANDER_DEVICE:
3929 leapraid_exp_rm(
3930 adapter,
3931 sas_port->remote_identify.sas_address,
3932 sas_port->card_port);
3933 break;
3934 default:
3935 break;
3936 }
3937 }
3938
3939 port_id = topo_node_exp->card_port->port_id;
3940 leapraid_transport_port_remove(adapter, topo_node_exp->sas_address,
3941 topo_node_exp->sas_address_parent,
3942 topo_node_exp->card_port);
3943 dev_info(&adapter->pdev->dev,
3944 "removing exp: port=%d, SAS addr=0x%016llx, hdl=0x%04x\n",
3945 port_id, (unsigned long long)topo_node_exp->sas_address,
3946 topo_node_exp->hdl);
3947 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags);
3948 list_del(&topo_node_exp->list);
3949 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock, flags);
3950 kfree(topo_node_exp->card_phy);
3951 kfree(topo_node_exp);
3952 }
3953
leapraid_exp_rm(struct leapraid_adapter * adapter,u64 sas_addr,struct leapraid_card_port * port)3954 void leapraid_exp_rm(struct leapraid_adapter *adapter, u64 sas_addr,
3955 struct leapraid_card_port *port)
3956 {
3957 struct leapraid_topo_node *topo_node_exp;
3958 unsigned long flags;
3959
3960 if (adapter->access_ctrl.shost_recovering)
3961 return;
3962
3963 if (!port)
3964 return;
3965
3966 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags);
3967 topo_node_exp = leapraid_exp_find_by_sas_address(adapter,
3968 sas_addr,
3969 port);
3970 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock, flags);
3971
3972 if (topo_node_exp)
3973 leapraid_exp_node_rm(adapter, topo_node_exp);
3974 }
3975
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)3976 static void leapraid_internal_sas_topo_chg_evt(
3977 struct leapraid_adapter *adapter,
3978 struct leapraid_card_port *card_port,
3979 struct leapraid_topo_node *topo_node_exp,
3980 struct leapraid_fw_evt_work *fw_evt,
3981 u64 sas_addr, u8 max_phys)
3982 {
3983 struct leapraid_evt_data_sas_topo_change_list *evt_data;
3984 u8 phy_number;
3985 u8 link_rate;
3986 u16 reason_code;
3987 u16 hdl;
3988 int i;
3989
3990 evt_data = fw_evt->evt_data;
3991 for (i = 0; i < evt_data->entry_num; i++) {
3992 if (fw_evt->ignore)
3993 return;
3994
3995 if (adapter->access_ctrl.host_removing ||
3996 adapter->access_ctrl.pcie_recovering)
3997 return;
3998
3999 phy_number = evt_data->start_phy_num + i;
4000 if (phy_number >= max_phys)
4001 continue;
4002
4003 reason_code = evt_data->phy[i].phy_status &
4004 LEAPRAID_EVT_SAS_TOPO_RC_MASK;
4005
4006 hdl = le16_to_cpu(evt_data->phy[i].attached_dev_hdl);
4007 if (!hdl ||
4008 hdl > adapter->adapter_attr.features.max_dev_handle) {
4009 dev_warn(&adapter->pdev->dev,
4010 "%s: Invalid device handle\n", __func__);
4011 continue;
4012 }
4013 link_rate = evt_data->phy[i].link_rate >>
4014 LEAPRAID_SAS_NEG_LINK_RATE_SHIFT;
4015 switch (reason_code) {
4016 case LEAPRAID_EVT_SAS_TOPO_RC_TARG_ADDED:
4017 if (adapter->access_ctrl.shost_recovering)
4018 break;
4019 leapraid_transport_update_links(adapter, sas_addr,
4020 hdl, phy_number,
4021 link_rate, card_port);
4022 if (link_rate < LEAPRAID_SAS_NEG_LINK_RATE_1_5)
4023 break;
4024 leapraid_add_dev(adapter, hdl);
4025 break;
4026 case LEAPRAID_EVT_SAS_TOPO_RC_TARG_NOT_RESPONDING:
4027 leapraid_sas_dev_remove_by_hdl(adapter, hdl);
4028 break;
4029 }
4030 }
4031
4032 if (evt_data->exp_status == LEAPRAID_EVT_SAS_TOPO_ES_NOT_RESPONDING &&
4033 topo_node_exp)
4034 leapraid_exp_rm(adapter, sas_addr, card_port);
4035 }
4036
leapraid_sas_topo_chg_evt(struct leapraid_adapter * adapter,struct leapraid_fw_evt_work * fw_evt)4037 static void leapraid_sas_topo_chg_evt(struct leapraid_adapter *adapter,
4038 struct leapraid_fw_evt_work *fw_evt)
4039 {
4040 struct leapraid_topo_node *topo_node_exp;
4041 struct leapraid_card_port *card_port;
4042 struct leapraid_evt_data_sas_topo_change_list *evt_data;
4043 u16 phdl;
4044 u8 max_phys;
4045 u64 sas_addr;
4046 unsigned long flags;
4047
4048 if (adapter->access_ctrl.shost_recovering ||
4049 adapter->access_ctrl.host_removing ||
4050 adapter->access_ctrl.pcie_recovering)
4051 return;
4052
4053 evt_data = fw_evt->evt_data;
4054 leapraid_sas_host_add(adapter, adapter->dev_topo.card.phys_num > 0);
4055
4056 if (fw_evt->ignore)
4057 return;
4058
4059 phdl = le16_to_cpu(evt_data->exp_dev_hdl);
4060 card_port = leapraid_get_port_by_id(adapter,
4061 evt_data->physical_port,
4062 false);
4063 if (evt_data->exp_status == LEAPRAID_EVT_SAS_TOPO_ES_ADDED &&
4064 leapraid_exp_add(adapter, phdl) != 0)
4065 return;
4066
4067 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags);
4068 topo_node_exp = leapraid_exp_find_by_hdl(adapter, phdl);
4069 if (topo_node_exp) {
4070 sas_addr = topo_node_exp->sas_address;
4071 max_phys = topo_node_exp->phys_num;
4072 card_port = topo_node_exp->card_port;
4073 } else if (phdl < adapter->dev_topo.card.phys_num) {
4074 sas_addr = adapter->dev_topo.card.sas_address;
4075 max_phys = adapter->dev_topo.card.phys_num;
4076 } else {
4077 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock,
4078 flags);
4079 return;
4080 }
4081 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock, flags);
4082
4083 leapraid_internal_sas_topo_chg_evt(adapter, card_port,
4084 topo_node_exp, fw_evt,
4085 sas_addr, max_phys);
4086 }
4087
leapraid_reprobe_lun(struct scsi_device * sdev,void * no_uld_attach)4088 static void leapraid_reprobe_lun(struct scsi_device *sdev, void *no_uld_attach)
4089 {
4090 sdev->no_uld_attach = no_uld_attach ? 1 : 0;
4091 sdev_printk(KERN_INFO, sdev,
4092 "%s RAID component to upper layer\n",
4093 sdev->no_uld_attach ? "hide" : "expose");
4094 WARN_ON(scsi_device_reprobe(sdev));
4095 }
4096
leapraid_sas_pd_add(struct leapraid_adapter * adapter,struct leapraid_evt_data_ir_change * evt_data)4097 static void leapraid_sas_pd_add(
4098 struct leapraid_adapter *adapter,
4099 struct leapraid_evt_data_ir_change *evt_data)
4100 {
4101 union cfg_param_1 cfgp1 = {0};
4102 union cfg_param_2 cfgp2 = {0};
4103 struct leapraid_sas_dev_p0 sas_dev_p0;
4104 struct leapraid_sas_dev *sas_dev;
4105 u64 sas_address;
4106 u16 parent_hdl;
4107 u16 hdl;
4108
4109 hdl = le16_to_cpu(evt_data->phys_disk_dev_hdl);
4110 if (!hdl || hdl > adapter->adapter_attr.features.max_dev_handle) {
4111 dev_warn(&adapter->pdev->dev,
4112 "%s: Invalid device handle\n", __func__);
4113 return;
4114 }
4115
4116 set_bit(hdl, adapter->dev_topo.pd_hdls);
4117 sas_dev = leapraid_get_sas_dev_by_hdl(adapter, hdl);
4118 if (sas_dev) {
4119 leapraid_sdev_put(sas_dev);
4120 dev_warn(&adapter->pdev->dev,
4121 "Dev handle 0x%x already exists\n", hdl);
4122 return;
4123 }
4124
4125 cfgp1.form = LEAPRAID_SAS_DEV_CFG_PGAD_HDL;
4126 cfgp2.handle = hdl;
4127 if (leapraid_op_config_page(adapter, &sas_dev_p0, cfgp1, cfgp2,
4128 GET_SAS_DEVICE_PG0)) {
4129 dev_warn(&adapter->pdev->dev, "Failed to read dev page0\n");
4130 return;
4131 }
4132
4133 parent_hdl = le16_to_cpu(sas_dev_p0.parent_dev_hdl);
4134 if (!leapraid_get_sas_address(adapter, parent_hdl, &sas_address))
4135 leapraid_transport_update_links(adapter, sas_address, hdl,
4136 sas_dev_p0.phy_num,
4137 LEAPRAID_SAS_NEG_LINK_RATE_1_5,
4138 leapraid_get_port_by_id(adapter,
4139 sas_dev_p0.physical_port,
4140 false));
4141 leapraid_add_dev(adapter, hdl);
4142 }
4143
leapraid_sas_pd_delete(struct leapraid_adapter * adapter,struct leapraid_evt_data_ir_change * evt_data)4144 static void leapraid_sas_pd_delete(
4145 struct leapraid_adapter *adapter,
4146 struct leapraid_evt_data_ir_change *evt_data)
4147 {
4148 u16 hdl;
4149
4150 hdl = le16_to_cpu(evt_data->phys_disk_dev_hdl);
4151 leapraid_sas_dev_remove_by_hdl(adapter, hdl);
4152 }
4153
leapraid_sas_pd_hide(struct leapraid_adapter * adapter,struct leapraid_evt_data_ir_change * evt_data)4154 static void leapraid_sas_pd_hide(
4155 struct leapraid_adapter *adapter,
4156 struct leapraid_evt_data_ir_change *evt_data)
4157 {
4158 struct leapraid_starget_priv *starget_priv;
4159 struct scsi_target *starget = NULL;
4160 struct leapraid_sas_dev *sas_dev;
4161 unsigned long flags;
4162 u64 volume_wwid = 0;
4163 u16 volume_hdl;
4164 u16 hdl;
4165
4166 hdl = le16_to_cpu(evt_data->phys_disk_dev_hdl);
4167 if (!hdl || hdl > adapter->adapter_attr.features.max_dev_handle) {
4168 dev_warn(&adapter->pdev->dev,
4169 "%s: Invalid device handle\n", __func__);
4170 return;
4171 }
4172 leapraid_cfg_get_volume_hdl(adapter, hdl, &volume_hdl);
4173 if (volume_hdl)
4174 leapraid_cfg_get_volume_wwid(adapter,
4175 volume_hdl,
4176 &volume_wwid);
4177
4178 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags);
4179 sas_dev = leapraid_hold_lock_get_sas_dev_by_hdl(adapter, hdl);
4180 if (!sas_dev) {
4181 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags);
4182 return;
4183 }
4184
4185 set_bit(hdl, adapter->dev_topo.pd_hdls);
4186 if (sas_dev->starget && sas_dev->starget->hostdata) {
4187 starget = sas_dev->starget;
4188 starget_priv = starget->hostdata;
4189 starget_priv->flg |= LEAPRAID_TGT_FLG_RAID_MEMBER;
4190 sas_dev->volume_hdl = volume_hdl;
4191 sas_dev->volume_wwid = volume_wwid;
4192 }
4193 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags);
4194 if (starget) {
4195 starget_for_each_device(starget,
4196 (void *)LEAPRAID_NO_ULD_ATTACH_FLAG,
4197 leapraid_reprobe_lun);
4198 }
4199
4200 leapraid_sdev_put(sas_dev);
4201 }
4202
leapraid_sas_pd_expose(struct leapraid_adapter * adapter,struct leapraid_evt_data_ir_change * evt_data)4203 static void leapraid_sas_pd_expose(
4204 struct leapraid_adapter *adapter,
4205 struct leapraid_evt_data_ir_change *evt_data)
4206 {
4207 struct leapraid_starget_priv *starget_priv;
4208 struct scsi_target *starget = NULL;
4209 struct leapraid_sas_dev *sas_dev;
4210 unsigned long flags;
4211 u16 hdl;
4212
4213 hdl = le16_to_cpu(evt_data->phys_disk_dev_hdl);
4214 if (!hdl || hdl > adapter->adapter_attr.features.max_dev_handle) {
4215 dev_warn(&adapter->pdev->dev,
4216 "%s: Invalid device handle\n", __func__);
4217 return;
4218 }
4219
4220 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags);
4221 sas_dev = leapraid_hold_lock_get_sas_dev_by_hdl(adapter, hdl);
4222 if (!sas_dev) {
4223 dev_warn(&adapter->pdev->dev,
4224 "%s:%d: sas_dev not found, hdl=0x%x\n",
4225 __func__, __LINE__, hdl);
4226 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags);
4227 return;
4228 }
4229
4230 sas_dev->volume_hdl = 0;
4231 sas_dev->volume_wwid = 0;
4232 clear_bit(hdl, adapter->dev_topo.pd_hdls);
4233 if (sas_dev->starget && sas_dev->starget->hostdata) {
4234 starget = sas_dev->starget;
4235 starget_priv = starget->hostdata;
4236 starget_priv->flg &= ~LEAPRAID_TGT_FLG_RAID_MEMBER;
4237 sas_dev->led_on = 0;
4238 }
4239 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags);
4240
4241 if (starget) {
4242 starget_for_each_device(starget,
4243 NULL,
4244 leapraid_reprobe_lun);
4245 }
4246
4247 leapraid_sdev_put(sas_dev);
4248 }
4249
leapraid_sas_vol_visibility(struct leapraid_adapter * adapter,struct leapraid_evt_data_ir_change * evt_data)4250 static void leapraid_sas_vol_visibility(
4251 struct leapraid_adapter *adapter,
4252 struct leapraid_evt_data_ir_change *evt_data)
4253 {
4254 struct leapraid_raid_volume *raid_volume;
4255 struct scsi_device *sdev;
4256 bool reprobe_flg = false;
4257 bool sdev_held = false;
4258 unsigned long flags;
4259 u16 hdl;
4260 u8 rc;
4261
4262 hdl = le16_to_cpu(evt_data->vol_dev_hdl);
4263 rc = evt_data->reason_code;
4264 raid_volume = leapraid_raid_volume_find_by_hdl(adapter, hdl);
4265 if (!raid_volume) {
4266 dev_warn(&adapter->pdev->dev,
4267 "%s:%d: Volume handle 0x%x not found\n",
4268 __func__, __LINE__, hdl);
4269 return;
4270 }
4271
4272 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags);
4273 sdev = raid_volume->sdev;
4274 if (!sdev) {
4275 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock,
4276 flags);
4277 leapraid_raid_volume_put(raid_volume);
4278 dev_warn(&adapter->pdev->dev,
4279 "%s:%d: Volume handle 0x%x has no sdev\n",
4280 __func__, __LINE__, hdl);
4281 return;
4282 }
4283
4284 if (sdev->no_uld_attach &&
4285 rc == LEAPRAID_EVT_IR_RC_VOLUME_UNHIDE) {
4286 sdev->no_uld_attach = 0;
4287 reprobe_flg = true;
4288 } else if (!sdev->no_uld_attach &&
4289 rc == LEAPRAID_EVT_IR_RC_VOLUME_HIDE) {
4290 sdev->no_uld_attach = 1;
4291 reprobe_flg = true;
4292 }
4293
4294 if (reprobe_flg && !scsi_device_get(sdev))
4295 sdev_held = true;
4296 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, flags);
4297 leapraid_raid_volume_put(raid_volume);
4298
4299 if (!reprobe_flg) {
4300 dev_warn(&adapter->pdev->dev,
4301 "%s:rc(0x%x): Request matches, skipping\n",
4302 __func__, rc);
4303 return;
4304 }
4305
4306 if (!sdev_held) {
4307 dev_warn(&adapter->pdev->dev,
4308 "%s: Failed to hold sdev for reprobe, hdl=0x%x\n",
4309 __func__, hdl);
4310 return;
4311 }
4312
4313 if (sdev->no_uld_attach)
4314 sdev_printk(KERN_INFO, sdev, "hide vol\n");
4315 else
4316 sdev_printk(KERN_INFO, sdev, "unhide vol\n");
4317
4318 WARN_ON(scsi_device_reprobe(sdev));
4319 scsi_device_put(sdev);
4320 }
4321
leapraid_sas_volume_add(struct leapraid_adapter * adapter,struct leapraid_evt_data_ir_change * evt_data)4322 static void leapraid_sas_volume_add(
4323 struct leapraid_adapter *adapter,
4324 struct leapraid_evt_data_ir_change *evt_data)
4325 {
4326 struct leapraid_raid_volume *raid_volume;
4327 unsigned long flags;
4328 u64 wwid;
4329 u16 hdl;
4330
4331 hdl = le16_to_cpu(evt_data->vol_dev_hdl);
4332
4333 if (leapraid_cfg_get_volume_wwid(adapter, hdl, &wwid)) {
4334 dev_warn(&adapter->pdev->dev, "Failed to read volume page1\n");
4335 return;
4336 }
4337
4338 if (!wwid) {
4339 dev_warn(&adapter->pdev->dev, "Invalid WWID(handle=0x%x)\n",
4340 hdl);
4341 return;
4342 }
4343
4344 raid_volume = leapraid_raid_volume_find_by_wwid(adapter, wwid);
4345 if (raid_volume) {
4346 dev_warn(&adapter->pdev->dev,
4347 "Volume handle 0x%x already exists\n", hdl);
4348 leapraid_raid_volume_put(raid_volume);
4349 return;
4350 }
4351
4352 raid_volume = kzalloc_obj(*raid_volume);
4353 if (!raid_volume)
4354 return;
4355
4356 INIT_LIST_HEAD(&raid_volume->list);
4357 kref_init(&raid_volume->refcnt);
4358 raid_volume->id = adapter->dev_topo.sas_id++;
4359 raid_volume->channel = RAID_CHANNEL;
4360 raid_volume->hdl = hdl;
4361 raid_volume->wwid = wwid;
4362 leapraid_raid_volume_add(adapter, raid_volume);
4363 if (!adapter->scan_dev_desc.wait_scan_dev_done) {
4364 if (scsi_add_device(adapter->shost, RAID_CHANNEL,
4365 raid_volume->id, 0))
4366 leapraid_raid_volume_remove(adapter, raid_volume);
4367 dev_info(&adapter->pdev->dev,
4368 "add RAID volume: hdl=0x%x, wwid=0x%llx\n", hdl, wwid);
4369 } else {
4370 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags);
4371 leapraid_check_boot_dev(adapter, raid_volume, RAID_CHANNEL);
4372 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock,
4373 flags);
4374 }
4375 leapraid_raid_volume_put(raid_volume);
4376 }
4377
leapraid_sas_volume_delete_by_ptr(struct leapraid_adapter * adapter,struct leapraid_raid_volume * raid_volume)4378 static void leapraid_sas_volume_delete_by_ptr(
4379 struct leapraid_adapter *adapter,
4380 struct leapraid_raid_volume *raid_volume)
4381 {
4382 struct leapraid_starget_priv *starget_priv;
4383 struct scsi_target *starget = NULL;
4384 unsigned long flags;
4385 bool in_list;
4386
4387 if (!raid_volume)
4388 return;
4389
4390 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags);
4391 in_list = !list_empty(&raid_volume->list);
4392 if (in_list && raid_volume->starget) {
4393 starget = raid_volume->starget;
4394 starget_priv = starget->hostdata;
4395 if (starget_priv)
4396 starget_priv->deleted = 1;
4397 }
4398 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, flags);
4399
4400 if (!in_list)
4401 return;
4402
4403 dev_info(&adapter->pdev->dev,
4404 "delete RAID volume: hdl=0x%x, wwid=0x%llx\n",
4405 raid_volume->hdl, raid_volume->wwid);
4406 leapraid_raid_volume_remove(adapter, raid_volume);
4407
4408 if (starget)
4409 scsi_remove_target(&starget->dev);
4410 }
4411
leapraid_sas_volume_delete(struct leapraid_adapter * adapter,u16 hdl)4412 static void leapraid_sas_volume_delete(struct leapraid_adapter *adapter,
4413 u16 hdl)
4414 {
4415 struct leapraid_raid_volume *raid_volume;
4416
4417 raid_volume = leapraid_raid_volume_find_by_hdl(adapter, hdl);
4418 if (!raid_volume) {
4419 dev_warn(&adapter->pdev->dev,
4420 "%s:%d: Volume handle 0x%x not found\n",
4421 __func__, __LINE__, hdl);
4422 return;
4423 }
4424
4425 leapraid_sas_volume_delete_by_ptr(adapter, raid_volume);
4426 leapraid_raid_volume_put(raid_volume);
4427 }
4428
leapraid_sas_ir_chg_evt(struct leapraid_adapter * adapter,struct leapraid_fw_evt_work * fw_evt)4429 static void leapraid_sas_ir_chg_evt(struct leapraid_adapter *adapter,
4430 struct leapraid_fw_evt_work *fw_evt)
4431 {
4432 struct leapraid_evt_data_ir_change *evt_data;
4433
4434 evt_data = fw_evt->evt_data;
4435
4436 switch (evt_data->reason_code) {
4437 case LEAPRAID_EVT_IR_RC_VOLUME_ADD:
4438 leapraid_sas_volume_add(adapter, evt_data);
4439 break;
4440 case LEAPRAID_EVT_IR_RC_VOLUME_DELETE:
4441 leapraid_sas_volume_delete(adapter,
4442 le16_to_cpu(evt_data->vol_dev_hdl));
4443 break;
4444 case LEAPRAID_EVT_IR_RC_PD_HIDDEN_TO_ADD:
4445 leapraid_sas_pd_add(adapter, evt_data);
4446 break;
4447 case LEAPRAID_EVT_IR_RC_PD_UNHIDDEN_TO_DELETE:
4448 leapraid_sas_pd_delete(adapter, evt_data);
4449 break;
4450 case LEAPRAID_EVT_IR_RC_PD_CREATED_TO_HIDE:
4451 leapraid_sas_pd_hide(adapter, evt_data);
4452 break;
4453 case LEAPRAID_EVT_IR_RC_PD_DELETED_TO_EXPOSE:
4454 leapraid_sas_pd_expose(adapter, evt_data);
4455 break;
4456 case LEAPRAID_EVT_IR_RC_VOLUME_HIDE:
4457 case LEAPRAID_EVT_IR_RC_VOLUME_UNHIDE:
4458 leapraid_sas_vol_visibility(adapter, evt_data);
4459 break;
4460 default:
4461 break;
4462 }
4463 }
4464
leapraid_sas_enc_dev_stat_add_node(struct leapraid_adapter * adapter,u16 hdl)4465 static void leapraid_sas_enc_dev_stat_add_node(
4466 struct leapraid_adapter *adapter, u16 hdl)
4467 {
4468 union cfg_param_1 cfgp1 = {0};
4469 union cfg_param_2 cfgp2 = {0};
4470 struct leapraid_enc_node *enc_node;
4471 struct leapraid_enc_node *enc_exist;
4472 unsigned long flags;
4473 int rc;
4474
4475 enc_node = kzalloc_obj(*enc_node);
4476 if (!enc_node)
4477 return;
4478
4479 cfgp1.form = LEAPRAID_SAS_ENC_CFG_PGAD_HDL;
4480 cfgp2.handle = hdl;
4481 rc = leapraid_op_config_page(adapter, &enc_node->pg0, cfgp1, cfgp2,
4482 GET_SAS_ENCLOSURE_PG0);
4483 if (rc) {
4484 kfree(enc_node);
4485 return;
4486 }
4487
4488 spin_lock_irqsave(&adapter->dev_topo.enc_lock, flags);
4489 enc_exist = leapraid_enc_find_by_hdl(adapter, hdl);
4490 if (enc_exist) {
4491 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, flags);
4492 kfree(enc_node);
4493 return;
4494 }
4495 list_add_tail(&enc_node->list, &adapter->dev_topo.enc_list);
4496 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, flags);
4497 }
4498
leapraid_sas_enc_dev_stat_del_node(struct leapraid_adapter * adapter,u16 hdl)4499 static void leapraid_sas_enc_dev_stat_del_node(
4500 struct leapraid_adapter *adapter, u16 hdl)
4501 {
4502 struct leapraid_enc_node *enc_node;
4503 unsigned long flags;
4504
4505 if (!hdl)
4506 return;
4507
4508 spin_lock_irqsave(&adapter->dev_topo.enc_lock, flags);
4509 enc_node = leapraid_enc_find_by_hdl(adapter, hdl);
4510 if (enc_node)
4511 list_del(&enc_node->list);
4512 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, flags);
4513
4514 kfree(enc_node);
4515 }
4516
leapraid_sas_enc_dev_stat_chg_evt(struct leapraid_adapter * adapter,struct leapraid_fw_evt_work * fw_evt)4517 static void leapraid_sas_enc_dev_stat_chg_evt(
4518 struct leapraid_adapter *adapter,
4519 struct leapraid_fw_evt_work *fw_evt)
4520 {
4521 struct leapraid_evt_data_sas_enc_dev_status_change *evt_data;
4522 u16 enc_hdl;
4523
4524 if (adapter->access_ctrl.shost_recovering)
4525 return;
4526
4527 evt_data = fw_evt->evt_data;
4528 enc_hdl = le16_to_cpu(evt_data->enc_hdl);
4529 switch (evt_data->reason_code) {
4530 case LEAPRAID_EVT_SAS_ENCL_RC_ADDED:
4531 if (enc_hdl)
4532 leapraid_sas_enc_dev_stat_add_node(adapter, enc_hdl);
4533 break;
4534 case LEAPRAID_EVT_SAS_ENCL_RC_NOT_RESPONDING:
4535 leapraid_sas_enc_dev_stat_del_node(adapter, enc_hdl);
4536 break;
4537 default:
4538 break;
4539 }
4540 }
4541
leapraid_remove_unresp_sas_end_dev(struct leapraid_adapter * adapter)4542 static void leapraid_remove_unresp_sas_end_dev(
4543 struct leapraid_adapter *adapter)
4544 {
4545 struct leapraid_sas_dev *sas_dev, *sas_dev_next;
4546 unsigned long flags;
4547 LIST_HEAD(head);
4548
4549 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags);
4550 list_for_each_entry_safe(sas_dev, sas_dev_next,
4551 &adapter->dev_topo.sas_dev_init_list, list) {
4552 if (sas_dev->rphy || sas_dev->pend_sas_rphy_add)
4553 continue;
4554
4555 list_del_init(&sas_dev->list);
4556 leapraid_clear_cached_boot_dev(adapter, sas_dev, 0);
4557 leapraid_sdev_put(sas_dev);
4558 }
4559 list_for_each_entry_safe(sas_dev, sas_dev_next,
4560 &adapter->dev_topo.sas_dev_list, list) {
4561 if (!sas_dev->resp)
4562 list_move_tail(&sas_dev->list, &head);
4563 else
4564 sas_dev->resp = 0;
4565 }
4566 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags);
4567
4568 list_for_each_entry_safe(sas_dev, sas_dev_next, &head, list) {
4569 leapraid_remove_device(adapter, sas_dev);
4570 list_del_init(&sas_dev->list);
4571 leapraid_sdev_put(sas_dev);
4572 }
4573
4574 dev_warn(&adapter->pdev->dev,
4575 "Unresponsive SAS end devices removed\n");
4576 }
4577
leapraid_remove_unresp_raid_volumes(struct leapraid_adapter * adapter)4578 static void leapraid_remove_unresp_raid_volumes(
4579 struct leapraid_adapter *adapter)
4580 {
4581 unsigned long flags;
4582 struct leapraid_raid_volume *raid_volume, *raid_volume_next;
4583 LIST_HEAD(head);
4584
4585 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags);
4586 list_for_each_entry_safe(raid_volume, raid_volume_next,
4587 &adapter->dev_topo.raid_volume_list, list) {
4588 if (!raid_volume->resp)
4589 list_move_tail(&raid_volume->list, &head);
4590 else
4591 raid_volume->resp = 0;
4592 }
4593 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, flags);
4594
4595 list_for_each_entry_safe(raid_volume, raid_volume_next, &head, list) {
4596 leapraid_sas_volume_delete_by_ptr(adapter, raid_volume);
4597 }
4598
4599 dev_warn(&adapter->pdev->dev,
4600 "Unresponsive RAID volumes removed\n");
4601 }
4602
leapraid_remove_unresp_sas_exp(struct leapraid_adapter * adapter)4603 static void leapraid_remove_unresp_sas_exp(struct leapraid_adapter *adapter)
4604 {
4605 struct leapraid_topo_node *topo_node_exp, *topo_node_exp_next;
4606 unsigned long flags;
4607 LIST_HEAD(head);
4608
4609 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags);
4610 list_for_each_entry_safe(topo_node_exp, topo_node_exp_next,
4611 &adapter->dev_topo.exp_list, list) {
4612 if (!topo_node_exp->resp)
4613 list_move_tail(&topo_node_exp->list, &head);
4614 else
4615 topo_node_exp->resp = 0;
4616 }
4617 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock, flags);
4618
4619 list_for_each_entry_safe(topo_node_exp, topo_node_exp_next,
4620 &head, list)
4621 leapraid_exp_node_rm(adapter, topo_node_exp);
4622
4623 dev_warn(&adapter->pdev->dev,
4624 "Unresponsive SAS expanders removed\n");
4625 }
4626
leapraid_remove_unresp_dev(struct leapraid_adapter * adapter)4627 static void leapraid_remove_unresp_dev(struct leapraid_adapter *adapter)
4628 {
4629 leapraid_remove_unresp_sas_end_dev(adapter);
4630 if (adapter->adapter_attr.raid_support)
4631 leapraid_remove_unresp_raid_volumes(adapter);
4632 leapraid_remove_unresp_sas_exp(adapter);
4633 leapraid_ublk_io_all_dev(adapter);
4634 }
4635
leapraid_del_dirty_vphy(struct leapraid_adapter * adapter)4636 static void leapraid_del_dirty_vphy(struct leapraid_adapter *adapter)
4637 {
4638 struct leapraid_card_port *card_port, *card_port_next;
4639 struct leapraid_vphy *vphy, *vphy_next;
4640
4641 list_for_each_entry_safe(card_port, card_port_next,
4642 &adapter->dev_topo.card_port_list, list) {
4643 if (!card_port->vphys_mask)
4644 continue;
4645
4646 list_for_each_entry_safe(vphy, vphy_next,
4647 &card_port->vphys_list, list) {
4648 if (!(vphy->flg & LEAPRAID_VPHY_FLG_DIRTY))
4649 continue;
4650
4651 card_port->vphys_mask &= ~vphy->phy_mask;
4652 list_del(&vphy->list);
4653 kfree(vphy);
4654 }
4655
4656 if (!card_port->vphys_mask && !card_port->sas_address)
4657 card_port->flg |= LEAPRAID_CARD_PORT_FLG_DIRTY;
4658 }
4659 }
4660
leapraid_del_dirty_card_port(struct leapraid_adapter * adapter)4661 static void leapraid_del_dirty_card_port(struct leapraid_adapter *adapter)
4662 {
4663 struct leapraid_card_port *card_port, *card_port_next;
4664
4665 list_for_each_entry_safe(card_port, card_port_next,
4666 &adapter->dev_topo.card_port_list, list) {
4667 if (!(card_port->flg & LEAPRAID_CARD_PORT_FLG_DIRTY) ||
4668 card_port->flg & LEAPRAID_CARD_PORT_FLG_NEW)
4669 continue;
4670
4671 list_del(&card_port->list);
4672 kfree(card_port);
4673 }
4674 }
4675
leapraid_update_dev_qdepth(struct leapraid_adapter * adapter)4676 static void leapraid_update_dev_qdepth(struct leapraid_adapter *adapter)
4677 {
4678 struct leapraid_sdev_priv *sdev_priv;
4679 struct leapraid_sas_dev *sas_dev;
4680 struct leapraid_adapter_attr *attr;
4681 struct scsi_device *sdev;
4682 u16 qdepth;
4683
4684 attr = &adapter->adapter_attr;
4685 shost_for_each_device(sdev, adapter->shost) {
4686 sdev_priv = sdev->hostdata;
4687 if (!sdev_priv || !sdev_priv->starget_priv)
4688 continue;
4689 sas_dev = sdev_priv->starget_priv->sas_dev;
4690 if (sas_dev && sas_dev->dev_info & LEAPRAID_DEVTYP_SSP_TGT)
4691 qdepth = (sas_dev->port_connection > 1) ?
4692 attr->wideport_max_queue_depth :
4693 attr->narrowport_max_queue_depth;
4694 else if (sas_dev && sas_dev->dev_info &
4695 LEAPRAID_DEVTYP_SATA_DEV)
4696 qdepth = attr->sata_max_queue_depth;
4697 else
4698 continue;
4699
4700 leapraid_change_queue_depth(sdev, qdepth);
4701 }
4702 }
4703
leapraid_update_exp_links(struct leapraid_adapter * adapter,struct leapraid_topo_node * topo_node_exp,u16 hdl)4704 static void leapraid_update_exp_links(struct leapraid_adapter *adapter,
4705 struct leapraid_topo_node *topo_node_exp,
4706 u16 hdl)
4707 {
4708 union cfg_param_1 cfgp1 = {0};
4709 union cfg_param_2 cfgp2 = {0};
4710 struct leapraid_exp_p1 exp_p1;
4711 int i;
4712
4713 cfgp2.handle = hdl;
4714 for (i = 0; i < topo_node_exp->phys_num; i++) {
4715 cfgp1.phy_number = i;
4716 if (leapraid_op_config_page(adapter, &exp_p1, cfgp1, cfgp2,
4717 GET_SAS_EXPANDER_PG1))
4718 return;
4719
4720 leapraid_transport_update_links(
4721 adapter,
4722 topo_node_exp->sas_address,
4723 le16_to_cpu(exp_p1.attached_dev_hdl),
4724 i,
4725 exp_p1.neg_link_rate >>
4726 LEAPRAID_SAS_NEG_LINK_RATE_SHIFT,
4727 topo_node_exp->card_port);
4728 }
4729 }
4730
leapraid_scan_exp_after_reset(struct leapraid_adapter * adapter)4731 static void leapraid_scan_exp_after_reset(struct leapraid_adapter *adapter)
4732 {
4733 union cfg_param_1 cfgp1 = {0};
4734 union cfg_param_2 cfgp2 = {0};
4735 struct leapraid_topo_node *topo_node_exp;
4736 struct leapraid_exp_p0 exp_p0;
4737 unsigned long flags;
4738 u16 hdl;
4739 u8 port_id;
4740
4741 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP;
4742 for (hdl = 0xFFFF, cfgp2.handle = hdl;
4743 !leapraid_op_config_page(adapter, &exp_p0, cfgp1, cfgp2,
4744 GET_SAS_EXPANDER_PG0);
4745 cfgp2.handle = hdl) {
4746 hdl = le16_to_cpu(exp_p0.dev_hdl);
4747 port_id = exp_p0.physical_port;
4748 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags);
4749 topo_node_exp =
4750 leapraid_exp_find_by_sas_address(
4751 adapter,
4752 le64_to_cpu(exp_p0.sas_address),
4753 leapraid_get_port_by_id(adapter,
4754 port_id,
4755 false));
4756 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock,
4757 flags);
4758
4759 if (topo_node_exp) {
4760 leapraid_update_exp_links(adapter, topo_node_exp, hdl);
4761 } else {
4762 leapraid_exp_add(adapter, hdl);
4763
4764 dev_info(&adapter->pdev->dev,
4765 "add exp: hdl=0x%04x, SAS addr=0x%016llx\n",
4766 hdl,
4767 (unsigned long long)le64_to_cpu(
4768 exp_p0.sas_address));
4769 }
4770 }
4771 }
4772
leapraid_scan_phy_disks_after_reset(struct leapraid_adapter * adapter)4773 static void leapraid_scan_phy_disks_after_reset(
4774 struct leapraid_adapter *adapter)
4775 {
4776 union cfg_param_1 cfgp1 = {0};
4777 union cfg_param_2 cfgp2 = {0};
4778 union cfg_param_1 cfgp1_extra = {0};
4779 union cfg_param_2 cfgp2_extra = {0};
4780 struct leapraid_sas_dev_p0 sas_dev_p0;
4781 struct leapraid_raidpd_p0 raidpd_p0;
4782 struct leapraid_sas_dev *sas_dev;
4783 u8 phys_disk_num, port_id;
4784 u16 hdl, parent_hdl;
4785 u64 sas_addr;
4786
4787 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP;
4788 for (phys_disk_num = 0xFF, cfgp2.form_specific = phys_disk_num;
4789 !leapraid_op_config_page(adapter, &raidpd_p0,
4790 cfgp1, cfgp2, GET_PHY_DISK_PG0);
4791 cfgp2.form_specific = phys_disk_num) {
4792 phys_disk_num = raidpd_p0.phys_disk_num;
4793 hdl = le16_to_cpu(raidpd_p0.dev_hdl);
4794 sas_dev = leapraid_get_sas_dev_by_hdl(adapter, hdl);
4795 if (sas_dev) {
4796 leapraid_sdev_put(sas_dev);
4797 continue;
4798 }
4799
4800 cfgp1_extra.form = LEAPRAID_SAS_DEV_CFG_PGAD_HDL;
4801 cfgp2_extra.handle = hdl;
4802 if (leapraid_op_config_page(adapter, &sas_dev_p0, cfgp1_extra,
4803 cfgp2_extra, GET_SAS_DEVICE_PG0) !=
4804 0)
4805 continue;
4806
4807 parent_hdl = le16_to_cpu(sas_dev_p0.parent_dev_hdl);
4808 if (!leapraid_get_sas_address(adapter,
4809 parent_hdl,
4810 &sas_addr)) {
4811 port_id = sas_dev_p0.physical_port;
4812 leapraid_transport_update_links(
4813 adapter, sas_addr, hdl,
4814 sas_dev_p0.phy_num,
4815 LEAPRAID_SAS_NEG_LINK_RATE_1_5,
4816 leapraid_get_port_by_id(
4817 adapter, port_id, false));
4818 if (!hdl || hdl >
4819 adapter->adapter_attr.features.max_dev_handle) {
4820 dev_warn(&adapter->pdev->dev,
4821 "%s: Invalid device handle\n",
4822 __func__);
4823 } else {
4824 set_bit(hdl, adapter->dev_topo.pd_hdls);
4825 leapraid_add_dev(adapter, hdl);
4826
4827 dev_info(&adapter->pdev->dev,
4828 "add pd hdl=0x%04x saddr=0x%016llx\n",
4829 hdl,
4830 (unsigned long long)le64_to_cpu(
4831 sas_dev_p0.sas_address));
4832 }
4833 }
4834 }
4835 }
4836
leapraid_scan_vol_after_reset(struct leapraid_adapter * adapter)4837 static void leapraid_scan_vol_after_reset(struct leapraid_adapter *adapter)
4838 {
4839 union cfg_param_1 cfgp1 = {0};
4840 union cfg_param_2 cfgp2 = {0};
4841 union cfg_param_1 cfgp1_extra = {0};
4842 union cfg_param_2 cfgp2_extra = {0};
4843 struct leapraid_evt_data_ir_change evt_data;
4844 struct leapraid_raid_volume *raid_volume;
4845 struct leapraid_raidvol_p1 *vol_p1;
4846 struct leapraid_raidvol_p0 *vol_p0;
4847 u16 hdl;
4848
4849 vol_p0 = kzalloc_obj(*vol_p0);
4850 if (!vol_p0)
4851 return;
4852
4853 vol_p1 = kzalloc_obj(*vol_p1);
4854 if (!vol_p1) {
4855 kfree(vol_p0);
4856 return;
4857 }
4858
4859 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP;
4860 for (hdl = 0xFFFF, cfgp2.handle = hdl;
4861 !leapraid_op_config_page(adapter, vol_p1, cfgp1,
4862 cfgp2, GET_RAID_VOLUME_PG1);
4863 cfgp2.handle = hdl) {
4864 hdl = le16_to_cpu(vol_p1->dev_hdl);
4865 raid_volume = leapraid_raid_volume_find_by_wwid(
4866 adapter,
4867 le64_to_cpu(vol_p1->wwid));
4868 if (raid_volume) {
4869 leapraid_raid_volume_put(raid_volume);
4870 continue;
4871 }
4872
4873 cfgp1_extra.size = sizeof(struct leapraid_raidvol_p0);
4874 cfgp2_extra.handle = hdl;
4875 if (leapraid_op_config_page(adapter, vol_p0, cfgp1_extra,
4876 cfgp2_extra, GET_RAID_VOLUME_PG0))
4877 continue;
4878
4879 if (vol_p0->volume_state == LEAPRAID_VOL_STATE_OPTIMAL ||
4880 vol_p0->volume_state == LEAPRAID_VOL_STATE_ONLINE ||
4881 vol_p0->volume_state == LEAPRAID_VOL_STATE_DEGRADED) {
4882 memset(&evt_data, 0,
4883 sizeof(struct leapraid_evt_data_ir_change));
4884 evt_data.reason_code = LEAPRAID_EVT_IR_RC_VOLUME_ADD;
4885 evt_data.vol_dev_hdl = vol_p1->dev_hdl;
4886 leapraid_sas_volume_add(adapter, &evt_data);
4887 dev_info(&adapter->pdev->dev,
4888 "add volume: hdl=0x%04x\n",
4889 vol_p1->dev_hdl);
4890 }
4891 }
4892
4893 kfree(vol_p0);
4894 kfree(vol_p1);
4895 }
4896
leapraid_scan_sas_dev_after_reset(struct leapraid_adapter * adapter)4897 static void leapraid_scan_sas_dev_after_reset(struct leapraid_adapter *adapter)
4898 {
4899 union cfg_param_1 cfgp1 = {0};
4900 union cfg_param_2 cfgp2 = {0};
4901 struct leapraid_sas_dev_p0 sas_dev_p0;
4902 struct leapraid_sas_dev *sas_dev;
4903 u16 hdl, parent_hdl;
4904 u64 sas_address;
4905 u8 port_id;
4906
4907 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP;
4908 for (hdl = 0xFFFF, cfgp2.handle = hdl;
4909 !leapraid_op_config_page(adapter, &sas_dev_p0, cfgp1, cfgp2,
4910 GET_SAS_DEVICE_PG0);
4911 cfgp2.handle = hdl) {
4912 hdl = le16_to_cpu(sas_dev_p0.dev_hdl);
4913 if (!hdl ||
4914 hdl > adapter->adapter_attr.features.max_dev_handle) {
4915 dev_warn(&adapter->pdev->dev,
4916 "%s: Invalid device handle\n", __func__);
4917 continue;
4918 }
4919
4920 if (!(leapraid_is_end_dev(le32_to_cpu(sas_dev_p0.dev_info))))
4921 continue;
4922
4923 port_id = sas_dev_p0.physical_port;
4924 sas_dev = leapraid_get_sas_dev_by_addr(
4925 adapter,
4926 le64_to_cpu(sas_dev_p0.sas_address),
4927 leapraid_get_port_by_id(
4928 adapter,
4929 port_id,
4930 false));
4931 if (sas_dev) {
4932 leapraid_sdev_put(sas_dev);
4933 continue;
4934 }
4935
4936 parent_hdl = le16_to_cpu(sas_dev_p0.parent_dev_hdl);
4937 if (!leapraid_get_sas_address(adapter, parent_hdl,
4938 &sas_address)) {
4939 leapraid_transport_update_links(
4940 adapter,
4941 sas_address,
4942 hdl,
4943 sas_dev_p0.phy_num,
4944 LEAPRAID_SAS_NEG_LINK_RATE_1_5,
4945 leapraid_get_port_by_id(adapter,
4946 port_id,
4947 false));
4948 leapraid_add_dev(adapter, hdl);
4949 dev_info(&adapter->pdev->dev,
4950 "Add SAS dev: hdl=0x%04x, saddr=0x%016llx\n",
4951 hdl,
4952 (unsigned long long)le64_to_cpu(
4953 sas_dev_p0.sas_address));
4954 }
4955 }
4956 }
4957
leapraid_scan_all_dev_after_reset(struct leapraid_adapter * adapter)4958 static void leapraid_scan_all_dev_after_reset(struct leapraid_adapter *adapter)
4959 {
4960 leapraid_sas_host_add(adapter, adapter->dev_topo.card.phys_num > 0);
4961 leapraid_scan_exp_after_reset(adapter);
4962 if (adapter->adapter_attr.raid_support) {
4963 leapraid_scan_phy_disks_after_reset(adapter);
4964 leapraid_scan_vol_after_reset(adapter);
4965 }
4966 leapraid_scan_sas_dev_after_reset(adapter);
4967 }
4968
leapraid_hardreset_async_logic(struct leapraid_adapter * adapter)4969 static void leapraid_hardreset_async_logic(struct leapraid_adapter *adapter)
4970 {
4971 unsigned long flags;
4972
4973 leapraid_remove_unresp_dev(adapter);
4974 leapraid_del_dirty_vphy(adapter);
4975 leapraid_del_dirty_card_port(adapter);
4976 leapraid_update_dev_qdepth(adapter);
4977 leapraid_scan_all_dev_after_reset(adapter);
4978
4979 if (adapter->scan_dev_desc.driver_loading)
4980 leapraid_scan_dev_done(adapter);
4981 spin_lock_irqsave(&adapter->reset_desc.adapter_reset_lock, flags);
4982 adapter->access_ctrl.shost_recover_async = 0;
4983 spin_unlock_irqrestore(&adapter->reset_desc.adapter_reset_lock, flags);
4984 wake_up(&adapter->access_ctrl.shost_recover_wq);
4985 }
4986
leapraid_send_enc_cmd(struct leapraid_adapter * adapter,struct leapraid_sep_rep * sep_rep,struct leapraid_sep_req * sep_req)4987 static int leapraid_send_enc_cmd(struct leapraid_adapter *adapter,
4988 struct leapraid_sep_rep *sep_rep,
4989 struct leapraid_sep_req *sep_req)
4990 {
4991 void *req;
4992 bool reset_flg = false;
4993 int rc;
4994 u16 smid;
4995
4996 mutex_lock(&adapter->driver_cmds.enc_cmd.mutex);
4997 rc = leapraid_check_adapter_is_op(adapter, LEAPRAID_DB_WAIT_OP_SHORT,
4998 __func__);
4999 if (rc)
5000 goto unlock;
5001
5002 adapter->driver_cmds.enc_cmd.status = LEAPRAID_CMD_PENDING;
5003 smid = adapter->driver_cmds.enc_cmd.inter_taskid;
5004 req = leapraid_get_task_desc(adapter, smid);
5005 memset(req, 0, LEAPRAID_REQUEST_SIZE);
5006 memcpy(req, sep_req, sizeof(struct leapraid_sep_req));
5007 init_completion(&adapter->driver_cmds.enc_cmd.done);
5008 leapraid_fire_task(adapter, smid);
5009 wait_for_completion_timeout(&adapter->driver_cmds.enc_cmd.done,
5010 LEAPRAID_ENC_CMD_TIMEOUT * HZ);
5011 if (!(adapter->driver_cmds.enc_cmd.status & LEAPRAID_CMD_DONE)) {
5012 dev_err(&adapter->pdev->dev,
5013 "%s: SEP command timeout, status=0x%x\n",
5014 __func__, adapter->driver_cmds.enc_cmd.status);
5015 leapraid_log_req_context(adapter, smid, sep_req);
5016 reset_flg =
5017 leapraid_check_reset(
5018 adapter->driver_cmds.enc_cmd.status);
5019 rc = -EFAULT;
5020 goto do_hard_reset;
5021 }
5022
5023 if (adapter->driver_cmds.enc_cmd.status & LEAPRAID_CMD_REPLY_VALID)
5024 memcpy(sep_rep, &adapter->driver_cmds.enc_cmd.reply,
5025 sizeof(struct leapraid_sep_rep));
5026 do_hard_reset:
5027 if (reset_flg) {
5028 dev_info(&adapter->pdev->dev, "%s:%d: call hard_reset\n",
5029 __func__, __LINE__);
5030 leapraid_hard_reset_handler(adapter, FULL_RESET);
5031 }
5032
5033 adapter->driver_cmds.enc_cmd.status = LEAPRAID_CMD_NOT_USED;
5034 unlock:
5035 mutex_unlock(&adapter->driver_cmds.enc_cmd.mutex);
5036 return rc;
5037 }
5038
leapraid_set_led(struct leapraid_adapter * adapter,struct leapraid_sas_dev * sas_dev,bool on)5039 static void leapraid_set_led(struct leapraid_adapter *adapter,
5040 struct leapraid_sas_dev *sas_dev, bool on)
5041 {
5042 struct leapraid_sep_rep sep_rep;
5043 struct leapraid_sep_req sep_req;
5044
5045 if (!sas_dev)
5046 return;
5047
5048 memset(&sep_req, 0, sizeof(struct leapraid_sep_req));
5049 memset(&sep_rep, 0, sizeof(struct leapraid_sep_rep));
5050 sep_req.func = LEAPRAID_FUNC_SCSI_ENC_PROCESSOR;
5051 sep_req.act = LEAPRAID_SEP_REQ_ACT_WRITE_STATUS;
5052 if (on) {
5053 u32 status = LEAPRAID_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT;
5054
5055 sep_req.slot_status = cpu_to_le32(status);
5056 sep_req.dev_hdl = cpu_to_le16(sas_dev->hdl);
5057 sep_req.flg = LEAPRAID_SEP_REQ_FLG_DEVHDL_ADDRESS;
5058 if (leapraid_send_enc_cmd(adapter, &sep_rep, &sep_req)) {
5059 leapraid_sdev_put(sas_dev);
5060 return;
5061 }
5062
5063 sas_dev->led_on = 1;
5064 leapraid_sdev_put(sas_dev);
5065 } else {
5066 sep_req.slot_status = 0;
5067 sep_req.slot = cpu_to_le16(sas_dev->slot);
5068 sep_req.dev_hdl = 0;
5069 sep_req.enc_hdl = cpu_to_le16(sas_dev->enc_hdl);
5070 sep_req.flg = LEAPRAID_SEP_REQ_FLG_ENCLOSURE_SLOT_ADDRESS;
5071 leapraid_send_enc_cmd(adapter, &sep_rep, &sep_req);
5072 }
5073 }
5074
leapraid_wait_adapter_recovery(struct leapraid_adapter * adapter)5075 static int leapraid_wait_adapter_recovery(struct leapraid_adapter *adapter)
5076 {
5077 unsigned long flags;
5078
5079 while (leapraid_shost_in_recovery(adapter->shost) ||
5080 READ_ONCE(adapter->access_ctrl.shost_recovering)) {
5081 if (READ_ONCE(adapter->access_ctrl.host_removing) ||
5082 READ_ONCE(adapter->fw_evt_s.fw_evt_cleanup)) {
5083 spin_lock_irqsave(
5084 &adapter->reset_desc.adapter_reset_lock,
5085 flags);
5086 adapter->access_ctrl.shost_recover_async = 0;
5087 spin_unlock_irqrestore(
5088 &adapter->reset_desc.adapter_reset_lock,
5089 flags);
5090
5091 wake_up(&adapter->access_ctrl.shost_recover_wq);
5092
5093 dev_warn(&adapter->pdev->dev,
5094 "%s: Failed, shost %d, host %d\n",
5095 __func__,
5096 adapter->access_ctrl.shost_recovering,
5097 adapter->access_ctrl.host_removing);
5098
5099 return -EFAULT;
5100 }
5101
5102 wait_event_timeout(
5103 adapter->access_ctrl.recovery_waitq,
5104 (!leapraid_shost_in_recovery(adapter->shost) &&
5105 !READ_ONCE(adapter->access_ctrl.shost_recovering)),
5106 msecs_to_jiffies(1000));
5107 }
5108
5109 return 0;
5110 }
5111
leapraid_fw_work(struct leapraid_adapter * adapter,struct leapraid_fw_evt_work * fw_evt)5112 static void leapraid_fw_work(struct leapraid_adapter *adapter,
5113 struct leapraid_fw_evt_work *fw_evt)
5114 {
5115 struct leapraid_sas_dev *sas_dev;
5116 unsigned long flags;
5117
5118 spin_lock_irqsave(&adapter->fw_evt_s.fw_evt_lock, flags);
5119 adapter->fw_evt_s.cur_evt = fw_evt;
5120 adapter->fw_evt_s.cur_evt_task = current;
5121 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags);
5122 leapraid_del_fw_evt_from_list(adapter, fw_evt);
5123 if (adapter->access_ctrl.host_removing ||
5124 adapter->access_ctrl.pcie_recovering) {
5125 spin_lock_irqsave(&adapter->fw_evt_s.fw_evt_lock, flags);
5126 leapraid_fw_evt_put(fw_evt);
5127 adapter->fw_evt_s.cur_evt = NULL;
5128 adapter->fw_evt_s.cur_evt_task = NULL;
5129 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags);
5130 return;
5131 }
5132 switch (fw_evt->evt_type) {
5133 case LEAPRAID_EVT_SAS_TOPO_CHANGE_LIST:
5134 leapraid_sas_topo_chg_evt(adapter, fw_evt);
5135 break;
5136 case LEAPRAID_EVT_IR_CHANGE:
5137 leapraid_sas_ir_chg_evt(adapter, fw_evt);
5138 break;
5139 case LEAPRAID_EVT_SAS_ENCL_DEV_STATUS_CHANGE:
5140 leapraid_sas_enc_dev_stat_chg_evt(adapter, fw_evt);
5141 break;
5142 case LEAPRAID_EVT_REMOVE_DEAD_DEV:
5143 if (leapraid_wait_adapter_recovery(adapter))
5144 goto out_cleanup;
5145
5146 leapraid_hardreset_async_logic(adapter);
5147 break;
5148 case LEAPRAID_EVT_TURN_ON_PFA_LED:
5149 sas_dev = leapraid_get_sas_dev_by_hdl(adapter,
5150 fw_evt->dev_handle);
5151 leapraid_set_led(adapter, sas_dev, true);
5152 break;
5153 case LEAPRAID_EVT_SCAN_DEV_DONE:
5154 adapter->scan_dev_desc.scan_start = 0;
5155 break;
5156 default:
5157 break;
5158 }
5159 out_cleanup:
5160 spin_lock_irqsave(&adapter->fw_evt_s.fw_evt_lock, flags);
5161 leapraid_fw_evt_put(fw_evt);
5162 adapter->fw_evt_s.cur_evt = NULL;
5163 adapter->fw_evt_s.cur_evt_task = NULL;
5164 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags);
5165 }
5166
leapraid_sas_dev_stat_chg_evt(struct leapraid_adapter * adapter,struct leapraid_evt_data_sas_dev_status_change * event_data)5167 static void leapraid_sas_dev_stat_chg_evt(
5168 struct leapraid_adapter *adapter,
5169 struct leapraid_evt_data_sas_dev_status_change *event_data)
5170 {
5171 struct leapraid_starget_priv *starget_priv;
5172 struct leapraid_sas_dev *sas_dev;
5173 u64 sas_address;
5174 unsigned long flags;
5175
5176 switch (event_data->reason_code) {
5177 case LEAPRAID_EVT_SAS_DEV_STAT_RC_INTERNAL_DEV_RESET:
5178 case LEAPRAID_EVT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET:
5179 break;
5180 default:
5181 return;
5182 }
5183
5184 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags);
5185
5186 sas_address = le64_to_cpu(event_data->sas_address);
5187 sas_dev = leapraid_hold_lock_get_sas_dev_by_addr(
5188 adapter,
5189 sas_address,
5190 leapraid_get_port_by_id(adapter,
5191 event_data->physical_port,
5192 false));
5193 if (!sas_dev || !sas_dev->starget)
5194 goto out_unlock;
5195
5196 starget_priv = sas_dev->starget->hostdata;
5197 if (starget_priv) {
5198 switch (event_data->reason_code) {
5199 case LEAPRAID_EVT_SAS_DEV_STAT_RC_INTERNAL_DEV_RESET:
5200 starget_priv->tm_busy = 1;
5201 break;
5202 case LEAPRAID_EVT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET:
5203 starget_priv->tm_busy = 0;
5204 break;
5205 }
5206 }
5207
5208 out_unlock:
5209 if (sas_dev)
5210 leapraid_sdev_put(sas_dev);
5211 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags);
5212 }
5213
leapraid_set_volume_delete_flag(struct leapraid_adapter * adapter,u16 handle)5214 static void leapraid_set_volume_delete_flag(struct leapraid_adapter *adapter,
5215 u16 handle)
5216 {
5217 struct leapraid_raid_volume *raid_volume;
5218 struct leapraid_starget_priv *sas_target_priv_data;
5219 unsigned long flags;
5220
5221 raid_volume = leapraid_raid_volume_find_by_hdl(adapter, handle);
5222 if (raid_volume) {
5223 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags);
5224 if (raid_volume->starget &&
5225 raid_volume->starget->hostdata) {
5226 sas_target_priv_data = raid_volume->starget->hostdata;
5227 sas_target_priv_data->deleted = 1;
5228 }
5229 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock,
5230 flags);
5231 leapraid_raid_volume_put(raid_volume);
5232 }
5233 }
5234
leapraid_check_ir_change_evt(struct leapraid_adapter * adapter,struct leapraid_evt_data_ir_change * evt_data)5235 static void leapraid_check_ir_change_evt(
5236 struct leapraid_adapter *adapter,
5237 struct leapraid_evt_data_ir_change *evt_data)
5238 {
5239 u16 phys_disk_dev_hdl;
5240
5241 switch (evt_data->reason_code) {
5242 case LEAPRAID_EVT_IR_RC_VOLUME_DELETE:
5243 leapraid_set_volume_delete_flag(
5244 adapter,
5245 le16_to_cpu(evt_data->vol_dev_hdl));
5246 break;
5247 case LEAPRAID_EVT_IR_RC_PD_UNHIDDEN_TO_DELETE:
5248 phys_disk_dev_hdl =
5249 le16_to_cpu(evt_data->phys_disk_dev_hdl);
5250 if (!phys_disk_dev_hdl ||
5251 phys_disk_dev_hdl >
5252 adapter->adapter_attr.features.max_dev_handle) {
5253 dev_warn(&adapter->pdev->dev,
5254 "%s: Invalid device handle\n", __func__);
5255 } else {
5256 clear_bit(phys_disk_dev_hdl,
5257 adapter->dev_topo.pd_hdls);
5258 leapraid_tgt_rst_send(adapter, phys_disk_dev_hdl);
5259 }
5260 break;
5261 }
5262 }
5263
leapraid_topo_del_evts_process_exp_status(struct leapraid_adapter * adapter,struct leapraid_evt_data_sas_topo_change_list * evt_data)5264 static void leapraid_topo_del_evts_process_exp_status(
5265 struct leapraid_adapter *adapter,
5266 struct leapraid_evt_data_sas_topo_change_list *evt_data)
5267 {
5268 struct leapraid_fw_evt_work *fw_evt = NULL;
5269 struct leapraid_evt_data_sas_topo_change_list *loc_evt_data;
5270 unsigned long flags;
5271 u16 exp_hdl;
5272
5273 exp_hdl = le16_to_cpu(evt_data->exp_dev_hdl);
5274
5275 switch (evt_data->exp_status) {
5276 case LEAPRAID_EVT_SAS_TOPO_ES_NOT_RESPONDING:
5277 spin_lock_irqsave(&adapter->fw_evt_s.fw_evt_lock, flags);
5278 list_for_each_entry(fw_evt,
5279 &adapter->fw_evt_s.fw_evt_list, list) {
5280 if (fw_evt->evt_type !=
5281 LEAPRAID_EVT_SAS_TOPO_CHANGE_LIST ||
5282 fw_evt->ignore)
5283 continue;
5284
5285 loc_evt_data = fw_evt->evt_data;
5286 if ((loc_evt_data->exp_status ==
5287 LEAPRAID_EVT_SAS_TOPO_ES_ADDED ||
5288 loc_evt_data->exp_status ==
5289 LEAPRAID_EVT_SAS_TOPO_ES_RESPONDING) &&
5290 le16_to_cpu(loc_evt_data->exp_dev_hdl) == exp_hdl)
5291 fw_evt->ignore = 1;
5292 }
5293 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags);
5294 break;
5295 default:
5296 break;
5297 }
5298 }
5299
leapraid_check_topo_del_evts(struct leapraid_adapter * adapter,struct leapraid_evt_data_sas_topo_change_list * evt_data)5300 static void leapraid_check_topo_del_evts(
5301 struct leapraid_adapter *adapter,
5302 struct leapraid_evt_data_sas_topo_change_list *evt_data)
5303 {
5304 int reason_code;
5305 u16 hdl;
5306 int i;
5307
5308 for (i = 0; i < evt_data->entry_num; i++) {
5309 hdl = le16_to_cpu(evt_data->phy[i].attached_dev_hdl);
5310 if (!hdl)
5311 continue;
5312
5313 reason_code = evt_data->phy[i].phy_status &
5314 LEAPRAID_EVT_SAS_TOPO_RC_MASK;
5315 if (reason_code ==
5316 LEAPRAID_EVT_SAS_TOPO_RC_TARG_NOT_RESPONDING)
5317 leapraid_tgt_not_responding(adapter, hdl);
5318 }
5319 leapraid_topo_del_evts_process_exp_status(adapter, evt_data);
5320 }
5321
leapraid_async_evt_validate(struct leapraid_adapter * adapter,struct leapraid_evt_notify_rep * event_notify_rep)5322 static bool leapraid_async_evt_validate(
5323 struct leapraid_adapter *adapter,
5324 struct leapraid_evt_notify_rep *event_notify_rep)
5325 {
5326 size_t msg_len;
5327 size_t evt_sz;
5328 size_t evt_avail;
5329 u16 evt;
5330
5331 msg_len = event_notify_rep->msg_len * sizeof(u32);
5332 if (msg_len > LEAPRAID_REPLY_SIZE ||
5333 msg_len < offsetof(struct leapraid_evt_notify_rep, evt_data)) {
5334 dev_warn(&adapter->pdev->dev,
5335 "%s: Invalid async event msg_len=%zu\n",
5336 __func__, msg_len);
5337 return false;
5338 }
5339
5340 evt_sz = le16_to_cpu(event_notify_rep->evt_data_len) * sizeof(u32);
5341 evt_avail = msg_len -
5342 offsetof(struct leapraid_evt_notify_rep, evt_data);
5343 if (evt_sz > evt_avail) {
5344 dev_warn(&adapter->pdev->dev,
5345 "%s: Invalid async event evt_data_len=%zu\n",
5346 __func__, evt_sz);
5347 return false;
5348 }
5349
5350 evt = le16_to_cpu(event_notify_rep->evt);
5351 switch (evt) {
5352 case LEAPRAID_EVT_SAS_DEV_STATUS_CHANGE:
5353 if (evt_sz <
5354 sizeof(struct leapraid_evt_data_sas_dev_status_change))
5355 goto invalid_evt_sz;
5356 break;
5357 case LEAPRAID_EVT_IR_CHANGE:
5358 if (evt_sz < sizeof(struct leapraid_evt_data_ir_change))
5359 goto invalid_evt_sz;
5360 break;
5361 case LEAPRAID_EVT_SAS_TOPO_CHANGE_LIST:
5362 {
5363 struct leapraid_evt_data_sas_topo_change_list *evt_data =
5364 (void *)event_notify_rep->evt_data;
5365 size_t hdr_sz;
5366
5367 hdr_sz =
5368 offsetof(struct leapraid_evt_data_sas_topo_change_list,
5369 phy);
5370 if (evt_sz < hdr_sz)
5371 goto invalid_evt_sz;
5372
5373 if (evt_data->entry_num >
5374 (evt_sz - hdr_sz) / sizeof(evt_data->phy[0]))
5375 goto invalid_evt_sz;
5376 break;
5377 }
5378 case LEAPRAID_EVT_SAS_ENCL_DEV_STATUS_CHANGE:
5379 if (evt_sz <
5380 sizeof(struct leapraid_evt_data_sas_enc_dev_status_change))
5381 goto invalid_evt_sz;
5382 break;
5383 default:
5384 break;
5385 }
5386
5387 return true;
5388
5389 invalid_evt_sz:
5390 dev_warn(&adapter->pdev->dev,
5391 "%s: Invalid async event size=%zu for evt=0x%x\n",
5392 __func__, evt_sz, evt);
5393 return false;
5394 }
5395
leapraid_async_process_evt(struct leapraid_adapter * adapter,struct leapraid_evt_notify_rep * event_notify_rep)5396 static bool leapraid_async_process_evt(
5397 struct leapraid_adapter *adapter,
5398 struct leapraid_evt_notify_rep *event_notify_rep)
5399 {
5400 u16 evt = le16_to_cpu(event_notify_rep->evt);
5401 bool exit_flag = false;
5402
5403 if (adapter->access_ctrl.host_removing ||
5404 adapter->access_ctrl.pcie_recovering)
5405 return true;
5406
5407 switch (evt) {
5408 case LEAPRAID_EVT_SAS_DEV_STATUS_CHANGE:
5409 leapraid_sas_dev_stat_chg_evt(
5410 adapter,
5411 (struct leapraid_evt_data_sas_dev_status_change
5412 *)event_notify_rep->evt_data);
5413 break;
5414 case LEAPRAID_EVT_IR_CHANGE:
5415 leapraid_check_ir_change_evt(
5416 adapter,
5417 (struct leapraid_evt_data_ir_change
5418 *)event_notify_rep->evt_data);
5419 break;
5420 case LEAPRAID_EVT_SAS_TOPO_CHANGE_LIST:
5421 leapraid_check_topo_del_evts(
5422 adapter,
5423 (struct leapraid_evt_data_sas_topo_change_list
5424 *)event_notify_rep->evt_data);
5425 if (adapter->access_ctrl.shost_recovering) {
5426 exit_flag = true;
5427 return exit_flag;
5428 }
5429 break;
5430 case LEAPRAID_EVT_SAS_ENCL_DEV_STATUS_CHANGE:
5431 break;
5432 default:
5433 exit_flag = true;
5434 return exit_flag;
5435 }
5436
5437 return exit_flag;
5438 }
5439
leapraid_async_evt_cb_enqueue(struct leapraid_adapter * adapter,struct leapraid_evt_notify_rep * evt_notify_rep)5440 static void leapraid_async_evt_cb_enqueue(
5441 struct leapraid_adapter *adapter,
5442 struct leapraid_evt_notify_rep *evt_notify_rep)
5443 {
5444 struct leapraid_fw_evt_work *fw_evt;
5445 u16 evt_sz;
5446
5447 fw_evt = leapraid_alloc_fw_evt_work();
5448 if (!fw_evt)
5449 return;
5450
5451 evt_sz = le16_to_cpu(evt_notify_rep->evt_data_len) * sizeof(u32);
5452 fw_evt->evt_data = kmemdup(evt_notify_rep->evt_data,
5453 evt_sz, GFP_ATOMIC);
5454 if (!fw_evt->evt_data) {
5455 leapraid_fw_evt_put(fw_evt);
5456 return;
5457 }
5458 fw_evt->adapter = adapter;
5459 fw_evt->evt_type = le16_to_cpu(evt_notify_rep->evt);
5460 leapraid_fw_evt_add(adapter, fw_evt);
5461 leapraid_fw_evt_put(fw_evt);
5462 }
5463
leapraid_async_evt_cb(struct leapraid_adapter * adapter,u8 msix_index,u32 rep_paddr)5464 static void leapraid_async_evt_cb(struct leapraid_adapter *adapter,
5465 u8 msix_index, u32 rep_paddr)
5466 {
5467 struct leapraid_evt_notify_rep *evt_notify_rep;
5468
5469 if (adapter->access_ctrl.host_removing ||
5470 adapter->access_ctrl.pcie_recovering)
5471 return;
5472
5473 evt_notify_rep = leapraid_get_reply_vaddr(adapter, rep_paddr);
5474 if (unlikely(!evt_notify_rep))
5475 return;
5476
5477 if (!leapraid_async_evt_validate(adapter, evt_notify_rep))
5478 return;
5479
5480 if (leapraid_async_process_evt(adapter, evt_notify_rep))
5481 return;
5482
5483 leapraid_async_evt_cb_enqueue(adapter, evt_notify_rep);
5484 }
5485
leapraid_handle_async_event(struct leapraid_adapter * adapter,u8 msix_index,u32 reply)5486 static void leapraid_handle_async_event(struct leapraid_adapter *adapter,
5487 u8 msix_index, u32 reply)
5488 {
5489 struct leapraid_evt_notify_rep *leap_mpi_rep =
5490 leapraid_get_reply_vaddr(adapter, reply);
5491
5492 if (!leap_mpi_rep)
5493 return;
5494
5495 if (leap_mpi_rep->func != LEAPRAID_FUNC_EVENT_NOTIFY)
5496 return;
5497
5498 leapraid_async_evt_cb(adapter, msix_index, reply);
5499 }
5500
leapraid_async_turn_on_led(struct leapraid_adapter * adapter,u16 handle)5501 void leapraid_async_turn_on_led(struct leapraid_adapter *adapter, u16 handle)
5502 {
5503 struct leapraid_fw_evt_work *fw_event;
5504
5505 fw_event = leapraid_alloc_fw_evt_work();
5506 if (!fw_event)
5507 return;
5508
5509 fw_event->dev_handle = handle;
5510 fw_event->adapter = adapter;
5511 fw_event->evt_type = LEAPRAID_EVT_TURN_ON_PFA_LED;
5512 leapraid_fw_evt_add(adapter, fw_event);
5513 leapraid_fw_evt_put(fw_event);
5514 }
5515
leapraid_hardreset_barrier(struct leapraid_adapter * adapter)5516 static void leapraid_hardreset_barrier(struct leapraid_adapter *adapter)
5517 {
5518 struct leapraid_fw_evt_work *fw_event;
5519
5520 fw_event = leapraid_alloc_fw_evt_work();
5521 if (!fw_event)
5522 return;
5523
5524 fw_event->adapter = adapter;
5525 fw_event->evt_type = LEAPRAID_EVT_REMOVE_DEAD_DEV;
5526 leapraid_fw_evt_add(adapter, fw_event);
5527 leapraid_fw_evt_put(fw_event);
5528 }
5529
leapraid_scan_dev_complete(struct leapraid_adapter * adapter)5530 static void leapraid_scan_dev_complete(struct leapraid_adapter *adapter)
5531 {
5532 struct leapraid_fw_evt_work *fw_evt;
5533
5534 fw_evt = leapraid_alloc_fw_evt_work();
5535 if (!fw_evt)
5536 return;
5537
5538 fw_evt->evt_type = LEAPRAID_EVT_SCAN_DEV_DONE;
5539 fw_evt->adapter = adapter;
5540 leapraid_fw_evt_add(adapter, fw_evt);
5541 leapraid_fw_evt_put(fw_evt);
5542 }
5543
leapraid_handle_scan_cb(struct leapraid_adapter * adapter,struct leapraid_driver_cmd * cmd,struct leapraid_rep * rep)5544 static void leapraid_handle_scan_cb(struct leapraid_adapter *adapter,
5545 struct leapraid_driver_cmd *cmd,
5546 struct leapraid_rep *rep)
5547 {
5548 u16 status;
5549
5550 cmd->status &= ~LEAPRAID_CMD_PENDING;
5551
5552 status = le16_to_cpu(rep->adapter_status) &
5553 LEAPRAID_ADAPTER_STATUS_MASK;
5554 if (status != LEAPRAID_ADAPTER_STATUS_SUCCESS)
5555 adapter->scan_dev_desc.scan_dev_failed = 1;
5556
5557 if (!cmd->async_scan_dev) {
5558 complete(&cmd->done);
5559 return;
5560 }
5561
5562 if (status == LEAPRAID_ADAPTER_STATUS_SUCCESS)
5563 leapraid_scan_dev_complete(adapter);
5564 else
5565 adapter->scan_dev_desc.scan_start_failed = status;
5566 }
5567
leapraid_handle_ctl_cb(struct leapraid_adapter * adapter,struct leapraid_rep * rep,u16 taskid)5568 static void leapraid_handle_ctl_cb(struct leapraid_adapter *adapter,
5569 struct leapraid_rep *rep,
5570 u16 taskid)
5571 {
5572 struct leapraid_scsiio_rep *scsiio_reply;
5573
5574 if (rep->function != LEAPRAID_FUNC_SCSIIO &&
5575 rep->function != LEAPRAID_FUNC_SCSIIO_RAID_PASSTHROUGH)
5576 return;
5577
5578 scsiio_reply = (struct leapraid_scsiio_rep *)rep;
5579 if (!(scsiio_reply->scsi_state &
5580 LEAPRAID_SCSI_STATE_AUTOSENSE_VALID))
5581 return;
5582
5583 memcpy(&adapter->driver_cmds.ctl_cmd.sense,
5584 leapraid_get_sense_buffer(adapter, taskid),
5585 min_t(u32, SCSI_SENSE_BUFFERSIZE,
5586 le32_to_cpu(scsiio_reply->sense_count)));
5587 }
5588
leapraid_driver_cmds_done(struct leapraid_adapter * adapter,u16 taskid,u8 msix_index,u32 rep_paddr,u8 cb_idx)5589 static bool leapraid_driver_cmds_done(struct leapraid_adapter *adapter,
5590 u16 taskid, u8 msix_index,
5591 u32 rep_paddr, u8 cb_idx)
5592 {
5593 struct leapraid_rep *leap_mpi_rep =
5594 leapraid_get_reply_vaddr(adapter, rep_paddr);
5595 struct leapraid_driver_cmd *sp_cmd, *_sp_cmd = NULL;
5596 u8 reply_len;
5597
5598 list_for_each_entry(sp_cmd, &adapter->driver_cmds.special_cmd_list,
5599 list)
5600 if (cb_idx == sp_cmd->cb_idx) {
5601 _sp_cmd = sp_cmd;
5602 break;
5603 }
5604
5605 if (WARN_ON(!_sp_cmd))
5606 return true;
5607 if (WARN_ON(_sp_cmd->status == LEAPRAID_CMD_NOT_USED))
5608 return true;
5609 if (WARN_ON(taskid != _sp_cmd->hp_taskid &&
5610 taskid != _sp_cmd->taskid &&
5611 taskid != _sp_cmd->inter_taskid))
5612 return true;
5613 _sp_cmd->status |= LEAPRAID_CMD_DONE;
5614 if (leap_mpi_rep) {
5615 reply_len = leap_mpi_rep->msg_len * sizeof(u32);
5616 if (reply_len > LEAPRAID_REPLY_SIZE)
5617 reply_len = LEAPRAID_REPLY_SIZE;
5618 memcpy(&_sp_cmd->reply, leap_mpi_rep, reply_len);
5619 _sp_cmd->status |= LEAPRAID_CMD_REPLY_VALID;
5620
5621 if (_sp_cmd->cb_idx == LEAPRAID_SCAN_DEV_CB_IDX) {
5622 leapraid_handle_scan_cb(adapter, _sp_cmd,
5623 leap_mpi_rep);
5624 return true;
5625 }
5626
5627 if (_sp_cmd->cb_idx == LEAPRAID_CTL_CB_IDX)
5628 leapraid_handle_ctl_cb(adapter, leap_mpi_rep, taskid);
5629 }
5630
5631 _sp_cmd->status &= ~LEAPRAID_CMD_PENDING;
5632 complete(&_sp_cmd->done);
5633
5634 return true;
5635 }
5636
leapraid_complete_task(struct leapraid_adapter * adapter,u16 taskid,u8 msix_idx,u32 rep)5637 static void leapraid_complete_task(struct leapraid_adapter *adapter,
5638 u16 taskid, u8 msix_idx, u32 rep)
5639 {
5640 bool scsiio_task = taskid <= adapter->shost->can_queue;
5641
5642 if (scsiio_task) {
5643 if (leapraid_scsiio_done(adapter, taskid, msix_idx, rep))
5644 leapraid_free_taskid(adapter, taskid);
5645 return;
5646 }
5647
5648 if (leapraid_driver_cmds_done(adapter, taskid, msix_idx, rep,
5649 leapraid_get_cb_idx(adapter, taskid)))
5650 leapraid_free_taskid(adapter, taskid);
5651 }
5652
leapraid_request_descript_handler(struct leapraid_adapter * adapter,union leapraid_rep_desc_union * rpf,u8 req_desc_type,u8 msix_idx)5653 static void leapraid_request_descript_handler(
5654 struct leapraid_adapter *adapter,
5655 union leapraid_rep_desc_union *rpf,
5656 u8 req_desc_type, u8 msix_idx)
5657 {
5658 u32 rep;
5659 u16 taskid;
5660
5661 rep = 0;
5662 taskid = le16_to_cpu(rpf->dflt_rep.taskid);
5663 switch (req_desc_type) {
5664 case LEAPRAID_RPY_DESC_FLG_FP_SCSI_IO_SUCCESS:
5665 case LEAPRAID_RPY_DESC_FLG_SCSI_IO_SUCCESS:
5666 leapraid_complete_task(adapter, taskid, msix_idx, 0);
5667 break;
5668 case LEAPRAID_RPY_DESC_FLG_ADDRESS_REPLY:
5669 rep = le32_to_cpu(rpf->addr_rep.rep_frame_addr);
5670 if (rep > (u32)adapter->mem_desc.rep_msg_dma +
5671 adapter->adapter_attr.rep_msg_qd *
5672 LEAPRAID_REPLY_SIZE ||
5673 rep < (u32)adapter->mem_desc.rep_msg_dma)
5674 rep = 0;
5675
5676 if (taskid)
5677 leapraid_complete_task(adapter, taskid, msix_idx, rep);
5678 else
5679 leapraid_handle_async_event(adapter, msix_idx, rep);
5680
5681 if (!rep)
5682 return;
5683
5684 adapter->rep_msg_host_idx =
5685 (adapter->rep_msg_host_idx ==
5686 (adapter->adapter_attr.rep_msg_qd - 1)) ?
5687 0 : adapter->rep_msg_host_idx + 1;
5688 adapter->mem_desc.rep_msg_addr[adapter->rep_msg_host_idx] =
5689 cpu_to_le32(rep);
5690 wmb(); /* Make sure that all write ops are in order */
5691 writel(adapter->rep_msg_host_idx,
5692 &adapter->iomem_base->rep_msg_host_idx);
5693
5694 break;
5695 default:
5696 break;
5697 }
5698 }
5699
leapraid_rep_queue_handler(struct leapraid_rq * rq)5700 int leapraid_rep_queue_handler(struct leapraid_rq *rq)
5701 {
5702 struct leapraid_adapter *adapter = rq->adapter;
5703 union leapraid_rep_desc_union *rep_desc;
5704 u8 req_desc_type;
5705 u64 finish_cmds;
5706 u8 msix_idx;
5707
5708 msix_idx = rq->msix_idx;
5709 finish_cmds = 0;
5710 if (!atomic_add_unless(&rq->busy, LEAPRAID_BUSY_LIMIT,
5711 LEAPRAID_BUSY_LIMIT))
5712 return finish_cmds;
5713
5714 rep_desc = &rq->rep_desc[rq->rep_post_host_idx];
5715 req_desc_type = rep_desc->dflt_rep.rep_flg &
5716 LEAPRAID_RPY_DESC_FLG_TYPE_MASK;
5717 if (req_desc_type == LEAPRAID_RPY_DESC_FLG_UNUSED) {
5718 atomic_dec(&rq->busy);
5719 return finish_cmds;
5720 }
5721
5722 for (;;) {
5723 if (rep_desc->u.low == UINT_MAX ||
5724 rep_desc->u.high == UINT_MAX)
5725 break;
5726
5727 leapraid_request_descript_handler(adapter, rep_desc,
5728 req_desc_type, msix_idx);
5729 dev_dbg(&adapter->pdev->dev,
5730 "LEAPRAID_SCSIIO: Handled Desc taskid %d, msix %d\n",
5731 rep_desc->dflt_rep.taskid, msix_idx);
5732 rep_desc->words = cpu_to_le64(ULLONG_MAX);
5733 rq->rep_post_host_idx =
5734 (rq->rep_post_host_idx ==
5735 (adapter->adapter_attr.rep_desc_qd -
5736 LEAPRAID_BUSY_LIMIT)) ?
5737 0 : rq->rep_post_host_idx + 1;
5738 req_desc_type =
5739 rq->rep_desc[rq->rep_post_host_idx].dflt_rep.rep_flg &
5740 LEAPRAID_RPY_DESC_FLG_TYPE_MASK;
5741 finish_cmds++;
5742 if (req_desc_type == LEAPRAID_RPY_DESC_FLG_UNUSED)
5743 break;
5744 rep_desc = rq->rep_desc + rq->rep_post_host_idx;
5745 }
5746
5747 if (!finish_cmds) {
5748 atomic_dec(&rq->busy);
5749 return finish_cmds;
5750 }
5751
5752 wmb(); /* Make sure that all write ops are in order */
5753 writel(rq->rep_post_host_idx | ((msix_idx & LEAPRAID_MSIX_GROUP_MASK) <<
5754 LEAPRAID_RPHI_MSIX_IDX_SHIFT),
5755 &adapter->iomem_base->rep_post_reg_idx[
5756 msix_idx / LEAPRAID_MSIX_GROUP_SIZE].idx);
5757 atomic_dec(&rq->busy);
5758 return finish_cmds;
5759 }
5760
leapraid_irq_handler(int irq,void * bus_id)5761 static irqreturn_t leapraid_irq_handler(int irq, void *bus_id)
5762 {
5763 struct leapraid_rq *rq = bus_id;
5764 struct leapraid_adapter *adapter = rq->adapter;
5765
5766 dev_dbg(&adapter->pdev->dev,
5767 "LEAPRAID_SCSIIO: Receive a interrupt, irq %d msix %d\n",
5768 irq, rq->msix_idx);
5769
5770 if (adapter->mask_int)
5771 return IRQ_NONE;
5772
5773 return (leapraid_rep_queue_handler(rq) > 0 ?
5774 IRQ_HANDLED : IRQ_NONE);
5775 }
5776
leapraid_sync_irqs(struct leapraid_adapter * adapter,bool poll)5777 void leapraid_sync_irqs(struct leapraid_adapter *adapter, bool poll)
5778 {
5779 struct leapraid_int_rq *int_rq;
5780 struct leapraid_blk_mq_poll_rq *blk_mq_poll_rq;
5781 unsigned int i;
5782
5783 if (!adapter->notification_desc.msix_enable)
5784 return;
5785
5786 if (adapter->access_ctrl.shost_recovering ||
5787 adapter->access_ctrl.host_removing ||
5788 adapter->access_ctrl.pcie_recovering)
5789 return;
5790
5791 for (i = 0; i < adapter->notification_desc.iopoll_qdex; i++) {
5792 int_rq = &adapter->notification_desc.int_rqs[i];
5793 if (adapter->access_ctrl.shost_recovering ||
5794 adapter->access_ctrl.host_removing ||
5795 adapter->access_ctrl.pcie_recovering)
5796 return;
5797
5798 if (int_rq->rq.msix_idx == 0)
5799 continue;
5800
5801 synchronize_irq(pci_irq_vector(adapter->pdev,
5802 int_rq->rq.msix_idx));
5803 if (poll)
5804 leapraid_rep_queue_handler(&int_rq->rq);
5805 }
5806
5807 for (i = 0; i < adapter->notification_desc.iopoll_qcnt; i++) {
5808 blk_mq_poll_rq =
5809 &adapter->notification_desc.blk_mq_poll_rqs[i];
5810 if (adapter->access_ctrl.shost_recovering ||
5811 adapter->access_ctrl.host_removing ||
5812 adapter->access_ctrl.pcie_recovering)
5813 return;
5814
5815 if (blk_mq_poll_rq->rq.msix_idx == 0)
5816 continue;
5817
5818 leapraid_rep_queue_handler(&blk_mq_poll_rq->rq);
5819 }
5820 }
5821
leapraid_sync_irqs_for_cleanup(struct leapraid_adapter * adapter)5822 static void leapraid_sync_irqs_for_cleanup(struct leapraid_adapter *adapter)
5823 {
5824 struct leapraid_notification_desc *desc = &adapter->notification_desc;
5825 struct leapraid_int_rq *int_rq;
5826 unsigned int i;
5827
5828 if (!adapter->mask_int && leapraid_pci_active(adapter))
5829 leapraid_mask_int(adapter);
5830
5831 for (i = 0; i < desc->int_rqs_allocated; i++) {
5832 int_rq = &desc->int_rqs[i];
5833 synchronize_irq(pci_irq_vector(adapter->pdev,
5834 int_rq->rq.msix_idx));
5835 }
5836 }
5837
leapraid_mq_polling_pause(struct leapraid_adapter * adapter)5838 void leapraid_mq_polling_pause(struct leapraid_adapter *adapter)
5839 {
5840 struct leapraid_notification_desc *desc;
5841 int iopoll_q_count;
5842 int qid;
5843
5844 desc = &adapter->notification_desc;
5845 iopoll_q_count = adapter->adapter_attr.rq_cnt - desc->iopoll_qdex;
5846
5847 for (qid = 0; qid < iopoll_q_count; qid++)
5848 atomic_set(&desc->blk_mq_poll_rqs[qid].pause, 1);
5849
5850 for (qid = 0; qid < iopoll_q_count; qid++) {
5851 while (atomic_read(&desc->blk_mq_poll_rqs[qid].busy)) {
5852 cpu_relax();
5853 udelay(LEAPRAID_IO_POLL_DELAY_US);
5854 }
5855 }
5856 }
5857
leapraid_mq_polling_resume(struct leapraid_adapter * adapter)5858 void leapraid_mq_polling_resume(struct leapraid_adapter *adapter)
5859 {
5860 struct leapraid_notification_desc *desc;
5861 int iopoll_q_count;
5862 int qid;
5863
5864 desc = &adapter->notification_desc;
5865 iopoll_q_count = adapter->adapter_attr.rq_cnt - desc->iopoll_qdex;
5866
5867 for (qid = 0; qid < iopoll_q_count; qid++)
5868 atomic_set(&desc->blk_mq_poll_rqs[qid].pause, 0);
5869 }
5870
leapraid_unlock_host_diag(struct leapraid_adapter * adapter,u32 * host_diag)5871 static int leapraid_unlock_host_diag(struct leapraid_adapter *adapter,
5872 u32 *host_diag)
5873 {
5874 const u32 unlock_seq[] = {
5875 LEAPRAID_WRSEQ_FLUSH_KEY_VALUE,
5876 LEAPRAID_WRSEQ_1ST_KEY_VALUE,
5877 LEAPRAID_WRSEQ_2ND_KEY_VALUE,
5878 LEAPRAID_WRSEQ_3RD_KEY_VALUE,
5879 LEAPRAID_WRSEQ_4TH_KEY_VALUE,
5880 LEAPRAID_WRSEQ_5TH_KEY_VALUE,
5881 LEAPRAID_WRSEQ_6TH_KEY_VALUE
5882 };
5883
5884 const int max_retries = LEAPRAID_UNLOCK_RETRY_LIMIT;
5885 int retry = 0;
5886 unsigned int i;
5887
5888 *host_diag = 0;
5889 while (retry++ <= max_retries) {
5890 for (i = 0; i < ARRAY_SIZE(unlock_seq); i++)
5891 writel(unlock_seq[i], &adapter->iomem_base->ws);
5892
5893 msleep(LEAPRAID_UNLOCK_SLEEP_MS);
5894
5895 *host_diag = leapraid_readl(&adapter->iomem_base->host_diag);
5896 if (*host_diag & LEAPRAID_DIAG_WRITE_ENABLE)
5897 return 0;
5898 }
5899
5900 dev_err(&adapter->pdev->dev, "Try host reset timeout!\n");
5901 return -EFAULT;
5902 }
5903
leapraid_host_diag_reset(struct leapraid_adapter * adapter)5904 static int leapraid_host_diag_reset(struct leapraid_adapter *adapter)
5905 {
5906 u32 host_diag;
5907
5908 pci_cfg_access_lock(adapter->pdev);
5909
5910 mutex_lock(&adapter->reset_desc.host_diag_mutex);
5911 if (leapraid_unlock_host_diag(adapter, &host_diag))
5912 goto out_cleanup;
5913
5914 writel(host_diag | LEAPRAID_DIAG_RESET,
5915 &adapter->iomem_base->host_diag);
5916
5917 msleep(LEAPRAID_MSLEEP_EXTRA_LONG_MS);
5918 msleep(LEAPRAID_MSLEEP_NORMAL_MS);
5919
5920 host_diag = leapraid_readl(&adapter->iomem_base->host_diag);
5921 if (host_diag == LEAPRAID_INVALID_HOST_DIAG_VAL ||
5922 host_diag & LEAPRAID_DIAG_RESET)
5923 goto out_cleanup;
5924
5925 writel(0x0, &adapter->iomem_base->ws);
5926 mutex_unlock(&adapter->reset_desc.host_diag_mutex);
5927 if (!leapraid_wait_adapter_ready(adapter))
5928 goto out_failed;
5929
5930 pci_cfg_access_unlock(adapter->pdev);
5931 return 0;
5932
5933 out_cleanup:
5934 mutex_unlock(&adapter->reset_desc.host_diag_mutex);
5935 out_failed:
5936 pci_cfg_access_unlock(adapter->pdev);
5937 dev_err(&adapter->pdev->dev, "Host diag failed\n");
5938 return -EFAULT;
5939 }
5940
leapraid_find_matching_port(struct leapraid_card_port * card_port_table,u8 count,u8 port_id,u64 sas_addr)5941 static int leapraid_find_matching_port(
5942 struct leapraid_card_port *card_port_table,
5943 u8 count, u8 port_id, u64 sas_addr)
5944 {
5945 int i;
5946
5947 for (i = 0; i < count; i++)
5948 if (card_port_table[i].port_id == port_id &&
5949 card_port_table[i].sas_address == sas_addr)
5950 return i;
5951
5952 return LEAPRAID_INVALID_INDEX;
5953 }
5954
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)5955 static u8 leapraid_fill_card_port_table(
5956 struct leapraid_adapter *adapter,
5957 struct leapraid_sas_io_unit_p0 *sas_iounit_p0,
5958 struct leapraid_card_port *new_card_port_table)
5959 {
5960 u8 port_entry_num = 0, port_id;
5961 u16 attached_hdl;
5962 u64 attached_sas_addr;
5963 int i, idx;
5964
5965 for (i = 0; i < adapter->dev_topo.card.phys_num; i++) {
5966 if (sas_iounit_p0->phy_info[i].neg_link_rate >>
5967 LEAPRAID_SAS_NEG_LINK_RATE_SHIFT <
5968 LEAPRAID_SAS_NEG_LINK_RATE_1_5)
5969 continue;
5970
5971 attached_hdl = le16_to_cpu(sas_iounit_p0->phy_info[i]
5972 .attached_dev_hdl);
5973 if (leapraid_get_sas_address(adapter,
5974 attached_hdl,
5975 &attached_sas_addr) != 0)
5976 continue;
5977
5978 port_id = sas_iounit_p0->phy_info[i].port;
5979
5980 idx = leapraid_find_matching_port(new_card_port_table,
5981 port_entry_num,
5982 port_id,
5983 attached_sas_addr);
5984 if (idx >= 0) {
5985 new_card_port_table[idx].phy_mask |= BIT(i);
5986 } else {
5987 new_card_port_table[port_entry_num].port_id = port_id;
5988 new_card_port_table[port_entry_num].phy_mask = BIT(i);
5989 new_card_port_table[port_entry_num].sas_address =
5990 attached_sas_addr;
5991 port_entry_num++;
5992 }
5993 }
5994
5995 return port_entry_num;
5996 }
5997
leapraid_set_new_card_port_table_after_reset(struct leapraid_adapter * adapter,struct leapraid_card_port * new_card_port_table)5998 static u8 leapraid_set_new_card_port_table_after_reset(
5999 struct leapraid_adapter *adapter,
6000 struct leapraid_card_port *new_card_port_table)
6001 {
6002 union cfg_param_1 cfgp1 = {0};
6003 union cfg_param_2 cfgp2 = {0};
6004 struct leapraid_sas_io_unit_p0 *sas_iounit_p0;
6005 u8 port_entry_num = 0;
6006 u16 sz;
6007
6008 sz = offsetof(struct leapraid_sas_io_unit_p0, phy_info) +
6009 (adapter->dev_topo.card.phys_num *
6010 sizeof(struct leapraid_sas_io_unit0_phy_info));
6011 sas_iounit_p0 = kzalloc(sz, GFP_KERNEL);
6012 if (!sas_iounit_p0)
6013 return port_entry_num;
6014
6015 cfgp1.size = sz;
6016 if (leapraid_op_config_page(adapter, sas_iounit_p0, cfgp1, cfgp2,
6017 GET_SAS_IOUNIT_PG0) != 0)
6018 goto out_free;
6019
6020 port_entry_num = leapraid_fill_card_port_table(adapter,
6021 sas_iounit_p0,
6022 new_card_port_table);
6023 out_free:
6024 kfree(sas_iounit_p0);
6025 return port_entry_num;
6026 }
6027
leapraid_update_existing_port(struct leapraid_adapter * adapter,struct leapraid_card_port * new_table,int entry_idx,int port_entry_num)6028 static void leapraid_update_existing_port(struct leapraid_adapter *adapter,
6029 struct leapraid_card_port *new_table,
6030 int entry_idx, int port_entry_num)
6031 {
6032 struct leapraid_card_port *matched_card_port;
6033 int matched_code;
6034 int count, lcount = 0;
6035 u64 sas_addr;
6036 int i;
6037
6038 matched_code = leapraid_check_card_port(adapter,
6039 &new_table[entry_idx],
6040 &matched_card_port,
6041 &count);
6042
6043 if (!matched_card_port)
6044 return;
6045
6046 if (matched_code == SAME_PORT_WITH_PARTIALLY_CHANGED_PHYS ||
6047 matched_code == SAME_ADDR_WITH_PARTIALLY_CHANGED_PHYS) {
6048 leapraid_add_or_del_phys_from_existing_port(adapter,
6049 matched_card_port,
6050 new_table,
6051 entry_idx,
6052 port_entry_num);
6053 } else if (matched_code == SAME_ADDR_ONLY) {
6054 sas_addr = new_table[entry_idx].sas_address;
6055 for (i = 0; i < port_entry_num; i++)
6056 if (new_table[i].sas_address == sas_addr)
6057 lcount++;
6058
6059 if (count > 1 || lcount > 1)
6060 return;
6061
6062 leapraid_add_or_del_phys_from_existing_port(adapter,
6063 matched_card_port,
6064 new_table,
6065 entry_idx,
6066 port_entry_num);
6067 }
6068
6069 if (matched_card_port->port_id != new_table[entry_idx].port_id)
6070 matched_card_port->port_id = new_table[entry_idx].port_id;
6071
6072 matched_card_port->flg &= ~LEAPRAID_CARD_PORT_FLG_DIRTY;
6073 matched_card_port->phy_mask = new_table[entry_idx].phy_mask;
6074 }
6075
leapraid_update_card_port_after_reset(struct leapraid_adapter * adapter)6076 static void leapraid_update_card_port_after_reset(
6077 struct leapraid_adapter *adapter)
6078 {
6079 struct leapraid_card_port *new_card_port_table;
6080 struct leapraid_card_port *matched_card_port;
6081 u8 port_entry_num;
6082 u8 nr_phys;
6083 int i;
6084
6085 if (leapraid_get_adapter_phys(adapter, &nr_phys) || !nr_phys)
6086 return;
6087
6088 if (!adapter->dev_topo.card.card_phy) {
6089 adapter->dev_topo.card.card_phy =
6090 kzalloc_objs(struct leapraid_card_phy, nr_phys);
6091 if (!adapter->dev_topo.card.card_phy)
6092 return;
6093 }
6094
6095 adapter->dev_topo.card.phys_num = nr_phys;
6096
6097 new_card_port_table = kzalloc_objs(struct leapraid_card_port,
6098 adapter->dev_topo.card.phys_num);
6099 if (!new_card_port_table)
6100 return;
6101
6102 port_entry_num =
6103 leapraid_set_new_card_port_table_after_reset(
6104 adapter,
6105 new_card_port_table);
6106 if (!port_entry_num)
6107 goto out_free_port_table;
6108
6109 list_for_each_entry(matched_card_port,
6110 &adapter->dev_topo.card_port_list, list)
6111 matched_card_port->flg |= LEAPRAID_CARD_PORT_FLG_DIRTY;
6112
6113 matched_card_port = NULL;
6114 for (i = 0; i < port_entry_num; i++)
6115 leapraid_update_existing_port(adapter,
6116 new_card_port_table,
6117 i, port_entry_num);
6118 out_free_port_table:
6119 kfree(new_card_port_table);
6120 }
6121
leapraid_is_valid_vphy(struct leapraid_adapter * adapter,struct leapraid_sas_io_unit_p0 * sas_io_unit_p0,int phy_index)6122 static bool leapraid_is_valid_vphy(
6123 struct leapraid_adapter *adapter,
6124 struct leapraid_sas_io_unit_p0 *sas_io_unit_p0,
6125 int phy_index)
6126 {
6127 union cfg_param_1 cfgp1 = {0};
6128 union cfg_param_2 cfgp2 = {0};
6129 struct leapraid_sas_phy_p0 phy_p0;
6130 u32 dev_info;
6131
6132 if (sas_io_unit_p0->phy_info[phy_index].neg_link_rate >>
6133 LEAPRAID_SAS_NEG_LINK_RATE_SHIFT <
6134 LEAPRAID_SAS_NEG_LINK_RATE_1_5)
6135 return false;
6136
6137 dev_info = le32_to_cpu(sas_io_unit_p0->phy_info[phy_index]
6138 .controller_phy_dev_info);
6139 if (!(dev_info & LEAPRAID_DEVTYP_SEP))
6140 return false;
6141
6142 cfgp1.phy_number = phy_index;
6143 if (leapraid_op_config_page(adapter, &phy_p0, cfgp1, cfgp2,
6144 GET_PHY_PG0))
6145 return false;
6146
6147 if (!(le32_to_cpu(phy_p0.phy_info) & LEAPRAID_SAS_PHYINFO_VPHY))
6148 return false;
6149
6150 return true;
6151 }
6152
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)6153 static void leapraid_update_vphy_binding(struct leapraid_adapter *adapter,
6154 struct leapraid_card_port *card_port,
6155 struct leapraid_vphy *vphy,
6156 int phy_index, u8 may_new_port_id,
6157 u64 attached_sas_addr)
6158 {
6159 struct leapraid_card_port *may_new_card_port;
6160 struct leapraid_sas_dev *sas_dev;
6161
6162 may_new_card_port = leapraid_get_port_by_id(adapter,
6163 may_new_port_id,
6164 true);
6165 if (!may_new_card_port) {
6166 may_new_card_port = kzalloc_obj(*may_new_card_port);
6167 if (!may_new_card_port)
6168 return;
6169 may_new_card_port->port_id = may_new_port_id;
6170 dev_err(&adapter->pdev->dev,
6171 "%s: New card port %p added, port=%d\n",
6172 __func__, may_new_card_port, may_new_port_id);
6173 list_add_tail(&may_new_card_port->list,
6174 &adapter->dev_topo.card_port_list);
6175 }
6176
6177 if (card_port != may_new_card_port) {
6178 if (!may_new_card_port->vphys_mask)
6179 INIT_LIST_HEAD(&may_new_card_port->vphys_list);
6180 may_new_card_port->vphys_mask |= BIT(phy_index);
6181 card_port->vphys_mask &= ~BIT(phy_index);
6182 list_move(&vphy->list, &may_new_card_port->vphys_list);
6183
6184 sas_dev = leapraid_get_sas_dev_by_addr(adapter,
6185 attached_sas_addr,
6186 card_port);
6187 if (sas_dev) {
6188 sas_dev->card_port = may_new_card_port;
6189 leapraid_sdev_put(sas_dev);
6190 }
6191 }
6192
6193 if (may_new_card_port->flg & LEAPRAID_CARD_PORT_FLG_DIRTY) {
6194 may_new_card_port->sas_address = 0;
6195 may_new_card_port->phy_mask = 0;
6196 may_new_card_port->flg &= ~LEAPRAID_CARD_PORT_FLG_DIRTY;
6197 }
6198 vphy->flg &= ~LEAPRAID_VPHY_FLG_DIRTY;
6199 }
6200
leapraid_update_vphys_after_reset(struct leapraid_adapter * adapter)6201 static void leapraid_update_vphys_after_reset(struct leapraid_adapter *adapter)
6202 {
6203 union cfg_param_1 cfgp1 = {0};
6204 union cfg_param_2 cfgp2 = {0};
6205 struct leapraid_sas_io_unit_p0 *sas_iounit_p0;
6206 struct leapraid_card_port *card_port, *card_port_next;
6207 struct leapraid_vphy *vphy, *vphy_next;
6208 u64 attached_sas_addr;
6209 u16 sz;
6210 u16 attached_hdl;
6211 bool found = false;
6212 u8 port_id;
6213 int i;
6214
6215 list_for_each_entry_safe(card_port, card_port_next,
6216 &adapter->dev_topo.card_port_list, list) {
6217 if (!card_port->vphys_mask)
6218 continue;
6219
6220 list_for_each_entry_safe(vphy, vphy_next,
6221 &card_port->vphys_list, list)
6222 vphy->flg |= LEAPRAID_VPHY_FLG_DIRTY;
6223 }
6224
6225 sz = offsetof(struct leapraid_sas_io_unit_p0, phy_info) +
6226 (adapter->dev_topo.card.phys_num *
6227 sizeof(struct leapraid_sas_io_unit0_phy_info));
6228 sas_iounit_p0 = kzalloc(sz, GFP_KERNEL);
6229 if (!sas_iounit_p0)
6230 return;
6231
6232 cfgp1.size = sz;
6233 if (leapraid_op_config_page(adapter, sas_iounit_p0, cfgp1, cfgp2,
6234 GET_SAS_IOUNIT_PG0) != 0)
6235 goto out_free;
6236
6237 for (i = 0; i < adapter->dev_topo.card.phys_num; i++) {
6238 if (!leapraid_is_valid_vphy(adapter, sas_iounit_p0, i))
6239 continue;
6240
6241 attached_hdl =
6242 le16_to_cpu(sas_iounit_p0->phy_info[i]
6243 .attached_dev_hdl);
6244 if (leapraid_get_sas_address(adapter, attached_hdl,
6245 &attached_sas_addr) != 0)
6246 continue;
6247
6248 found = false;
6249 card_port = NULL;
6250 card_port_next = NULL;
6251 list_for_each_entry_safe(card_port, card_port_next,
6252 &adapter->dev_topo.card_port_list,
6253 list) {
6254 if (!card_port->vphys_mask)
6255 continue;
6256
6257 list_for_each_entry_safe(vphy, vphy_next,
6258 &card_port->vphys_list,
6259 list) {
6260 if (!(vphy->flg & LEAPRAID_VPHY_FLG_DIRTY))
6261 continue;
6262
6263 if (vphy->sas_address != attached_sas_addr)
6264 continue;
6265
6266 if (!(vphy->phy_mask & BIT(i)))
6267 vphy->phy_mask = BIT(i);
6268
6269 port_id = sas_iounit_p0->phy_info[i].port;
6270
6271 leapraid_update_vphy_binding(adapter,
6272 card_port,
6273 vphy,
6274 i,
6275 port_id,
6276 attached_sas_addr);
6277
6278 found = true;
6279 break;
6280 }
6281 if (found)
6282 break;
6283 }
6284 }
6285 out_free:
6286 kfree(sas_iounit_p0);
6287 }
6288
leapraid_mark_all_dev_deleted(struct leapraid_adapter * adapter)6289 static void leapraid_mark_all_dev_deleted(struct leapraid_adapter *adapter)
6290 {
6291 struct leapraid_sdev_priv *sdev_priv;
6292 struct scsi_device *sdev;
6293
6294 shost_for_each_device(sdev, adapter->shost) {
6295 sdev_priv = sdev->hostdata;
6296 if (sdev_priv && sdev_priv->starget_priv)
6297 sdev_priv->starget_priv->deleted = 1;
6298 }
6299 }
6300
leapraid_free_enc_list(struct leapraid_adapter * adapter)6301 static void leapraid_free_enc_list(struct leapraid_adapter *adapter)
6302 {
6303 struct leapraid_enc_node *enc_dev, *enc_dev_next;
6304 LIST_HEAD(free_list);
6305 unsigned long flags;
6306
6307 spin_lock_irqsave(&adapter->dev_topo.enc_lock, flags);
6308 list_splice_init(&adapter->dev_topo.enc_list, &free_list);
6309 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, flags);
6310
6311 list_for_each_entry_safe(enc_dev, enc_dev_next, &free_list, list) {
6312 list_del(&enc_dev->list);
6313 kfree(enc_dev);
6314 }
6315 }
6316
leapraid_rebuild_enc_list_after_reset(struct leapraid_adapter * adapter)6317 static void leapraid_rebuild_enc_list_after_reset(
6318 struct leapraid_adapter *adapter)
6319 {
6320 union cfg_param_1 cfgp1 = {0};
6321 union cfg_param_2 cfgp2 = {0};
6322 struct leapraid_enc_node *enc_node;
6323 u16 enc_hdl;
6324 unsigned long flags;
6325 int rc;
6326
6327 leapraid_free_enc_list(adapter);
6328
6329 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP;
6330 for (enc_hdl = 0xFFFF; ; enc_hdl = le16_to_cpu(enc_node->pg0.enc_hdl)) {
6331 enc_node = kzalloc_obj(*enc_node);
6332 if (!enc_node)
6333 return;
6334
6335 cfgp2.handle = enc_hdl;
6336 rc = leapraid_op_config_page(adapter, &enc_node->pg0, cfgp1,
6337 cfgp2, GET_SAS_ENCLOSURE_PG0);
6338 if (rc) {
6339 kfree(enc_node);
6340 return;
6341 }
6342
6343 spin_lock_irqsave(&adapter->dev_topo.enc_lock, flags);
6344 list_add_tail(&enc_node->list, &adapter->dev_topo.enc_list);
6345 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, flags);
6346 }
6347 }
6348
leapraid_mark_resp_sas_dev(struct leapraid_adapter * adapter,struct leapraid_sas_dev_p0 * sas_dev_p0)6349 static void leapraid_mark_resp_sas_dev(struct leapraid_adapter *adapter,
6350 struct leapraid_sas_dev_p0 *sas_dev_p0)
6351 {
6352 struct leapraid_starget_priv *starget_priv;
6353 struct leapraid_enc_node *enc_node = NULL;
6354 struct leapraid_card_port *card_port;
6355 struct leapraid_sas_dev *sas_dev;
6356 struct scsi_target *starget;
6357 unsigned long flags;
6358 unsigned long enc_flags = 0;
6359 u16 enc_hdl;
6360 u64 enc_lid = 0;
6361
6362 card_port = leapraid_get_port_by_id(adapter, sas_dev_p0->physical_port,
6363 false);
6364 enc_hdl = le16_to_cpu(sas_dev_p0->enc_hdl);
6365 if (enc_hdl) {
6366 spin_lock_irqsave(&adapter->dev_topo.enc_lock, enc_flags);
6367 enc_node = leapraid_enc_find_by_hdl(adapter, enc_hdl);
6368 if (enc_node)
6369 enc_lid = le64_to_cpu(enc_node->pg0.enc_lid);
6370 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, enc_flags);
6371 if (!enc_node)
6372 dev_info(&adapter->pdev->dev,
6373 "enc hdl 0x%04x has no matched enc dev\n",
6374 enc_hdl);
6375 }
6376
6377 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags);
6378 list_for_each_entry(sas_dev, &adapter->dev_topo.sas_dev_list, list) {
6379 if (sas_dev->sas_addr != le64_to_cpu(sas_dev_p0->sas_address) ||
6380 sas_dev->slot != le16_to_cpu(sas_dev_p0->slot) ||
6381 sas_dev->card_port != card_port)
6382 continue;
6383
6384 sas_dev->resp = 1;
6385 starget = sas_dev->starget;
6386 if (starget && starget->hostdata) {
6387 starget_priv = starget->hostdata;
6388 starget_priv->tm_busy = 0;
6389 starget_priv->deleted = 0;
6390 } else {
6391 starget_priv = NULL;
6392 }
6393
6394 if (starget) {
6395 starget_printk(
6396 KERN_INFO, starget,
6397 "dev: hdl=0x%04x saddr=0x%016llx port_id=%d\n",
6398 sas_dev->hdl,
6399 (unsigned long long)sas_dev->sas_addr,
6400 sas_dev->card_port->port_id);
6401 if (sas_dev->enc_hdl != 0)
6402 starget_printk(
6403 KERN_INFO,
6404 starget,
6405 "enc info: enc_lid=0x%016llx slot=%d\n",
6406 (unsigned long long)sas_dev->enc_lid,
6407 sas_dev->slot);
6408 }
6409
6410 if (le16_to_cpu(sas_dev_p0->flg) &
6411 LEAPRAID_SAS_DEV_P0_FLG_ENC_LEVEL_VALID) {
6412 sas_dev->enc_level = sas_dev_p0->enc_level;
6413 memcpy(sas_dev->connector_name,
6414 sas_dev_p0->connector_name,
6415 LEAPRAID_SAS_DEV_P0_CON_NAME_LEN);
6416 sas_dev->connector_name[
6417 LEAPRAID_SAS_DEV_P0_CON_NAME_LEN] = '\0';
6418 } else {
6419 sas_dev->enc_level = 0;
6420 sas_dev->connector_name[0] = '\0';
6421 }
6422
6423 sas_dev->enc_hdl = enc_hdl;
6424 sas_dev->enc_lid = enc_lid;
6425
6426 if (sas_dev->hdl == le16_to_cpu(sas_dev_p0->dev_hdl))
6427 goto unlock;
6428
6429 dev_info(&adapter->pdev->dev,
6430 "hdl changed: 0x%04x -> 0x%04x\n",
6431 sas_dev->hdl, sas_dev_p0->dev_hdl);
6432 sas_dev->hdl = le16_to_cpu(sas_dev_p0->dev_hdl);
6433 if (starget_priv)
6434 starget_priv->hdl = le16_to_cpu(sas_dev_p0->dev_hdl);
6435
6436 goto unlock;
6437 }
6438 unlock:
6439 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags);
6440 }
6441
leapraid_search_resp_sas_dev(struct leapraid_adapter * adapter)6442 static void leapraid_search_resp_sas_dev(struct leapraid_adapter *adapter)
6443 {
6444 union cfg_param_1 cfgp1 = {0};
6445 union cfg_param_2 cfgp2 = {0};
6446 struct leapraid_sas_dev_p0 sas_dev_p0;
6447 u32 device_info;
6448
6449 if (list_empty(&adapter->dev_topo.sas_dev_list))
6450 return;
6451
6452 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP;
6453 for (cfgp2.handle = 0xFFFF;
6454 !leapraid_op_config_page(adapter, &sas_dev_p0,
6455 cfgp1, cfgp2, GET_SAS_DEVICE_PG0);
6456 cfgp2.handle = le16_to_cpu(sas_dev_p0.dev_hdl)) {
6457 device_info = le32_to_cpu(sas_dev_p0.dev_info);
6458 if (!(leapraid_is_end_dev(device_info)))
6459 continue;
6460
6461 leapraid_mark_resp_sas_dev(adapter, &sas_dev_p0);
6462 }
6463 }
6464
leapraid_mark_resp_raid_volume(struct leapraid_adapter * adapter,u64 wwid,u16 hdl)6465 static void leapraid_mark_resp_raid_volume(struct leapraid_adapter *adapter,
6466 u64 wwid, u16 hdl)
6467 {
6468 struct leapraid_raid_volume *raid_volume;
6469 struct leapraid_starget_priv *starget_priv = NULL;
6470 struct scsi_target *starget;
6471 unsigned long flags;
6472 u64 volume_wwid;
6473 u16 old_hdl;
6474
6475 raid_volume = leapraid_raid_volume_find_by_wwid(adapter, wwid);
6476 if (!raid_volume)
6477 return;
6478
6479 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags);
6480 if (!raid_volume->starget) {
6481 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock,
6482 flags);
6483 leapraid_raid_volume_put(raid_volume);
6484 return;
6485 }
6486
6487 starget = raid_volume->starget;
6488 if (starget->hostdata) {
6489 starget_priv = starget->hostdata;
6490 starget_priv->deleted = 0;
6491 }
6492
6493 raid_volume->resp = 1;
6494 volume_wwid = raid_volume->wwid;
6495 old_hdl = raid_volume->hdl;
6496 if (old_hdl != hdl) {
6497 raid_volume->hdl = hdl;
6498 if (starget_priv)
6499 starget_priv->hdl = hdl;
6500 }
6501 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, flags);
6502
6503 starget_printk(KERN_INFO, starget,
6504 "raid volume: hdl=0x%04x, wwid=0x%016llx\n",
6505 hdl, (unsigned long long)volume_wwid);
6506 if (old_hdl != hdl)
6507 dev_info(&adapter->pdev->dev,
6508 "hdl changed: 0x%04x -> 0x%04x\n",
6509 old_hdl, hdl);
6510
6511 leapraid_raid_volume_put(raid_volume);
6512 }
6513
leapraid_search_resp_raid_volume(struct leapraid_adapter * adapter)6514 static void leapraid_search_resp_raid_volume(struct leapraid_adapter *adapter)
6515 {
6516 union cfg_param_1 cfgp1 = {0};
6517 union cfg_param_1 cfgp1_extra = {0};
6518 union cfg_param_2 cfgp2 = {0};
6519 union cfg_param_2 cfgp2_extra = {0};
6520 struct leapraid_raidvol_p1 raidvol_p1;
6521 struct leapraid_raidvol_p0 raidvol_p0;
6522 struct leapraid_raidpd_p0 raidpd_p0;
6523 unsigned long flags;
6524 u16 hdl;
6525 u8 phys_disk_num;
6526 bool is_empty;
6527
6528 if (!adapter->adapter_attr.raid_support)
6529 return;
6530
6531 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags);
6532 is_empty = list_empty(&adapter->dev_topo.raid_volume_list);
6533 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, flags);
6534 if (is_empty)
6535 return;
6536
6537 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP;
6538 for (hdl = 0xFFFF, cfgp2.handle = hdl;
6539 !leapraid_op_config_page(adapter, &raidvol_p1, cfgp1, cfgp2,
6540 GET_RAID_VOLUME_PG1);
6541 cfgp2.handle = hdl) {
6542 hdl = le16_to_cpu(raidvol_p1.dev_hdl);
6543 cfgp1_extra.size = sizeof(struct leapraid_raidvol_p0);
6544 cfgp2_extra.handle = hdl;
6545 if (leapraid_op_config_page(adapter, &raidvol_p0, cfgp1_extra,
6546 cfgp2_extra, GET_RAID_VOLUME_PG0))
6547 continue;
6548
6549 if (raidvol_p0.volume_state == LEAPRAID_VOL_STATE_OPTIMAL ||
6550 raidvol_p0.volume_state == LEAPRAID_VOL_STATE_ONLINE ||
6551 raidvol_p0.volume_state == LEAPRAID_VOL_STATE_DEGRADED)
6552 leapraid_mark_resp_raid_volume(
6553 adapter,
6554 le64_to_cpu(raidvol_p1.wwid),
6555 hdl);
6556 }
6557
6558 memset(adapter->dev_topo.pd_hdls, 0, adapter->dev_topo.pd_hdls_sz);
6559 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP;
6560 for (phys_disk_num = 0xFF, cfgp2.form_specific = phys_disk_num;
6561 !leapraid_op_config_page(adapter, &raidpd_p0, cfgp1, cfgp2,
6562 GET_PHY_DISK_PG0);
6563 cfgp2.form_specific = phys_disk_num) {
6564 phys_disk_num = raidpd_p0.phys_disk_num;
6565 hdl = le16_to_cpu(raidpd_p0.dev_hdl);
6566 if (!hdl ||
6567 hdl > adapter->adapter_attr.features.max_dev_handle)
6568 dev_warn(&adapter->pdev->dev,
6569 "%s: Invalid device handle\n", __func__);
6570 else
6571 set_bit(hdl, adapter->dev_topo.pd_hdls);
6572 }
6573 }
6574
leapraid_mark_resp_exp(struct leapraid_adapter * adapter,struct leapraid_exp_p0 * exp_pg0)6575 static void leapraid_mark_resp_exp(struct leapraid_adapter *adapter,
6576 struct leapraid_exp_p0 *exp_pg0)
6577 {
6578 struct leapraid_enc_node *enc_node = NULL;
6579 struct leapraid_topo_node *topo_node_exp;
6580 u16 enc_hdl = le16_to_cpu(exp_pg0->enc_hdl);
6581 u64 sas_address = le64_to_cpu(exp_pg0->sas_address);
6582 u16 hdl = le16_to_cpu(exp_pg0->dev_hdl);
6583 u8 port_id = exp_pg0->physical_port;
6584 struct leapraid_card_port *card_port = leapraid_get_port_by_id(adapter,
6585 port_id,
6586 false);
6587 unsigned long flags;
6588 unsigned long enc_flags = 0;
6589 u64 enc_lid = 0;
6590 int i;
6591
6592 if (enc_hdl) {
6593 spin_lock_irqsave(&adapter->dev_topo.enc_lock, enc_flags);
6594 enc_node = leapraid_enc_find_by_hdl(adapter, enc_hdl);
6595 if (enc_node)
6596 enc_lid = le64_to_cpu(enc_node->pg0.enc_lid);
6597 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, enc_flags);
6598 }
6599
6600 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags);
6601 list_for_each_entry(topo_node_exp, &adapter->dev_topo.exp_list, list) {
6602 if (topo_node_exp->sas_address != sas_address ||
6603 topo_node_exp->card_port != card_port)
6604 continue;
6605
6606 topo_node_exp->resp = 1;
6607 topo_node_exp->enc_hdl = enc_hdl;
6608 topo_node_exp->enc_lid = enc_lid;
6609 if (topo_node_exp->hdl == hdl)
6610 goto unlock;
6611
6612 dev_info(&adapter->pdev->dev,
6613 "hdl changed: 0x%04x -> 0x%04x\n",
6614 topo_node_exp->hdl, hdl);
6615 topo_node_exp->hdl = hdl;
6616 for (i = 0; i < topo_node_exp->phys_num; i++)
6617 topo_node_exp->card_phy[i].hdl = hdl;
6618 goto unlock;
6619 }
6620 unlock:
6621 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock, flags);
6622 }
6623
leapraid_search_resp_exp(struct leapraid_adapter * adapter)6624 static void leapraid_search_resp_exp(struct leapraid_adapter *adapter)
6625 {
6626 union cfg_param_1 cfgp1 = {0};
6627 union cfg_param_2 cfgp2 = {0};
6628 struct leapraid_exp_p0 exp_p0;
6629 u64 sas_address;
6630 u16 hdl;
6631 u8 port;
6632
6633 if (list_empty(&adapter->dev_topo.exp_list))
6634 return;
6635
6636 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP;
6637 for (hdl = 0xFFFF, cfgp2.handle = hdl;
6638 !leapraid_op_config_page(adapter, &exp_p0, cfgp1, cfgp2,
6639 GET_SAS_EXPANDER_PG0);
6640 cfgp2.handle = hdl) {
6641 hdl = le16_to_cpu(exp_p0.dev_hdl);
6642 sas_address = le64_to_cpu(exp_p0.sas_address);
6643 port = exp_p0.physical_port;
6644
6645 dev_dbg(&adapter->pdev->dev,
6646 "exp detected: hdl=0x%04x, sas=0x%016llx, port=%u",
6647 hdl, (unsigned long long)sas_address,
6648 adapter->adapter_attr.enable_mp ? port :
6649 LEAPRAID_DISABLE_MP_PORT_ID);
6650 leapraid_mark_resp_exp(adapter, &exp_p0);
6651 }
6652 }
6653
leapraid_wait_cmds_done(struct leapraid_adapter * adapter)6654 void leapraid_wait_cmds_done(struct leapraid_adapter *adapter)
6655 {
6656 struct leapraid_io_req_tracker *io_req_tracker;
6657 unsigned long flags;
6658 u16 i;
6659
6660 adapter->reset_desc.pending_io_cnt = 0;
6661 if (!leapraid_pci_active(adapter)) {
6662 dev_err(&adapter->pdev->dev,
6663 "%s %s: PCI error, device reset or unplugged!\n",
6664 adapter->adapter_attr.name, __func__);
6665 return;
6666 }
6667
6668 if (leapraid_get_adapter_state(adapter) != LEAPRAID_DB_OPERATIONAL)
6669 return;
6670
6671 spin_lock_irqsave(&adapter->dynamic_task_desc.task_lock, flags);
6672 for (i = 1; i <= adapter->shost->can_queue; i++) {
6673 io_req_tracker = leapraid_get_io_tracker_from_taskid(adapter,
6674 i);
6675 if (io_req_tracker && io_req_tracker->taskid != 0 &&
6676 io_req_tracker->scmd)
6677 adapter->reset_desc.pending_io_cnt++;
6678 }
6679 spin_unlock_irqrestore(&adapter->dynamic_task_desc.task_lock, flags);
6680
6681 if (!adapter->reset_desc.pending_io_cnt)
6682 return;
6683
6684 wait_event_timeout(adapter->reset_desc.reset_wait_queue,
6685 adapter->reset_desc.pending_io_cnt == 0,
6686 LEAPRAID_IO_CMD_TIMEOUT * HZ);
6687 }
6688
leapraid_hard_reset_handler(struct leapraid_adapter * adapter,enum reset_type type)6689 int leapraid_hard_reset_handler(struct leapraid_adapter *adapter,
6690 enum reset_type type)
6691 {
6692 unsigned long flags;
6693 bool wake = false;
6694 int rc;
6695
6696 mutex_lock(&adapter->reset_desc.adapter_reset_mutex);
6697
6698 if (adapter->access_ctrl.shost_recover_async) {
6699 rc = adapter->reset_desc.adapter_reset_results;
6700 dev_info(&adapter->pdev->dev,
6701 "Skip nested hard reset, async evt running, rc=%d\n",
6702 rc);
6703 mutex_unlock(&adapter->reset_desc.adapter_reset_mutex);
6704 return rc;
6705 }
6706
6707 if (!leapraid_pci_active(adapter)) {
6708 if (leapraid_pci_removed(adapter)) {
6709 dev_info(&adapter->pdev->dev,
6710 "pci_dev removed, pause poll, clean cmds\n");
6711 leapraid_mq_polling_pause(adapter);
6712 leapraid_clean_active_scsi_cmds(adapter);
6713 leapraid_mq_polling_resume(adapter);
6714 }
6715 dev_err(&adapter->pdev->dev, "PCIe unavailable!\n");
6716 mutex_unlock(&adapter->reset_desc.adapter_reset_mutex);
6717 return -ENXIO;
6718 }
6719
6720 dev_info(&adapter->pdev->dev, "Starting hard reset\n");
6721
6722 spin_lock_irqsave(&adapter->reset_desc.adapter_reset_lock, flags);
6723 adapter->access_ctrl.shost_recovering = 1;
6724 adapter->access_ctrl.shost_recover_async = 1;
6725 spin_unlock_irqrestore(&adapter->reset_desc.adapter_reset_lock, flags);
6726
6727 leapraid_wait_cmds_done(adapter);
6728 leapraid_mask_int(adapter);
6729 leapraid_mq_polling_pause(adapter);
6730 rc = leapraid_make_adapter_ready(adapter, type);
6731 if (rc) {
6732 dev_err(&adapter->pdev->dev,
6733 "Failed to make adapter ready, rc=%d\n", rc);
6734 goto out_cleanup;
6735 }
6736
6737 rc = leapraid_fw_log_init(adapter);
6738 if (rc) {
6739 dev_err(&adapter->pdev->dev, "Firmware log init failed\n");
6740 goto out_cleanup;
6741 }
6742
6743 leapraid_clean_active_cmds(adapter);
6744 if (adapter->scan_dev_desc.driver_loading &&
6745 adapter->scan_dev_desc.scan_dev_failed) {
6746 dev_err(&adapter->pdev->dev,
6747 "Previous device scan failed or driver loading\n");
6748 adapter->access_ctrl.host_removing = 1;
6749 rc = -EFAULT;
6750 goto out_cleanup;
6751 }
6752
6753 rc = leapraid_make_adapter_available(adapter);
6754 if (!rc) {
6755 dev_info(&adapter->pdev->dev,
6756 "Adapter is now available, rebuilding topology\n");
6757 if (adapter->adapter_attr.enable_mp) {
6758 leapraid_update_card_port_after_reset(adapter);
6759 leapraid_update_vphys_after_reset(adapter);
6760 }
6761 leapraid_mark_all_dev_deleted(adapter);
6762 leapraid_rebuild_enc_list_after_reset(adapter);
6763 leapraid_search_resp_sas_dev(adapter);
6764 leapraid_search_resp_raid_volume(adapter);
6765 leapraid_search_resp_exp(adapter);
6766 leapraid_hardreset_barrier(adapter);
6767 }
6768 out_cleanup:
6769 if (rc)
6770 dev_err(&adapter->pdev->dev, "Hard reset failed\n");
6771
6772 spin_lock_irqsave(&adapter->reset_desc.adapter_reset_lock, flags);
6773 adapter->reset_desc.adapter_reset_results = rc;
6774 adapter->access_ctrl.shost_recovering = 0;
6775 wake_up(&adapter->access_ctrl.recovery_waitq);
6776 if (rc) {
6777 adapter->access_ctrl.shost_recover_async = 0;
6778 wake = true;
6779 }
6780 spin_unlock_irqrestore(&adapter->reset_desc.adapter_reset_lock, flags);
6781 if (wake)
6782 wake_up(&adapter->access_ctrl.shost_recover_wq);
6783
6784 adapter->reset_desc.reset_cnt++;
6785 mutex_unlock(&adapter->reset_desc.adapter_reset_mutex);
6786
6787 if (rc)
6788 leapraid_clean_active_scsi_cmds(adapter);
6789 leapraid_mq_polling_resume(adapter);
6790
6791 return rc;
6792 }
6793
leapraid_get_adapter_features(struct leapraid_adapter * adapter)6794 static int leapraid_get_adapter_features(struct leapraid_adapter *adapter)
6795 {
6796 struct leapraid_adapter_features_req leap_mpi_req;
6797 struct leapraid_adapter_features_rep leap_mpi_rep;
6798 u8 fw_major, fw_minor, fw_build, fw_release;
6799 u32 req_sz;
6800 u32 rep_sz;
6801 u32 db;
6802 int r;
6803
6804 db = leapraid_readl(&adapter->iomem_base->db);
6805 if (db & LEAPRAID_DB_USED ||
6806 (db & LEAPRAID_DB_MASK) == LEAPRAID_DB_FAULT) {
6807 dev_err(&adapter->pdev->dev,
6808 "%s: Doorbell used or fault\n", __func__);
6809 return -EFAULT;
6810 }
6811
6812 if ((db & LEAPRAID_DB_MASK) != LEAPRAID_DB_READY &&
6813 (db & LEAPRAID_DB_MASK) != LEAPRAID_DB_OPERATIONAL &&
6814 !leapraid_wait_adapter_ready(adapter)) {
6815 dev_err(&adapter->pdev->dev,
6816 "%s: adapter not ready\n", __func__);
6817 return -EFAULT;
6818 }
6819
6820 req_sz = sizeof(struct leapraid_adapter_features_req);
6821 rep_sz = sizeof(struct leapraid_adapter_features_rep);
6822 memset(&leap_mpi_req, 0, req_sz);
6823 memset(&leap_mpi_rep, 0, rep_sz);
6824 leap_mpi_req.func = LEAPRAID_FUNC_GET_ADAPTER_FEATURES;
6825 r = leapraid_handshake_func(adapter,
6826 req_sz,
6827 (u32 *)&leap_mpi_req,
6828 rep_sz,
6829 (u16 *)&leap_mpi_rep);
6830 if (r) {
6831 dev_err(&adapter->pdev->dev,
6832 "%s %s: Handshake failed, r=%d\n",
6833 adapter->adapter_attr.name, __func__, r);
6834 return r;
6835 }
6836
6837 memset(&adapter->adapter_attr.features, 0,
6838 sizeof(struct leapraid_adapter_features));
6839 adapter->adapter_attr.features.req_slot =
6840 le16_to_cpu(leap_mpi_rep.req_slot);
6841 adapter->adapter_attr.features.hp_slot =
6842 le16_to_cpu(leap_mpi_rep.hp_slot);
6843 adapter->adapter_attr.features.adapter_caps =
6844 le32_to_cpu(leap_mpi_rep.adapter_caps);
6845 adapter->adapter_attr.features.max_msix_vectors =
6846 leap_mpi_rep.max_msix_vectors;
6847 adapter->adapter_attr.features.max_volumes =
6848 leap_mpi_rep.max_volumes;
6849 if (!adapter->adapter_attr.features.max_volumes)
6850 adapter->adapter_attr.features.max_volumes =
6851 LEAPRAID_MAX_VOLUMES_DEFAULT;
6852 adapter->adapter_attr.features.max_dev_handle =
6853 le16_to_cpu(leap_mpi_rep.max_dev_hdl);
6854 if (!adapter->adapter_attr.features.max_dev_handle)
6855 adapter->adapter_attr.features.max_dev_handle =
6856 LEAPRAID_MAX_DEV_HANDLE_DEFAULT;
6857 adapter->adapter_attr.features.min_dev_handle =
6858 le16_to_cpu(leap_mpi_rep.min_dev_hdl);
6859 if (adapter->adapter_attr.features.adapter_caps &
6860 LEAPRAID_ADAPTER_FEATURES_CAP_INTEGRATED_RAID)
6861 adapter->adapter_attr.raid_support = 1;
6862 adapter->adapter_attr.wideport_max_queue_depth =
6863 le16_to_cpu(leap_mpi_rep.sas_wide_max_qdepth) ?
6864 le16_to_cpu(leap_mpi_rep.sas_wide_max_qdepth) :
6865 LEAPRAID_SAS_QUEUE_DEPTH;
6866 adapter->adapter_attr.narrowport_max_queue_depth =
6867 le16_to_cpu(leap_mpi_rep.sas_narrow_max_qdepth) ?
6868 le16_to_cpu(leap_mpi_rep.sas_narrow_max_qdepth) :
6869 LEAPRAID_SAS_QUEUE_DEPTH;
6870 adapter->adapter_attr.sata_max_queue_depth =
6871 leap_mpi_rep.sata_max_qdepth ?
6872 leap_mpi_rep.sata_max_qdepth :
6873 LEAPRAID_SATA_QUEUE_DEPTH;
6874 adapter->adapter_attr.raid_volume_max_queue_depth =
6875 LEAPRAID_RAID_QUEUE_DEPTH;
6876 dev_info(&adapter->pdev->dev,
6877 "max: wp qd=%d, np qd=%d, SATA qd=%d, raid qd=%d\n",
6878 adapter->adapter_attr.wideport_max_queue_depth,
6879 adapter->adapter_attr.narrowport_max_queue_depth,
6880 adapter->adapter_attr.sata_max_queue_depth,
6881 adapter->adapter_attr.raid_volume_max_queue_depth);
6882 if (WARN_ON(!(adapter->adapter_attr.features.adapter_caps &
6883 LEAPRAID_ADAPTER_FEATURES_CAP_ATOMIC_REQ)))
6884 return -EFAULT;
6885 adapter->adapter_attr.features.fw_version =
6886 le32_to_cpu(leap_mpi_rep.fw_version);
6887
6888 fw_major = (adapter->adapter_attr.features.fw_version >>
6889 LEAPRAID_VER_MAJOR_SHIFT) & LEAPRAID_VER_MASK;
6890 fw_minor = (adapter->adapter_attr.features.fw_version >>
6891 LEAPRAID_VER_MINOR_SHIFT) & LEAPRAID_VER_MASK;
6892 fw_build = (adapter->adapter_attr.features.fw_version >>
6893 LEAPRAID_VER_BUILD_SHIFT) & LEAPRAID_VER_MASK;
6894 fw_release =
6895 adapter->adapter_attr.features.fw_version & LEAPRAID_VER_MASK;
6896
6897 dev_info(&adapter->pdev->dev,
6898 "Firmware version: %u.%u.%u.%u (0x%08x)\n",
6899 fw_major, fw_minor, fw_build, fw_release,
6900 adapter->adapter_attr.features.fw_version);
6901
6902 adapter->adapter_attr.features.msg_ver =
6903 le16_to_cpu(leap_mpi_rep.msg_ver);
6904 adapter->adapter_attr.features.product_id =
6905 le16_to_cpu(leap_mpi_rep.product_id);
6906 dev_info(&adapter->pdev->dev,
6907 "message version: 0x%x, product id 0x%x\n",
6908 adapter->adapter_attr.features.msg_ver,
6909 adapter->adapter_attr.features.product_id);
6910
6911 if (adapter->adapter_attr.features.msg_ver < 0x1000) {
6912 dev_err(&adapter->pdev->dev, "Device not supported\n");
6913 return -EFAULT;
6914 }
6915 adapter->shost->max_id = LEAPRAID_INVALID_INITIAL_VALUE;
6916
6917 return 0;
6918 }
6919
leapraid_disable_pcie(struct leapraid_adapter * adapter)6920 static inline void leapraid_disable_pcie(struct leapraid_adapter *adapter)
6921 {
6922 mutex_lock(&adapter->access_ctrl.pci_access_lock);
6923 if (adapter->iomem_base) {
6924 iounmap(adapter->iomem_base);
6925 adapter->iomem_base = NULL;
6926 }
6927 if (pci_is_enabled(adapter->pdev)) {
6928 pci_release_regions(adapter->pdev);
6929 pci_disable_device(adapter->pdev);
6930 }
6931 mutex_unlock(&adapter->access_ctrl.pci_access_lock);
6932 }
6933
leapraid_enable_pcie(struct leapraid_adapter * adapter)6934 static int leapraid_enable_pcie(struct leapraid_adapter *adapter)
6935 {
6936 u64 dma_mask;
6937 int rc;
6938
6939 rc = pci_enable_device(adapter->pdev);
6940 if (rc) {
6941 dev_err(&adapter->pdev->dev, "Failed to enable PCI device\n");
6942 return rc;
6943 }
6944
6945 rc = pci_request_regions(adapter->pdev, LEAPRAID_DRIVER_NAME);
6946 if (rc) {
6947 dev_err(&adapter->pdev->dev,
6948 "Failed to obtain PCI resources\n");
6949 return rc;
6950 }
6951
6952 if (sizeof(dma_addr_t) > 4) {
6953 dma_mask = DMA_BIT_MASK(DMA_64_BITS);
6954 adapter->adapter_attr.use_32_dma_mask = 0;
6955 } else {
6956 dma_mask = DMA_BIT_MASK(DMA_32_BITS);
6957 adapter->adapter_attr.use_32_dma_mask = 1;
6958 }
6959
6960 rc = dma_set_mask_and_coherent(&adapter->pdev->dev, dma_mask);
6961 if (rc) {
6962 dev_err(&adapter->pdev->dev,
6963 "Failed to set %lld DMA mask\n", dma_mask);
6964 return rc;
6965 }
6966 adapter->iomem_base = ioremap(pci_resource_start(adapter->pdev, 0),
6967 sizeof(struct leapraid_reg_base));
6968 if (!adapter->iomem_base) {
6969 dev_err(&adapter->pdev->dev,
6970 "Failed to map memory for controller registers\n");
6971 return -ENOMEM;
6972 }
6973
6974 pci_set_master(adapter->pdev);
6975
6976 return 0;
6977 }
6978
leapraid_cpus_on_irq(struct leapraid_adapter * adapter)6979 static void leapraid_cpus_on_irq(struct leapraid_adapter *adapter)
6980 {
6981 struct leapraid_int_rq *int_rq;
6982 unsigned int i, base_group, this_group;
6983 unsigned int cpu, nr_cpus, total_msix, index;
6984
6985 total_msix = adapter->notification_desc.iopoll_qdex;
6986 nr_cpus = num_online_cpus();
6987
6988 if (!nr_cpus || !total_msix)
6989 return;
6990 base_group = nr_cpus / total_msix;
6991
6992 cpu = cpumask_first(cpu_online_mask);
6993 for (index = 0; index < adapter->notification_desc.iopoll_qdex;
6994 index++) {
6995 int_rq = &adapter->notification_desc.int_rqs[index];
6996
6997 if (cpu >= adapter->notification_desc.msix_cpu_map_sz)
6998 break;
6999
7000 this_group = base_group +
7001 (index < (nr_cpus % total_msix) ? 1 : 0);
7002
7003 for (i = 0 ; i < this_group ; i++) {
7004 if (cpu >= adapter->notification_desc.msix_cpu_map_sz)
7005 break;
7006
7007 adapter->notification_desc.msix_cpu_map[cpu] =
7008 int_rq->rq.msix_idx;
7009 cpu = cpumask_next(cpu, cpu_online_mask);
7010 }
7011 }
7012 }
7013
leapraid_map_msix_to_cpu(struct leapraid_adapter * adapter)7014 static void leapraid_map_msix_to_cpu(struct leapraid_adapter *adapter)
7015 {
7016 struct leapraid_int_rq *int_rq;
7017 const cpumask_t *affinity_mask;
7018 int cpu;
7019 u32 i;
7020
7021 if (!adapter->adapter_attr.rq_cnt)
7022 return;
7023
7024 for (i = 0; i < adapter->notification_desc.iopoll_qdex; i++) {
7025 int_rq = &adapter->notification_desc.int_rqs[i];
7026 affinity_mask = pci_irq_get_affinity(adapter->pdev,
7027 int_rq->rq.msix_idx);
7028 if (!affinity_mask) {
7029 dev_warn(&adapter->pdev->dev,
7030 "%s: IRQ affinity NULL, msix_idx=%d\n",
7031 __func__, int_rq->rq.msix_idx);
7032 goto out_apply_irq_affinity;
7033 }
7034
7035 for_each_cpu_and(cpu, affinity_mask, cpu_online_mask) {
7036 if (cpu >= adapter->notification_desc.msix_cpu_map_sz)
7037 continue;
7038
7039 adapter->notification_desc.msix_cpu_map[cpu] =
7040 int_rq->rq.msix_idx;
7041 }
7042 }
7043 return;
7044 out_apply_irq_affinity:
7045 leapraid_cpus_on_irq(adapter);
7046 }
7047
leapraid_alloc_msix_cpu_map(struct leapraid_adapter * adapter)7048 static int leapraid_alloc_msix_cpu_map(struct leapraid_adapter *adapter)
7049 {
7050 adapter->notification_desc.msix_cpu_map_sz = nr_cpu_ids;
7051 adapter->notification_desc.msix_cpu_map =
7052 kzalloc(adapter->notification_desc.msix_cpu_map_sz,
7053 GFP_KERNEL);
7054 if (!adapter->notification_desc.msix_cpu_map)
7055 return -ENOMEM;
7056
7057 return 0;
7058 }
7059
leapraid_configure_reply_queue_affinity(struct leapraid_adapter * adapter)7060 static void leapraid_configure_reply_queue_affinity(
7061 struct leapraid_adapter *adapter)
7062 {
7063 if (!adapter || !adapter->notification_desc.msix_enable)
7064 return;
7065
7066 leapraid_map_msix_to_cpu(adapter);
7067 }
7068
leapraid_free_irq(struct leapraid_adapter * adapter)7069 static void leapraid_free_irq(struct leapraid_adapter *adapter)
7070 {
7071 struct leapraid_int_rq *int_rq;
7072 unsigned int i;
7073 int irq;
7074
7075 for (i = 0; adapter->notification_desc.int_rqs &&
7076 i < adapter->notification_desc.int_rqs_allocated; i++) {
7077 int_rq = &adapter->notification_desc.int_rqs[i];
7078 if (!int_rq)
7079 continue;
7080
7081 irq = pci_irq_vector(adapter->pdev, int_rq->rq.msix_idx);
7082 irq_set_affinity_hint(irq, NULL);
7083 free_irq(irq, &int_rq->rq);
7084 }
7085 adapter->notification_desc.int_rqs_allocated = 0;
7086
7087 if (adapter->notification_desc.irq_vectors_allocated) {
7088 pci_free_irq_vectors(adapter->pdev);
7089 adapter->notification_desc.irq_vectors_allocated = 0;
7090 }
7091
7092 adapter->notification_desc.msix_enable = 0;
7093
7094 kfree(adapter->notification_desc.blk_mq_poll_rqs);
7095 adapter->notification_desc.blk_mq_poll_rqs = NULL;
7096
7097 kfree(adapter->notification_desc.int_rqs);
7098 adapter->notification_desc.int_rqs = NULL;
7099
7100 kfree(adapter->notification_desc.msix_cpu_map);
7101 adapter->notification_desc.msix_cpu_map = NULL;
7102 adapter->notification_desc.msix_cpu_map_sz = 0;
7103 adapter->notification_desc.iopoll_qdex = 0;
7104 adapter->notification_desc.iopoll_qcnt = 0;
7105 }
7106
leapraid_setup_irqs(struct leapraid_adapter * adapter)7107 static int leapraid_setup_irqs(struct leapraid_adapter *adapter)
7108 {
7109 int irq_mode = adapter->notification_desc.irq_mode;
7110 unsigned int i;
7111 int rc = 0;
7112
7113 if (irq_mode == LEAPRAID_INTERRUPT_MODE_MSIX) {
7114 rc = pci_alloc_irq_vectors_affinity(
7115 adapter->pdev,
7116 adapter->notification_desc.iopoll_qdex,
7117 adapter->notification_desc.iopoll_qdex,
7118 PCI_IRQ_MSIX | PCI_IRQ_AFFINITY, NULL);
7119 if (rc < 0) {
7120 dev_err(&adapter->pdev->dev,
7121 "%d MSI/MSIX vectors allocated failed!\n",
7122 adapter->notification_desc.iopoll_qdex);
7123 return rc;
7124 }
7125
7126 adapter->notification_desc.irq_vectors_allocated = 1;
7127 }
7128
7129 for (i = 0; i < adapter->notification_desc.iopoll_qdex; i++) {
7130 adapter->notification_desc.int_rqs[i].rq.adapter = adapter;
7131 adapter->notification_desc.int_rqs[i].rq.msix_idx = i;
7132 atomic_set(&adapter->notification_desc.int_rqs[i].rq.busy, 0);
7133 if (irq_mode == LEAPRAID_INTERRUPT_MODE_MSIX)
7134 snprintf(adapter->notification_desc.int_rqs[i].rq.name,
7135 LEAPRAID_NAME_LENGTH, "%s%u-MSIx%u",
7136 LEAPRAID_DRIVER_NAME,
7137 adapter->adapter_attr.id, i);
7138 else if (irq_mode == LEAPRAID_INTERRUPT_MODE_MSI)
7139 snprintf(adapter->notification_desc.int_rqs[i].rq.name,
7140 LEAPRAID_NAME_LENGTH, "%s%u-MSI%u",
7141 LEAPRAID_DRIVER_NAME,
7142 adapter->adapter_attr.id, i);
7143
7144 rc = request_irq(pci_irq_vector(adapter->pdev, i),
7145 leapraid_irq_handler,
7146 IRQF_SHARED,
7147 adapter->notification_desc.int_rqs[i].rq.name,
7148 &adapter->notification_desc.int_rqs[i].rq);
7149 if (rc) {
7150 dev_err(&adapter->pdev->dev,
7151 "MSI/MSIx: request_irq %s failed!\n",
7152 adapter->notification_desc.int_rqs[i].rq.name);
7153 return rc;
7154 }
7155 adapter->notification_desc.int_rqs_allocated++;
7156 }
7157
7158 return 0;
7159 }
7160
leapraid_setup_legacy_int(struct leapraid_adapter * adapter)7161 static int leapraid_setup_legacy_int(struct leapraid_adapter *adapter)
7162 {
7163 int rc;
7164
7165 adapter->notification_desc.int_rqs[0].rq.adapter = adapter;
7166 adapter->notification_desc.int_rqs[0].rq.msix_idx = 0;
7167 atomic_set(&adapter->notification_desc.int_rqs[0].rq.busy, 0);
7168 snprintf(adapter->notification_desc.int_rqs[0].rq.name,
7169 LEAPRAID_NAME_LENGTH, "%s%d-LegacyInt",
7170 LEAPRAID_DRIVER_NAME, adapter->adapter_attr.id);
7171
7172 rc = pci_alloc_irq_vectors_affinity(
7173 adapter->pdev,
7174 adapter->notification_desc.iopoll_qdex,
7175 adapter->notification_desc.iopoll_qdex,
7176 PCI_IRQ_INTX | PCI_IRQ_AFFINITY,
7177 NULL);
7178 if (rc < 0) {
7179 dev_err(&adapter->pdev->dev,
7180 "Legacy irq allocated failed!\n");
7181 return rc;
7182 }
7183
7184 adapter->notification_desc.irq_vectors_allocated = 1;
7185 adapter->notification_desc.irq_mode = LEAPRAID_INTERRUPT_MODE_LEGACY;
7186 rc = request_irq(pci_irq_vector(adapter->pdev, 0),
7187 leapraid_irq_handler,
7188 IRQF_SHARED,
7189 adapter->notification_desc.int_rqs[0].rq.name,
7190 &adapter->notification_desc.int_rqs[0].rq);
7191 if (rc) {
7192 irq_set_affinity_hint(pci_irq_vector(adapter->pdev, 0), NULL);
7193 pci_free_irq_vectors(adapter->pdev);
7194 adapter->notification_desc.irq_vectors_allocated = 0;
7195 dev_err(&adapter->pdev->dev,
7196 "Legacy Int: request_irq %s failed!\n",
7197 adapter->notification_desc.int_rqs[0].rq.name);
7198 return -EBUSY;
7199 }
7200 adapter->notification_desc.int_rqs_allocated = 1;
7201 return rc;
7202 }
7203
leapraid_set_legacy_int(struct leapraid_adapter * adapter)7204 static int leapraid_set_legacy_int(struct leapraid_adapter *adapter)
7205 {
7206 int rc;
7207
7208 rc = leapraid_alloc_msix_cpu_map(adapter);
7209 if (rc)
7210 return rc;
7211
7212 adapter->adapter_attr.rq_cnt = 1;
7213 adapter->notification_desc.iopoll_qdex =
7214 adapter->adapter_attr.rq_cnt;
7215 adapter->notification_desc.iopoll_qcnt = 0;
7216 dev_info(&adapter->pdev->dev,
7217 "Legacy Intr: req queue cnt=%d intr=%d/poll=%d rep queues!\n",
7218 adapter->adapter_attr.rq_cnt,
7219 adapter->notification_desc.iopoll_qdex,
7220 adapter->notification_desc.iopoll_qcnt);
7221 adapter->notification_desc.int_rqs =
7222 kzalloc_objs(struct leapraid_int_rq,
7223 adapter->notification_desc.iopoll_qdex);
7224 if (!adapter->notification_desc.int_rqs)
7225 return -ENOMEM;
7226
7227 return leapraid_setup_legacy_int(adapter);
7228 }
7229
leapraid_set_msix(struct leapraid_adapter * adapter)7230 static int leapraid_set_msix(struct leapraid_adapter *adapter)
7231 {
7232 int iopoll_qcnt = 0;
7233 unsigned int i;
7234 int rc, msix_cnt;
7235
7236 msix_cnt = pci_msix_vec_count(adapter->pdev);
7237 if (msix_cnt <= 0 ||
7238 adapter->adapter_attr.features.max_msix_vectors == 0) {
7239 dev_info(&adapter->pdev->dev, "MSIX unsupported!\n");
7240 return -EOPNOTSUPP;
7241 }
7242
7243 msix_cnt = min_t(int, msix_cnt,
7244 adapter->adapter_attr.features.max_msix_vectors);
7245
7246 if (reset_devices)
7247 adapter->adapter_attr.rq_cnt = 1;
7248 else
7249 adapter->adapter_attr.rq_cnt = min_t(int,
7250 num_online_cpus(),
7251 msix_cnt);
7252
7253 if (max_msix_vectors > 0)
7254 adapter->adapter_attr.rq_cnt = min_t(
7255 int, max_msix_vectors, adapter->adapter_attr.rq_cnt);
7256
7257 if (adapter->adapter_attr.rq_cnt <= 1)
7258 adapter->shost->host_tagset = 0;
7259 if (adapter->shost->host_tagset) {
7260 iopoll_qcnt = poll_queues;
7261 if (iopoll_qcnt >= adapter->adapter_attr.rq_cnt)
7262 iopoll_qcnt = 0;
7263 }
7264 if (iopoll_qcnt) {
7265 adapter->notification_desc.blk_mq_poll_rqs =
7266 kzalloc_objs(struct leapraid_blk_mq_poll_rq,
7267 iopoll_qcnt);
7268 if (!adapter->notification_desc.blk_mq_poll_rqs)
7269 return -ENOMEM;
7270 adapter->adapter_attr.rq_cnt =
7271 min(adapter->adapter_attr.rq_cnt + iopoll_qcnt,
7272 msix_cnt);
7273 }
7274
7275 adapter->notification_desc.iopoll_qdex =
7276 adapter->adapter_attr.rq_cnt - iopoll_qcnt;
7277
7278 adapter->notification_desc.iopoll_qcnt = iopoll_qcnt;
7279 dev_info(&adapter->pdev->dev,
7280 "MSIx: req queue cnt=%d, intr=%d/poll=%d rep queues!\n",
7281 adapter->adapter_attr.rq_cnt,
7282 adapter->notification_desc.iopoll_qdex,
7283 adapter->notification_desc.iopoll_qcnt);
7284
7285 adapter->notification_desc.int_rqs =
7286 kzalloc_objs(struct leapraid_int_rq,
7287 adapter->notification_desc.iopoll_qdex);
7288 if (!adapter->notification_desc.int_rqs)
7289 return -ENOMEM;
7290
7291 for (i = 0; i < adapter->notification_desc.iopoll_qcnt; i++) {
7292 adapter->notification_desc.blk_mq_poll_rqs[i].rq.adapter =
7293 adapter;
7294 adapter->notification_desc.blk_mq_poll_rqs[i].rq.msix_idx =
7295 i + adapter->notification_desc.iopoll_qdex;
7296 atomic_set(
7297 &adapter->notification_desc.blk_mq_poll_rqs[i].rq.busy,
7298 0);
7299 snprintf(adapter->notification_desc.blk_mq_poll_rqs[i].rq.name,
7300 LEAPRAID_NAME_LENGTH,
7301 "%s%u-MQ-Poll%u", LEAPRAID_DRIVER_NAME,
7302 adapter->adapter_attr.id, i);
7303 atomic_set(&adapter->notification_desc.blk_mq_poll_rqs[i].busy,
7304 0);
7305 atomic_set(&adapter->notification_desc.blk_mq_poll_rqs[i].pause,
7306 0);
7307 }
7308
7309 rc = leapraid_alloc_msix_cpu_map(adapter);
7310 if (rc)
7311 return rc;
7312
7313 adapter->notification_desc.irq_mode = LEAPRAID_INTERRUPT_MODE_MSIX;
7314 adapter->notification_desc.msix_enable = 1;
7315 rc = leapraid_setup_irqs(adapter);
7316 if (rc) {
7317 leapraid_free_irq(adapter);
7318 adapter->notification_desc.msix_enable = 0;
7319 return rc;
7320 }
7321
7322 return 0;
7323 }
7324
leapraid_set_msi(struct leapraid_adapter * adapter)7325 static int leapraid_set_msi(struct leapraid_adapter *adapter)
7326 {
7327 int iopoll_qcnt = 0;
7328 unsigned int i;
7329 int rc, msi_cnt;
7330
7331 msi_cnt = pci_msi_vec_count(adapter->pdev);
7332 if (msi_cnt <= 0 ||
7333 adapter->adapter_attr.features.max_msix_vectors == 0) {
7334 dev_info(&adapter->pdev->dev, "MSI unsupported!\n");
7335 return -EOPNOTSUPP;
7336 }
7337
7338 msi_cnt = min_t(int, msi_cnt,
7339 adapter->adapter_attr.features.max_msix_vectors);
7340
7341 if (reset_devices)
7342 adapter->adapter_attr.rq_cnt = 1;
7343 else
7344 adapter->adapter_attr.rq_cnt = min_t(int,
7345 num_online_cpus(),
7346 msi_cnt);
7347
7348 if (max_msix_vectors > 0)
7349 adapter->adapter_attr.rq_cnt = min_t(
7350 int, max_msix_vectors, adapter->adapter_attr.rq_cnt);
7351
7352 if (adapter->adapter_attr.rq_cnt <= 1)
7353 adapter->shost->host_tagset = 0;
7354 if (adapter->shost->host_tagset) {
7355 iopoll_qcnt = poll_queues;
7356 if (iopoll_qcnt >= adapter->adapter_attr.rq_cnt)
7357 iopoll_qcnt = 0;
7358 }
7359
7360 if (iopoll_qcnt) {
7361 adapter->notification_desc.blk_mq_poll_rqs =
7362 kzalloc_objs(struct leapraid_blk_mq_poll_rq,
7363 iopoll_qcnt);
7364 if (!adapter->notification_desc.blk_mq_poll_rqs)
7365 return -ENOMEM;
7366
7367 adapter->adapter_attr.rq_cnt =
7368 min(adapter->adapter_attr.rq_cnt + iopoll_qcnt,
7369 msi_cnt);
7370 }
7371
7372 adapter->notification_desc.iopoll_qdex =
7373 adapter->adapter_attr.rq_cnt - iopoll_qcnt;
7374 rc = pci_alloc_irq_vectors_affinity(
7375 adapter->pdev,
7376 1,
7377 adapter->notification_desc.iopoll_qdex,
7378 PCI_IRQ_MSI | PCI_IRQ_AFFINITY, NULL);
7379 if (rc < 0) {
7380 dev_err(&adapter->pdev->dev,
7381 "%d MSI vectors allocated failed!\n",
7382 adapter->notification_desc.iopoll_qdex);
7383 leapraid_free_irq(adapter);
7384 return rc;
7385 }
7386 adapter->notification_desc.irq_vectors_allocated = 1;
7387 if (rc != adapter->notification_desc.iopoll_qdex) {
7388 adapter->notification_desc.iopoll_qdex = rc;
7389 adapter->adapter_attr.rq_cnt =
7390 adapter->notification_desc.iopoll_qdex + iopoll_qcnt;
7391 }
7392 adapter->notification_desc.iopoll_qcnt = iopoll_qcnt;
7393 dev_info(&adapter->pdev->dev,
7394 "MSI: req queue cnt=%d, intr=%d/poll=%d rep queues!\n",
7395 adapter->adapter_attr.rq_cnt,
7396 adapter->notification_desc.iopoll_qdex,
7397 adapter->notification_desc.iopoll_qcnt);
7398
7399 adapter->notification_desc.int_rqs =
7400 kzalloc_objs(struct leapraid_int_rq,
7401 adapter->notification_desc.iopoll_qdex);
7402 if (!adapter->notification_desc.int_rqs)
7403 return -ENOMEM;
7404
7405 for (i = 0; i < adapter->notification_desc.iopoll_qcnt; i++) {
7406 adapter->notification_desc.blk_mq_poll_rqs[i].rq.adapter =
7407 adapter;
7408 adapter->notification_desc.blk_mq_poll_rqs[i].rq.msix_idx =
7409 i + adapter->notification_desc.iopoll_qdex;
7410 atomic_set(
7411 &adapter->notification_desc.blk_mq_poll_rqs[i].rq.busy,
7412 0);
7413 snprintf(adapter->notification_desc.blk_mq_poll_rqs[i].rq.name,
7414 LEAPRAID_NAME_LENGTH,
7415 "%s%u-MQ-Poll%u", LEAPRAID_DRIVER_NAME,
7416 adapter->adapter_attr.id, i);
7417 atomic_set(
7418 &adapter->notification_desc.blk_mq_poll_rqs[i].busy,
7419 0);
7420 atomic_set(
7421 &adapter->notification_desc.blk_mq_poll_rqs[i].pause,
7422 0);
7423 }
7424
7425 rc = leapraid_alloc_msix_cpu_map(adapter);
7426 if (rc)
7427 return rc;
7428
7429 adapter->notification_desc.irq_mode = LEAPRAID_INTERRUPT_MODE_MSI;
7430 adapter->notification_desc.msix_enable = 1;
7431 rc = leapraid_setup_irqs(adapter);
7432 if (rc) {
7433 leapraid_free_irq(adapter);
7434 adapter->notification_desc.msix_enable = 0;
7435 return rc;
7436 }
7437
7438 return 0;
7439 }
7440
leapraid_set_notification_auto(struct leapraid_adapter * adapter)7441 static int leapraid_set_notification_auto(struct leapraid_adapter *adapter)
7442 {
7443 int rc;
7444
7445 rc = leapraid_set_msix(adapter);
7446 if (!rc)
7447 return 0;
7448
7449 leapraid_free_irq(adapter);
7450 dev_info(&adapter->pdev->dev,
7451 "MSI-X setup failed (%d), trying MSI\n", rc);
7452
7453 rc = leapraid_set_msi(adapter);
7454 if (!rc)
7455 return 0;
7456
7457 leapraid_free_irq(adapter);
7458 dev_info(&adapter->pdev->dev,
7459 "MSI setup failed (%d), back to legacy INTx\n", rc);
7460
7461 rc = leapraid_set_legacy_int(adapter);
7462 if (rc)
7463 dev_err(&adapter->pdev->dev,
7464 "%s: Enable legacy irq failed!\n", __func__);
7465
7466 return rc;
7467 }
7468
leapraid_set_pcie_and_notification(struct leapraid_adapter * adapter)7469 int leapraid_set_pcie_and_notification(struct leapraid_adapter *adapter)
7470 {
7471 int rc;
7472
7473 rc = leapraid_enable_pcie(adapter);
7474 if (rc)
7475 goto out_fail;
7476
7477 leapraid_mask_int(adapter);
7478
7479 rc = leapraid_make_adapter_ready(adapter, PART_RESET);
7480 if (rc) {
7481 dev_err(&adapter->pdev->dev, "Make adapter ready failure\n");
7482 goto out_fail;
7483 }
7484
7485 rc = leapraid_get_adapter_features(adapter);
7486 if (rc) {
7487 dev_err(&adapter->pdev->dev, "Get adapter feature failure\n");
7488 goto out_fail;
7489 }
7490
7491 rc = leapraid_set_notification_auto(adapter);
7492 if (rc)
7493 goto out_fail;
7494
7495 pci_save_state(adapter->pdev);
7496
7497 return 0;
7498
7499 out_fail:
7500 leapraid_free_irq(adapter);
7501 leapraid_disable_pcie(adapter);
7502 return rc;
7503 }
7504
leapraid_disable_controller(struct leapraid_adapter * adapter)7505 void leapraid_disable_controller(struct leapraid_adapter *adapter)
7506 {
7507 if (!adapter->iomem_base)
7508 return;
7509
7510 leapraid_mask_int(adapter);
7511
7512 adapter->access_ctrl.shost_recovering = 1;
7513 leapraid_make_adapter_ready(adapter, PART_RESET);
7514 adapter->access_ctrl.shost_recovering = 0;
7515 wake_up(&adapter->access_ctrl.recovery_waitq);
7516
7517 leapraid_free_irq(adapter);
7518 leapraid_disable_pcie(adapter);
7519 }
7520
leapraid_adapter_unit_reset(struct leapraid_adapter * adapter)7521 static int leapraid_adapter_unit_reset(struct leapraid_adapter *adapter)
7522 {
7523 int rc = 0;
7524
7525 writel(LEAPRAID_FUNC_ADAPTER_UNIT_RESET << LEAPRAID_DB_FUNC_SHIFT,
7526 &adapter->iomem_base->db);
7527 if (leapraid_db_wait_ack_and_clear_int(adapter))
7528 rc = -EFAULT;
7529
7530 if (!leapraid_wait_adapter_ready(adapter)) {
7531 dev_err(&adapter->pdev->dev, "unit reset failed\n");
7532 return -EFAULT;
7533 }
7534
7535 return rc;
7536 }
7537
leapraid_make_adapter_ready(struct leapraid_adapter * adapter,enum reset_type type)7538 static int leapraid_make_adapter_ready(struct leapraid_adapter *adapter,
7539 enum reset_type type)
7540 {
7541 u32 db;
7542 int count;
7543
7544 if (!leapraid_pci_active(adapter))
7545 return 0;
7546
7547 count = 0;
7548 db = leapraid_readl(&adapter->iomem_base->db);
7549 if ((db & LEAPRAID_DB_MASK) == LEAPRAID_DB_RESET) {
7550 while ((db & LEAPRAID_DB_MASK) != LEAPRAID_DB_READY) {
7551 if (count++ == LEAPRAID_DB_RETRY_COUNT_MAX) {
7552 dev_err(&adapter->pdev->dev,
7553 "Wait adapter ready timeout\n");
7554 return -EFAULT;
7555 }
7556 ssleep(1);
7557 db = leapraid_readl(&adapter->iomem_base->db);
7558 dev_info(&adapter->pdev->dev,
7559 "Wait adapter ready, count=%d, db=0x%x\n",
7560 count, db);
7561 }
7562 }
7563 if ((db & LEAPRAID_DB_MASK) == LEAPRAID_DB_READY)
7564 return 0;
7565
7566 if (db & LEAPRAID_DB_USED)
7567 goto full_reset;
7568
7569 if ((db & LEAPRAID_DB_MASK) == LEAPRAID_DB_FAULT)
7570 goto full_reset;
7571
7572 if (type == FULL_RESET)
7573 goto full_reset;
7574
7575 if ((db & LEAPRAID_DB_MASK) == LEAPRAID_DB_OPERATIONAL &&
7576 !leapraid_adapter_unit_reset(adapter))
7577 return 0;
7578
7579 full_reset:
7580 return leapraid_host_diag_reset(adapter);
7581 }
7582
leapraid_fw_log_exit(struct leapraid_adapter * adapter)7583 static void leapraid_fw_log_exit(struct leapraid_adapter *adapter)
7584 {
7585 if (!adapter->fw_log_desc.open_pcie_trace)
7586 return;
7587
7588 if (adapter->fw_log_desc.fw_log_buffer) {
7589 wait_event(adapter->fw_log_desc.mmap_waitq,
7590 !atomic_read(&adapter->fw_log_desc.mmap_refcnt));
7591 dma_free_coherent(&adapter->pdev->dev,
7592 (LEAPRAID_SYS_LOG_BUF_SIZE +
7593 LEAPRAID_SYS_LOG_BUF_RESERVE),
7594 adapter->fw_log_desc.fw_log_buffer,
7595 adapter->fw_log_desc.fw_log_buffer_dma);
7596 adapter->fw_log_desc.fw_log_buffer = NULL;
7597 }
7598 }
7599
leapraid_fw_log_init(struct leapraid_adapter * adapter)7600 static int leapraid_fw_log_init(struct leapraid_adapter *adapter)
7601 {
7602 struct leapraid_adapter_log_req adapter_log_req;
7603 struct leapraid_adapter_log_rep adapter_log_rep;
7604 u16 adapter_status;
7605 u64 buf_addr;
7606 u32 rc;
7607
7608 if (!adapter->fw_log_desc.open_pcie_trace)
7609 return 0;
7610
7611 if (!adapter->fw_log_desc.fw_log_buffer) {
7612 adapter->fw_log_desc.fw_log_buffer =
7613 dma_alloc_coherent(
7614 &adapter->pdev->dev,
7615 (LEAPRAID_SYS_LOG_BUF_SIZE +
7616 LEAPRAID_SYS_LOG_BUF_RESERVE),
7617 &adapter->fw_log_desc.fw_log_buffer_dma,
7618 GFP_KERNEL);
7619 if (!adapter->fw_log_desc.fw_log_buffer)
7620 return -ENOMEM;
7621 }
7622
7623 memset(&adapter_log_req, 0, sizeof(struct leapraid_adapter_log_req));
7624 adapter_log_req.func = LEAPRAID_FUNC_LOGBUF_INIT;
7625 buf_addr = adapter->fw_log_desc.fw_log_buffer_dma;
7626
7627 adapter_log_req.mbox.w[0] =
7628 cpu_to_le32((u32)(buf_addr & 0xFFFFFFFF));
7629 adapter_log_req.mbox.w[1] =
7630 cpu_to_le32((u32)((buf_addr >> 32) & 0xFFFFFFFF));
7631 adapter_log_req.mbox.w[2] =
7632 cpu_to_le32(LEAPRAID_SYS_LOG_BUF_SIZE);
7633 rc = leapraid_handshake_func(adapter,
7634 sizeof(struct leapraid_adapter_log_req),
7635 (u32 *)&adapter_log_req,
7636 sizeof(struct leapraid_adapter_log_rep),
7637 (u16 *)&adapter_log_rep);
7638 if (rc != 0) {
7639 dev_err(&adapter->pdev->dev, "%s: Handshake failed, rc=%d\n",
7640 __func__, rc);
7641 return rc;
7642 }
7643
7644 adapter_status = le16_to_cpu(adapter_log_rep.adapter_status) &
7645 LEAPRAID_ADAPTER_STATUS_MASK;
7646 if (adapter_status != LEAPRAID_ADAPTER_STATUS_SUCCESS) {
7647 dev_err(&adapter->pdev->dev, "%s: failed!\n", __func__);
7648 rc = -EIO;
7649 }
7650
7651 return rc;
7652 }
7653
leapraid_free_host_memory(struct leapraid_adapter * adapter)7654 static void leapraid_free_host_memory(struct leapraid_adapter *adapter)
7655 {
7656 unsigned int i;
7657
7658 if (adapter->mem_desc.task_desc) {
7659 dma_free_coherent(&adapter->pdev->dev,
7660 adapter->adapter_attr.task_desc_dma_size,
7661 adapter->mem_desc.task_desc,
7662 adapter->mem_desc.task_desc_dma);
7663 adapter->mem_desc.task_desc = NULL;
7664 }
7665
7666 if (adapter->mem_desc.sense_data) {
7667 dma_free_coherent(
7668 &adapter->pdev->dev,
7669 adapter->adapter_attr.io_qd * SCSI_SENSE_BUFFERSIZE,
7670 adapter->mem_desc.sense_data,
7671 adapter->mem_desc.sense_data_dma);
7672 adapter->mem_desc.sense_data = NULL;
7673 }
7674
7675 if (adapter->mem_desc.rep_msg) {
7676 dma_free_coherent(
7677 &adapter->pdev->dev,
7678 adapter->adapter_attr.rep_msg_qd * LEAPRAID_REPLY_SIZE,
7679 adapter->mem_desc.rep_msg,
7680 adapter->mem_desc.rep_msg_dma);
7681 adapter->mem_desc.rep_msg = NULL;
7682 }
7683
7684 if (adapter->mem_desc.rep_msg_addr) {
7685 dma_free_coherent(&adapter->pdev->dev,
7686 adapter->adapter_attr.rep_msg_qd *
7687 LEAPRAID_REP_MSG_ADDR_SIZE,
7688 adapter->mem_desc.rep_msg_addr,
7689 adapter->mem_desc.rep_msg_addr_dma);
7690 adapter->mem_desc.rep_msg_addr = NULL;
7691 }
7692
7693 if (adapter->mem_desc.rep_desc_seg_maint) {
7694 for (i = 0; i < adapter->adapter_attr.rep_desc_q_seg_cnt;
7695 i++) {
7696 if (adapter->mem_desc.rep_desc_seg_maint[i]
7697 .rep_desc_seg) {
7698 dma_free_coherent(
7699 &adapter->pdev->dev,
7700 (adapter->adapter_attr.rep_desc_qd *
7701 LEAPRAID_REP_DESC_ENTRY_SIZE) *
7702 LEAPRAID_REP_DESC_CHUNK_SIZE,
7703 adapter->mem_desc.rep_desc_seg_maint[i]
7704 .rep_desc_seg,
7705 adapter->mem_desc.rep_desc_seg_maint[i]
7706 .rep_desc_seg_dma);
7707 adapter->mem_desc.rep_desc_seg_maint[i]
7708 .rep_desc_seg = NULL;
7709 }
7710 }
7711
7712 if (adapter->mem_desc.rep_desc_q_arr) {
7713 dma_free_coherent(
7714 &adapter->pdev->dev,
7715 adapter->adapter_attr.rq_cnt *
7716 LEAPRAID_REP_RQ_CNT_SIZE,
7717 adapter->mem_desc.rep_desc_q_arr,
7718 adapter->mem_desc.rep_desc_q_arr_dma);
7719 adapter->mem_desc.rep_desc_q_arr = NULL;
7720 }
7721
7722 for (i = 0; i < adapter->adapter_attr.rep_desc_q_seg_cnt; i++) {
7723 struct leapraid_mem_desc *mem_desc =
7724 &adapter->mem_desc;
7725 kfree(adapter->mem_desc.rep_desc_seg_maint[i]
7726 .rep_desc_maint);
7727 mem_desc->rep_desc_seg_maint[i].rep_desc_maint = NULL;
7728 }
7729 kfree(adapter->mem_desc.rep_desc_seg_maint);
7730 adapter->mem_desc.rep_desc_seg_maint = NULL;
7731 }
7732
7733 kfree(adapter->mem_desc.taskid_to_uniq_tag);
7734 adapter->mem_desc.taskid_to_uniq_tag = NULL;
7735
7736 dma_pool_destroy(adapter->mem_desc.sg_chain_pool);
7737 adapter->mem_desc.sg_chain_pool = NULL;
7738 }
7739
leapraid_is_in_same_4g_seg(dma_addr_t start,u32 size)7740 static inline bool leapraid_is_in_same_4g_seg(dma_addr_t start, u32 size)
7741 {
7742 return upper_32_bits(start) == upper_32_bits(start + size - 1);
7743 }
7744
leapraid_internal_init_cmd_priv(struct leapraid_adapter * adapter,struct leapraid_io_req_tracker * io_tracker)7745 int leapraid_internal_init_cmd_priv(struct leapraid_adapter *adapter,
7746 struct leapraid_io_req_tracker *io_tracker)
7747 {
7748 io_tracker->chain =
7749 dma_pool_alloc(adapter->mem_desc.sg_chain_pool,
7750 GFP_KERNEL,
7751 &io_tracker->chain_dma);
7752
7753 if (!io_tracker->chain)
7754 return -ENOMEM;
7755
7756 return 0;
7757 }
7758
leapraid_internal_exit_cmd_priv(struct leapraid_adapter * adapter,struct leapraid_io_req_tracker * io_tracker)7759 void leapraid_internal_exit_cmd_priv(struct leapraid_adapter *adapter,
7760 struct leapraid_io_req_tracker *io_tracker)
7761 {
7762 if (io_tracker && io_tracker->chain)
7763 dma_pool_free(adapter->mem_desc.sg_chain_pool,
7764 io_tracker->chain,
7765 io_tracker->chain_dma);
7766 }
7767
leapraid_request_host_memory(struct leapraid_adapter * adapter)7768 static int leapraid_request_host_memory(struct leapraid_adapter *adapter)
7769 {
7770 struct leapraid_adapter_features *facts =
7771 &adapter->adapter_attr.features;
7772 u16 rep_desc_q_cnt_allocated;
7773 unsigned int i, j;
7774 int rc;
7775
7776 /* Scatter-gather table size. */
7777 adapter->shost->sg_tablesize = LEAPRAID_SG_DEPTH;
7778 if (reset_devices)
7779 adapter->shost->sg_tablesize =
7780 LEAPRAID_KDUMP_MIN_PHYS_SEGMENTS;
7781 /* High-priority commands queue depth. */
7782 adapter->dynamic_task_desc.hp_cmd_qd = LEAPRAID_FIXED_HP_CMDS;
7783 /* Internal commands queue depth. */
7784 adapter->dynamic_task_desc.inter_cmd_qd = LEAPRAID_FIXED_INTER_CMDS;
7785 /* Adapter commands total queue depth. */
7786 if (reset_devices)
7787 adapter->adapter_attr.adapter_total_qd =
7788 LEAPRAID_DEFAULT_CMD_QD_OFFSET +
7789 adapter->dynamic_task_desc.inter_cmd_qd +
7790 adapter->dynamic_task_desc.hp_cmd_qd;
7791 else
7792 adapter->adapter_attr.adapter_total_qd = facts->req_slot +
7793 adapter->dynamic_task_desc.hp_cmd_qd;
7794 /* Reply message queue depth. */
7795 adapter->adapter_attr.rep_msg_qd =
7796 adapter->adapter_attr.adapter_total_qd +
7797 LEAPRAID_DEFAULT_CMD_QD_OFFSET;
7798 /* Reply descriptor queue depth. */
7799 adapter->adapter_attr.rep_desc_qd =
7800 round_up(adapter->adapter_attr.adapter_total_qd +
7801 adapter->adapter_attr.rep_msg_qd +
7802 LEAPRAID_TASKID_OFFSET_CTRL_CMD,
7803 LEAPRAID_REPLY_QD_ALIGNMENT);
7804 /* SCSI command I/O depth. */
7805 adapter->adapter_attr.io_qd =
7806 adapter->adapter_attr.adapter_total_qd -
7807 adapter->dynamic_task_desc.hp_cmd_qd -
7808 adapter->dynamic_task_desc.inter_cmd_qd;
7809 /* SCSI host can queue. */
7810 adapter->shost->can_queue = adapter->adapter_attr.io_qd -
7811 LEAPRAID_TASKID_OFFSET_CTRL_CMD;
7812 adapter->driver_cmds.ctl_cmd.taskid = adapter->shost->can_queue +
7813 LEAPRAID_TASKID_OFFSET_CTRL_CMD;
7814
7815 /* Allocate task descriptor. */
7816 try_again:
7817 adapter->adapter_attr.task_desc_dma_size =
7818 (adapter->adapter_attr.adapter_total_qd +
7819 LEAPRAID_TASKID_OFFSET_CTRL_CMD) *
7820 LEAPRAID_REQUEST_SIZE;
7821 adapter->mem_desc.task_desc =
7822 dma_alloc_coherent(&adapter->pdev->dev,
7823 adapter->adapter_attr.task_desc_dma_size,
7824 &adapter->mem_desc.task_desc_dma,
7825 GFP_KERNEL);
7826 if (!adapter->mem_desc.task_desc)
7827 return -ENOMEM;
7828
7829 /* Allocate chain message pool. */
7830 adapter->mem_desc.sg_chain_pool_size =
7831 LEAPRAID_DEFAULT_CHAINS_PER_IO * LEAPRAID_CHAIN_SEG_SIZE;
7832 adapter->mem_desc.sg_chain_pool =
7833 dma_pool_create("leapraid chain pool",
7834 &adapter->pdev->dev,
7835 adapter->mem_desc.sg_chain_pool_size,
7836 LEAPRAID_DMA_ALIGN, 0);
7837 if (!adapter->mem_desc.sg_chain_pool)
7838 return -ENOMEM;
7839
7840 /* Allocate I/O tracker to SCSI I/O. */
7841 adapter->mem_desc.taskid_to_uniq_tag =
7842 kcalloc(adapter->shost->can_queue, sizeof(u16), GFP_KERNEL);
7843 if (!adapter->mem_desc.taskid_to_uniq_tag)
7844 return -ENOMEM;
7845
7846 adapter->dynamic_task_desc.hp_taskid =
7847 adapter->adapter_attr.io_qd +
7848 LEAPRAID_HP_TASKID_OFFSET_CTL_CMD;
7849 /* Allocate static high-priority task ID. */
7850 adapter->driver_cmds.ctl_cmd.hp_taskid =
7851 adapter->dynamic_task_desc.hp_taskid;
7852 adapter->driver_cmds.tm_cmd.hp_taskid =
7853 adapter->dynamic_task_desc.hp_taskid +
7854 LEAPRAID_HP_TASKID_OFFSET_TM_CMD;
7855
7856 adapter->dynamic_task_desc.inter_taskid =
7857 adapter->dynamic_task_desc.hp_taskid +
7858 adapter->dynamic_task_desc.hp_cmd_qd;
7859 adapter->driver_cmds.scan_dev_cmd.inter_taskid =
7860 adapter->dynamic_task_desc.inter_taskid;
7861 adapter->driver_cmds.cfg_op_cmd.inter_taskid =
7862 adapter->dynamic_task_desc.inter_taskid +
7863 LEAPRAID_TASKID_OFFSET_CFG_OP_CMD;
7864 adapter->driver_cmds.transport_cmd.inter_taskid =
7865 adapter->dynamic_task_desc.inter_taskid +
7866 LEAPRAID_TASKID_OFFSET_TRANSPORT_CMD;
7867 adapter->driver_cmds.enc_cmd.inter_taskid =
7868 adapter->dynamic_task_desc.inter_taskid +
7869 LEAPRAID_TASKID_OFFSET_ENC_CMD;
7870 adapter->driver_cmds.notify_event_cmd.inter_taskid =
7871 adapter->dynamic_task_desc.inter_taskid +
7872 LEAPRAID_TASKID_OFFSET_NOTIFY_EVENT_CMD;
7873 dev_info(&adapter->pdev->dev, "queue depth:\n");
7874 dev_info(&adapter->pdev->dev, " host->can_queue: %d\n",
7875 adapter->shost->can_queue);
7876 dev_info(&adapter->pdev->dev, " io_qd: %d\n",
7877 adapter->adapter_attr.io_qd);
7878 dev_info(&adapter->pdev->dev, " hpr_cmd_qd: %d\n",
7879 adapter->dynamic_task_desc.hp_cmd_qd);
7880 dev_info(&adapter->pdev->dev, " inter_cmd_qd: %d\n",
7881 adapter->dynamic_task_desc.inter_cmd_qd);
7882 dev_info(&adapter->pdev->dev, " adapter_total_qd: %d\n",
7883 adapter->adapter_attr.adapter_total_qd);
7884
7885 dev_info(&adapter->pdev->dev, "taskid range:\n");
7886 dev_info(&adapter->pdev->dev,
7887 " adapter->dynamic_task_desc.hp_taskid: %d\n",
7888 adapter->dynamic_task_desc.hp_taskid);
7889 dev_info(&adapter->pdev->dev,
7890 " adapter->dynamic_task_desc.inter_taskid: %d\n",
7891 adapter->dynamic_task_desc.inter_taskid);
7892
7893 /*
7894 * Allocate sense data DMA buffer.
7895 * Constraint: Must reside within the same 4GB segment
7896 * (driver-maintained).
7897 */
7898 adapter->mem_desc.sense_data =
7899 dma_alloc_coherent(
7900 &adapter->pdev->dev,
7901 adapter->adapter_attr.io_qd * SCSI_SENSE_BUFFERSIZE,
7902 &adapter->mem_desc.sense_data_dma,
7903 GFP_KERNEL);
7904 if (!adapter->mem_desc.sense_data)
7905 return -ENOMEM;
7906
7907 if (!leapraid_is_in_same_4g_seg(adapter->mem_desc.sense_data_dma,
7908 adapter->adapter_attr.io_qd *
7909 SCSI_SENSE_BUFFERSIZE)) {
7910 dev_warn(&adapter->pdev->dev,
7911 "Try 32bit DMA: Sense not in same 4G\n");
7912 rc = -EAGAIN;
7913 goto out_fail;
7914 }
7915
7916 /*
7917 * Allocate reply frame buffer.
7918 * Constraint: Must reside in the same 4GB segment as the sense DMA.
7919 */
7920 adapter->mem_desc.rep_msg =
7921 dma_alloc_coherent(&adapter->pdev->dev,
7922 adapter->adapter_attr.rep_msg_qd *
7923 LEAPRAID_REPLY_SIZE,
7924 &adapter->mem_desc.rep_msg_dma,
7925 GFP_KERNEL);
7926 if (!adapter->mem_desc.rep_msg) {
7927 rc = -ENOMEM;
7928 goto out_fail;
7929 }
7930
7931 if (!leapraid_is_in_same_4g_seg(adapter->mem_desc.rep_msg_dma,
7932 adapter->adapter_attr.rep_msg_qd *
7933 LEAPRAID_REPLY_SIZE)) {
7934 dev_warn(&adapter->pdev->dev,
7935 "Use 32 bit DMA due to rep msg is not in same 4g!\n");
7936 rc = -EAGAIN;
7937 goto out_fail;
7938 }
7939
7940 /* Address of reply frame. */
7941 adapter->mem_desc.rep_msg_addr =
7942 dma_alloc_coherent(&adapter->pdev->dev,
7943 adapter->adapter_attr.rep_msg_qd *
7944 LEAPRAID_REP_MSG_ADDR_SIZE,
7945 &adapter->mem_desc.rep_msg_addr_dma,
7946 GFP_KERNEL);
7947 if (!adapter->mem_desc.rep_msg_addr)
7948 return -ENOMEM;
7949 adapter->adapter_attr.rep_desc_q_seg_cnt =
7950 DIV_ROUND_UP(adapter->adapter_attr.rq_cnt,
7951 LEAPRAID_REP_DESC_CHUNK_SIZE);
7952 adapter->mem_desc.rep_desc_seg_maint =
7953 kzalloc_objs(struct leapraid_rep_desc_seg_maint,
7954 adapter->adapter_attr.rep_desc_q_seg_cnt);
7955 if (!adapter->mem_desc.rep_desc_seg_maint)
7956 return -ENOMEM;
7957
7958 rep_desc_q_cnt_allocated = 0;
7959 for (i = 0; i < adapter->adapter_attr.rep_desc_q_seg_cnt; i++) {
7960 adapter->mem_desc.rep_desc_seg_maint[i].rep_desc_maint =
7961 kzalloc_objs(struct leapraid_rep_desc_maint,
7962 LEAPRAID_REP_DESC_CHUNK_SIZE);
7963 if (!adapter->mem_desc.rep_desc_seg_maint[i].rep_desc_maint)
7964 return -ENOMEM;
7965
7966 adapter->mem_desc.rep_desc_seg_maint[i].rep_desc_seg =
7967 dma_alloc_coherent(
7968 &adapter->pdev->dev,
7969 (adapter->adapter_attr.rep_desc_qd *
7970 LEAPRAID_REP_DESC_ENTRY_SIZE) *
7971 LEAPRAID_REP_DESC_CHUNK_SIZE,
7972 &adapter->mem_desc.rep_desc_seg_maint[i]
7973 .rep_desc_seg_dma,
7974 GFP_KERNEL);
7975 if (!adapter->mem_desc.rep_desc_seg_maint[i].rep_desc_seg)
7976 return -ENOMEM;
7977
7978 for (j = 0; j < LEAPRAID_REP_DESC_CHUNK_SIZE; j++) {
7979 if (rep_desc_q_cnt_allocated >=
7980 adapter->adapter_attr.rq_cnt)
7981 break;
7982 adapter->mem_desc
7983 .rep_desc_seg_maint[i]
7984 .rep_desc_maint[j]
7985 .rep_desc =
7986 (void *)((u8 *)(
7987 adapter->mem_desc
7988 .rep_desc_seg_maint[i]
7989 .rep_desc_seg) +
7990 j *
7991 (adapter->adapter_attr.rep_desc_qd *
7992 LEAPRAID_REP_DESC_ENTRY_SIZE));
7993 adapter->mem_desc
7994 .rep_desc_seg_maint[i]
7995 .rep_desc_maint[j]
7996 .rep_desc_dma =
7997 adapter->mem_desc
7998 .rep_desc_seg_maint[i]
7999 .rep_desc_seg_dma +
8000 j *
8001 (adapter->adapter_attr.rep_desc_qd *
8002 LEAPRAID_REP_DESC_ENTRY_SIZE);
8003 rep_desc_q_cnt_allocated++;
8004 }
8005 }
8006
8007 if (!reset_devices) {
8008 adapter->mem_desc.rep_desc_q_arr =
8009 dma_alloc_coherent(
8010 &adapter->pdev->dev,
8011 adapter->adapter_attr.rq_cnt *
8012 LEAPRAID_REP_RQ_CNT_SIZE,
8013 &adapter->mem_desc.rep_desc_q_arr_dma,
8014 GFP_KERNEL);
8015 if (!adapter->mem_desc.rep_desc_q_arr)
8016 return -ENOMEM;
8017 }
8018
8019 return 0;
8020 out_fail:
8021 if (rc == -EAGAIN) {
8022 leapraid_free_host_memory(adapter);
8023 adapter->adapter_attr.use_32_dma_mask = 1;
8024 rc = dma_set_mask_and_coherent(&adapter->pdev->dev,
8025 DMA_BIT_MASK(DMA_32_BITS));
8026 if (rc) {
8027 dev_err(&adapter->pdev->dev,
8028 "Failed to set 32 DMA mask\n");
8029 return rc;
8030 }
8031 goto try_again;
8032 }
8033 return rc;
8034 }
8035
leapraid_alloc_dev_topo_bitmaps(struct leapraid_adapter * adapter)8036 static int leapraid_alloc_dev_topo_bitmaps(struct leapraid_adapter *adapter)
8037 {
8038 u16 pd_hdls_sz;
8039
8040 pd_hdls_sz =
8041 BITS_TO_LONGS(
8042 adapter->adapter_attr.features.max_dev_handle + 1) *
8043 sizeof(unsigned long);
8044
8045 adapter->dev_topo.pd_hdls_sz = pd_hdls_sz;
8046 adapter->dev_topo.pd_hdls =
8047 kzalloc(adapter->dev_topo.pd_hdls_sz, GFP_KERNEL);
8048 if (!adapter->dev_topo.pd_hdls)
8049 return -ENOMEM;
8050
8051 adapter->dev_topo.blocking_hdls =
8052 kzalloc(adapter->dev_topo.pd_hdls_sz, GFP_KERNEL);
8053 if (!adapter->dev_topo.blocking_hdls)
8054 return -ENOMEM;
8055
8056 return 0;
8057 }
8058
leapraid_free_dev_topo_bitmaps(struct leapraid_adapter * adapter)8059 static void leapraid_free_dev_topo_bitmaps(struct leapraid_adapter *adapter)
8060 {
8061 kfree(adapter->dev_topo.pd_hdls);
8062 kfree(adapter->dev_topo.blocking_hdls);
8063 }
8064
leapraid_init_driver_cmds(struct leapraid_adapter * adapter)8065 static int leapraid_init_driver_cmds(struct leapraid_adapter *adapter)
8066 {
8067 INIT_LIST_HEAD(&adapter->driver_cmds.special_cmd_list);
8068
8069 adapter->driver_cmds.scan_dev_cmd.status = LEAPRAID_CMD_NOT_USED;
8070 adapter->driver_cmds.scan_dev_cmd.cb_idx = LEAPRAID_SCAN_DEV_CB_IDX;
8071 list_add_tail(&adapter->driver_cmds.scan_dev_cmd.list,
8072 &adapter->driver_cmds.special_cmd_list);
8073
8074 adapter->driver_cmds.cfg_op_cmd.status = LEAPRAID_CMD_NOT_USED;
8075 adapter->driver_cmds.cfg_op_cmd.cb_idx = LEAPRAID_CONFIG_CB_IDX;
8076 mutex_init(&adapter->driver_cmds.cfg_op_cmd.mutex);
8077 list_add_tail(&adapter->driver_cmds.cfg_op_cmd.list,
8078 &adapter->driver_cmds.special_cmd_list);
8079
8080 adapter->driver_cmds.transport_cmd.status = LEAPRAID_CMD_NOT_USED;
8081 adapter->driver_cmds.transport_cmd.cb_idx = LEAPRAID_TRANSPORT_CB_IDX;
8082 mutex_init(&adapter->driver_cmds.transport_cmd.mutex);
8083 list_add_tail(&adapter->driver_cmds.transport_cmd.list,
8084 &adapter->driver_cmds.special_cmd_list);
8085
8086 adapter->driver_cmds.enc_cmd.status = LEAPRAID_CMD_NOT_USED;
8087 adapter->driver_cmds.enc_cmd.cb_idx = LEAPRAID_ENC_CB_IDX;
8088 mutex_init(&adapter->driver_cmds.enc_cmd.mutex);
8089 list_add_tail(&adapter->driver_cmds.enc_cmd.list,
8090 &adapter->driver_cmds.special_cmd_list);
8091
8092 adapter->driver_cmds.notify_event_cmd.status = LEAPRAID_CMD_NOT_USED;
8093 adapter->driver_cmds.notify_event_cmd.cb_idx =
8094 LEAPRAID_NOTIFY_EVENT_CB_IDX;
8095 mutex_init(&adapter->driver_cmds.notify_event_cmd.mutex);
8096 list_add_tail(&adapter->driver_cmds.notify_event_cmd.list,
8097 &adapter->driver_cmds.special_cmd_list);
8098
8099 adapter->driver_cmds.ctl_cmd.status = LEAPRAID_CMD_NOT_USED;
8100 adapter->driver_cmds.ctl_cmd.cb_idx = LEAPRAID_CTL_CB_IDX;
8101 mutex_init(&adapter->driver_cmds.ctl_cmd.mutex);
8102 list_add_tail(&adapter->driver_cmds.ctl_cmd.list,
8103 &adapter->driver_cmds.special_cmd_list);
8104
8105 adapter->driver_cmds.tm_cmd.status = LEAPRAID_CMD_NOT_USED;
8106 adapter->driver_cmds.tm_cmd.cb_idx = LEAPRAID_TM_CB_IDX;
8107 mutex_init(&adapter->driver_cmds.tm_cmd.mutex);
8108 list_add_tail(&adapter->driver_cmds.tm_cmd.list,
8109 &adapter->driver_cmds.special_cmd_list);
8110
8111 return 0;
8112 }
8113
leapraid_unmask_evts(struct leapraid_adapter * adapter,u16 evt)8114 static void leapraid_unmask_evts(struct leapraid_adapter *adapter, u16 evt)
8115 {
8116 if (evt >= LEAPRAID_MAX_EVENT_NUM)
8117 return;
8118
8119 clear_bit(evt, (unsigned long *)adapter->fw_evt_s.leapraid_evt_masks);
8120 }
8121
leapraid_init_event_mask(struct leapraid_adapter * adapter)8122 static void leapraid_init_event_mask(struct leapraid_adapter *adapter)
8123 {
8124 int i;
8125
8126 for (i = 0; i < LEAPRAID_EVT_MASK_COUNT; i++)
8127 adapter->fw_evt_s.leapraid_evt_masks[i] =
8128 LEAPRAID_INVALID_INITIAL_VALUE;
8129
8130 leapraid_unmask_evts(adapter, LEAPRAID_EVT_SAS_TOPO_CHANGE_LIST);
8131 leapraid_unmask_evts(adapter, LEAPRAID_EVT_SAS_ENCL_DEV_STATUS_CHANGE);
8132 leapraid_unmask_evts(adapter, LEAPRAID_EVT_SAS_DEV_STATUS_CHANGE);
8133 leapraid_unmask_evts(adapter, LEAPRAID_EVT_IR_CHANGE);
8134 }
8135
leapraid_prepare_adapter_init_req(struct leapraid_adapter * adapter,struct leapraid_adapter_init_req * init_req)8136 static void leapraid_prepare_adapter_init_req(
8137 struct leapraid_adapter *adapter,
8138 struct leapraid_adapter_init_req *init_req)
8139 {
8140 ktime_t cur_time;
8141 int i, chunk;
8142 u32 reply_post_free_ary_sz;
8143
8144 memset(init_req, 0, sizeof(struct leapraid_adapter_init_req));
8145 init_req->func = LEAPRAID_FUNC_ADAPTER_INIT;
8146 init_req->who_init = LEAPRAID_WHOINIT_LINUX_DRIVER;
8147 init_req->msg_ver = cpu_to_le16(LEAPRAID_MSG_VERSION);
8148 init_req->header_ver = cpu_to_le16(LEAPRAID_HEADER_VERSION);
8149 init_req->driver_ver =
8150 cpu_to_le32((LEAPRAID_MAJOR_VERSION <<
8151 LEAPRAID_VER_MAJOR_SHIFT) |
8152 (LEAPRAID_MINOR_VERSION << LEAPRAID_VER_MINOR_SHIFT) |
8153 (LEAPRAID_BUILD_VERSION << LEAPRAID_VER_BUILD_SHIFT) |
8154 LEAPRAID_RELEASE_VERSION);
8155 if (adapter->notification_desc.msix_enable)
8156 init_req->host_msix_vectors = adapter->adapter_attr.rq_cnt;
8157
8158 init_req->req_frame_size =
8159 cpu_to_le16(LEAPRAID_REQUEST_SIZE / LEAPRAID_DWORDS_BYTE_SIZE);
8160 init_req->rep_desc_qd =
8161 cpu_to_le16(adapter->adapter_attr.rep_desc_qd);
8162 init_req->rep_msg_qd =
8163 cpu_to_le16(adapter->adapter_attr.rep_msg_qd);
8164 init_req->sense_buffer_add_high =
8165 cpu_to_le32((u64)adapter->mem_desc.sense_data_dma >> 32);
8166 init_req->rep_msg_dma_high =
8167 cpu_to_le32((u64)adapter->mem_desc.rep_msg_dma >> 32);
8168 init_req->task_desc_base_addr =
8169 cpu_to_le64((u64)adapter->mem_desc.task_desc_dma);
8170 init_req->rep_msg_addr_dma =
8171 cpu_to_le64((u64)adapter->mem_desc.rep_msg_addr_dma);
8172 if (!reset_devices) {
8173 reply_post_free_ary_sz =
8174 adapter->adapter_attr.rq_cnt * LEAPRAID_REP_RQ_CNT_SIZE;
8175 memset(adapter->mem_desc.rep_desc_q_arr, 0,
8176 reply_post_free_ary_sz);
8177
8178 chunk = LEAPRAID_REP_DESC_CHUNK_SIZE;
8179 for (i = 0; i < adapter->adapter_attr.rq_cnt; i++)
8180 adapter->mem_desc.rep_desc_q_arr[i].rep_desc_base_addr =
8181 cpu_to_le64 ((u64)adapter->mem_desc
8182 .rep_desc_seg_maint[i / chunk]
8183 .rep_desc_maint[i % chunk]
8184 .rep_desc_dma);
8185
8186 init_req->msg_flg =
8187 LEAPRAID_ADAPTER_INIT_MSGFLG_RDPQ_ARRAY_MODE;
8188 init_req->rep_desc_q_arr_addr =
8189 cpu_to_le64((u64)adapter->mem_desc.rep_desc_q_arr_dma);
8190 } else {
8191 init_req->rep_desc_q_arr_addr =
8192 cpu_to_le64((u64)adapter->mem_desc
8193 .rep_desc_seg_maint[0]
8194 .rep_desc_maint[0]
8195 .rep_desc_dma);
8196 }
8197 cur_time = ktime_get_real();
8198 init_req->time_stamp = cpu_to_le64(ktime_to_ms(cur_time));
8199 }
8200
leapraid_send_adapter_init(struct leapraid_adapter * adapter)8201 static int leapraid_send_adapter_init(struct leapraid_adapter *adapter)
8202 {
8203 struct leapraid_adapter_init_req init_req;
8204 struct leapraid_adapter_init_rep init_rep;
8205 u16 adapter_status;
8206 int rc;
8207
8208 leapraid_prepare_adapter_init_req(adapter, &init_req);
8209
8210 rc = leapraid_handshake_func(adapter,
8211 sizeof(struct leapraid_adapter_init_req),
8212 (u32 *)&init_req,
8213 sizeof(struct leapraid_adapter_init_rep),
8214 (u16 *)&init_rep);
8215 if (rc != 0) {
8216 dev_err(&adapter->pdev->dev, "%s: Handshake failed, rc=%d\n",
8217 __func__, rc);
8218 return rc;
8219 }
8220
8221 adapter_status =
8222 le16_to_cpu(init_rep.adapter_status) &
8223 LEAPRAID_ADAPTER_STATUS_MASK;
8224 if (adapter_status != LEAPRAID_ADAPTER_STATUS_SUCCESS) {
8225 dev_err(&adapter->pdev->dev, "%s: failed\n", __func__);
8226 rc = -EIO;
8227 }
8228
8229 return rc;
8230 }
8231
leapraid_cfg_pages(struct leapraid_adapter * adapter)8232 static int leapraid_cfg_pages(struct leapraid_adapter *adapter)
8233 {
8234 union cfg_param_1 cfgp1 = {0};
8235 union cfg_param_2 cfgp2 = {0};
8236 union {
8237 struct leapraid_manufacturing_p0 manufacturing_page0;
8238 struct leapraid_bios_page3 bios_page3;
8239 struct leapraid_bios_page2 bios_page2;
8240 } cfg_page;
8241 int rc;
8242
8243 rc = leapraid_op_config_page(adapter, &cfg_page.bios_page3, cfgp1,
8244 cfgp2, GET_BIOS_PG3);
8245 if (rc)
8246 return rc;
8247
8248 adapter->adapter_attr.bios_version =
8249 le32_to_cpu(cfg_page.bios_page3.bios_version);
8250
8251 rc = leapraid_op_config_page(adapter, &cfg_page.bios_page2, cfgp1,
8252 cfgp2, GET_BIOS_PG2);
8253 if (rc)
8254 return rc;
8255
8256 adapter->boot_devs.requested_boot_dev.form =
8257 cfg_page.bios_page2.requested_boot_dev_form;
8258 memcpy(adapter->boot_devs.requested_boot_dev.pg_dev,
8259 &cfg_page.bios_page2.requested_boot_dev,
8260 LEAPRAID_BOOT_DEV_SIZE);
8261 adapter->boot_devs.requested_alt_boot_dev.form =
8262 cfg_page.bios_page2.requested_alt_boot_dev_form;
8263 memcpy(adapter->boot_devs.requested_alt_boot_dev.pg_dev,
8264 &cfg_page.bios_page2.requested_alt_boot_dev,
8265 LEAPRAID_BOOT_DEV_SIZE);
8266 adapter->boot_devs.current_boot_dev.form =
8267 cfg_page.bios_page2.current_boot_dev_form;
8268 memcpy(adapter->boot_devs.current_boot_dev.pg_dev,
8269 &cfg_page.bios_page2.current_boot_dev,
8270 LEAPRAID_BOOT_DEV_SIZE);
8271
8272 rc = leapraid_op_config_page(adapter, &cfg_page.manufacturing_page0,
8273 cfgp1, cfgp2, GET_MANUFACTURING_PG0);
8274 if (rc)
8275 return rc;
8276
8277 snprintf(adapter->adapter_attr.board_name,
8278 sizeof(adapter->adapter_attr.board_name),
8279 "%.*s",
8280 (int)sizeof(cfg_page.manufacturing_page0.board_name),
8281 cfg_page.manufacturing_page0.board_name);
8282 return rc;
8283 }
8284
leapraid_evt_notify(struct leapraid_adapter * adapter)8285 static int leapraid_evt_notify(struct leapraid_adapter *adapter)
8286 {
8287 struct leapraid_evt_notify_req *evt_notify_req;
8288 struct leapraid_evt_notify_rep *evt_notify_rep;
8289 u16 adapter_status;
8290 int rc = 0;
8291 int i;
8292
8293 mutex_lock(&adapter->driver_cmds.notify_event_cmd.mutex);
8294 adapter->driver_cmds.notify_event_cmd.status = LEAPRAID_CMD_PENDING;
8295 evt_notify_req =
8296 leapraid_get_task_desc(
8297 adapter,
8298 adapter->driver_cmds.notify_event_cmd.inter_taskid);
8299 memset(evt_notify_req, 0, sizeof(struct leapraid_evt_notify_req));
8300 evt_notify_req->func = LEAPRAID_FUNC_EVENT_NOTIFY;
8301 for (i = 0; i < LEAPRAID_EVT_MASK_COUNT; i++)
8302 evt_notify_req->evt_masks[i] =
8303 cpu_to_le32(adapter->fw_evt_s.leapraid_evt_masks[i]);
8304 init_completion(&adapter->driver_cmds.notify_event_cmd.done);
8305 leapraid_fire_task(adapter,
8306 adapter->driver_cmds.notify_event_cmd.inter_taskid);
8307 wait_for_completion_timeout(
8308 &adapter->driver_cmds.notify_event_cmd.done,
8309 LEAPRAID_NOTIFY_EVENT_CMD_TIMEOUT * HZ);
8310
8311 if (!(adapter->driver_cmds.notify_event_cmd.status &
8312 LEAPRAID_CMD_DONE)) {
8313 rc = -EFAULT;
8314 goto out_cleanup;
8315 }
8316
8317 if (!(adapter->driver_cmds.notify_event_cmd.status &
8318 LEAPRAID_CMD_REPLY_VALID)) {
8319 rc = -EFAULT;
8320 goto out_cleanup;
8321 }
8322
8323 evt_notify_rep = (void *)&adapter->driver_cmds.notify_event_cmd.reply;
8324 adapter_status = le16_to_cpu(evt_notify_rep->adapter_status) &
8325 LEAPRAID_ADAPTER_STATUS_MASK;
8326 if (adapter_status != LEAPRAID_ADAPTER_STATUS_SUCCESS)
8327 rc = -EFAULT;
8328
8329 out_cleanup:
8330 adapter->driver_cmds.notify_event_cmd.status = LEAPRAID_CMD_NOT_USED;
8331 mutex_unlock(&adapter->driver_cmds.notify_event_cmd.mutex);
8332
8333 return rc;
8334 }
8335
leapraid_scan_dev(struct leapraid_adapter * adapter,bool async_scan_dev)8336 int leapraid_scan_dev(struct leapraid_adapter *adapter, bool async_scan_dev)
8337 {
8338 struct leapraid_scan_dev_req *scan_dev_req;
8339 struct leapraid_scan_dev_rep *scan_dev_rep;
8340 u16 adapter_status;
8341 int rc = 0;
8342
8343 dev_info(&adapter->pdev->dev,
8344 "Send device scan, async_scan_dev=%d!\n", async_scan_dev);
8345
8346 adapter->driver_cmds.scan_dev_cmd.status = LEAPRAID_CMD_PENDING;
8347 adapter->driver_cmds.scan_dev_cmd.async_scan_dev = async_scan_dev;
8348 scan_dev_req =
8349 leapraid_get_task_desc(
8350 adapter,
8351 adapter->driver_cmds.scan_dev_cmd.inter_taskid);
8352 memset(scan_dev_req, 0, sizeof(struct leapraid_scan_dev_req));
8353 scan_dev_req->func = LEAPRAID_FUNC_SCAN_DEV;
8354
8355 if (async_scan_dev) {
8356 adapter->scan_dev_desc.first_scan_dev_fired = 1;
8357 leapraid_fire_task(
8358 adapter,
8359 adapter->driver_cmds.scan_dev_cmd.inter_taskid);
8360 return 0;
8361 }
8362
8363 init_completion(&adapter->driver_cmds.scan_dev_cmd.done);
8364 leapraid_fire_task(adapter,
8365 adapter->driver_cmds.scan_dev_cmd.inter_taskid);
8366 wait_for_completion_timeout(&adapter->driver_cmds.scan_dev_cmd.done,
8367 LEAPRAID_SCAN_DEV_CMD_TIMEOUT * HZ);
8368 if (!(adapter->driver_cmds.scan_dev_cmd.status & LEAPRAID_CMD_DONE)) {
8369 dev_err(&adapter->pdev->dev, "Device scan timeout!\n");
8370 if (adapter->driver_cmds.scan_dev_cmd.status &
8371 LEAPRAID_CMD_RESET)
8372 rc = -EFAULT;
8373 else
8374 rc = -ETIME;
8375 goto out_cleanup;
8376 }
8377
8378 scan_dev_rep = (void *)&adapter->driver_cmds.scan_dev_cmd.reply;
8379 adapter_status =
8380 le16_to_cpu(scan_dev_rep->adapter_status) &
8381 LEAPRAID_ADAPTER_STATUS_MASK;
8382 if (adapter_status != LEAPRAID_ADAPTER_STATUS_SUCCESS) {
8383 dev_err(&adapter->pdev->dev, "Device scan failure!\n");
8384 rc = -EFAULT;
8385 goto out_cleanup;
8386 }
8387
8388 out_cleanup:
8389 adapter->driver_cmds.scan_dev_cmd.status = LEAPRAID_CMD_NOT_USED;
8390 return rc;
8391 }
8392
leapraid_init_task_tracker(struct leapraid_adapter * adapter)8393 static void leapraid_init_task_tracker(struct leapraid_adapter *adapter)
8394 {
8395 unsigned long flags;
8396
8397 spin_lock_irqsave(&adapter->dynamic_task_desc.task_lock, flags);
8398
8399 spin_unlock_irqrestore(&adapter->dynamic_task_desc.task_lock, flags);
8400 }
8401
leapraid_init_rep_msg_addr(struct leapraid_adapter * adapter)8402 static void leapraid_init_rep_msg_addr(struct leapraid_adapter *adapter)
8403 {
8404 u32 reply_address;
8405 unsigned int i;
8406
8407 for (i = 0, reply_address = (u32)adapter->mem_desc.rep_msg_dma;
8408 i < adapter->adapter_attr.rep_msg_qd;
8409 i++, reply_address += LEAPRAID_REPLY_SIZE)
8410 adapter->mem_desc.rep_msg_addr[i] = cpu_to_le32(reply_address);
8411 }
8412
init_rep_desc(struct leapraid_rq * rq,int index,union leapraid_rep_desc_union * reply_post_free_contig)8413 static void init_rep_desc(
8414 struct leapraid_rq *rq,
8415 int index,
8416 union leapraid_rep_desc_union *reply_post_free_contig)
8417 {
8418 struct leapraid_adapter *adapter = rq->adapter;
8419 unsigned int i;
8420
8421 if (!reset_devices)
8422 rq->rep_desc =
8423 adapter->mem_desc
8424 .rep_desc_seg_maint[index /
8425 LEAPRAID_REP_DESC_CHUNK_SIZE]
8426 .rep_desc_maint[index %
8427 LEAPRAID_REP_DESC_CHUNK_SIZE]
8428 .rep_desc;
8429 else
8430 rq->rep_desc = reply_post_free_contig;
8431
8432 rq->rep_post_host_idx = 0;
8433 for (i = 0; i < adapter->adapter_attr.rep_desc_qd; i++)
8434 rq->rep_desc[i].words = cpu_to_le64(ULLONG_MAX);
8435 }
8436
leapraid_init_rep_desc(struct leapraid_adapter * adapter)8437 static void leapraid_init_rep_desc(struct leapraid_adapter *adapter)
8438 {
8439 union leapraid_rep_desc_union *reply_post_free_contig;
8440 struct leapraid_int_rq *int_rq;
8441 struct leapraid_blk_mq_poll_rq *blk_mq_poll_rq;
8442 unsigned int i;
8443 int index;
8444
8445 index = 0;
8446 reply_post_free_contig = adapter->mem_desc
8447 .rep_desc_seg_maint[0]
8448 .rep_desc_maint[0]
8449 .rep_desc;
8450
8451 for (i = 0; i < adapter->notification_desc.iopoll_qdex; i++) {
8452 int_rq = &adapter->notification_desc.int_rqs[i];
8453 init_rep_desc(&int_rq->rq, index, reply_post_free_contig);
8454 if (!reset_devices)
8455 index++;
8456 else
8457 reply_post_free_contig +=
8458 adapter->adapter_attr.rep_desc_qd;
8459 }
8460
8461 for (i = 0; i < adapter->notification_desc.iopoll_qcnt; i++) {
8462 blk_mq_poll_rq = &adapter->notification_desc.blk_mq_poll_rqs[i];
8463 init_rep_desc(&blk_mq_poll_rq->rq,
8464 index, reply_post_free_contig);
8465 if (!reset_devices)
8466 index++;
8467 else
8468 reply_post_free_contig +=
8469 adapter->adapter_attr.rep_desc_qd;
8470 }
8471 }
8472
leapraid_init_bar_idx_regs(struct leapraid_adapter * adapter)8473 static void leapraid_init_bar_idx_regs(struct leapraid_adapter *adapter)
8474 {
8475 struct leapraid_int_rq *int_rq;
8476 struct leapraid_blk_mq_poll_rq *blk_mq_poll_rq;
8477 unsigned int i, j;
8478
8479 adapter->rep_msg_host_idx = adapter->adapter_attr.rep_msg_qd - 1;
8480 writel(adapter->rep_msg_host_idx,
8481 &adapter->iomem_base->rep_msg_host_idx);
8482
8483 for (i = 0; i < adapter->notification_desc.iopoll_qdex; i++) {
8484 int_rq = &adapter->notification_desc.int_rqs[i];
8485 for (j = 0; j < REP_POST_HOST_IDX_REG_CNT; j++)
8486 writel((int_rq->rq.msix_idx & 7) <<
8487 LEAPRAID_RPHI_MSIX_IDX_SHIFT,
8488 &adapter->iomem_base->rep_post_reg_idx[j].idx);
8489 }
8490
8491 for (i = 0; i < adapter->notification_desc.iopoll_qcnt; i++) {
8492 blk_mq_poll_rq =
8493 &adapter->notification_desc.blk_mq_poll_rqs[i];
8494 for (j = 0; j < REP_POST_HOST_IDX_REG_CNT; j++)
8495 writel((blk_mq_poll_rq->rq.msix_idx & 7) <<
8496 LEAPRAID_RPHI_MSIX_IDX_SHIFT,
8497 &adapter->iomem_base->rep_post_reg_idx[j].idx);
8498 }
8499 }
8500
leapraid_make_adapter_available(struct leapraid_adapter * adapter)8501 static int leapraid_make_adapter_available(struct leapraid_adapter *adapter)
8502 {
8503 int rc;
8504
8505 leapraid_init_task_tracker(adapter);
8506 leapraid_init_rep_msg_addr(adapter);
8507
8508 if (adapter->scan_dev_desc.driver_loading)
8509 leapraid_configure_reply_queue_affinity(adapter);
8510
8511 leapraid_init_rep_desc(adapter);
8512 rc = leapraid_send_adapter_init(adapter);
8513 if (rc)
8514 return rc;
8515
8516 leapraid_init_bar_idx_regs(adapter);
8517 leapraid_unmask_int(adapter);
8518 rc = leapraid_cfg_pages(adapter);
8519 if (rc)
8520 return rc;
8521
8522 rc = leapraid_evt_notify(adapter);
8523 if (rc)
8524 return rc;
8525
8526 if (!adapter->access_ctrl.shost_recovering) {
8527 adapter->scan_dev_desc.wait_scan_dev_done = 1;
8528 return 0;
8529 }
8530
8531 return leapraid_scan_dev(adapter, false);
8532 }
8533
leapraid_ctrl_init(struct leapraid_adapter * adapter)8534 int leapraid_ctrl_init(struct leapraid_adapter *adapter)
8535 {
8536 u32 cap;
8537 int rc;
8538
8539 rc = leapraid_init_driver_cmds(adapter);
8540 if (rc) {
8541 dev_err(&adapter->pdev->dev, "Init driver cmds failure\n");
8542 goto out_free;
8543 }
8544
8545 rc = leapraid_set_pcie_and_notification(adapter);
8546 if (rc)
8547 goto out_free;
8548
8549 pci_set_drvdata(adapter->pdev, adapter->shost);
8550
8551 pcie_capability_read_dword(adapter->pdev, PCI_EXP_DEVCAP, &cap);
8552
8553 if (cap & PCI_EXP_DEVCAP_EXT_TAG)
8554 pcie_capability_set_word(adapter->pdev, PCI_EXP_DEVCTL,
8555 PCI_EXP_DEVCTL_EXT_TAG);
8556
8557 rc = leapraid_fw_log_init(adapter);
8558 if (rc) {
8559 dev_err(&adapter->pdev->dev, "FW log init failure\n");
8560 goto out_free;
8561 }
8562
8563 rc = leapraid_request_host_memory(adapter);
8564 if (rc) {
8565 dev_err(&adapter->pdev->dev, "Request host memory failure\n");
8566 goto out_free;
8567 }
8568
8569 init_waitqueue_head(&adapter->reset_desc.reset_wait_queue);
8570 init_waitqueue_head(&adapter->access_ctrl.shost_recover_wq);
8571
8572 rc = leapraid_alloc_dev_topo_bitmaps(adapter);
8573 if (rc) {
8574 dev_err(&adapter->pdev->dev, "Alloc topo bitmaps failure\n");
8575 goto out_free;
8576 }
8577
8578 leapraid_init_event_mask(adapter);
8579
8580 rc = leapraid_make_adapter_available(adapter);
8581 if (rc) {
8582 dev_err(&adapter->pdev->dev,
8583 "Make adapter available failure\n");
8584 goto out_free;
8585 }
8586
8587 leapraid_overheat_init(adapter);
8588 if (!adapter->overheat_desc.fault_overheat_wq) {
8589 rc = -ENOMEM;
8590 goto out_free;
8591 }
8592
8593 return 0;
8594
8595 out_free:
8596 adapter->access_ctrl.host_removing = 1;
8597 leapraid_fw_log_exit(adapter);
8598 leapraid_disable_controller(adapter);
8599 leapraid_free_host_memory(adapter);
8600 leapraid_free_dev_topo_bitmaps(adapter);
8601 pci_set_drvdata(adapter->pdev, NULL);
8602 return rc;
8603 }
8604
leapraid_remove_ctrl(struct leapraid_adapter * adapter)8605 void leapraid_remove_ctrl(struct leapraid_adapter *adapter)
8606 {
8607 leapraid_overheat_cleanup(adapter);
8608 leapraid_check_scheduled_fault_stop(adapter);
8609 leapraid_fw_log_stop(adapter);
8610 leapraid_fw_log_exit(adapter);
8611 leapraid_disable_controller(adapter);
8612 leapraid_free_host_memory(adapter);
8613 leapraid_free_dev_topo_bitmaps(adapter);
8614 leapraid_free_enc_list(adapter);
8615 pci_set_drvdata(adapter->pdev, NULL);
8616 }
8617