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