xref: /openbmc/linux/drivers/scsi/mpi3mr/mpi3mr_os.c (revision c9566231)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Driver for Broadcom MPI3 Storage Controllers
4  *
5  * Copyright (C) 2017-2021 Broadcom Inc.
6  *  (mailto: mpi3mr-linuxdrv.pdl@broadcom.com)
7  *
8  */
9 
10 #include "mpi3mr.h"
11 
12 /* global driver scop variables */
13 LIST_HEAD(mrioc_list);
14 DEFINE_SPINLOCK(mrioc_list_lock);
15 static int mrioc_ids;
16 static int warn_non_secure_ctlr;
17 
18 MODULE_AUTHOR(MPI3MR_DRIVER_AUTHOR);
19 MODULE_DESCRIPTION(MPI3MR_DRIVER_DESC);
20 MODULE_LICENSE(MPI3MR_DRIVER_LICENSE);
21 MODULE_VERSION(MPI3MR_DRIVER_VERSION);
22 
23 /* Module parameters*/
24 int logging_level;
25 module_param(logging_level, int, 0);
26 MODULE_PARM_DESC(logging_level,
27 	" bits for enabling additional logging info (default=0)");
28 
29 /**
30  * mpi3mr_map_queues - Map queues callback handler
31  * @shost: SCSI host reference
32  *
33  * Call the blk_mq_pci_map_queues with from which operational
34  * queue the mapping has to be done
35  *
36  * Return: return of blk_mq_pci_map_queues
37  */
38 static int mpi3mr_map_queues(struct Scsi_Host *shost)
39 {
40 	struct mpi3mr_ioc *mrioc = shost_priv(shost);
41 
42 	return blk_mq_pci_map_queues(&shost->tag_set.map[HCTX_TYPE_DEFAULT],
43 	    mrioc->pdev, mrioc->op_reply_q_offset);
44 }
45 
46 /**
47  * mpi3mr_slave_destroy - Slave destroy callback handler
48  * @sdev: SCSI device reference
49  *
50  * Cleanup and free per device(lun) private data.
51  *
52  * Return: Nothing.
53  */
54 static void mpi3mr_slave_destroy(struct scsi_device *sdev)
55 {
56 }
57 
58 /**
59  * mpi3mr_target_destroy - Target destroy callback handler
60  * @starget: SCSI target reference
61  *
62  * Cleanup and free per target private data.
63  *
64  * Return: Nothing.
65  */
66 static void mpi3mr_target_destroy(struct scsi_target *starget)
67 {
68 }
69 
70 /**
71  * mpi3mr_slave_configure - Slave configure callback handler
72  * @sdev: SCSI device reference
73  *
74  * Configure queue depth, max hardware sectors and virt boundary
75  * as required
76  *
77  * Return: 0 always.
78  */
79 static int mpi3mr_slave_configure(struct scsi_device *sdev)
80 {
81 	int retval = 0;
82 	return retval;
83 }
84 
85 /**
86  * mpi3mr_slave_alloc -Slave alloc callback handler
87  * @sdev: SCSI device reference
88  *
89  * Allocate per device(lun) private data and initialize it.
90  *
91  * Return: 0 on success -ENOMEM on memory allocation failure.
92  */
93 static int mpi3mr_slave_alloc(struct scsi_device *sdev)
94 {
95 	int retval = 0;
96 	return retval;
97 }
98 
99 /**
100  * mpi3mr_target_alloc - Target alloc callback handler
101  * @starget: SCSI target reference
102  *
103  * Allocate per target private data and initialize it.
104  *
105  * Return: 0 on success -ENOMEM on memory allocation failure.
106  */
107 static int mpi3mr_target_alloc(struct scsi_target *starget)
108 {
109 	int retval = -ENODEV;
110 	return retval;
111 }
112 
113 /**
114  * mpi3mr_qcmd - I/O request despatcher
115  * @shost: SCSI Host reference
116  * @scmd: SCSI Command reference
117  *
118  * Issues the SCSI Command as an MPI3 request.
119  *
120  * Return: 0 on successful queueing of the request or if the
121  *         request is completed with failure.
122  *         SCSI_MLQUEUE_DEVICE_BUSY when the device is busy.
123  *         SCSI_MLQUEUE_HOST_BUSY when the host queue is full.
124  */
125 static int mpi3mr_qcmd(struct Scsi_Host *shost,
126 	struct scsi_cmnd *scmd)
127 {
128 	int retval = 0;
129 
130 	scmd->result = DID_NO_CONNECT << 16;
131 	scmd->scsi_done(scmd);
132 	return retval;
133 }
134 
135 static struct scsi_host_template mpi3mr_driver_template = {
136 	.module				= THIS_MODULE,
137 	.name				= "MPI3 Storage Controller",
138 	.proc_name			= MPI3MR_DRIVER_NAME,
139 	.queuecommand			= mpi3mr_qcmd,
140 	.target_alloc			= mpi3mr_target_alloc,
141 	.slave_alloc			= mpi3mr_slave_alloc,
142 	.slave_configure		= mpi3mr_slave_configure,
143 	.target_destroy			= mpi3mr_target_destroy,
144 	.slave_destroy			= mpi3mr_slave_destroy,
145 	.map_queues			= mpi3mr_map_queues,
146 	.no_write_same			= 1,
147 	.can_queue			= 1,
148 	.this_id			= -1,
149 	.sg_tablesize			= MPI3MR_SG_DEPTH,
150 	/* max xfer supported is 1M (2K in 512 byte sized sectors)
151 	 */
152 	.max_sectors			= 2048,
153 	.cmd_per_lun			= MPI3MR_MAX_CMDS_LUN,
154 	.track_queue_depth		= 1,
155 	.cmd_size			= sizeof(struct scmd_priv),
156 };
157 
158 /**
159  * mpi3mr_init_drv_cmd - Initialize internal command tracker
160  * @cmdptr: Internal command tracker
161  * @host_tag: Host tag used for the specific command
162  *
163  * Initialize the internal command tracker structure with
164  * specified host tag.
165  *
166  * Return: Nothing.
167  */
168 static inline void mpi3mr_init_drv_cmd(struct mpi3mr_drv_cmd *cmdptr,
169 	u16 host_tag)
170 {
171 	mutex_init(&cmdptr->mutex);
172 	cmdptr->reply = NULL;
173 	cmdptr->state = MPI3MR_CMD_NOTUSED;
174 	cmdptr->dev_handle = MPI3MR_INVALID_DEV_HANDLE;
175 	cmdptr->host_tag = host_tag;
176 }
177 
178 /**
179  * mpi3mr_probe - PCI probe callback
180  * @pdev: PCI device instance
181  * @id: PCI device ID details
182  *
183  * controller initialization routine. Checks the security status
184  * of the controller and if it is invalid or tampered return the
185  * probe without initializing the controller. Otherwise,
186  * allocate per adapter instance through shost_priv and
187  * initialize controller specific data structures, initializae
188  * the controller hardware, add shost to the SCSI subsystem.
189  *
190  * Return: 0 on success, non-zero on failure.
191  */
192 
193 static int
194 mpi3mr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
195 {
196 	struct mpi3mr_ioc *mrioc = NULL;
197 	struct Scsi_Host *shost = NULL;
198 	int retval = 0;
199 
200 	shost = scsi_host_alloc(&mpi3mr_driver_template,
201 	    sizeof(struct mpi3mr_ioc));
202 	if (!shost) {
203 		retval = -ENODEV;
204 		goto shost_failed;
205 	}
206 
207 	mrioc = shost_priv(shost);
208 	mrioc->id = mrioc_ids++;
209 	sprintf(mrioc->driver_name, "%s", MPI3MR_DRIVER_NAME);
210 	sprintf(mrioc->name, "%s%d", mrioc->driver_name, mrioc->id);
211 	INIT_LIST_HEAD(&mrioc->list);
212 	spin_lock(&mrioc_list_lock);
213 	list_add_tail(&mrioc->list, &mrioc_list);
214 	spin_unlock(&mrioc_list_lock);
215 
216 	spin_lock_init(&mrioc->admin_req_lock);
217 	spin_lock_init(&mrioc->reply_free_queue_lock);
218 	spin_lock_init(&mrioc->sbq_lock);
219 
220 	mpi3mr_init_drv_cmd(&mrioc->init_cmds, MPI3MR_HOSTTAG_INITCMDS);
221 	if (pdev->revision)
222 		mrioc->enable_segqueue = true;
223 
224 	mrioc->logging_level = logging_level;
225 	mrioc->shost = shost;
226 	mrioc->pdev = pdev;
227 
228 	/* init shost parameters */
229 	shost->max_cmd_len = MPI3MR_MAX_CDB_LENGTH;
230 	shost->max_lun = -1;
231 	shost->unique_id = mrioc->id;
232 
233 	shost->max_channel = 1;
234 	shost->max_id = 0xFFFFFFFF;
235 
236 	mrioc->is_driver_loading = 1;
237 	if (mpi3mr_init_ioc(mrioc)) {
238 		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
239 		    __FILE__, __LINE__, __func__);
240 		retval = -ENODEV;
241 		goto out_iocinit_failed;
242 	}
243 
244 	shost->nr_hw_queues = mrioc->num_op_reply_q;
245 	shost->can_queue = mrioc->max_host_ios;
246 	shost->sg_tablesize = MPI3MR_SG_DEPTH;
247 	shost->max_id = mrioc->facts.max_perids;
248 
249 	retval = scsi_add_host(shost, &pdev->dev);
250 	if (retval) {
251 		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
252 		    __FILE__, __LINE__, __func__);
253 		goto addhost_failed;
254 	}
255 
256 	scsi_scan_host(shost);
257 	return retval;
258 
259 addhost_failed:
260 	mpi3mr_cleanup_ioc(mrioc);
261 out_iocinit_failed:
262 	spin_lock(&mrioc_list_lock);
263 	list_del(&mrioc->list);
264 	spin_unlock(&mrioc_list_lock);
265 	scsi_host_put(shost);
266 shost_failed:
267 	return retval;
268 }
269 
270 /**
271  * mpi3mr_remove - PCI remove callback
272  * @pdev: PCI device instance
273  *
274  * Free up all memory and resources associated with the
275  * controllerand target devices, unregister the shost.
276  *
277  * Return: Nothing.
278  */
279 static void mpi3mr_remove(struct pci_dev *pdev)
280 {
281 	struct Scsi_Host *shost = pci_get_drvdata(pdev);
282 	struct mpi3mr_ioc *mrioc;
283 
284 	mrioc = shost_priv(shost);
285 	while (mrioc->reset_in_progress || mrioc->is_driver_loading)
286 		ssleep(1);
287 
288 	scsi_remove_host(shost);
289 
290 	mpi3mr_cleanup_ioc(mrioc);
291 
292 	spin_lock(&mrioc_list_lock);
293 	list_del(&mrioc->list);
294 	spin_unlock(&mrioc_list_lock);
295 
296 	scsi_host_put(shost);
297 }
298 
299 /**
300  * mpi3mr_shutdown - PCI shutdown callback
301  * @pdev: PCI device instance
302  *
303  * Free up all memory and resources associated with the
304  * controller
305  *
306  * Return: Nothing.
307  */
308 static void mpi3mr_shutdown(struct pci_dev *pdev)
309 {
310 	struct Scsi_Host *shost = pci_get_drvdata(pdev);
311 	struct mpi3mr_ioc *mrioc;
312 
313 	if (!shost)
314 		return;
315 
316 	mrioc = shost_priv(shost);
317 	while (mrioc->reset_in_progress || mrioc->is_driver_loading)
318 		ssleep(1);
319 
320 	mpi3mr_cleanup_ioc(mrioc);
321 }
322 
323 static const struct pci_device_id mpi3mr_pci_id_table[] = {
324 	{
325 		PCI_DEVICE_SUB(PCI_VENDOR_ID_LSI_LOGIC, 0x00A5,
326 		    PCI_ANY_ID, PCI_ANY_ID)
327 	},
328 	{ 0 }
329 };
330 MODULE_DEVICE_TABLE(pci, mpi3mr_pci_id_table);
331 
332 static struct pci_driver mpi3mr_pci_driver = {
333 	.name = MPI3MR_DRIVER_NAME,
334 	.id_table = mpi3mr_pci_id_table,
335 	.probe = mpi3mr_probe,
336 	.remove = mpi3mr_remove,
337 	.shutdown = mpi3mr_shutdown,
338 };
339 
340 static int __init mpi3mr_init(void)
341 {
342 	int ret_val;
343 
344 	pr_info("Loading %s version %s\n", MPI3MR_DRIVER_NAME,
345 	    MPI3MR_DRIVER_VERSION);
346 
347 	ret_val = pci_register_driver(&mpi3mr_pci_driver);
348 
349 	return ret_val;
350 }
351 
352 static void __exit mpi3mr_exit(void)
353 {
354 	if (warn_non_secure_ctlr)
355 		pr_warn(
356 		    "Unloading %s version %s while managing a non secure controller\n",
357 		    MPI3MR_DRIVER_NAME, MPI3MR_DRIVER_VERSION);
358 	else
359 		pr_info("Unloading %s version %s\n", MPI3MR_DRIVER_NAME,
360 		    MPI3MR_DRIVER_VERSION);
361 
362 	pci_unregister_driver(&mpi3mr_pci_driver);
363 }
364 
365 module_init(mpi3mr_init);
366 module_exit(mpi3mr_exit);
367