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