18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Device driver for the SYMBIOS/LSILOGIC 53C8XX and 53C1010 family
48c2ecf20Sopenharmony_ci * of PCI-SCSI IO processors.
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * Copyright (C) 1999-2001  Gerard Roudier <groudier@free.fr>
78c2ecf20Sopenharmony_ci *
88c2ecf20Sopenharmony_ci * This driver is derived from the Linux sym53c8xx driver.
98c2ecf20Sopenharmony_ci * Copyright (C) 1998-2000  Gerard Roudier
108c2ecf20Sopenharmony_ci *
118c2ecf20Sopenharmony_ci * The sym53c8xx driver is derived from the ncr53c8xx driver that had been
128c2ecf20Sopenharmony_ci * a port of the FreeBSD ncr driver to Linux-1.2.13.
138c2ecf20Sopenharmony_ci *
148c2ecf20Sopenharmony_ci * The original ncr driver has been written for 386bsd and FreeBSD by
158c2ecf20Sopenharmony_ci *         Wolfgang Stanglmeier        <wolf@cologne.de>
168c2ecf20Sopenharmony_ci *         Stefan Esser                <se@mi.Uni-Koeln.de>
178c2ecf20Sopenharmony_ci * Copyright (C) 1994  Wolfgang Stanglmeier
188c2ecf20Sopenharmony_ci *
198c2ecf20Sopenharmony_ci * Other major contributions:
208c2ecf20Sopenharmony_ci *
218c2ecf20Sopenharmony_ci * NVRAM detection and reading.
228c2ecf20Sopenharmony_ci * Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk>
238c2ecf20Sopenharmony_ci *
248c2ecf20Sopenharmony_ci *-----------------------------------------------------------------------------
258c2ecf20Sopenharmony_ci */
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci#ifndef SYM_GLUE_H
288c2ecf20Sopenharmony_ci#define SYM_GLUE_H
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci#include <linux/completion.h>
318c2ecf20Sopenharmony_ci#include <linux/delay.h>
328c2ecf20Sopenharmony_ci#include <linux/interrupt.h>
338c2ecf20Sopenharmony_ci#include <linux/ioport.h>
348c2ecf20Sopenharmony_ci#include <linux/pci.h>
358c2ecf20Sopenharmony_ci#include <linux/string.h>
368c2ecf20Sopenharmony_ci#include <linux/timer.h>
378c2ecf20Sopenharmony_ci#include <linux/types.h>
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci#include <asm/io.h>
408c2ecf20Sopenharmony_ci#ifdef __sparc__
418c2ecf20Sopenharmony_ci#  include <asm/irq.h>
428c2ecf20Sopenharmony_ci#endif
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci#include <scsi/scsi.h>
458c2ecf20Sopenharmony_ci#include <scsi/scsi_cmnd.h>
468c2ecf20Sopenharmony_ci#include <scsi/scsi_device.h>
478c2ecf20Sopenharmony_ci#include <scsi/scsi_transport_spi.h>
488c2ecf20Sopenharmony_ci#include <scsi/scsi_host.h>
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci#include "sym53c8xx.h"
518c2ecf20Sopenharmony_ci#include "sym_defs.h"
528c2ecf20Sopenharmony_ci#include "sym_misc.h"
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci/*
558c2ecf20Sopenharmony_ci * Configuration addendum for Linux.
568c2ecf20Sopenharmony_ci */
578c2ecf20Sopenharmony_ci#define	SYM_CONF_TIMER_INTERVAL		((HZ+1)/2)
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci#undef SYM_OPT_HANDLE_DEVICE_QUEUEING
608c2ecf20Sopenharmony_ci#define SYM_OPT_LIMIT_COMMAND_REORDERING
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci/*
638c2ecf20Sopenharmony_ci *  Print a message with severity.
648c2ecf20Sopenharmony_ci */
658c2ecf20Sopenharmony_ci#define printf_emerg(args...)	printk(KERN_EMERG args)
668c2ecf20Sopenharmony_ci#define	printf_alert(args...)	printk(KERN_ALERT args)
678c2ecf20Sopenharmony_ci#define	printf_crit(args...)	printk(KERN_CRIT args)
688c2ecf20Sopenharmony_ci#define	printf_err(args...)	printk(KERN_ERR	args)
698c2ecf20Sopenharmony_ci#define	printf_warning(args...)	printk(KERN_WARNING args)
708c2ecf20Sopenharmony_ci#define	printf_notice(args...)	printk(KERN_NOTICE args)
718c2ecf20Sopenharmony_ci#define	printf_info(args...)	printk(KERN_INFO args)
728c2ecf20Sopenharmony_ci#define	printf_debug(args...)	printk(KERN_DEBUG args)
738c2ecf20Sopenharmony_ci#define	printf(args...)		printk(args)
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci/*
768c2ecf20Sopenharmony_ci *  A 'read barrier' flushes any data that have been prefetched
778c2ecf20Sopenharmony_ci *  by the processor due to out of order execution. Such a barrier
788c2ecf20Sopenharmony_ci *  must notably be inserted prior to looking at data that have
798c2ecf20Sopenharmony_ci *  been DMAed, assuming that program does memory READs in proper
808c2ecf20Sopenharmony_ci *  order and that the device ensured proper ordering of WRITEs.
818c2ecf20Sopenharmony_ci *
828c2ecf20Sopenharmony_ci *  A 'write barrier' prevents any previous WRITEs to pass further
838c2ecf20Sopenharmony_ci *  WRITEs. Such barriers must be inserted each time another agent
848c2ecf20Sopenharmony_ci *  relies on ordering of WRITEs.
858c2ecf20Sopenharmony_ci *
868c2ecf20Sopenharmony_ci *  Note that, due to posting of PCI memory writes, we also must
878c2ecf20Sopenharmony_ci *  insert dummy PCI read transactions when some ordering involving
888c2ecf20Sopenharmony_ci *  both directions over the PCI does matter. PCI transactions are
898c2ecf20Sopenharmony_ci *  fully ordered in each direction.
908c2ecf20Sopenharmony_ci */
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ci#define MEMORY_READ_BARRIER()	rmb()
938c2ecf20Sopenharmony_ci#define MEMORY_WRITE_BARRIER()	wmb()
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_ci/*
968c2ecf20Sopenharmony_ci *  IO functions definition for big/little endian CPU support.
978c2ecf20Sopenharmony_ci *  For now, PCI chips are only supported in little endian addressing mode,
988c2ecf20Sopenharmony_ci */
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ci#ifdef	__BIG_ENDIAN
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci#define	readw_l2b	readw
1038c2ecf20Sopenharmony_ci#define	readl_l2b	readl
1048c2ecf20Sopenharmony_ci#define	writew_b2l	writew
1058c2ecf20Sopenharmony_ci#define	writel_b2l	writel
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_ci#else	/* little endian */
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_ci#define	readw_raw	readw
1108c2ecf20Sopenharmony_ci#define	readl_raw	readl
1118c2ecf20Sopenharmony_ci#define	writew_raw	writew
1128c2ecf20Sopenharmony_ci#define	writel_raw	writel
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ci#endif /* endian */
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ci#ifdef	SYM_CONF_CHIP_BIG_ENDIAN
1178c2ecf20Sopenharmony_ci#error	"Chips in BIG ENDIAN addressing mode are not (yet) supported"
1188c2ecf20Sopenharmony_ci#endif
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_ci/*
1218c2ecf20Sopenharmony_ci *  If the CPU and the chip use same endian-ness addressing,
1228c2ecf20Sopenharmony_ci *  no byte reordering is needed for script patching.
1238c2ecf20Sopenharmony_ci *  Macro cpu_to_scr() is to be used for script patching.
1248c2ecf20Sopenharmony_ci *  Macro scr_to_cpu() is to be used for getting a DWORD
1258c2ecf20Sopenharmony_ci *  from the script.
1268c2ecf20Sopenharmony_ci */
1278c2ecf20Sopenharmony_ci
1288c2ecf20Sopenharmony_ci#define cpu_to_scr(dw)	cpu_to_le32(dw)
1298c2ecf20Sopenharmony_ci#define scr_to_cpu(dw)	le32_to_cpu(dw)
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_ci/*
1328c2ecf20Sopenharmony_ci *  These ones are used as return code from
1338c2ecf20Sopenharmony_ci *  error recovery handlers under Linux.
1348c2ecf20Sopenharmony_ci */
1358c2ecf20Sopenharmony_ci#define SCSI_SUCCESS	SUCCESS
1368c2ecf20Sopenharmony_ci#define SCSI_FAILED	FAILED
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_ci/*
1398c2ecf20Sopenharmony_ci *  System specific target data structure.
1408c2ecf20Sopenharmony_ci *  None for now, under Linux.
1418c2ecf20Sopenharmony_ci */
1428c2ecf20Sopenharmony_ci/* #define SYM_HAVE_STCB */
1438c2ecf20Sopenharmony_ci
1448c2ecf20Sopenharmony_ci/*
1458c2ecf20Sopenharmony_ci *  System specific lun data structure.
1468c2ecf20Sopenharmony_ci */
1478c2ecf20Sopenharmony_ci#define SYM_HAVE_SLCB
1488c2ecf20Sopenharmony_cistruct sym_slcb {
1498c2ecf20Sopenharmony_ci	u_short	reqtags;	/* Number of tags requested by user */
1508c2ecf20Sopenharmony_ci	u_short scdev_depth;	/* Queue depth set in select_queue_depth() */
1518c2ecf20Sopenharmony_ci};
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_ci/*
1548c2ecf20Sopenharmony_ci *  System specific command data structure.
1558c2ecf20Sopenharmony_ci *  Not needed under Linux.
1568c2ecf20Sopenharmony_ci */
1578c2ecf20Sopenharmony_ci/* struct sym_sccb */
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci/*
1608c2ecf20Sopenharmony_ci *  System specific host data structure.
1618c2ecf20Sopenharmony_ci */
1628c2ecf20Sopenharmony_cistruct sym_shcb {
1638c2ecf20Sopenharmony_ci	/*
1648c2ecf20Sopenharmony_ci	 *  Chip and controller identification.
1658c2ecf20Sopenharmony_ci	 */
1668c2ecf20Sopenharmony_ci	int		unit;
1678c2ecf20Sopenharmony_ci	char		inst_name[16];
1688c2ecf20Sopenharmony_ci	char		chip_name[8];
1698c2ecf20Sopenharmony_ci
1708c2ecf20Sopenharmony_ci	struct Scsi_Host *host;
1718c2ecf20Sopenharmony_ci
1728c2ecf20Sopenharmony_ci	void __iomem *	ioaddr;		/* MMIO kernel io address	*/
1738c2ecf20Sopenharmony_ci	void __iomem *	ramaddr;	/* RAM  kernel io address	*/
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_ci	struct timer_list timer;	/* Timer handler link header	*/
1768c2ecf20Sopenharmony_ci	u_long		lasttime;
1778c2ecf20Sopenharmony_ci	u_long		settle_time;	/* Resetting the SCSI BUS	*/
1788c2ecf20Sopenharmony_ci	u_char		settle_time_valid;
1798c2ecf20Sopenharmony_ci};
1808c2ecf20Sopenharmony_ci
1818c2ecf20Sopenharmony_ci/*
1828c2ecf20Sopenharmony_ci *  Return the name of the controller.
1838c2ecf20Sopenharmony_ci */
1848c2ecf20Sopenharmony_ci#define sym_name(np) (np)->s.inst_name
1858c2ecf20Sopenharmony_ci
1868c2ecf20Sopenharmony_cistruct sym_nvram;
1878c2ecf20Sopenharmony_ci
1888c2ecf20Sopenharmony_ci/*
1898c2ecf20Sopenharmony_ci * The IO macros require a struct called 's' and are abused in sym_nvram.c
1908c2ecf20Sopenharmony_ci */
1918c2ecf20Sopenharmony_cistruct sym_device {
1928c2ecf20Sopenharmony_ci	struct pci_dev *pdev;
1938c2ecf20Sopenharmony_ci	unsigned long mmio_base;
1948c2ecf20Sopenharmony_ci	unsigned long ram_base;
1958c2ecf20Sopenharmony_ci	struct {
1968c2ecf20Sopenharmony_ci		void __iomem *ioaddr;
1978c2ecf20Sopenharmony_ci		void __iomem *ramaddr;
1988c2ecf20Sopenharmony_ci	} s;
1998c2ecf20Sopenharmony_ci	struct sym_chip chip;
2008c2ecf20Sopenharmony_ci	struct sym_nvram *nvram;
2018c2ecf20Sopenharmony_ci	u_char host_id;
2028c2ecf20Sopenharmony_ci};
2038c2ecf20Sopenharmony_ci
2048c2ecf20Sopenharmony_ci/*
2058c2ecf20Sopenharmony_ci *  Driver host data structure.
2068c2ecf20Sopenharmony_ci */
2078c2ecf20Sopenharmony_cistruct sym_data {
2088c2ecf20Sopenharmony_ci	struct sym_hcb *ncb;
2098c2ecf20Sopenharmony_ci	struct completion *io_reset;		/* PCI error handling */
2108c2ecf20Sopenharmony_ci	struct pci_dev *pdev;
2118c2ecf20Sopenharmony_ci};
2128c2ecf20Sopenharmony_ci
2138c2ecf20Sopenharmony_cistatic inline struct sym_hcb * sym_get_hcb(struct Scsi_Host *host)
2148c2ecf20Sopenharmony_ci{
2158c2ecf20Sopenharmony_ci	return ((struct sym_data *)host->hostdata)->ncb;
2168c2ecf20Sopenharmony_ci}
2178c2ecf20Sopenharmony_ci
2188c2ecf20Sopenharmony_ci#include "sym_fw.h"
2198c2ecf20Sopenharmony_ci#include "sym_hipd.h"
2208c2ecf20Sopenharmony_ci
2218c2ecf20Sopenharmony_ci/*
2228c2ecf20Sopenharmony_ci *  Set the status field of a CAM CCB.
2238c2ecf20Sopenharmony_ci */
2248c2ecf20Sopenharmony_cistatic inline void
2258c2ecf20Sopenharmony_cisym_set_cam_status(struct scsi_cmnd *cmd, int status)
2268c2ecf20Sopenharmony_ci{
2278c2ecf20Sopenharmony_ci	cmd->result &= ~(0xff  << 16);
2288c2ecf20Sopenharmony_ci	cmd->result |= (status << 16);
2298c2ecf20Sopenharmony_ci}
2308c2ecf20Sopenharmony_ci
2318c2ecf20Sopenharmony_ci/*
2328c2ecf20Sopenharmony_ci *  Get the status field of a CAM CCB.
2338c2ecf20Sopenharmony_ci */
2348c2ecf20Sopenharmony_cistatic inline int
2358c2ecf20Sopenharmony_cisym_get_cam_status(struct scsi_cmnd *cmd)
2368c2ecf20Sopenharmony_ci{
2378c2ecf20Sopenharmony_ci	return host_byte(cmd->result);
2388c2ecf20Sopenharmony_ci}
2398c2ecf20Sopenharmony_ci
2408c2ecf20Sopenharmony_ci/*
2418c2ecf20Sopenharmony_ci *  Build CAM result for a successful IO and for a failed IO.
2428c2ecf20Sopenharmony_ci */
2438c2ecf20Sopenharmony_cistatic inline void sym_set_cam_result_ok(struct sym_ccb *cp, struct scsi_cmnd *cmd, int resid)
2448c2ecf20Sopenharmony_ci{
2458c2ecf20Sopenharmony_ci	scsi_set_resid(cmd, resid);
2468c2ecf20Sopenharmony_ci	cmd->result = (DID_OK << 16) | (cp->ssss_status & 0x7f);
2478c2ecf20Sopenharmony_ci}
2488c2ecf20Sopenharmony_civoid sym_set_cam_result_error(struct sym_hcb *np, struct sym_ccb *cp, int resid);
2498c2ecf20Sopenharmony_ci
2508c2ecf20Sopenharmony_civoid sym_xpt_done(struct sym_hcb *np, struct scsi_cmnd *ccb);
2518c2ecf20Sopenharmony_ci#define sym_print_addr(cmd, arg...) dev_info(&cmd->device->sdev_gendev , ## arg)
2528c2ecf20Sopenharmony_civoid sym_xpt_async_bus_reset(struct sym_hcb *np);
2538c2ecf20Sopenharmony_ciint  sym_setup_data_and_start (struct sym_hcb *np, struct scsi_cmnd *csio, struct sym_ccb *cp);
2548c2ecf20Sopenharmony_civoid sym_log_bus_error(struct Scsi_Host *);
2558c2ecf20Sopenharmony_civoid sym_dump_registers(struct Scsi_Host *);
2568c2ecf20Sopenharmony_ci
2578c2ecf20Sopenharmony_ci#endif /* SYM_GLUE_H */
258