162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Device driver for the SYMBIOS/LSILOGIC 53C8XX and 53C1010 family 462306a36Sopenharmony_ci * of PCI-SCSI IO processors. 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Copyright (C) 1999-2001 Gerard Roudier <groudier@free.fr> 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * This driver is derived from the Linux sym53c8xx driver. 962306a36Sopenharmony_ci * Copyright (C) 1998-2000 Gerard Roudier 1062306a36Sopenharmony_ci * 1162306a36Sopenharmony_ci * The sym53c8xx driver is derived from the ncr53c8xx driver that had been 1262306a36Sopenharmony_ci * a port of the FreeBSD ncr driver to Linux-1.2.13. 1362306a36Sopenharmony_ci * 1462306a36Sopenharmony_ci * The original ncr driver has been written for 386bsd and FreeBSD by 1562306a36Sopenharmony_ci * Wolfgang Stanglmeier <wolf@cologne.de> 1662306a36Sopenharmony_ci * Stefan Esser <se@mi.Uni-Koeln.de> 1762306a36Sopenharmony_ci * Copyright (C) 1994 Wolfgang Stanglmeier 1862306a36Sopenharmony_ci * 1962306a36Sopenharmony_ci * Other major contributions: 2062306a36Sopenharmony_ci * 2162306a36Sopenharmony_ci * NVRAM detection and reading. 2262306a36Sopenharmony_ci * Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk> 2362306a36Sopenharmony_ci * 2462306a36Sopenharmony_ci *----------------------------------------------------------------------------- 2562306a36Sopenharmony_ci */ 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci#ifndef SYM_GLUE_H 2862306a36Sopenharmony_ci#define SYM_GLUE_H 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci#include <linux/completion.h> 3162306a36Sopenharmony_ci#include <linux/delay.h> 3262306a36Sopenharmony_ci#include <linux/interrupt.h> 3362306a36Sopenharmony_ci#include <linux/ioport.h> 3462306a36Sopenharmony_ci#include <linux/pci.h> 3562306a36Sopenharmony_ci#include <linux/string.h> 3662306a36Sopenharmony_ci#include <linux/timer.h> 3762306a36Sopenharmony_ci#include <linux/types.h> 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci#include <asm/io.h> 4062306a36Sopenharmony_ci#ifdef __sparc__ 4162306a36Sopenharmony_ci# include <asm/irq.h> 4262306a36Sopenharmony_ci#endif 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci#include <scsi/scsi.h> 4562306a36Sopenharmony_ci#include <scsi/scsi_cmnd.h> 4662306a36Sopenharmony_ci#include <scsi/scsi_device.h> 4762306a36Sopenharmony_ci#include <scsi/scsi_transport_spi.h> 4862306a36Sopenharmony_ci#include <scsi/scsi_host.h> 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci#include "sym53c8xx.h" 5162306a36Sopenharmony_ci#include "sym_defs.h" 5262306a36Sopenharmony_ci#include "sym_misc.h" 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci/* 5562306a36Sopenharmony_ci * Configuration addendum for Linux. 5662306a36Sopenharmony_ci */ 5762306a36Sopenharmony_ci#define SYM_CONF_TIMER_INTERVAL ((HZ+1)/2) 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci#undef SYM_OPT_HANDLE_DEVICE_QUEUEING 6062306a36Sopenharmony_ci#define SYM_OPT_LIMIT_COMMAND_REORDERING 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci/* 6362306a36Sopenharmony_ci * Print a message with severity. 6462306a36Sopenharmony_ci */ 6562306a36Sopenharmony_ci#define printf_emerg(args...) printk(KERN_EMERG args) 6662306a36Sopenharmony_ci#define printf_alert(args...) printk(KERN_ALERT args) 6762306a36Sopenharmony_ci#define printf_crit(args...) printk(KERN_CRIT args) 6862306a36Sopenharmony_ci#define printf_err(args...) printk(KERN_ERR args) 6962306a36Sopenharmony_ci#define printf_warning(args...) printk(KERN_WARNING args) 7062306a36Sopenharmony_ci#define printf_notice(args...) printk(KERN_NOTICE args) 7162306a36Sopenharmony_ci#define printf_info(args...) printk(KERN_INFO args) 7262306a36Sopenharmony_ci#define printf_debug(args...) printk(KERN_DEBUG args) 7362306a36Sopenharmony_ci#define printf(args...) printk(args) 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci/* 7662306a36Sopenharmony_ci * A 'read barrier' flushes any data that have been prefetched 7762306a36Sopenharmony_ci * by the processor due to out of order execution. Such a barrier 7862306a36Sopenharmony_ci * must notably be inserted prior to looking at data that have 7962306a36Sopenharmony_ci * been DMAed, assuming that program does memory READs in proper 8062306a36Sopenharmony_ci * order and that the device ensured proper ordering of WRITEs. 8162306a36Sopenharmony_ci * 8262306a36Sopenharmony_ci * A 'write barrier' prevents any previous WRITEs to pass further 8362306a36Sopenharmony_ci * WRITEs. Such barriers must be inserted each time another agent 8462306a36Sopenharmony_ci * relies on ordering of WRITEs. 8562306a36Sopenharmony_ci * 8662306a36Sopenharmony_ci * Note that, due to posting of PCI memory writes, we also must 8762306a36Sopenharmony_ci * insert dummy PCI read transactions when some ordering involving 8862306a36Sopenharmony_ci * both directions over the PCI does matter. PCI transactions are 8962306a36Sopenharmony_ci * fully ordered in each direction. 9062306a36Sopenharmony_ci */ 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci#define MEMORY_READ_BARRIER() rmb() 9362306a36Sopenharmony_ci#define MEMORY_WRITE_BARRIER() wmb() 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci/* 9662306a36Sopenharmony_ci * IO functions definition for big/little endian CPU support. 9762306a36Sopenharmony_ci * For now, PCI chips are only supported in little endian addressing mode, 9862306a36Sopenharmony_ci */ 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci#ifdef __BIG_ENDIAN 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci#define readw_l2b readw 10362306a36Sopenharmony_ci#define readl_l2b readl 10462306a36Sopenharmony_ci#define writew_b2l writew 10562306a36Sopenharmony_ci#define writel_b2l writel 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci#else /* little endian */ 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci#define readw_raw readw 11062306a36Sopenharmony_ci#define readl_raw readl 11162306a36Sopenharmony_ci#define writew_raw writew 11262306a36Sopenharmony_ci#define writel_raw writel 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci#endif /* endian */ 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci#ifdef SYM_CONF_CHIP_BIG_ENDIAN 11762306a36Sopenharmony_ci#error "Chips in BIG ENDIAN addressing mode are not (yet) supported" 11862306a36Sopenharmony_ci#endif 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci/* 12162306a36Sopenharmony_ci * If the CPU and the chip use same endian-ness addressing, 12262306a36Sopenharmony_ci * no byte reordering is needed for script patching. 12362306a36Sopenharmony_ci * Macro cpu_to_scr() is to be used for script patching. 12462306a36Sopenharmony_ci * Macro scr_to_cpu() is to be used for getting a DWORD 12562306a36Sopenharmony_ci * from the script. 12662306a36Sopenharmony_ci */ 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci#define cpu_to_scr(dw) cpu_to_le32(dw) 12962306a36Sopenharmony_ci#define scr_to_cpu(dw) le32_to_cpu(dw) 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci/* 13262306a36Sopenharmony_ci * These ones are used as return code from 13362306a36Sopenharmony_ci * error recovery handlers under Linux. 13462306a36Sopenharmony_ci */ 13562306a36Sopenharmony_ci#define SCSI_SUCCESS SUCCESS 13662306a36Sopenharmony_ci#define SCSI_FAILED FAILED 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci/* 13962306a36Sopenharmony_ci * System specific target data structure. 14062306a36Sopenharmony_ci * None for now, under Linux. 14162306a36Sopenharmony_ci */ 14262306a36Sopenharmony_ci/* #define SYM_HAVE_STCB */ 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci/* 14562306a36Sopenharmony_ci * System specific lun data structure. 14662306a36Sopenharmony_ci */ 14762306a36Sopenharmony_ci#define SYM_HAVE_SLCB 14862306a36Sopenharmony_cistruct sym_slcb { 14962306a36Sopenharmony_ci u_short reqtags; /* Number of tags requested by user */ 15062306a36Sopenharmony_ci u_short scdev_depth; /* Queue depth set in select_queue_depth() */ 15162306a36Sopenharmony_ci}; 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci/* 15462306a36Sopenharmony_ci * System specific command data structure. 15562306a36Sopenharmony_ci * Not needed under Linux. 15662306a36Sopenharmony_ci */ 15762306a36Sopenharmony_ci/* struct sym_sccb */ 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci/* 16062306a36Sopenharmony_ci * System specific host data structure. 16162306a36Sopenharmony_ci */ 16262306a36Sopenharmony_cistruct sym_shcb { 16362306a36Sopenharmony_ci /* 16462306a36Sopenharmony_ci * Chip and controller identification. 16562306a36Sopenharmony_ci */ 16662306a36Sopenharmony_ci int unit; 16762306a36Sopenharmony_ci char inst_name[16]; 16862306a36Sopenharmony_ci char chip_name[8]; 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci struct Scsi_Host *host; 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci void __iomem * ioaddr; /* MMIO kernel io address */ 17362306a36Sopenharmony_ci void __iomem * ramaddr; /* RAM kernel io address */ 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci struct timer_list timer; /* Timer handler link header */ 17662306a36Sopenharmony_ci u_long lasttime; 17762306a36Sopenharmony_ci u_long settle_time; /* Resetting the SCSI BUS */ 17862306a36Sopenharmony_ci u_char settle_time_valid; 17962306a36Sopenharmony_ci}; 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ci/* 18262306a36Sopenharmony_ci * Return the name of the controller. 18362306a36Sopenharmony_ci */ 18462306a36Sopenharmony_ci#define sym_name(np) (np)->s.inst_name 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_cistruct sym_nvram; 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ci/* 18962306a36Sopenharmony_ci * The IO macros require a struct called 's' and are abused in sym_nvram.c 19062306a36Sopenharmony_ci */ 19162306a36Sopenharmony_cistruct sym_device { 19262306a36Sopenharmony_ci struct pci_dev *pdev; 19362306a36Sopenharmony_ci unsigned long mmio_base; 19462306a36Sopenharmony_ci unsigned long ram_base; 19562306a36Sopenharmony_ci struct { 19662306a36Sopenharmony_ci void __iomem *ioaddr; 19762306a36Sopenharmony_ci void __iomem *ramaddr; 19862306a36Sopenharmony_ci } s; 19962306a36Sopenharmony_ci struct sym_chip chip; 20062306a36Sopenharmony_ci struct sym_nvram *nvram; 20162306a36Sopenharmony_ci u_char host_id; 20262306a36Sopenharmony_ci}; 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci/* 20562306a36Sopenharmony_ci * Driver host data structure. 20662306a36Sopenharmony_ci */ 20762306a36Sopenharmony_cistruct sym_data { 20862306a36Sopenharmony_ci struct sym_hcb *ncb; 20962306a36Sopenharmony_ci struct completion *io_reset; /* PCI error handling */ 21062306a36Sopenharmony_ci struct pci_dev *pdev; 21162306a36Sopenharmony_ci}; 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_cistatic inline struct sym_hcb * sym_get_hcb(struct Scsi_Host *host) 21462306a36Sopenharmony_ci{ 21562306a36Sopenharmony_ci return ((struct sym_data *)host->hostdata)->ncb; 21662306a36Sopenharmony_ci} 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ci#include "sym_fw.h" 21962306a36Sopenharmony_ci#include "sym_hipd.h" 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ci/* 22262306a36Sopenharmony_ci * Set the status field of a CAM CCB. 22362306a36Sopenharmony_ci */ 22462306a36Sopenharmony_cistatic inline void 22562306a36Sopenharmony_cisym_set_cam_status(struct scsi_cmnd *cmd, int status) 22662306a36Sopenharmony_ci{ 22762306a36Sopenharmony_ci cmd->result &= ~(0xff << 16); 22862306a36Sopenharmony_ci cmd->result |= (status << 16); 22962306a36Sopenharmony_ci} 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci/* 23262306a36Sopenharmony_ci * Get the status field of a CAM CCB. 23362306a36Sopenharmony_ci */ 23462306a36Sopenharmony_cistatic inline int 23562306a36Sopenharmony_cisym_get_cam_status(struct scsi_cmnd *cmd) 23662306a36Sopenharmony_ci{ 23762306a36Sopenharmony_ci return host_byte(cmd->result); 23862306a36Sopenharmony_ci} 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci/* 24162306a36Sopenharmony_ci * Build CAM result for a successful IO and for a failed IO. 24262306a36Sopenharmony_ci */ 24362306a36Sopenharmony_cistatic inline void sym_set_cam_result_ok(struct sym_ccb *cp, struct scsi_cmnd *cmd, int resid) 24462306a36Sopenharmony_ci{ 24562306a36Sopenharmony_ci scsi_set_resid(cmd, resid); 24662306a36Sopenharmony_ci cmd->result = (DID_OK << 16) | (cp->ssss_status & 0x7f); 24762306a36Sopenharmony_ci} 24862306a36Sopenharmony_civoid sym_set_cam_result_error(struct sym_hcb *np, struct sym_ccb *cp, int resid); 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_civoid sym_xpt_done(struct sym_hcb *np, struct scsi_cmnd *ccb); 25162306a36Sopenharmony_ci#define sym_print_addr(cmd, arg...) dev_info(&cmd->device->sdev_gendev , ## arg) 25262306a36Sopenharmony_civoid sym_xpt_async_bus_reset(struct sym_hcb *np); 25362306a36Sopenharmony_ciint sym_setup_data_and_start (struct sym_hcb *np, struct scsi_cmnd *csio, struct sym_ccb *cp); 25462306a36Sopenharmony_civoid sym_log_bus_error(struct Scsi_Host *); 25562306a36Sopenharmony_civoid sym_dump_registers(struct Scsi_Host *); 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_ci#endif /* SYM_GLUE_H */ 258