xref: /openbmc/linux/drivers/scsi/isci/host.h (revision ce2b3261)
16f231ddaSDan Williams /*
26f231ddaSDan Williams  * This file is provided under a dual BSD/GPLv2 license.  When using or
36f231ddaSDan Williams  * redistributing this file, you may do so under either license.
46f231ddaSDan Williams  *
56f231ddaSDan Williams  * GPL LICENSE SUMMARY
66f231ddaSDan Williams  *
76f231ddaSDan Williams  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
86f231ddaSDan Williams  *
96f231ddaSDan Williams  * This program is free software; you can redistribute it and/or modify
106f231ddaSDan Williams  * it under the terms of version 2 of the GNU General Public License as
116f231ddaSDan Williams  * published by the Free Software Foundation.
126f231ddaSDan Williams  *
136f231ddaSDan Williams  * This program is distributed in the hope that it will be useful, but
146f231ddaSDan Williams  * WITHOUT ANY WARRANTY; without even the implied warranty of
156f231ddaSDan Williams  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
166f231ddaSDan Williams  * General Public License for more details.
176f231ddaSDan Williams  *
186f231ddaSDan Williams  * You should have received a copy of the GNU General Public License
196f231ddaSDan Williams  * along with this program; if not, write to the Free Software
206f231ddaSDan Williams  * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
216f231ddaSDan Williams  * The full GNU General Public License is included in this distribution
226f231ddaSDan Williams  * in the file called LICENSE.GPL.
236f231ddaSDan Williams  *
246f231ddaSDan Williams  * BSD LICENSE
256f231ddaSDan Williams  *
266f231ddaSDan Williams  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
276f231ddaSDan Williams  * All rights reserved.
286f231ddaSDan Williams  *
296f231ddaSDan Williams  * Redistribution and use in source and binary forms, with or without
306f231ddaSDan Williams  * modification, are permitted provided that the following conditions
316f231ddaSDan Williams  * are met:
326f231ddaSDan Williams  *
336f231ddaSDan Williams  *   * Redistributions of source code must retain the above copyright
346f231ddaSDan Williams  *     notice, this list of conditions and the following disclaimer.
356f231ddaSDan Williams  *   * Redistributions in binary form must reproduce the above copyright
366f231ddaSDan Williams  *     notice, this list of conditions and the following disclaimer in
376f231ddaSDan Williams  *     the documentation and/or other materials provided with the
386f231ddaSDan Williams  *     distribution.
396f231ddaSDan Williams  *   * Neither the name of Intel Corporation nor the names of its
406f231ddaSDan Williams  *     contributors may be used to endorse or promote products derived
416f231ddaSDan Williams  *     from this software without specific prior written permission.
426f231ddaSDan Williams  *
436f231ddaSDan Williams  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
446f231ddaSDan Williams  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
456f231ddaSDan Williams  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
466f231ddaSDan Williams  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
476f231ddaSDan Williams  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
486f231ddaSDan Williams  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
496f231ddaSDan Williams  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
506f231ddaSDan Williams  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
516f231ddaSDan Williams  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
526f231ddaSDan Williams  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
536f231ddaSDan Williams  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
546f231ddaSDan Williams  */
556f231ddaSDan Williams 
56ce2b3261SDan Williams #ifndef _SCI_HOST_H_
576f231ddaSDan Williams #define _SCI_HOST_H_
586f231ddaSDan Williams 
59cc3dbd0aSArtur Wojcik #include "scic_sds_controller.h"
606f231ddaSDan Williams #include "remote_device.h"
61ce2b3261SDan Williams #include "phy.h"
626f231ddaSDan Williams 
636f231ddaSDan Williams struct isci_host {
64cc3dbd0aSArtur Wojcik 	struct scic_sds_controller sci;
656f231ddaSDan Williams 	union scic_oem_parameters oem_parameters;
666f231ddaSDan Williams 
676f231ddaSDan Williams 	int id; /* unique within a given pci device */
687c40a803SDan Williams 	struct list_head timers;
696f231ddaSDan Williams 	void *core_ctrl_memory;
706f231ddaSDan Williams 	struct dma_pool *dma_pool;
716f231ddaSDan Williams 	struct isci_phy phys[SCI_MAX_PHYS];
72e531381eSDan Williams 	struct isci_port ports[SCI_MAX_PORTS + 1]; /* includes dummy port */
736f231ddaSDan Williams 	struct sas_ha_struct sas_ha;
746f231ddaSDan Williams 
756f231ddaSDan Williams 	int can_queue;
766f231ddaSDan Williams 	spinlock_t queue_lock;
776f231ddaSDan Williams 	spinlock_t state_lock;
786f231ddaSDan Williams 
796f231ddaSDan Williams 	struct pci_dev *pdev;
806f231ddaSDan Williams 
816f231ddaSDan Williams 	enum isci_status status;
820cf89d1dSDan Williams 	#define IHOST_START_PENDING 0
830cf89d1dSDan Williams 	#define IHOST_STOP_PENDING 1
840cf89d1dSDan Williams 	unsigned long flags;
850cf89d1dSDan Williams 	wait_queue_head_t eventq;
866f231ddaSDan Williams 	struct Scsi_Host *shost;
876f231ddaSDan Williams 	struct tasklet_struct completion_tasklet;
886f231ddaSDan Williams 	struct list_head requests_to_complete;
8911b00c19SJeff Skirvin 	struct list_head requests_to_errorback;
906f231ddaSDan Williams 	spinlock_t scic_lock;
91d9c37390SDan Williams 
9257f20f4eSDan Williams 	struct isci_remote_device devices[SCI_MAX_REMOTE_DEVICES];
936f231ddaSDan Williams };
946f231ddaSDan Williams 
956f231ddaSDan Williams /**
966f231ddaSDan Williams  * struct isci_pci_info - This class represents the pci function containing the
976f231ddaSDan Williams  *    controllers. Depending on PCI SKU, there could be up to 2 controllers in
986f231ddaSDan Williams  *    the PCI function.
996f231ddaSDan Williams  */
1006f231ddaSDan Williams #define SCI_MAX_MSIX_INT (SCI_NUM_MSI_X_INT*SCI_MAX_CONTROLLERS)
1016f231ddaSDan Williams 
1026f231ddaSDan Williams struct isci_pci_info {
1036f231ddaSDan Williams 	struct msix_entry msix_entries[SCI_MAX_MSIX_INT];
104b329aff1SDan Williams 	struct isci_host *hosts[SCI_MAX_CONTROLLERS];
105d044af17SDan Williams 	struct isci_orom *orom;
1066f231ddaSDan Williams };
1076f231ddaSDan Williams 
1086f231ddaSDan Williams static inline struct isci_pci_info *to_pci_info(struct pci_dev *pdev)
1096f231ddaSDan Williams {
1106f231ddaSDan Williams 	return pci_get_drvdata(pdev);
1116f231ddaSDan Williams }
1126f231ddaSDan Williams 
113b329aff1SDan Williams #define for_each_isci_host(id, ihost, pdev) \
114b329aff1SDan Williams 	for (id = 0, ihost = to_pci_info(pdev)->hosts[id]; \
115b329aff1SDan Williams 	     id < ARRAY_SIZE(to_pci_info(pdev)->hosts) && ihost; \
116b329aff1SDan Williams 	     ihost = to_pci_info(pdev)->hosts[++id])
1176f231ddaSDan Williams 
1186f231ddaSDan Williams static inline
1196f231ddaSDan Williams enum isci_status isci_host_get_state(
1206f231ddaSDan Williams 	struct isci_host *isci_host)
1216f231ddaSDan Williams {
1226f231ddaSDan Williams 	return isci_host->status;
1236f231ddaSDan Williams }
1246f231ddaSDan Williams 
1256f231ddaSDan Williams 
1266f231ddaSDan Williams static inline void isci_host_change_state(
1276f231ddaSDan Williams 	struct isci_host *isci_host,
1286f231ddaSDan Williams 	enum isci_status status)
1296f231ddaSDan Williams {
1306f231ddaSDan Williams 	unsigned long flags;
1316f231ddaSDan Williams 
1326f231ddaSDan Williams 	dev_dbg(&isci_host->pdev->dev,
1336f231ddaSDan Williams 		"%s: isci_host = %p, state = 0x%x",
1346f231ddaSDan Williams 		__func__,
1356f231ddaSDan Williams 		isci_host,
1366f231ddaSDan Williams 		status);
1376f231ddaSDan Williams 	spin_lock_irqsave(&isci_host->state_lock, flags);
1386f231ddaSDan Williams 	isci_host->status = status;
1396f231ddaSDan Williams 	spin_unlock_irqrestore(&isci_host->state_lock, flags);
1406f231ddaSDan Williams 
1416f231ddaSDan Williams }
1426f231ddaSDan Williams 
1436f231ddaSDan Williams static inline int isci_host_can_queue(
1446f231ddaSDan Williams 	struct isci_host *isci_host,
1456f231ddaSDan Williams 	int num)
1466f231ddaSDan Williams {
1476f231ddaSDan Williams 	int ret = 0;
1486f231ddaSDan Williams 	unsigned long flags;
1496f231ddaSDan Williams 
1506f231ddaSDan Williams 	spin_lock_irqsave(&isci_host->queue_lock, flags);
1516f231ddaSDan Williams 	if ((isci_host->can_queue - num) < 0) {
1526f231ddaSDan Williams 		dev_dbg(&isci_host->pdev->dev,
1536f231ddaSDan Williams 			"%s: isci_host->can_queue = %d\n",
1546f231ddaSDan Williams 			__func__,
1556f231ddaSDan Williams 			isci_host->can_queue);
1566f231ddaSDan Williams 		ret = -SAS_QUEUE_FULL;
1576f231ddaSDan Williams 
1586f231ddaSDan Williams 	} else
1596f231ddaSDan Williams 		isci_host->can_queue -= num;
1606f231ddaSDan Williams 
1616f231ddaSDan Williams 	spin_unlock_irqrestore(&isci_host->queue_lock, flags);
1626f231ddaSDan Williams 
1636f231ddaSDan Williams 	return ret;
1646f231ddaSDan Williams }
1656f231ddaSDan Williams 
1666f231ddaSDan Williams static inline void isci_host_can_dequeue(
1676f231ddaSDan Williams 	struct isci_host *isci_host,
1686f231ddaSDan Williams 	int num)
1696f231ddaSDan Williams {
1706f231ddaSDan Williams 	unsigned long flags;
1716f231ddaSDan Williams 
1726f231ddaSDan Williams 	spin_lock_irqsave(&isci_host->queue_lock, flags);
1736f231ddaSDan Williams 	isci_host->can_queue += num;
1746f231ddaSDan Williams 	spin_unlock_irqrestore(&isci_host->queue_lock, flags);
1756f231ddaSDan Williams }
1766f231ddaSDan Williams 
1770cf89d1dSDan Williams static inline void wait_for_start(struct isci_host *ihost)
1780cf89d1dSDan Williams {
1790cf89d1dSDan Williams 	wait_event(ihost->eventq, !test_bit(IHOST_START_PENDING, &ihost->flags));
1800cf89d1dSDan Williams }
1810cf89d1dSDan Williams 
1820cf89d1dSDan Williams static inline void wait_for_stop(struct isci_host *ihost)
1830cf89d1dSDan Williams {
1840cf89d1dSDan Williams 	wait_event(ihost->eventq, !test_bit(IHOST_STOP_PENDING, &ihost->flags));
1850cf89d1dSDan Williams }
1860cf89d1dSDan Williams 
1876ad31fecSDan Williams static inline void wait_for_device_start(struct isci_host *ihost, struct isci_remote_device *idev)
1886ad31fecSDan Williams {
1896ad31fecSDan Williams 	wait_event(ihost->eventq, !test_bit(IDEV_START_PENDING, &idev->flags));
1906ad31fecSDan Williams }
1916ad31fecSDan Williams 
1926ad31fecSDan Williams static inline void wait_for_device_stop(struct isci_host *ihost, struct isci_remote_device *idev)
1936ad31fecSDan Williams {
194d9c37390SDan Williams 	wait_event(ihost->eventq, !test_bit(IDEV_STOP_PENDING, &idev->flags));
1956ad31fecSDan Williams }
1960cf89d1dSDan Williams 
1974393aa4eSDan Williams static inline struct isci_host *dev_to_ihost(struct domain_device *dev)
1984393aa4eSDan Williams {
1994393aa4eSDan Williams 	return dev->port->ha->lldd_ha;
2004393aa4eSDan Williams }
2016f231ddaSDan Williams 
202cc3dbd0aSArtur Wojcik static inline struct isci_host *scic_to_ihost(struct scic_sds_controller *scic)
203cc3dbd0aSArtur Wojcik {
204cc3dbd0aSArtur Wojcik 	/* XXX delete after merging scic_sds_contoller and isci_host */
205cc3dbd0aSArtur Wojcik 	struct isci_host *ihost = container_of(scic, typeof(*ihost), sci);
206cc3dbd0aSArtur Wojcik 
207cc3dbd0aSArtur Wojcik 	return ihost;
208cc3dbd0aSArtur Wojcik }
209cc3dbd0aSArtur Wojcik 
2106f231ddaSDan Williams /**
2116f231ddaSDan Williams  * isci_host_scan_finished() -
2126f231ddaSDan Williams  *
2136f231ddaSDan Williams  * This function is one of the SCSI Host Template functions. The SCSI midlayer
2146f231ddaSDan Williams  * calls this function during a target scan, approx. once every 10 millisecs.
2156f231ddaSDan Williams  */
2166f231ddaSDan Williams int isci_host_scan_finished(
2176f231ddaSDan Williams 	struct Scsi_Host *,
2186f231ddaSDan Williams 	unsigned long);
2196f231ddaSDan Williams 
2206f231ddaSDan Williams 
2216f231ddaSDan Williams /**
2226f231ddaSDan Williams  * isci_host_scan_start() -
2236f231ddaSDan Williams  *
2246f231ddaSDan Williams  * This function is one of the SCSI Host Template function, called by the SCSI
2256f231ddaSDan Williams  * mid layer berfore a target scan begins. The core library controller start
2266f231ddaSDan Williams  * routine is called from here.
2276f231ddaSDan Williams  */
2286f231ddaSDan Williams void isci_host_scan_start(
2296f231ddaSDan Williams 	struct Scsi_Host *);
2306f231ddaSDan Williams 
2316f231ddaSDan Williams /**
2326f231ddaSDan Williams  * isci_host_start_complete() -
2336f231ddaSDan Williams  *
2346f231ddaSDan Williams  * This function is called by the core library, through the ISCI Module, to
2356f231ddaSDan Williams  * indicate controller start status.
2366f231ddaSDan Williams  */
2376f231ddaSDan Williams void isci_host_start_complete(
2386f231ddaSDan Williams 	struct isci_host *,
2396f231ddaSDan Williams 	enum sci_status);
2406f231ddaSDan Williams 
2416f231ddaSDan Williams void isci_host_stop_complete(
2426f231ddaSDan Williams 	struct isci_host *isci_host,
2436f231ddaSDan Williams 	enum sci_status completion_status);
2446f231ddaSDan Williams 
2456f231ddaSDan Williams int isci_host_init(struct isci_host *);
2466f231ddaSDan Williams 
2476f231ddaSDan Williams void isci_host_init_controller_names(
2486f231ddaSDan Williams 	struct isci_host *isci_host,
2496f231ddaSDan Williams 	unsigned int controller_idx);
2506f231ddaSDan Williams 
2516f231ddaSDan Williams void isci_host_deinit(
2526f231ddaSDan Williams 	struct isci_host *);
2536f231ddaSDan Williams 
2546f231ddaSDan Williams void isci_host_port_link_up(
2556f231ddaSDan Williams 	struct isci_host *,
2566f231ddaSDan Williams 	struct scic_sds_port *,
2576f231ddaSDan Williams 	struct scic_sds_phy *);
2586f231ddaSDan Williams int isci_host_dev_found(struct domain_device *);
2596f231ddaSDan Williams 
2606f231ddaSDan Williams void isci_host_remote_device_start_complete(
2616f231ddaSDan Williams 	struct isci_host *,
2626f231ddaSDan Williams 	struct isci_remote_device *,
2636f231ddaSDan Williams 	enum sci_status);
2646f231ddaSDan Williams 
2656f231ddaSDan Williams #endif /* !defined(_SCI_HOST_H_) */
266