Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /* qlogicpti.c: Performance Technologies QlogicISP sbus card driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  * Copyright (C) 1996, 2006, 2008 David S. Miller (davem@davemloft.net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * A lot of this driver was directly stolen from Erik H. Moe's PCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  * Qlogic ISP driver.  Mucho kudos to him for this code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  * An even bigger kudos to John Grana at Performance Technologies
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  * for providing me with the hardware to write this driver, you rule
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  * John you really do.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  * May, 2, 1997: Added support for QLGC,isp --jj
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <linux/gfp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <linux/proc_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <linux/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #include <linux/firmware.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #include <linux/pgtable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #include <asm/byteorder.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #include "qlogicpti.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #include <asm/dma.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) #include <asm/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) #include <asm/oplib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) #include <scsi/scsi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) #include <scsi/scsi_cmnd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) #include <scsi/scsi_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #include <scsi/scsi_eh.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) #include <scsi/scsi_tcq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) #include <scsi/scsi_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) #define MAX_TARGETS	16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) #define MAX_LUNS	8	/* 32 for 1.31 F/W */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) #define DEFAULT_LOOP_COUNT	10000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) static struct qlogicpti *qptichain = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) static DEFINE_SPINLOCK(qptichain_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) #define PACKB(a, b)			(((a)<<4)|(b))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) static const u_char mbox_param[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 	PACKB(1, 1),	/* MBOX_NO_OP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 	PACKB(5, 5),	/* MBOX_LOAD_RAM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 	PACKB(2, 0),	/* MBOX_EXEC_FIRMWARE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 	PACKB(5, 5),	/* MBOX_DUMP_RAM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 	PACKB(3, 3),	/* MBOX_WRITE_RAM_WORD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 	PACKB(2, 3),	/* MBOX_READ_RAM_WORD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 	PACKB(6, 6),	/* MBOX_MAILBOX_REG_TEST */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 	PACKB(2, 3),	/* MBOX_VERIFY_CHECKSUM	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 	PACKB(1, 3),	/* MBOX_ABOUT_FIRMWARE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 	PACKB(0, 0),	/* 0x0009 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 	PACKB(0, 0),	/* 0x000a */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 	PACKB(0, 0),	/* 0x000b */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 	PACKB(0, 0),	/* 0x000c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 	PACKB(0, 0),	/* 0x000d */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 	PACKB(1, 2),	/* MBOX_CHECK_FIRMWARE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 	PACKB(0, 0),	/* 0x000f */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 	PACKB(5, 5),	/* MBOX_INIT_REQ_QUEUE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 	PACKB(6, 6),	/* MBOX_INIT_RES_QUEUE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 	PACKB(4, 4),	/* MBOX_EXECUTE_IOCB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 	PACKB(2, 2),	/* MBOX_WAKE_UP	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 	PACKB(1, 6),	/* MBOX_STOP_FIRMWARE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 	PACKB(4, 4),	/* MBOX_ABORT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 	PACKB(2, 2),	/* MBOX_ABORT_DEVICE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 	PACKB(3, 3),	/* MBOX_ABORT_TARGET */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	PACKB(2, 2),	/* MBOX_BUS_RESET */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 	PACKB(2, 3),	/* MBOX_STOP_QUEUE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 	PACKB(2, 3),	/* MBOX_START_QUEUE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 	PACKB(2, 3),	/* MBOX_SINGLE_STEP_QUEUE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 	PACKB(2, 3),	/* MBOX_ABORT_QUEUE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 	PACKB(2, 4),	/* MBOX_GET_DEV_QUEUE_STATUS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	PACKB(0, 0),	/* 0x001e */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 	PACKB(1, 3),	/* MBOX_GET_FIRMWARE_STATUS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 	PACKB(1, 2),	/* MBOX_GET_INIT_SCSI_ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 	PACKB(1, 2),	/* MBOX_GET_SELECT_TIMEOUT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 	PACKB(1, 3),	/* MBOX_GET_RETRY_COUNT	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 	PACKB(1, 2),	/* MBOX_GET_TAG_AGE_LIMIT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 	PACKB(1, 2),	/* MBOX_GET_CLOCK_RATE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 	PACKB(1, 2),	/* MBOX_GET_ACT_NEG_STATE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 	PACKB(1, 2),	/* MBOX_GET_ASYNC_DATA_SETUP_TIME */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 	PACKB(1, 3),	/* MBOX_GET_SBUS_PARAMS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 	PACKB(2, 4),	/* MBOX_GET_TARGET_PARAMS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 	PACKB(2, 4),	/* MBOX_GET_DEV_QUEUE_PARAMS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 	PACKB(0, 0),	/* 0x002a */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	PACKB(0, 0),	/* 0x002b */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	PACKB(0, 0),	/* 0x002c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	PACKB(0, 0),	/* 0x002d */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 	PACKB(0, 0),	/* 0x002e */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 	PACKB(0, 0),	/* 0x002f */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 	PACKB(2, 2),	/* MBOX_SET_INIT_SCSI_ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	PACKB(2, 2),	/* MBOX_SET_SELECT_TIMEOUT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 	PACKB(3, 3),	/* MBOX_SET_RETRY_COUNT	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	PACKB(2, 2),	/* MBOX_SET_TAG_AGE_LIMIT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	PACKB(2, 2),	/* MBOX_SET_CLOCK_RATE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	PACKB(2, 2),	/* MBOX_SET_ACTIVE_NEG_STATE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	PACKB(2, 2),	/* MBOX_SET_ASYNC_DATA_SETUP_TIME */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	PACKB(3, 3),	/* MBOX_SET_SBUS_CONTROL_PARAMS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	PACKB(4, 4),	/* MBOX_SET_TARGET_PARAMS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	PACKB(4, 4),	/* MBOX_SET_DEV_QUEUE_PARAMS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 	PACKB(0, 0),	/* 0x003a */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 	PACKB(0, 0),	/* 0x003b */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 	PACKB(0, 0),	/* 0x003c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 	PACKB(0, 0),	/* 0x003d */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	PACKB(0, 0),	/* 0x003e */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 	PACKB(0, 0),	/* 0x003f */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 	PACKB(0, 0),	/* 0x0040 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	PACKB(0, 0),	/* 0x0041 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	PACKB(0, 0)	/* 0x0042 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) #define MAX_MBOX_COMMAND	ARRAY_SIZE(mbox_param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) /* queue length's _must_ be power of two: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) #define QUEUE_DEPTH(in, out, ql)	((in - out) & (ql))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) #define REQ_QUEUE_DEPTH(in, out)	QUEUE_DEPTH(in, out, 		     \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 						    QLOGICPTI_REQ_QUEUE_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) #define RES_QUEUE_DEPTH(in, out)	QUEUE_DEPTH(in, out, RES_QUEUE_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) static inline void qlogicpti_enable_irqs(struct qlogicpti *qpti)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 	sbus_writew(SBUS_CTRL_ERIRQ | SBUS_CTRL_GENAB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 		    qpti->qregs + SBUS_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) static inline void qlogicpti_disable_irqs(struct qlogicpti *qpti)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	sbus_writew(0, qpti->qregs + SBUS_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) static inline void set_sbus_cfg1(struct qlogicpti *qpti)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	u8 bursts = qpti->bursts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) #if 0	/* It appears that at least PTI cards do not support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 	 * 64-byte bursts and that setting the B64 bit actually
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	 * is a nop and the chip ends up using the smallest burst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	 * size. -DaveM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 	if (sbus_can_burst64() && (bursts & DMA_BURST64)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 		val = (SBUS_CFG1_BENAB | SBUS_CFG1_B64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 	if (bursts & DMA_BURST32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 		val = (SBUS_CFG1_BENAB | SBUS_CFG1_B32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 	} else if (bursts & DMA_BURST16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 		val = (SBUS_CFG1_BENAB | SBUS_CFG1_B16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	} else if (bursts & DMA_BURST8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 		val = (SBUS_CFG1_BENAB | SBUS_CFG1_B8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 		val = 0; /* No sbus bursts for you... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	sbus_writew(val, qpti->qregs + SBUS_CFG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) static int qlogicpti_mbox_command(struct qlogicpti *qpti, u_short param[], int force)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	int loop_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	u16 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	if (mbox_param[param[0]] == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	/* Set SBUS semaphore. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	tmp = sbus_readw(qpti->qregs + SBUS_SEMAPHORE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 	tmp |= SBUS_SEMAPHORE_LCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	sbus_writew(tmp, qpti->qregs + SBUS_SEMAPHORE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 	/* Wait for host IRQ bit to clear. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	loop_count = DEFAULT_LOOP_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	while (--loop_count && (sbus_readw(qpti->qregs + HCCTRL) & HCCTRL_HIRQ)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 		barrier();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 		cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	if (!loop_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 		printk(KERN_EMERG "qlogicpti%d: mbox_command loop timeout #1\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 		       qpti->qpti_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	/* Write mailbox command registers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	switch (mbox_param[param[0]] >> 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	case 6: sbus_writew(param[5], qpti->qregs + MBOX5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	case 5: sbus_writew(param[4], qpti->qregs + MBOX4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	case 4: sbus_writew(param[3], qpti->qregs + MBOX3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	case 3: sbus_writew(param[2], qpti->qregs + MBOX2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	case 2: sbus_writew(param[1], qpti->qregs + MBOX1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	case 1: sbus_writew(param[0], qpti->qregs + MBOX0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	/* Clear RISC interrupt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	tmp = sbus_readw(qpti->qregs + HCCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	tmp |= HCCTRL_CRIRQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	sbus_writew(tmp, qpti->qregs + HCCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	/* Clear SBUS semaphore. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	sbus_writew(0, qpti->qregs + SBUS_SEMAPHORE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	/* Set HOST interrupt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	tmp = sbus_readw(qpti->qregs + HCCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	tmp |= HCCTRL_SHIRQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	sbus_writew(tmp, qpti->qregs + HCCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	/* Wait for HOST interrupt clears. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	loop_count = DEFAULT_LOOP_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	while (--loop_count &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 	       (sbus_readw(qpti->qregs + HCCTRL) & HCCTRL_CRIRQ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 		udelay(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 	if (!loop_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 		printk(KERN_EMERG "qlogicpti%d: mbox_command[%04x] loop timeout #2\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 		       qpti->qpti_id, param[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 	/* Wait for SBUS semaphore to get set. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	loop_count = DEFAULT_LOOP_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	while (--loop_count &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 	       !(sbus_readw(qpti->qregs + SBUS_SEMAPHORE) & SBUS_SEMAPHORE_LCK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 		udelay(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 		/* Workaround for some buggy chips. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 		if (sbus_readw(qpti->qregs + MBOX0) & 0x4000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	if (!loop_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 		printk(KERN_EMERG "qlogicpti%d: mbox_command[%04x] loop timeout #3\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 		       qpti->qpti_id, param[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	/* Wait for MBOX busy condition to go away. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	loop_count = DEFAULT_LOOP_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 	while (--loop_count && (sbus_readw(qpti->qregs + MBOX0) == 0x04))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 		udelay(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	if (!loop_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 		printk(KERN_EMERG "qlogicpti%d: mbox_command[%04x] loop timeout #4\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 		       qpti->qpti_id, param[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 	/* Read back output parameters. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	switch (mbox_param[param[0]] & 0xf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 	case 6: param[5] = sbus_readw(qpti->qregs + MBOX5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 	case 5: param[4] = sbus_readw(qpti->qregs + MBOX4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 	case 4: param[3] = sbus_readw(qpti->qregs + MBOX3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 	case 3: param[2] = sbus_readw(qpti->qregs + MBOX2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	case 2: param[1] = sbus_readw(qpti->qregs + MBOX1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	case 1: param[0] = sbus_readw(qpti->qregs + MBOX0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	/* Clear RISC interrupt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 	tmp = sbus_readw(qpti->qregs + HCCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 	tmp |= HCCTRL_CRIRQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	sbus_writew(tmp, qpti->qregs + HCCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 	/* Release SBUS semaphore. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	tmp = sbus_readw(qpti->qregs + SBUS_SEMAPHORE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 	tmp &= ~(SBUS_SEMAPHORE_LCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 	sbus_writew(tmp, qpti->qregs + SBUS_SEMAPHORE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 	/* We're done. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) static inline void qlogicpti_set_hostdev_defaults(struct qlogicpti *qpti)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 	qpti->host_param.initiator_scsi_id = qpti->scsi_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 	qpti->host_param.bus_reset_delay = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 	qpti->host_param.retry_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 	qpti->host_param.retry_delay = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	qpti->host_param.async_data_setup_time = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 	qpti->host_param.req_ack_active_negation = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 	qpti->host_param.data_line_active_negation = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 	qpti->host_param.data_dma_burst_enable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 	qpti->host_param.command_dma_burst_enable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	qpti->host_param.tag_aging = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 	qpti->host_param.selection_timeout = 250;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	qpti->host_param.max_queue_depth = 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	for(i = 0; i < MAX_TARGETS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 		 * disconnect, parity, arq, reneg on reset, and, oddly enough
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 		 * tags...the midlayer's notion of tagged support has to match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 		 * our device settings, and since we base whether we enable a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 		 * tag on a  per-cmnd basis upon what the midlayer sez, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 		 * actually enable the capability here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 		qpti->dev_param[i].device_flags = 0xcd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 		qpti->dev_param[i].execution_throttle = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 		if (qpti->ultra) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 			qpti->dev_param[i].synchronous_period = 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 			qpti->dev_param[i].synchronous_offset = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 			qpti->dev_param[i].synchronous_period = 25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 			qpti->dev_param[i].synchronous_offset = 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 		qpti->dev_param[i].device_enable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) static int qlogicpti_reset_hardware(struct Scsi_Host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 	struct qlogicpti *qpti = (struct qlogicpti *) host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	u_short param[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	unsigned short risc_code_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 	int loop_count, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 	risc_code_addr = 0x1000;	/* all load addresses are at 0x1000 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	spin_lock_irqsave(host->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	sbus_writew(HCCTRL_PAUSE, qpti->qregs + HCCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 	/* Only reset the scsi bus if it is not free. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	if (sbus_readw(qpti->qregs + CPU_PCTRL) & CPU_PCTRL_BSY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 		sbus_writew(CPU_ORIDE_RMOD, qpti->qregs + CPU_ORIDE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 		sbus_writew(CPU_CMD_BRESET, qpti->qregs + CPU_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 		udelay(400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	sbus_writew(SBUS_CTRL_RESET, qpti->qregs + SBUS_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	sbus_writew((DMA_CTRL_CCLEAR | DMA_CTRL_CIRQ), qpti->qregs + CMD_DMA_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 	sbus_writew((DMA_CTRL_CCLEAR | DMA_CTRL_CIRQ), qpti->qregs + DATA_DMA_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	loop_count = DEFAULT_LOOP_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 	while (--loop_count && ((sbus_readw(qpti->qregs + MBOX0) & 0xff) == 0x04))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 		udelay(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	if (!loop_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 		printk(KERN_EMERG "qlogicpti%d: reset_hardware loop timeout\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 		       qpti->qpti_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 	sbus_writew(HCCTRL_PAUSE, qpti->qregs + HCCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 	set_sbus_cfg1(qpti);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 	qlogicpti_enable_irqs(qpti);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	if (sbus_readw(qpti->qregs + RISC_PSR) & RISC_PSR_ULTRA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 		qpti->ultra = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 		sbus_writew((RISC_MTREG_P0ULTRA | RISC_MTREG_P1ULTRA),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 			    qpti->qregs + RISC_MTREG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 		qpti->ultra = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 		sbus_writew((RISC_MTREG_P0DFLT | RISC_MTREG_P1DFLT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 			    qpti->qregs + RISC_MTREG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	/* reset adapter and per-device default values. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 	/* do it after finding out whether we're ultra mode capable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 	qlogicpti_set_hostdev_defaults(qpti);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 	/* Release the RISC processor. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	sbus_writew(HCCTRL_REL, qpti->qregs + HCCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 	/* Get RISC to start executing the firmware code. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 	param[0] = MBOX_EXEC_FIRMWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 	param[1] = risc_code_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 	if (qlogicpti_mbox_command(qpti, param, 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 		printk(KERN_EMERG "qlogicpti%d: Cannot execute ISP firmware.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 		       qpti->qpti_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 		spin_unlock_irqrestore(host->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 	/* Set initiator scsi ID. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 	param[0] = MBOX_SET_INIT_SCSI_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 	param[1] = qpti->host_param.initiator_scsi_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 	if (qlogicpti_mbox_command(qpti, param, 1) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	   (param[0] != MBOX_COMMAND_COMPLETE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 		printk(KERN_EMERG "qlogicpti%d: Cannot set initiator SCSI ID.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 		       qpti->qpti_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 		spin_unlock_irqrestore(host->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	/* Initialize state of the queues, both hw and sw. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	qpti->req_in_ptr = qpti->res_out_ptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 	param[0] = MBOX_INIT_RES_QUEUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	param[1] = RES_QUEUE_LEN + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	param[2] = (u_short) (qpti->res_dvma >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	param[3] = (u_short) (qpti->res_dvma & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 	param[4] = param[5] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 	if (qlogicpti_mbox_command(qpti, param, 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 		printk(KERN_EMERG "qlogicpti%d: Cannot init response queue.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 		       qpti->qpti_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 		spin_unlock_irqrestore(host->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	param[0] = MBOX_INIT_REQ_QUEUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	param[1] = QLOGICPTI_REQ_QUEUE_LEN + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	param[2] = (u_short) (qpti->req_dvma >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	param[3] = (u_short) (qpti->req_dvma & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 	param[4] = param[5] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 	if (qlogicpti_mbox_command(qpti, param, 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 		printk(KERN_EMERG "qlogicpti%d: Cannot init request queue.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 		       qpti->qpti_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 		spin_unlock_irqrestore(host->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 	param[0] = MBOX_SET_RETRY_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 	param[1] = qpti->host_param.retry_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 	param[2] = qpti->host_param.retry_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	qlogicpti_mbox_command(qpti, param, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 	param[0] = MBOX_SET_TAG_AGE_LIMIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	param[1] = qpti->host_param.tag_aging;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 	qlogicpti_mbox_command(qpti, param, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	for (i = 0; i < MAX_TARGETS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 		param[0] = MBOX_GET_DEV_QUEUE_PARAMS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 		param[1] = (i << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 		qlogicpti_mbox_command(qpti, param, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 	param[0] = MBOX_GET_FIRMWARE_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 	qlogicpti_mbox_command(qpti, param, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	param[0] = MBOX_SET_SELECT_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 	param[1] = qpti->host_param.selection_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 	qlogicpti_mbox_command(qpti, param, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 	for (i = 0; i < MAX_TARGETS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 		param[0] = MBOX_SET_TARGET_PARAMS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 		param[1] = (i << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 		param[2] = (qpti->dev_param[i].device_flags << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 		 * Since we're now loading 1.31 f/w, force narrow/async.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 		param[2] |= 0xc0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 		param[3] = 0;	/* no offset, we do not have sync mode yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 		qlogicpti_mbox_command(qpti, param, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 	 * Always (sigh) do an initial bus reset (kicks f/w).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	param[0] = MBOX_BUS_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	param[1] = qpti->host_param.bus_reset_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 	qlogicpti_mbox_command(qpti, param, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 	qpti->send_marker = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 	spin_unlock_irqrestore(host->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) #define PTI_RESET_LIMIT 400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) static int qlogicpti_load_firmware(struct qlogicpti *qpti)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 	const struct firmware *fw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	const char fwname[] = "qlogic/isp1000.bin";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 	const __le16 *fw_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	struct Scsi_Host *host = qpti->qhost;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 	unsigned short csum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 	unsigned short param[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 	unsigned short risc_code_addr, risc_code_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 	int i, timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 	err = request_firmware(&fw, fwname, &qpti->op->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 		printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 		       fwname, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	if (fw->size % 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 		printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 		       fw->size, fwname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 		goto outfirm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 	fw_data = (const __le16 *)&fw->data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 	risc_code_addr = 0x1000;	/* all f/w modules load at 0x1000 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 	risc_code_length = fw->size / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	spin_lock_irqsave(host->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	/* Verify the checksum twice, one before loading it, and once
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	 * afterwards via the mailbox commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 	for (i = 0; i < risc_code_length; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 		csum += __le16_to_cpu(fw_data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 	if (csum) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 		printk(KERN_EMERG "qlogicpti%d: Aieee, firmware checksum failed!",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 		       qpti->qpti_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 		err = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	}		
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 	sbus_writew(SBUS_CTRL_RESET, qpti->qregs + SBUS_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	sbus_writew((DMA_CTRL_CCLEAR | DMA_CTRL_CIRQ), qpti->qregs + CMD_DMA_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 	sbus_writew((DMA_CTRL_CCLEAR | DMA_CTRL_CIRQ), qpti->qregs + DATA_DMA_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 	timeout = PTI_RESET_LIMIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 	while (--timeout && (sbus_readw(qpti->qregs + SBUS_CTRL) & SBUS_CTRL_RESET))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 		udelay(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	if (!timeout) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 		printk(KERN_EMERG "qlogicpti%d: Cannot reset the ISP.", qpti->qpti_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 		err = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 	sbus_writew(HCCTRL_RESET, qpti->qregs + HCCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 	mdelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	sbus_writew((SBUS_CTRL_GENAB | SBUS_CTRL_ERIRQ), qpti->qregs + SBUS_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	set_sbus_cfg1(qpti);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	sbus_writew(0, qpti->qregs + SBUS_SEMAPHORE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 	if (sbus_readw(qpti->qregs + RISC_PSR) & RISC_PSR_ULTRA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 		qpti->ultra = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 		sbus_writew((RISC_MTREG_P0ULTRA | RISC_MTREG_P1ULTRA),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 			    qpti->qregs + RISC_MTREG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 		qpti->ultra = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 		sbus_writew((RISC_MTREG_P0DFLT | RISC_MTREG_P1DFLT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 			    qpti->qregs + RISC_MTREG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 	sbus_writew(HCCTRL_REL, qpti->qregs + HCCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	/* Pin lines are only stable while RISC is paused. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	sbus_writew(HCCTRL_PAUSE, qpti->qregs + HCCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	if (sbus_readw(qpti->qregs + CPU_PDIFF) & CPU_PDIFF_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 		qpti->differential = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 		qpti->differential = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	sbus_writew(HCCTRL_REL, qpti->qregs + HCCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 	/* This shouldn't be necessary- we've reset things so we should be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	   running from the ROM now.. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 	param[0] = MBOX_STOP_FIRMWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	param[1] = param[2] = param[3] = param[4] = param[5] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	if (qlogicpti_mbox_command(qpti, param, 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 		printk(KERN_EMERG "qlogicpti%d: Cannot stop firmware for reload.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 		       qpti->qpti_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 		err = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	}		
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	/* Load it up.. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	for (i = 0; i < risc_code_length; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 		param[0] = MBOX_WRITE_RAM_WORD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 		param[1] = risc_code_addr + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 		param[2] = __le16_to_cpu(fw_data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 		if (qlogicpti_mbox_command(qpti, param, 1) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 		    param[0] != MBOX_COMMAND_COMPLETE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 			printk("qlogicpti%d: Firmware dload failed, I'm bolixed!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 			       qpti->qpti_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 			err = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	/* Reset the ISP again. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	sbus_writew(HCCTRL_RESET, qpti->qregs + HCCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	mdelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	qlogicpti_enable_irqs(qpti);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	sbus_writew(0, qpti->qregs + SBUS_SEMAPHORE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	sbus_writew(HCCTRL_REL, qpti->qregs + HCCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	/* Ask ISP to verify the checksum of the new code. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	param[0] = MBOX_VERIFY_CHECKSUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 	param[1] = risc_code_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 	if (qlogicpti_mbox_command(qpti, param, 1) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 	    (param[0] != MBOX_COMMAND_COMPLETE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 		printk(KERN_EMERG "qlogicpti%d: New firmware csum failure!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 		       qpti->qpti_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 		err = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 	/* Start using newly downloaded firmware. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	param[0] = MBOX_EXEC_FIRMWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 	param[1] = risc_code_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	qlogicpti_mbox_command(qpti, param, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	param[0] = MBOX_ABOUT_FIRMWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 	if (qlogicpti_mbox_command(qpti, param, 1) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 	    (param[0] != MBOX_COMMAND_COMPLETE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 		printk(KERN_EMERG "qlogicpti%d: AboutFirmware cmd fails.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 		       qpti->qpti_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 		err = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 	/* Snag the major and minor revisions from the result. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 	qpti->fware_majrev = param[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 	qpti->fware_minrev = param[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 	qpti->fware_micrev = param[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 	/* Set the clock rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 	param[0] = MBOX_SET_CLOCK_RATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 	param[1] = qpti->clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	if (qlogicpti_mbox_command(qpti, param, 1) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	    (param[0] != MBOX_COMMAND_COMPLETE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 		printk(KERN_EMERG "qlogicpti%d: could not set clock rate.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 		       qpti->qpti_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 		err = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 	if (qpti->is_pti != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 		/* Load scsi initiator ID and interrupt level into sbus static ram. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 		param[0] = MBOX_WRITE_RAM_WORD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 		param[1] = 0xff80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 		param[2] = (unsigned short) qpti->scsi_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 		qlogicpti_mbox_command(qpti, param, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 		param[0] = MBOX_WRITE_RAM_WORD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 		param[1] = 0xff00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 		param[2] = (unsigned short) 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 		qlogicpti_mbox_command(qpti, param, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 	spin_unlock_irqrestore(host->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) outfirm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 	release_firmware(fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) static int qlogicpti_verify_tmon(struct qlogicpti *qpti)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 	int curstat = sbus_readb(qpti->sreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 	curstat &= 0xf0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 	if (!(curstat & SREG_FUSE) && (qpti->swsreg & SREG_FUSE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 		printk("qlogicpti%d: Fuse returned to normal state.\n", qpti->qpti_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 	if (!(curstat & SREG_TPOWER) && (qpti->swsreg & SREG_TPOWER))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 		printk("qlogicpti%d: termpwr back to normal state.\n", qpti->qpti_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 	if (curstat != qpti->swsreg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 		int error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 		if (curstat & SREG_FUSE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 			error++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 			printk("qlogicpti%d: Fuse is open!\n", qpti->qpti_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 		if (curstat & SREG_TPOWER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 			error++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 			printk("qlogicpti%d: termpwr failure\n", qpti->qpti_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 		if (qpti->differential &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 		    (curstat & SREG_DSENSE) != SREG_DSENSE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 			error++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 			printk("qlogicpti%d: You have a single ended device on a "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 			       "differential bus!  Please fix!\n", qpti->qpti_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 		qpti->swsreg = curstat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) static irqreturn_t qpti_intr(int irq, void *dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) static void qpti_chain_add(struct qlogicpti *qpti)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	spin_lock_irq(&qptichain_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	if (qptichain != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 		struct qlogicpti *qlink = qptichain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 		while(qlink->next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 			qlink = qlink->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 		qlink->next = qpti;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 		qptichain = qpti;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	qpti->next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 	spin_unlock_irq(&qptichain_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) static void qpti_chain_del(struct qlogicpti *qpti)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	spin_lock_irq(&qptichain_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 	if (qptichain == qpti) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 		qptichain = qpti->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 		struct qlogicpti *qlink = qptichain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 		while(qlink->next != qpti)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 			qlink = qlink->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 		qlink->next = qpti->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	qpti->next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 	spin_unlock_irq(&qptichain_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) static int qpti_map_regs(struct qlogicpti *qpti)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 	struct platform_device *op = qpti->op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	qpti->qregs = of_ioremap(&op->resource[0], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 				 resource_size(&op->resource[0]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 				 "PTI Qlogic/ISP");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 	if (!qpti->qregs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 		printk("PTI: Qlogic/ISP registers are unmappable\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	if (qpti->is_pti) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 		qpti->sreg = of_ioremap(&op->resource[0], (16 * 4096),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 					sizeof(unsigned char),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 					"PTI Qlogic/ISP statreg");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 		if (!qpti->sreg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 			printk("PTI: Qlogic/ISP status register is unmappable\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 			return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) static int qpti_register_irq(struct qlogicpti *qpti)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 	struct platform_device *op = qpti->op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 	qpti->qhost->irq = qpti->irq = op->archdata.irqs[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 	/* We used to try various overly-clever things to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 	 * reduce the interrupt processing overhead on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 	 * sun4c/sun4m when multiple PTI's shared the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	 * same IRQ.  It was too complex and messy to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	 * sanely maintain.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	if (request_irq(qpti->irq, qpti_intr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 			IRQF_SHARED, "QlogicPTI", qpti))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 		goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 	printk("qlogicpti%d: IRQ %d ", qpti->qpti_id, qpti->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 	printk("qlogicpti%d: Cannot acquire irq line\n", qpti->qpti_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) static void qpti_get_scsi_id(struct qlogicpti *qpti)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	struct platform_device *op = qpti->op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 	struct device_node *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	dp = op->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 	qpti->scsi_id = of_getintprop_default(dp, "initiator-id", -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 	if (qpti->scsi_id == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 		qpti->scsi_id = of_getintprop_default(dp, "scsi-initiator-id",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 						      -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 	if (qpti->scsi_id == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 		qpti->scsi_id =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 			of_getintprop_default(dp->parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 					      "scsi-initiator-id", 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 	qpti->qhost->this_id = qpti->scsi_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 	qpti->qhost->max_sectors = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	printk("SCSI ID %d ", qpti->scsi_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) static void qpti_get_bursts(struct qlogicpti *qpti)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	struct platform_device *op = qpti->op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 	u8 bursts, bmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	bursts = of_getintprop_default(op->dev.of_node, "burst-sizes", 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	bmask = of_getintprop_default(op->dev.of_node->parent, "burst-sizes", 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 	if (bmask != 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 		bursts &= bmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	if (bursts == 0xff ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 	    (bursts & DMA_BURST16) == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 	    (bursts & DMA_BURST32) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 		bursts = (DMA_BURST32 - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	qpti->bursts = bursts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) static void qpti_get_clock(struct qlogicpti *qpti)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 	unsigned int cfreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 	/* Check for what the clock input to this card is.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 	 * Default to 40Mhz.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	cfreq = prom_getintdefault(qpti->prom_node,"clock-frequency",40000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	qpti->clock = (cfreq + 500000)/1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 	if (qpti->clock == 0) /* bullshit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 		qpti->clock = 40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) /* The request and response queues must each be aligned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815)  * on a page boundary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) static int qpti_map_queues(struct qlogicpti *qpti)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 	struct platform_device *op = qpti->op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) #define QSIZE(entries)	(((entries) + 1) * QUEUE_ENTRY_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 	qpti->res_cpu = dma_alloc_coherent(&op->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 					   QSIZE(RES_QUEUE_LEN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 					   &qpti->res_dvma, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	if (qpti->res_cpu == NULL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 	    qpti->res_dvma == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 		printk("QPTI: Cannot map response queue.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	qpti->req_cpu = dma_alloc_coherent(&op->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 					   QSIZE(QLOGICPTI_REQ_QUEUE_LEN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 					   &qpti->req_dvma, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 	if (qpti->req_cpu == NULL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	    qpti->req_dvma == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 		dma_free_coherent(&op->dev, QSIZE(RES_QUEUE_LEN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 				  qpti->res_cpu, qpti->res_dvma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 		printk("QPTI: Cannot map request queue.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 	memset(qpti->res_cpu, 0, QSIZE(RES_QUEUE_LEN));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	memset(qpti->req_cpu, 0, QSIZE(QLOGICPTI_REQ_QUEUE_LEN));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) const char *qlogicpti_info(struct Scsi_Host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 	static char buf[80];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 	struct qlogicpti *qpti = (struct qlogicpti *) host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	sprintf(buf, "PTI Qlogic,ISP SBUS SCSI irq %d regs at %p",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 		qpti->qhost->irq, qpti->qregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 	return buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) /* I am a certified frobtronicist. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) static inline void marker_frob(struct Command_Entry *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 	struct Marker_Entry *marker = (struct Marker_Entry *) cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 	memset(marker, 0, sizeof(struct Marker_Entry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 	marker->hdr.entry_cnt = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 	marker->hdr.entry_type = ENTRY_MARKER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 	marker->modifier = SYNC_ALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 	marker->rsvd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) static inline void cmd_frob(struct Command_Entry *cmd, struct scsi_cmnd *Cmnd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 			    struct qlogicpti *qpti)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 	memset(cmd, 0, sizeof(struct Command_Entry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 	cmd->hdr.entry_cnt = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	cmd->hdr.entry_type = ENTRY_COMMAND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	cmd->target_id = Cmnd->device->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	cmd->target_lun = Cmnd->device->lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 	cmd->cdb_length = Cmnd->cmd_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	cmd->control_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 	if (Cmnd->device->tagged_supported) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 		if (qpti->cmd_count[Cmnd->device->id] == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 			qpti->tag_ages[Cmnd->device->id] = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 		if (time_after(jiffies, qpti->tag_ages[Cmnd->device->id] + (5*HZ))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 			cmd->control_flags = CFLAG_ORDERED_TAG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 			qpti->tag_ages[Cmnd->device->id] = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 			cmd->control_flags = CFLAG_SIMPLE_TAG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 	if ((Cmnd->cmnd[0] == WRITE_6) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	    (Cmnd->cmnd[0] == WRITE_10) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 	    (Cmnd->cmnd[0] == WRITE_12))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 		cmd->control_flags |= CFLAG_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 		cmd->control_flags |= CFLAG_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	cmd->time_out = Cmnd->request->timeout/HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 	memcpy(cmd->cdb, Cmnd->cmnd, Cmnd->cmd_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) /* Do it to it baby. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) static inline int load_cmd(struct scsi_cmnd *Cmnd, struct Command_Entry *cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 			   struct qlogicpti *qpti, u_int in_ptr, u_int out_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 	struct dataseg *ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 	struct scatterlist *sg, *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 	int i, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	if (scsi_bufflen(Cmnd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 		int sg_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 		sg = scsi_sglist(Cmnd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 		sg_count = dma_map_sg(&qpti->op->dev, sg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 				      scsi_sg_count(Cmnd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 				      Cmnd->sc_data_direction);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 		ds = cmd->dataseg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 		cmd->segment_cnt = sg_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 		/* Fill in first four sg entries: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 		n = sg_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 		if (n > 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 			n = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 		for_each_sg(sg, s, n, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 			ds[i].d_base = sg_dma_address(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 			ds[i].d_count = sg_dma_len(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 		sg_count -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 		sg = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 		while (sg_count > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 			struct Continuation_Entry *cont;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 			++cmd->hdr.entry_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 			cont = (struct Continuation_Entry *) &qpti->req_cpu[in_ptr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 			in_ptr = NEXT_REQ_PTR(in_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 			if (in_ptr == out_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 				return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 			cont->hdr.entry_type = ENTRY_CONTINUATION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 			cont->hdr.entry_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 			cont->hdr.sys_def_1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 			cont->hdr.flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 			cont->reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 			ds = cont->dataseg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 			n = sg_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 			if (n > 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 				n = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 			for_each_sg(sg, s, n, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 				ds[i].d_base = sg_dma_address(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 				ds[i].d_count = sg_dma_len(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 			sg_count -= n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 			sg = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 		cmd->dataseg[0].d_base = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 		cmd->dataseg[0].d_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 		cmd->segment_cnt = 1; /* Shouldn't this be 0? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	/* Committed, record Scsi_Cmd so we can find it later. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	cmd->handle = in_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	qpti->cmd_slots[in_ptr] = Cmnd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	qpti->cmd_count[Cmnd->device->id]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	sbus_writew(in_ptr, qpti->qregs + MBOX4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	qpti->req_in_ptr = in_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 	return in_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) static inline void update_can_queue(struct Scsi_Host *host, u_int in_ptr, u_int out_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 	/* Temporary workaround until bug is found and fixed (one bug has been found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 	   already, but fixing it makes things even worse) -jj */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 	int num_free = QLOGICPTI_REQ_QUEUE_LEN - REQ_QUEUE_DEPTH(in_ptr, out_ptr) - 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 	host->can_queue = scsi_host_busy(host) + num_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 	host->sg_tablesize = QLOGICPTI_MAX_SG(num_free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) static int qlogicpti_slave_configure(struct scsi_device *sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	struct qlogicpti *qpti = shost_priv(sdev->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	int tgt = sdev->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	u_short param[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	/* tags handled in midlayer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	/* enable sync mode? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	if (sdev->sdtr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 		qpti->dev_param[tgt].device_flags |= 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 		qpti->dev_param[tgt].synchronous_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 		qpti->dev_param[tgt].synchronous_period = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	/* are we wide capable? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	if (sdev->wdtr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 		qpti->dev_param[tgt].device_flags |= 0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	param[0] = MBOX_SET_TARGET_PARAMS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	param[1] = (tgt << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	param[2] = (qpti->dev_param[tgt].device_flags << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	if (qpti->dev_param[tgt].device_flags & 0x10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 		param[3] = (qpti->dev_param[tgt].synchronous_offset << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 			qpti->dev_param[tgt].synchronous_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 		param[3] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	qlogicpti_mbox_command(qpti, param, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)  * The middle SCSI layer ensures that queuecommand never gets invoked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)  * concurrently with itself or the interrupt handler (though the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)  * interrupt handler may call this routine as part of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)  * request-completion handling).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)  * "This code must fly." -davem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) static int qlogicpti_queuecommand_lck(struct scsi_cmnd *Cmnd, void (*done)(struct scsi_cmnd *))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	struct Scsi_Host *host = Cmnd->device->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 	struct qlogicpti *qpti = (struct qlogicpti *) host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	struct Command_Entry *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 	u_int out_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	int in_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 	Cmnd->scsi_done = done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	in_ptr = qpti->req_in_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	cmd = (struct Command_Entry *) &qpti->req_cpu[in_ptr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 	out_ptr = sbus_readw(qpti->qregs + MBOX4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 	in_ptr = NEXT_REQ_PTR(in_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	if (in_ptr == out_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 		goto toss_command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	if (qpti->send_marker) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 		marker_frob(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 		qpti->send_marker = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 		if (NEXT_REQ_PTR(in_ptr) == out_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 			sbus_writew(in_ptr, qpti->qregs + MBOX4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 			qpti->req_in_ptr = in_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 			goto toss_command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 		cmd = (struct Command_Entry *) &qpti->req_cpu[in_ptr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 		in_ptr = NEXT_REQ_PTR(in_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 	cmd_frob(cmd, Cmnd, qpti);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 	if ((in_ptr = load_cmd(Cmnd, cmd, qpti, in_ptr, out_ptr)) == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 		goto toss_command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 	update_can_queue(host, in_ptr, out_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) toss_command:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 	printk(KERN_EMERG "qlogicpti%d: request queue overflow\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 	       qpti->qpti_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 	/* Unfortunately, unless you use the new EH code, which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	 * we don't, the midlayer will ignore the return value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 	 * which is insane.  We pick up the pieces like this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 	Cmnd->result = DID_BUS_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 	done(Cmnd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) static DEF_SCSI_QCMD(qlogicpti_queuecommand)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) static int qlogicpti_return_status(struct Status_Entry *sts, int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 	int host_status = DID_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 	switch (sts->completion_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	      case CS_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 		host_status = DID_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	      case CS_INCOMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 		if (!(sts->state_flags & SF_GOT_BUS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 			host_status = DID_NO_CONNECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 		else if (!(sts->state_flags & SF_GOT_TARGET))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 			host_status = DID_BAD_TARGET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 		else if (!(sts->state_flags & SF_SENT_CDB))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 			host_status = DID_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 		else if (!(sts->state_flags & SF_TRANSFERRED_DATA))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 			host_status = DID_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 		else if (!(sts->state_flags & SF_GOT_STATUS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 			host_status = DID_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 		else if (!(sts->state_flags & SF_GOT_SENSE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 			host_status = DID_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 	      case CS_DMA_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 	      case CS_TRANSPORT_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 		host_status = DID_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 	      case CS_RESET_OCCURRED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 	      case CS_BUS_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 		host_status = DID_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	      case CS_ABORTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 		host_status = DID_ABORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 	      case CS_TIMEOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 		host_status = DID_TIME_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 	      case CS_DATA_OVERRUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	      case CS_COMMAND_OVERRUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	      case CS_STATUS_OVERRUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	      case CS_BAD_MESSAGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	      case CS_NO_MESSAGE_OUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	      case CS_EXT_ID_FAILED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	      case CS_IDE_MSG_FAILED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	      case CS_ABORT_MSG_FAILED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	      case CS_NOP_MSG_FAILED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 	      case CS_PARITY_ERROR_MSG_FAILED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 	      case CS_DEVICE_RESET_MSG_FAILED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 	      case CS_ID_MSG_FAILED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 	      case CS_UNEXP_BUS_FREE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 		host_status = DID_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	      case CS_DATA_UNDERRUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 		host_status = DID_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 	      default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 		printk(KERN_EMERG "qlogicpti%d: unknown completion status 0x%04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 		       id, sts->completion_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 		host_status = DID_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 	return (sts->scsi_status & STATUS_MASK) | (host_status << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) static struct scsi_cmnd *qlogicpti_intr_handler(struct qlogicpti *qpti)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 	struct scsi_cmnd *Cmnd, *done_queue = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 	struct Status_Entry *sts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 	u_int in_ptr, out_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 	if (!(sbus_readw(qpti->qregs + SBUS_STAT) & SBUS_STAT_RINT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 		
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 	in_ptr = sbus_readw(qpti->qregs + MBOX5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 	sbus_writew(HCCTRL_CRIRQ, qpti->qregs + HCCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 	if (sbus_readw(qpti->qregs + SBUS_SEMAPHORE) & SBUS_SEMAPHORE_LCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 		switch (sbus_readw(qpti->qregs + MBOX0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 		case ASYNC_SCSI_BUS_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 		case EXECUTION_TIMEOUT_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 			qpti->send_marker = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 		case INVALID_COMMAND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 		case HOST_INTERFACE_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 		case COMMAND_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 		case COMMAND_PARAM_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 		};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 		sbus_writew(0, qpti->qregs + SBUS_SEMAPHORE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	/* This looks like a network driver! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 	out_ptr = qpti->res_out_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 	while (out_ptr != in_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 		u_int cmd_slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 		sts = (struct Status_Entry *) &qpti->res_cpu[out_ptr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 		out_ptr = NEXT_RES_PTR(out_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 		/* We store an index in the handle, not the pointer in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 		 * some form.  This avoids problems due to the fact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 		 * that the handle provided is only 32-bits. -DaveM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 		cmd_slot = sts->handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 		Cmnd = qpti->cmd_slots[cmd_slot];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 		qpti->cmd_slots[cmd_slot] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 		if (sts->completion_status == CS_RESET_OCCURRED ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 		    sts->completion_status == CS_ABORTED ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 		    (sts->status_flags & STF_BUS_RESET))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 			qpti->send_marker = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 		if (sts->state_flags & SF_GOT_SENSE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 			memcpy(Cmnd->sense_buffer, sts->req_sense_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 			       SCSI_SENSE_BUFFERSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 		if (sts->hdr.entry_type == ENTRY_STATUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 			Cmnd->result =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 			    qlogicpti_return_status(sts, qpti->qpti_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 			Cmnd->result = DID_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 		if (scsi_bufflen(Cmnd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 			dma_unmap_sg(&qpti->op->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 				     scsi_sglist(Cmnd), scsi_sg_count(Cmnd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 				     Cmnd->sc_data_direction);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 		qpti->cmd_count[Cmnd->device->id]--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 		sbus_writew(out_ptr, qpti->qregs + MBOX5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 		Cmnd->host_scribble = (unsigned char *) done_queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 		done_queue = Cmnd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 	qpti->res_out_ptr = out_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 	return done_queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) static irqreturn_t qpti_intr(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 	struct qlogicpti *qpti = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 	struct scsi_cmnd *dq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 	spin_lock_irqsave(qpti->qhost->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 	dq = qlogicpti_intr_handler(qpti);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 	if (dq != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 		do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 			struct scsi_cmnd *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 			next = (struct scsi_cmnd *) dq->host_scribble;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 			dq->scsi_done(dq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 			dq = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 		} while (dq != NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 	spin_unlock_irqrestore(qpti->qhost->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) static int qlogicpti_abort(struct scsi_cmnd *Cmnd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 	u_short param[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 	struct Scsi_Host *host = Cmnd->device->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 	struct qlogicpti *qpti = (struct qlogicpti *) host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 	int return_status = SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 	u32 cmd_cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 	printk(KERN_WARNING "qlogicpti%d: Aborting cmd for tgt[%d] lun[%d]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 	       qpti->qpti_id, (int)Cmnd->device->id, (int)Cmnd->device->lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 	qlogicpti_disable_irqs(qpti);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 	/* Find the 32-bit cookie we gave to the firmware for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 	 * this command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 	for (i = 0; i < QLOGICPTI_REQ_QUEUE_LEN + 1; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 		if (qpti->cmd_slots[i] == Cmnd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 	cmd_cookie = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 	param[0] = MBOX_ABORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 	param[1] = (((u_short) Cmnd->device->id) << 8) | Cmnd->device->lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 	param[2] = cmd_cookie >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 	param[3] = cmd_cookie & 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 	if (qlogicpti_mbox_command(qpti, param, 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 	    (param[0] != MBOX_COMMAND_COMPLETE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 		printk(KERN_EMERG "qlogicpti%d: scsi abort failure: %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 		       qpti->qpti_id, param[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 		return_status = FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 	qlogicpti_enable_irqs(qpti);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 	return return_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) static int qlogicpti_reset(struct scsi_cmnd *Cmnd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 	u_short param[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 	struct Scsi_Host *host = Cmnd->device->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 	struct qlogicpti *qpti = (struct qlogicpti *) host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 	int return_status = SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 	printk(KERN_WARNING "qlogicpti%d: Resetting SCSI bus!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 	       qpti->qpti_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 	qlogicpti_disable_irqs(qpti);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 	param[0] = MBOX_BUS_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 	param[1] = qpti->host_param.bus_reset_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 	if (qlogicpti_mbox_command(qpti, param, 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 	   (param[0] != MBOX_COMMAND_COMPLETE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 		printk(KERN_EMERG "qlogicisp%d: scsi bus reset failure: %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 		       qpti->qpti_id, param[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 		return_status = FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 	qlogicpti_enable_irqs(qpti);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 	return return_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) static struct scsi_host_template qpti_template = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 	.module			= THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 	.name			= "qlogicpti",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 	.info			= qlogicpti_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 	.queuecommand		= qlogicpti_queuecommand,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 	.slave_configure	= qlogicpti_slave_configure,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 	.eh_abort_handler	= qlogicpti_abort,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 	.eh_host_reset_handler	= qlogicpti_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 	.can_queue		= QLOGICPTI_REQ_QUEUE_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 	.this_id		= 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 	.sg_tablesize		= QLOGICPTI_MAX_SG(QLOGICPTI_REQ_QUEUE_LEN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) static const struct of_device_id qpti_match[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) static int qpti_sbus_probe(struct platform_device *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 	struct device_node *dp = op->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 	struct Scsi_Host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 	struct qlogicpti *qpti;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 	static int nqptis;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 	const char *fcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 	/* Sometimes Antares cards come up not completely
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 	 * setup, and we get a report of a zero IRQ.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 	if (op->archdata.irqs[0] == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 	host = scsi_host_alloc(&qpti_template, sizeof(struct qlogicpti));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 	if (!host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 	qpti = shost_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 	host->max_id = MAX_TARGETS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 	qpti->qhost = host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 	qpti->op = op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 	qpti->qpti_id = nqptis;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 	qpti->is_pti = !of_node_name_eq(op->dev.of_node, "QLGC,isp");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 	if (qpti_map_regs(qpti) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 		goto fail_unlink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 	if (qpti_register_irq(qpti) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 		goto fail_unmap_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 	qpti_get_scsi_id(qpti);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 	qpti_get_bursts(qpti);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 	qpti_get_clock(qpti);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 	/* Clear out scsi_cmnd array. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 	memset(qpti->cmd_slots, 0, sizeof(qpti->cmd_slots));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 	if (qpti_map_queues(qpti) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 		goto fail_free_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 	/* Load the firmware. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 	if (qlogicpti_load_firmware(qpti))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 		goto fail_unmap_queues;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 	if (qpti->is_pti) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 		/* Check the PTI status reg. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 		if (qlogicpti_verify_tmon(qpti))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 			goto fail_unmap_queues;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 	/* Reset the ISP and init res/req queues. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 	if (qlogicpti_reset_hardware(host))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 		goto fail_unmap_queues;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 	printk("(Firmware v%d.%d.%d)", qpti->fware_majrev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 	       qpti->fware_minrev, qpti->fware_micrev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 	fcode = of_get_property(dp, "isp-fcode", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 	if (fcode && fcode[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 		printk("(FCode %s)", fcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 	if (of_find_property(dp, "differential", NULL) != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 		qpti->differential = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 			
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 	printk("\nqlogicpti%d: [%s Wide, using %s interface]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 		qpti->qpti_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 		(qpti->ultra ? "Ultra" : "Fast"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 		(qpti->differential ? "differential" : "single ended"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 	if (scsi_add_host(host, &op->dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 		printk("qlogicpti%d: Failed scsi_add_host\n", qpti->qpti_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 		goto fail_unmap_queues;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 	dev_set_drvdata(&op->dev, qpti);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 	qpti_chain_add(qpti);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 	scsi_scan_host(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 	nqptis++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) fail_unmap_queues:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) #define QSIZE(entries)	(((entries) + 1) * QUEUE_ENTRY_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 	dma_free_coherent(&op->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 			  QSIZE(RES_QUEUE_LEN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 			  qpti->res_cpu, qpti->res_dvma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 	dma_free_coherent(&op->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 			  QSIZE(QLOGICPTI_REQ_QUEUE_LEN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 			  qpti->req_cpu, qpti->req_dvma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) #undef QSIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) fail_free_irq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 	free_irq(qpti->irq, qpti);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) fail_unmap_regs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 	of_iounmap(&op->resource[0], qpti->qregs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 		   resource_size(&op->resource[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 	if (qpti->is_pti)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 		of_iounmap(&op->resource[0], qpti->sreg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 			   sizeof(unsigned char));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) fail_unlink:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 	scsi_host_put(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 	return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) static int qpti_sbus_remove(struct platform_device *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 	struct qlogicpti *qpti = dev_get_drvdata(&op->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 	qpti_chain_del(qpti);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 	scsi_remove_host(qpti->qhost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 	/* Shut up the card. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 	sbus_writew(0, qpti->qregs + SBUS_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 	/* Free IRQ handler and unmap Qlogic,ISP and PTI status regs. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 	free_irq(qpti->irq, qpti);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) #define QSIZE(entries)	(((entries) + 1) * QUEUE_ENTRY_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 	dma_free_coherent(&op->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 			  QSIZE(RES_QUEUE_LEN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 			  qpti->res_cpu, qpti->res_dvma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 	dma_free_coherent(&op->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 			  QSIZE(QLOGICPTI_REQ_QUEUE_LEN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 			  qpti->req_cpu, qpti->req_dvma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) #undef QSIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 	of_iounmap(&op->resource[0], qpti->qregs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 		   resource_size(&op->resource[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 	if (qpti->is_pti)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 		of_iounmap(&op->resource[0], qpti->sreg, sizeof(unsigned char));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 	scsi_host_put(qpti->qhost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) static const struct of_device_id qpti_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 		.name = "ptisp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 		.name = "PTI,ptisp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 		.name = "QLGC,isp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 		.name = "SUNW,isp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 	{},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) MODULE_DEVICE_TABLE(of, qpti_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) static struct platform_driver qpti_sbus_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 		.name = "qpti",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 		.of_match_table = qpti_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 	.probe		= qpti_sbus_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 	.remove		= qpti_sbus_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) module_platform_driver(qpti_sbus_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) MODULE_DESCRIPTION("QlogicISP SBUS driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) MODULE_VERSION("2.1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) MODULE_FIRMWARE("qlogic/isp1000.bin");