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) /*======================================================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)     NinjaSCSI-3 / NinjaSCSI-32Bi PCMCIA SCSI host adapter card driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)       By: YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)     Ver.2.8   Support 32bit MMIO mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)               Support Synchronous Data Transfer Request (SDTR) mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)     Ver.2.0   Support 32bit PIO mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)     Ver.1.1.2 Fix for scatter list buffer exceeds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)     Ver.1.1   Support scatter list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)     Ver.0.1   Initial version
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)     This software may be used and distributed according to the terms of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)     the GNU General Public License.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) ======================================================================*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19)     This driver is for these PCcards.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) 	I-O DATA PCSC-F	 (Workbit NinjaSCSI-3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) 			"WBT", "NinjaSCSI-3", "R1.0"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) 	I-O DATA CBSC-II (Workbit NinjaSCSI-32Bi in 16bit mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) 			"IO DATA", "CBSC16	 ", "1"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) ***********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #include <linux/timer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #include <linux/major.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #include <linux/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) #include <../drivers/scsi/scsi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) #include <scsi/scsi_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) #include <scsi/scsi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #include <scsi/scsi_ioctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) #include <pcmcia/cistpl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) #include <pcmcia/cisreg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) #include <pcmcia/ds.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) #include "nsp_cs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) MODULE_AUTHOR("YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) MODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) MODULE_SUPPORTED_DEVICE("sd,sr,sg,st");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) #include "nsp_io.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) /*====================================================================*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) /* Parameters that can be set with 'insmod' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) static int       nsp_burst_mode = BURST_MEM32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) module_param(nsp_burst_mode, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) MODULE_PARM_DESC(nsp_burst_mode, "Burst transfer mode (0=io8, 1=io32, 2=mem32(default))");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) /* Release IO ports after configuration? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) static bool       free_ports = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) module_param(free_ports, bool, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) MODULE_PARM_DESC(free_ports, "Release IO ports after configuration? (default: 0 (=no))");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) static struct scsi_host_template nsp_driver_template = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 	.proc_name	         = "nsp_cs",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 	.show_info		 = nsp_show_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 	.name			 = "WorkBit NinjaSCSI-3/32Bi(16bit)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 	.info			 = nsp_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 	.queuecommand		 = nsp_queuecommand,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) /*	.eh_abort_handler	 = nsp_eh_abort,*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 	.eh_bus_reset_handler	 = nsp_eh_bus_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 	.eh_host_reset_handler	 = nsp_eh_host_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 	.can_queue		 = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 	.this_id		 = NSP_INITIATOR_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 	.sg_tablesize		 = SG_ALL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	.dma_boundary		 = PAGE_SIZE - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) static nsp_hw_data nsp_data_base; /* attach <-> detect glue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95)  * debug, error print
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) #ifndef NSP_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) # define NSP_DEBUG_MASK		0x000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) # define nsp_msg(type, args...) nsp_cs_message("", 0, (type), args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) # define nsp_dbg(mask, args...) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) # define NSP_DEBUG_MASK		0xffffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) # define nsp_msg(type, args...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 	nsp_cs_message (__func__, __LINE__, (type), args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) # define nsp_dbg(mask, args...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	nsp_cs_dmessage(__func__, __LINE__, (mask), args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) #define NSP_DEBUG_QUEUECOMMAND		BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) #define NSP_DEBUG_REGISTER		BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) #define NSP_DEBUG_AUTOSCSI		BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) #define NSP_DEBUG_INTR			BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) #define NSP_DEBUG_SGLIST		BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) #define NSP_DEBUG_BUSFREE		BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) #define NSP_DEBUG_CDB_CONTENTS		BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) #define NSP_DEBUG_RESELECTION		BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) #define NSP_DEBUG_MSGINOCCUR		BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) #define NSP_DEBUG_EEPROM		BIT(9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) #define NSP_DEBUG_MSGOUTOCCUR		BIT(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) #define NSP_DEBUG_BUSRESET		BIT(11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) #define NSP_DEBUG_RESTART		BIT(12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) #define NSP_DEBUG_SYNC			BIT(13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) #define NSP_DEBUG_WAIT			BIT(14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) #define NSP_DEBUG_TARGETFLAG		BIT(15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) #define NSP_DEBUG_PROC			BIT(16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) #define NSP_DEBUG_INIT			BIT(17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) #define NSP_DEBUG_DATA_IO      		BIT(18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) #define NSP_SPECIAL_PRINT_REGISTER	BIT(20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) #define NSP_DEBUG_BUF_LEN		150
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) static inline void nsp_inc_resid(struct scsi_cmnd *SCpnt, int residInc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	scsi_set_resid(SCpnt, scsi_get_resid(SCpnt) + residInc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) __printf(4, 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) static void nsp_cs_message(const char *func, int line, char *type, char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 	char buf[NSP_DEBUG_BUF_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	va_start(args, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	vsnprintf(buf, sizeof(buf), fmt, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) #ifndef NSP_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	printk("%snsp_cs: %s\n", type, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 	printk("%snsp_cs: %s (%d): %s\n", type, func, line, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) #ifdef NSP_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) static void nsp_cs_dmessage(const char *func, int line, int mask, char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 	va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	char buf[NSP_DEBUG_BUF_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	va_start(args, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 	vsnprintf(buf, sizeof(buf), fmt, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	if (mask & NSP_DEBUG_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 		printk("nsp_cs-debug: 0x%x %s (%d): %s\n", mask, func, line, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) /***********************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) /*====================================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173)  * Clenaup parameters and call done() functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174)  * You must be set SCpnt->result before call this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) static void nsp_scsi_done(struct scsi_cmnd *SCpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	data->CurrentSC = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	SCpnt->scsi_done(SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) static int nsp_queuecommand_lck(struct scsi_cmnd *SCpnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 			    void (*done)(struct scsi_cmnd *))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) #ifdef NSP_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 	/*unsigned int host_id = SCpnt->device->host->this_id;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 	/*unsigned int base    = SCpnt->device->host->io_port;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	unsigned char target = scmd_id(SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	nsp_dbg(NSP_DEBUG_QUEUECOMMAND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 		"SCpnt=0x%p target=%d lun=%llu sglist=0x%p bufflen=%d sg_count=%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 		SCpnt, target, SCpnt->device->lun, scsi_sglist(SCpnt),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 		scsi_bufflen(SCpnt), scsi_sg_count(SCpnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	//nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "before CurrentSC=0x%p", data->CurrentSC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	SCpnt->scsi_done	= done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	if (data->CurrentSC != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 		nsp_msg(KERN_DEBUG, "CurrentSC!=NULL this can't be happen");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 		SCpnt->result   = DID_BAD_TARGET << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 		nsp_scsi_done(SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	/* XXX: pcmcia-cs generates SCSI command with "scsi_info" utility.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	        This makes kernel crash when suspending... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	if (data->ScsiInfo->stop != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 		nsp_msg(KERN_INFO, "suspending device. reject command.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 		SCpnt->result  = DID_BAD_TARGET << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 		nsp_scsi_done(SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 		return SCSI_MLQUEUE_HOST_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	show_command(SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	data->CurrentSC		= SCpnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	SCpnt->SCp.Status	= CHECK_CONDITION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	SCpnt->SCp.Message	= 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	SCpnt->SCp.have_data_in = IO_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	SCpnt->SCp.sent_command = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	SCpnt->SCp.phase	= PH_UNDETERMINED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	scsi_set_resid(SCpnt, scsi_bufflen(SCpnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	/* setup scratch area
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 	   SCp.ptr		: buffer pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 	   SCp.this_residual	: buffer length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	   SCp.buffer		: next buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 	   SCp.buffers_residual : left buffers in list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 	   SCp.phase		: current state of the command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	if (scsi_bufflen(SCpnt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 		SCpnt->SCp.buffer	    = scsi_sglist(SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 		SCpnt->SCp.ptr		    = BUFFER_ADDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 		SCpnt->SCp.this_residual    = SCpnt->SCp.buffer->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 		SCpnt->SCp.buffers_residual = scsi_sg_count(SCpnt) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 		SCpnt->SCp.ptr		    = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 		SCpnt->SCp.this_residual    = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 		SCpnt->SCp.buffer	    = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 		SCpnt->SCp.buffers_residual = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 	if (nsphw_start_selection(SCpnt) == FALSE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 		nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "selection fail");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 		SCpnt->result   = DID_BUS_BUSY << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 		nsp_scsi_done(SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	//nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "out");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) #ifdef NSP_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	data->CmdId++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) static DEF_SCSI_QCMD(nsp_queuecommand)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268)  * setup PIO FIFO transfer mode and enable/disable to data out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) static void nsp_setup_fifo(nsp_hw_data *data, int enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	unsigned int  base = data->BaseAddress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	unsigned char transfer_mode_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 	//nsp_dbg(NSP_DEBUG_DATA_IO, "enabled=%d", enabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	if (enabled != FALSE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 		transfer_mode_reg = TRANSFER_GO | BRAIND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 		transfer_mode_reg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	transfer_mode_reg |= data->TransferMode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	nsp_index_write(base, TRANSFERMODE, transfer_mode_reg);
^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 void nsphw_init_sync(nsp_hw_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	sync_data tmp_sync = { .SyncNegotiation = SYNC_NOT_YET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 			       .SyncPeriod      = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 			       .SyncOffset      = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	/* setup sync data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 	for ( i = 0; i < ARRAY_SIZE(data->Sync); i++ ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 		data->Sync[i] = tmp_sync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303)  * Initialize Ninja hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) static int nsphw_init(nsp_hw_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	unsigned int base     = data->BaseAddress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	nsp_dbg(NSP_DEBUG_INIT, "in base=0x%x", base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	data->ScsiClockDiv = CLOCK_40M | FAST_20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	data->CurrentSC    = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 	data->FifoCount    = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 	data->TransferMode = MODE_IO8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 	nsphw_init_sync(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 	/* block all interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 	nsp_write(base,	      IRQCONTROL,   IRQCONTROL_ALLMASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 	/* setup SCSI interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 	nsp_write(base,	      IFSELECT,	    IF_IFSEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	nsp_index_write(base, SCSIIRQMODE,  0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	nsp_index_write(base, TRANSFERMODE, MODE_IO8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	nsp_index_write(base, CLOCKDIV,	    data->ScsiClockDiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	nsp_index_write(base, PARITYCTRL,   0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	nsp_index_write(base, POINTERCLR,   POINTER_CLEAR     |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 					    ACK_COUNTER_CLEAR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 					    REQ_COUNTER_CLEAR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 					    HOST_COUNTER_CLEAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 	/* setup fifo asic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	nsp_write(base,	      IFSELECT,	    IF_REGSEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	nsp_index_write(base, TERMPWRCTRL,  0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	if ((nsp_index_read(base, OTHERCONTROL) & TPWR_SENSE) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 		nsp_msg(KERN_INFO, "terminator power on");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 		nsp_index_write(base, TERMPWRCTRL, POWER_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	nsp_index_write(base, TIMERCOUNT,   0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	nsp_index_write(base, TIMERCOUNT,   0); /* requires 2 times!! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 	nsp_index_write(base, SYNCREG,	    0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	nsp_index_write(base, ACKWIDTH,	    0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 	/* enable interrupts and ack them */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	nsp_index_write(base, SCSIIRQMODE,  SCSI_PHASE_CHANGE_EI |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 					    RESELECT_EI		 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 					    SCSI_RESET_IRQ_EI	 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	nsp_write(base,	      IRQCONTROL,   IRQCONTROL_ALLCLEAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 	nsp_setup_fifo(data, FALSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 	return TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361)  * Start selection phase
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) static int nsphw_start_selection(struct scsi_cmnd *SCpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	unsigned int  host_id	 = SCpnt->device->host->this_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 	unsigned int  base	 = SCpnt->device->host->io_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 	unsigned char target	 = scmd_id(SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 	nsp_hw_data  *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	int	      time_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	unsigned char phase, arbit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	//nsp_dbg(NSP_DEBUG_RESELECTION, "in");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 	phase = nsp_index_read(base, SCSIBUSMON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 	if(phase != BUSMON_BUS_FREE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 		//nsp_dbg(NSP_DEBUG_RESELECTION, "bus busy");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 		return FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 	/* start arbitration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 	//nsp_dbg(NSP_DEBUG_RESELECTION, "start arbit");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 	SCpnt->SCp.phase = PH_ARBSTART;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 	nsp_index_write(base, SETARBIT, ARBIT_GO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 	time_out = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 		/* XXX: what a stupid chip! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 		arbit = nsp_index_read(base, ARBITSTATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 		//nsp_dbg(NSP_DEBUG_RESELECTION, "arbit=%d, wait_count=%d", arbit, wait_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 		udelay(1); /* hold 1.2us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 	} while((arbit & (ARBIT_WIN | ARBIT_FAIL)) == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 		(time_out-- != 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	if (!(arbit & ARBIT_WIN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 		//nsp_dbg(NSP_DEBUG_RESELECTION, "arbit fail");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 		nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 		return FALSE;
^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) 	/* assert select line */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	//nsp_dbg(NSP_DEBUG_RESELECTION, "assert SEL line");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	SCpnt->SCp.phase = PH_SELSTART;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 	udelay(3); /* wait 2.4us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	nsp_index_write(base, SCSIDATALATCH, BIT(host_id) | BIT(target));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	nsp_index_write(base, SCSIBUSCTRL,   SCSI_SEL | SCSI_BSY                    | SCSI_ATN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	udelay(2); /* wait >1.2us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 	nsp_index_write(base, SCSIBUSCTRL,   SCSI_SEL | SCSI_BSY | SCSI_DATAOUT_ENB | SCSI_ATN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 	nsp_index_write(base, SETARBIT,	     ARBIT_FLAG_CLEAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 	/*udelay(1);*/ /* wait >90ns */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	nsp_index_write(base, SCSIBUSCTRL,   SCSI_SEL            | SCSI_DATAOUT_ENB | SCSI_ATN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	/* check selection timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	nsp_start_timer(SCpnt, 1000/51);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	data->SelectionTimeOut = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	return TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) struct nsp_sync_table {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 	unsigned int min_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 	unsigned int max_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	unsigned int chip_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 	unsigned int ack_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) static struct nsp_sync_table nsp_sync_table_40M[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 	{0x0c, 0x0c, 0x1, 0},	/* 20MB	  50ns*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 	{0x19, 0x19, 0x3, 1},	/* 10MB	 100ns*/ 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 	{0x1a, 0x25, 0x5, 2},	/* 7.5MB 150ns*/ 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	{0x26, 0x32, 0x7, 3},	/* 5MB	 200ns*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 	{   0,    0,   0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) static struct nsp_sync_table nsp_sync_table_20M[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 	{0x19, 0x19, 0x1, 0},	/* 10MB	 100ns*/ 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	{0x1a, 0x25, 0x2, 0},	/* 7.5MB 150ns*/ 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 	{0x26, 0x32, 0x3, 1},	/* 5MB	 200ns*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	{   0,    0,   0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) };
^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)  * setup synchronous data transfer mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) static int nsp_analyze_sdtr(struct scsi_cmnd *SCpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 	unsigned char	       target = scmd_id(SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) //	unsigned char	       lun    = SCpnt->device->lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 	nsp_hw_data           *data   = (nsp_hw_data *)SCpnt->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 	sync_data	      *sync   = &(data->Sync[target]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 	struct nsp_sync_table *sync_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	unsigned int	       period, offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	int		       i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 	nsp_dbg(NSP_DEBUG_SYNC, "in");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 	period = sync->SyncPeriod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 	offset = sync->SyncOffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	nsp_dbg(NSP_DEBUG_SYNC, "period=0x%x, offset=0x%x", period, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 	if ((data->ScsiClockDiv & (BIT(0)|BIT(1))) == CLOCK_20M) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 		sync_table = nsp_sync_table_20M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 		sync_table = nsp_sync_table_40M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	for ( i = 0; sync_table->max_period != 0; i++, sync_table++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 		if ( period >= sync_table->min_period &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 		     period <= sync_table->max_period	 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	if (period != 0 && sync_table->max_period == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 		 * No proper period/offset found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 		nsp_dbg(NSP_DEBUG_SYNC, "no proper period/offset");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 		sync->SyncPeriod      = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 		sync->SyncOffset      = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 		sync->SyncRegister    = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 		sync->AckWidth	      = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 		return FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 	sync->SyncRegister    = (sync_table->chip_period << SYNCREG_PERIOD_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 		                (offset & SYNCREG_OFFSET_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	sync->AckWidth	      = sync_table->ack_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	nsp_dbg(NSP_DEBUG_SYNC, "sync_reg=0x%x, ack_width=0x%x", sync->SyncRegister, sync->AckWidth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 	return TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500)  * start ninja hardware timer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) static void nsp_start_timer(struct scsi_cmnd *SCpnt, int time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	unsigned int base = SCpnt->device->host->io_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	//nsp_dbg(NSP_DEBUG_INTR, "in SCpnt=0x%p, time=%d", SCpnt, time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 	data->TimerCount = time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 	nsp_index_write(base, TIMERCOUNT, time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513)  * wait for bus phase change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) static int nsp_negate_signal(struct scsi_cmnd *SCpnt, unsigned char mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 			     char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	unsigned int  base = SCpnt->device->host->io_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 	unsigned char reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 	int	      time_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 	//nsp_dbg(NSP_DEBUG_INTR, "in");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 	time_out = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 		reg = nsp_index_read(base, SCSIBUSMON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 		if (reg == 0xff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	} while ((--time_out != 0) && (reg & mask) != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	if (time_out == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 		nsp_msg(KERN_DEBUG, " %s signal off timeout", str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541)  * expect Ninja Irq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) static int nsp_expect_signal(struct scsi_cmnd *SCpnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 			     unsigned char current_phase,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 			     unsigned char mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	unsigned int  base	 = SCpnt->device->host->io_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	int	      time_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	unsigned char phase, i_src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	//nsp_dbg(NSP_DEBUG_INTR, "current_phase=0x%x, mask=0x%x", current_phase, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	time_out = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 		phase = nsp_index_read(base, SCSIBUSMON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 		if (phase == 0xff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 			//nsp_dbg(NSP_DEBUG_INTR, "ret -1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 		i_src = nsp_read(base, IRQSTATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 		if (i_src & IRQSTATUS_SCSI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 			//nsp_dbg(NSP_DEBUG_INTR, "ret 0 found scsi signal");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 		if ((phase & mask) != 0 && (phase & BUSMON_PHASE_MASK) == current_phase) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 			//nsp_dbg(NSP_DEBUG_INTR, "ret 1 phase=0x%x", phase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 			return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	} while(time_out-- != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 	//nsp_dbg(NSP_DEBUG_INTR, "timeout");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576)  * transfer SCSI message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) static int nsp_xfer(struct scsi_cmnd *SCpnt, int phase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	unsigned int  base = SCpnt->device->host->io_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	nsp_hw_data  *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	char	     *buf  = data->MsgBuffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	int	      len  = min(MSGBUF_SIZE, data->MsgLen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	int	      ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	int	      ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	//nsp_dbg(NSP_DEBUG_DATA_IO, "in");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	for (ptr = 0; len > 0; len--, ptr++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 		ret = nsp_expect_signal(SCpnt, phase, BUSMON_REQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 		if (ret <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 			nsp_dbg(NSP_DEBUG_DATA_IO, "xfer quit");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 		/* if last byte, negate ATN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 		if (len == 1 && SCpnt->SCp.phase == PH_MSG_OUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 			nsp_index_write(base, SCSIBUSCTRL, AUTODIRECTION | ACKENB);
^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) 		/* read & write message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 		if (phase & BUSMON_IO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 			nsp_dbg(NSP_DEBUG_DATA_IO, "read msg");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 			buf[ptr] = nsp_index_read(base, SCSIDATAWITHACK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 			nsp_dbg(NSP_DEBUG_DATA_IO, "write msg");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 			nsp_index_write(base, SCSIDATAWITHACK, buf[ptr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 		nsp_negate_signal(SCpnt, BUSMON_ACK, "xfer<ack>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	return len;
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616)  * get extra SCSI data from fifo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) static int nsp_dataphase_bypass(struct scsi_cmnd *SCpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 	unsigned int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	//nsp_dbg(NSP_DEBUG_DATA_IO, "in");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	if (SCpnt->SCp.have_data_in != IO_IN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 	count = nsp_fifo_count(SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	if (data->FifoCount == count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 		//nsp_dbg(NSP_DEBUG_DATA_IO, "not use bypass quirk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 	 * XXX: NSP_QUIRK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 	 * data phase skip only occures in case of SCSI_LOW_READ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	nsp_dbg(NSP_DEBUG_DATA_IO, "use bypass quirk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	SCpnt->SCp.phase = PH_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 	nsp_pio_read(SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 	nsp_setup_fifo(data, FALSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648)  * accept reselection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) static int nsp_reselected(struct scsi_cmnd *SCpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 	unsigned int  base    = SCpnt->device->host->io_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 	unsigned int  host_id = SCpnt->device->host->this_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	//nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 	unsigned char bus_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 	unsigned char id_reg, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 	int target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 	nsp_dbg(NSP_DEBUG_RESELECTION, "in");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 	id_reg = nsp_index_read(base, RESELECTID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 	tmp    = id_reg & (~BIT(host_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 	target = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 	while(tmp != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 		if (tmp & BIT(0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 		tmp >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 		target++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	if (scmd_id(SCpnt) != target) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 		nsp_msg(KERN_ERR, "XXX: reselect ID must be %d in this implementation.", target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 	nsp_negate_signal(SCpnt, BUSMON_SEL, "reselect<SEL>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 	nsp_nexus(SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	bus_reg = nsp_index_read(base, SCSIBUSCTRL) & ~(SCSI_BSY | SCSI_ATN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	nsp_index_write(base, SCSIBUSCTRL, bus_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	nsp_index_write(base, SCSIBUSCTRL, bus_reg | AUTODIRECTION | ACKENB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 	return TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687)  * count how many data transferd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) static int nsp_fifo_count(struct scsi_cmnd *SCpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	unsigned int base = SCpnt->device->host->io_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 	unsigned int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 	unsigned int l, m, h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 	nsp_index_write(base, POINTERCLR, POINTER_CLEAR | ACK_COUNTER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 	l     = nsp_index_read(base, TRANSFERCOUNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 	m     = nsp_index_read(base, TRANSFERCOUNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 	h     = nsp_index_read(base, TRANSFERCOUNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 	nsp_index_read(base, TRANSFERCOUNT); /* required this! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	count = (h << 16) | (m << 8) | (l << 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 	//nsp_dbg(NSP_DEBUG_DATA_IO, "count=0x%x", count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) /* fifo size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) #define RFIFO_CRIT 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) #define WFIFO_CRIT 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714)  * read data in DATA IN phase
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) static void nsp_pio_read(struct scsi_cmnd *SCpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 	unsigned int  base      = SCpnt->device->host->io_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	unsigned long mmio_base = SCpnt->device->host->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 	nsp_hw_data  *data      = (nsp_hw_data *)SCpnt->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 	long	      time_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 	int	      ocount, res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 	unsigned char stat, fifo_stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	ocount = data->FifoCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 	nsp_dbg(NSP_DEBUG_DATA_IO, "in SCpnt=0x%p resid=%d ocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 		SCpnt, scsi_get_resid(SCpnt), ocount, SCpnt->SCp.ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 		SCpnt->SCp.this_residual, SCpnt->SCp.buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 		SCpnt->SCp.buffers_residual);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 	time_out = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	while ((time_out-- != 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	       (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0 ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 		stat = nsp_index_read(base, SCSIBUSMON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 		stat &= BUSMON_PHASE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 		res = nsp_fifo_count(SCpnt) - ocount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 		//nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this=0x%x ocount=0x%x res=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, ocount, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 		if (res == 0) { /* if some data available ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 			if (stat == BUSPHASE_DATA_IN) { /* phase changed? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 				//nsp_dbg(NSP_DEBUG_DATA_IO, " wait for data this=%d", SCpnt->SCp.this_residual);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 				nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x", stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 		fifo_stat = nsp_read(base, FIFOSTATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 		if ((fifo_stat & FIFOSTATUS_FULL_EMPTY) == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 		    stat                                == BUSPHASE_DATA_IN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 		res = min(res, SCpnt->SCp.this_residual);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 		switch (data->TransferMode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 		case MODE_IO32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 			res &= ~(BIT(1)|BIT(0)); /* align 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 			nsp_fifo32_read(base, SCpnt->SCp.ptr, res >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 		case MODE_IO8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 			nsp_fifo8_read (base, SCpnt->SCp.ptr, res     );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 		case MODE_MEM32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 			res &= ~(BIT(1)|BIT(0)); /* align 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 			nsp_mmio_fifo32_read(mmio_base, SCpnt->SCp.ptr, res >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 			nsp_dbg(NSP_DEBUG_DATA_IO, "unknown read mode");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 		nsp_inc_resid(SCpnt, -res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 		SCpnt->SCp.ptr		 += res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 		SCpnt->SCp.this_residual -= res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 		ocount			 += res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 		//nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this_residual=0x%x ocount=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, ocount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 		/* go to next scatter list if available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 		if (SCpnt->SCp.this_residual	== 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 		    SCpnt->SCp.buffers_residual != 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 			//nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next timeout=%d", time_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 			SCpnt->SCp.buffers_residual--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 			SCpnt->SCp.buffer = sg_next(SCpnt->SCp.buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 			SCpnt->SCp.ptr		 = BUFFER_ADDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 			SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 			time_out = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 			//nsp_dbg(NSP_DEBUG_DATA_IO, "page: 0x%p, off: 0x%x", SCpnt->SCp.buffer->page, SCpnt->SCp.buffer->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 	data->FifoCount = ocount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 	if (time_out < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 		nsp_msg(KERN_DEBUG, "pio read timeout resid=%d this_residual=%d buffers_residual=%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 			scsi_get_resid(SCpnt), SCpnt->SCp.this_residual,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 			SCpnt->SCp.buffers_residual);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	nsp_dbg(NSP_DEBUG_DATA_IO, "read ocount=0x%x", ocount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	nsp_dbg(NSP_DEBUG_DATA_IO, "r cmd=%d resid=0x%x\n", data->CmdId,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	                                                scsi_get_resid(SCpnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813)  * write data in DATA OUT phase
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) static void nsp_pio_write(struct scsi_cmnd *SCpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 	unsigned int  base      = SCpnt->device->host->io_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 	unsigned long mmio_base = SCpnt->device->host->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 	nsp_hw_data  *data      = (nsp_hw_data *)SCpnt->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 	int	      time_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 	int           ocount, res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 	unsigned char stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	ocount	 = data->FifoCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 	nsp_dbg(NSP_DEBUG_DATA_IO, "in fifocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d resid=0x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 		data->FifoCount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 		SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 		scsi_get_resid(SCpnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	time_out = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	while ((time_out-- != 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 	       (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 		stat = nsp_index_read(base, SCSIBUSMON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 		stat &= BUSMON_PHASE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 		if (stat != BUSPHASE_DATA_OUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 			res = ocount - nsp_fifo_count(SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 			nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x, res=%d\n", stat, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 			/* Put back pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 			nsp_inc_resid(SCpnt, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 			SCpnt->SCp.ptr		 -= res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 			SCpnt->SCp.this_residual += res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 			ocount			 -= res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 		res = ocount - nsp_fifo_count(SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 		if (res > 0) { /* write all data? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 			nsp_dbg(NSP_DEBUG_DATA_IO, "wait for all data out. ocount=0x%x res=%d", ocount, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 		res = min(SCpnt->SCp.this_residual, WFIFO_CRIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 		//nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this=0x%x res=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 		switch (data->TransferMode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 		case MODE_IO32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 			res &= ~(BIT(1)|BIT(0)); /* align 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 			nsp_fifo32_write(base, SCpnt->SCp.ptr, res >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 		case MODE_IO8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 			nsp_fifo8_write (base, SCpnt->SCp.ptr, res     );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 		case MODE_MEM32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 			res &= ~(BIT(1)|BIT(0)); /* align 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 			nsp_mmio_fifo32_write(mmio_base, SCpnt->SCp.ptr, res >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 			nsp_dbg(NSP_DEBUG_DATA_IO, "unknown write mode");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 		nsp_inc_resid(SCpnt, -res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 		SCpnt->SCp.ptr		 += res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 		SCpnt->SCp.this_residual -= res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 		ocount			 += res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 		/* go to next scatter list if available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 		if (SCpnt->SCp.this_residual	== 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 		    SCpnt->SCp.buffers_residual != 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 			//nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 			SCpnt->SCp.buffers_residual--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 			SCpnt->SCp.buffer = sg_next(SCpnt->SCp.buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 			SCpnt->SCp.ptr		 = BUFFER_ADDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 			SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 			time_out = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	data->FifoCount = ocount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	if (time_out < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 		nsp_msg(KERN_DEBUG, "pio write timeout resid=0x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 		                                        scsi_get_resid(SCpnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 	nsp_dbg(NSP_DEBUG_DATA_IO, "write ocount=0x%x", ocount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 	nsp_dbg(NSP_DEBUG_DATA_IO, "w cmd=%d resid=0x%x\n", data->CmdId,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 	                                                scsi_get_resid(SCpnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) #undef RFIFO_CRIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) #undef WFIFO_CRIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910)  * setup synchronous/asynchronous data transfer mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) static int nsp_nexus(struct scsi_cmnd *SCpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 	unsigned int   base   = SCpnt->device->host->io_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 	unsigned char  target = scmd_id(SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) //	unsigned char  lun    = SCpnt->device->lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	sync_data     *sync   = &(data->Sync[target]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 	//nsp_dbg(NSP_DEBUG_DATA_IO, "in SCpnt=0x%p", SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	/* setup synch transfer registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 	nsp_index_write(base, SYNCREG,	sync->SyncRegister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	nsp_index_write(base, ACKWIDTH, sync->AckWidth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 	if (scsi_get_resid(SCpnt) % 4 != 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	    scsi_get_resid(SCpnt) <= PAGE_SIZE ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 		data->TransferMode = MODE_IO8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 	} else if (nsp_burst_mode == BURST_MEM32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 		data->TransferMode = MODE_MEM32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	} else if (nsp_burst_mode == BURST_IO32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 		data->TransferMode = MODE_IO32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 		data->TransferMode = MODE_IO8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	/* setup pdma fifo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	nsp_setup_fifo(data, TRUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	/* clear ack counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941)  	data->FifoCount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	nsp_index_write(base, POINTERCLR, POINTER_CLEAR	    |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 					  ACK_COUNTER_CLEAR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 					  REQ_COUNTER_CLEAR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 					  HOST_COUNTER_CLEAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) #include "nsp_message.c"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952)  * interrupt handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) static irqreturn_t nspintr(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	unsigned int   base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	unsigned char  irq_status, irq_phase, phase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	struct scsi_cmnd *tmpSC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	unsigned char  target, lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	unsigned int  *sync_neg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	int            i, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	nsp_hw_data   *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 	//nsp_dbg(NSP_DEBUG_INTR, "dev_id=0x%p", dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	//nsp_dbg(NSP_DEBUG_INTR, "host=0x%p", ((scsi_info_t *)dev_id)->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 	if (                dev_id        != NULL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 	    ((scsi_info_t *)dev_id)->host != NULL  ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 		scsi_info_t *info = (scsi_info_t *)dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 		data = (nsp_hw_data *)info->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 		nsp_dbg(NSP_DEBUG_INTR, "host data wrong");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 		return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	//nsp_dbg(NSP_DEBUG_INTR, "&nsp_data_base=0x%p, dev_id=0x%p", &nsp_data_base, dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	base = data->BaseAddress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	//nsp_dbg(NSP_DEBUG_INTR, "base=0x%x", base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	 * interrupt check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	nsp_write(base, IRQCONTROL, IRQCONTROL_IRQDISABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	irq_status = nsp_read(base, IRQSTATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	//nsp_dbg(NSP_DEBUG_INTR, "irq_status=0x%x", irq_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 	if ((irq_status == 0xff) || ((irq_status & IRQSTATUS_MASK) == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 		nsp_write(base, IRQCONTROL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 		//nsp_dbg(NSP_DEBUG_INTR, "no irq/shared irq");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 		return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	/* XXX: IMPORTANT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	 * Do not read an irq_phase register if no scsi phase interrupt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	 * Unless, you should lose a scsi phase interrupt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 	phase = nsp_index_read(base, SCSIBUSMON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 	if((irq_status & IRQSTATUS_SCSI) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 		irq_phase = nsp_index_read(base, IRQPHASESENCE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 		irq_phase = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	//nsp_dbg(NSP_DEBUG_INTR, "irq_phase=0x%x", irq_phase);
^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) 	 * timer interrupt handler (scsi vs timer interrupts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	//nsp_dbg(NSP_DEBUG_INTR, "timercount=%d", data->TimerCount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	if (data->TimerCount != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 		//nsp_dbg(NSP_DEBUG_INTR, "stop timer");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 		nsp_index_write(base, TIMERCOUNT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 		nsp_index_write(base, TIMERCOUNT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 		data->TimerCount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 	if ((irq_status & IRQSTATUS_MASK) == IRQSTATUS_TIMER &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	    data->SelectionTimeOut == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 		//nsp_dbg(NSP_DEBUG_INTR, "timer start");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 		nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 		return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR | IRQCONTROL_FIFO_CLEAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 	if ((irq_status & IRQSTATUS_SCSI) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 	    (irq_phase  & SCSI_RESET_IRQ)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 		nsp_msg(KERN_ERR, "bus reset (power off?)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 		nsphw_init(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 		nsp_bus_reset(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 		if(data->CurrentSC != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 			tmpSC = data->CurrentSC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 			tmpSC->result  = (DID_RESET                   << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 				         ((tmpSC->SCp.Message & 0xff) <<  8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 				         ((tmpSC->SCp.Status  & 0xff) <<  0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 			nsp_scsi_done(tmpSC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 		return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 	if (data->CurrentSC == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 		nsp_msg(KERN_ERR, "CurrentSC==NULL irq_status=0x%x phase=0x%x irq_phase=0x%x this can't be happen. reset everything", irq_status, phase, irq_phase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 		nsphw_init(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 		nsp_bus_reset(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 		return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 	tmpSC    = data->CurrentSC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 	target   = tmpSC->device->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 	lun      = tmpSC->device->lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 	sync_neg = &(data->Sync[target].SyncNegotiation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 	 * parse hardware SCSI irq reasons register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 	if (irq_status & IRQSTATUS_SCSI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 		if (irq_phase & RESELECT_IRQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 			nsp_dbg(NSP_DEBUG_INTR, "reselect");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 			nsp_write(base, IRQCONTROL, IRQCONTROL_RESELECT_CLEAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 			if (nsp_reselected(tmpSC) != FALSE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 				return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 		if ((irq_phase & (PHASE_CHANGE_IRQ | LATCHED_BUS_FREE)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 			return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 	//show_phase(tmpSC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 	switch(tmpSC->SCp.phase) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 	case PH_SELSTART:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 		// *sync_neg = SYNC_NOT_YET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 		if ((phase & BUSMON_BSY) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 			//nsp_dbg(NSP_DEBUG_INTR, "selection count=%d", data->SelectionTimeOut);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 			if (data->SelectionTimeOut >= NSP_SELTIMEOUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 				nsp_dbg(NSP_DEBUG_INTR, "selection time out");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 				data->SelectionTimeOut = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 				nsp_index_write(base, SCSIBUSCTRL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 				tmpSC->result   = DID_TIME_OUT << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 				nsp_scsi_done(tmpSC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 				return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 			data->SelectionTimeOut += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 			nsp_start_timer(tmpSC, 1000/51);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 			return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 		/* attention assert */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 		//nsp_dbg(NSP_DEBUG_INTR, "attention assert");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 		data->SelectionTimeOut = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 		tmpSC->SCp.phase       = PH_SELECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 		nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 		udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 		nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN | AUTODIRECTION | ACKENB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 		return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	case PH_RESELECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 		//nsp_dbg(NSP_DEBUG_INTR, "phase reselect");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 		// *sync_neg = SYNC_NOT_YET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 		if ((phase & BUSMON_PHASE_MASK) != BUSPHASE_MESSAGE_IN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 			tmpSC->result	= DID_ABORT << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 			nsp_scsi_done(tmpSC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 			return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 		if ((irq_status & (IRQSTATUS_SCSI | IRQSTATUS_FIFO)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 			return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 	 * SCSI sequencer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 	//nsp_dbg(NSP_DEBUG_INTR, "start scsi seq");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 	/* normal disconnect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 	if (((tmpSC->SCp.phase == PH_MSG_IN) || (tmpSC->SCp.phase == PH_MSG_OUT)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 	    (irq_phase & LATCHED_BUS_FREE) != 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 		nsp_dbg(NSP_DEBUG_INTR, "normal disconnect irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 		//*sync_neg       = SYNC_NOT_YET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 		/* all command complete and return status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 		if (tmpSC->SCp.Message == MSG_COMMAND_COMPLETE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 			tmpSC->result = (DID_OK		             << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 					((tmpSC->SCp.Message & 0xff) <<  8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 					((tmpSC->SCp.Status  & 0xff) <<  0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 			nsp_dbg(NSP_DEBUG_INTR, "command complete result=0x%x", tmpSC->result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 			nsp_scsi_done(tmpSC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 			return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 		return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 	/* check unexpected bus free state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	if (phase == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 		nsp_msg(KERN_DEBUG, "unexpected bus free. irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 		*sync_neg       = SYNC_NG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 		tmpSC->result   = DID_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 		nsp_scsi_done(tmpSC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 		return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 	switch (phase & BUSMON_PHASE_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 	case BUSPHASE_COMMAND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 		nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_COMMAND");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 		if ((phase & BUSMON_REQ) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 			nsp_dbg(NSP_DEBUG_INTR, "REQ == 0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 			return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 		tmpSC->SCp.phase = PH_COMMAND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 		nsp_nexus(tmpSC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 		/* write scsi command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 		nsp_dbg(NSP_DEBUG_INTR, "cmd_len=%d", tmpSC->cmd_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 		nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 		for (i = 0; i < tmpSC->cmd_len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 			nsp_index_write(base, COMMANDDATA, tmpSC->cmnd[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 		nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER | AUTO_COMMAND_GO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 	case BUSPHASE_DATA_OUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 		nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_OUT");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 		tmpSC->SCp.phase        = PH_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 		tmpSC->SCp.have_data_in = IO_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 		nsp_pio_write(tmpSC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 	case BUSPHASE_DATA_IN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 		nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_IN");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 		tmpSC->SCp.phase        = PH_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 		tmpSC->SCp.have_data_in = IO_IN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 		nsp_pio_read(tmpSC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 	case BUSPHASE_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 		nsp_dataphase_bypass(tmpSC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 		nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_STATUS");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 		tmpSC->SCp.phase = PH_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 		tmpSC->SCp.Status = nsp_index_read(base, SCSIDATAWITHACK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 		nsp_dbg(NSP_DEBUG_INTR, "message=0x%x status=0x%x", tmpSC->SCp.Message, tmpSC->SCp.Status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 	case BUSPHASE_MESSAGE_OUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 		nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_OUT");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 		if ((phase & BUSMON_REQ) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 			goto timer_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 		tmpSC->SCp.phase = PH_MSG_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 		//*sync_neg = SYNC_NOT_YET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 		data->MsgLen = i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 		data->MsgBuffer[i] = IDENTIFY(TRUE, lun); i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 		if (*sync_neg == SYNC_NOT_YET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 			data->Sync[target].SyncPeriod = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 			data->Sync[target].SyncOffset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 			/**/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 			data->MsgBuffer[i] = MSG_EXTENDED; i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 			data->MsgBuffer[i] = 3;            i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 			data->MsgBuffer[i] = MSG_EXT_SDTR; i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 			data->MsgBuffer[i] = 0x0c;         i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 			data->MsgBuffer[i] = 15;           i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 			/**/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 		data->MsgLen = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 		nsp_analyze_sdtr(tmpSC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 		show_message(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 		nsp_message_out(tmpSC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 	case BUSPHASE_MESSAGE_IN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 		nsp_dataphase_bypass(tmpSC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 		nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_IN");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 		if ((phase & BUSMON_REQ) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 			goto timer_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 		tmpSC->SCp.phase = PH_MSG_IN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 		nsp_message_in(tmpSC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 		/**/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 		if (*sync_neg == SYNC_NOT_YET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 			//nsp_dbg(NSP_DEBUG_INTR, "sync target=%d,lun=%d",target,lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 			if (data->MsgLen       >= 5            &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 			    data->MsgBuffer[0] == MSG_EXTENDED &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 			    data->MsgBuffer[1] == 3            &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 			    data->MsgBuffer[2] == MSG_EXT_SDTR ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 				data->Sync[target].SyncPeriod = data->MsgBuffer[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 				data->Sync[target].SyncOffset = data->MsgBuffer[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 				//nsp_dbg(NSP_DEBUG_INTR, "sync ok, %d %d", data->MsgBuffer[3], data->MsgBuffer[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 				*sync_neg = SYNC_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 				data->Sync[target].SyncPeriod = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 				data->Sync[target].SyncOffset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 				*sync_neg = SYNC_NG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 			nsp_analyze_sdtr(tmpSC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 		/**/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 		/* search last messeage byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 		tmp = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 		for (i = 0; i < data->MsgLen; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 			tmp = data->MsgBuffer[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 			if (data->MsgBuffer[i] == MSG_EXTENDED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 				i += (1 + data->MsgBuffer[i+1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 		tmpSC->SCp.Message = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 		nsp_dbg(NSP_DEBUG_INTR, "message=0x%x len=%d", tmpSC->SCp.Message, data->MsgLen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 		show_message(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 	case BUSPHASE_SELECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 		nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE other");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 	//nsp_dbg(NSP_DEBUG_INTR, "out");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 	return IRQ_HANDLED; 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) timer_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 	nsp_start_timer(tmpSC, 1000/102);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) #ifdef NSP_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) #include "nsp_debug.c"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) #endif	/* NSP_DEBUG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) /*----------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) /* look for ninja3 card and init if found			  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) /*----------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) static struct Scsi_Host *nsp_detect(struct scsi_host_template *sht)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 	struct Scsi_Host *host;	/* registered host structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 	nsp_hw_data *data_b = &nsp_data_base, *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 	nsp_dbg(NSP_DEBUG_INIT, "this_id=%d", sht->this_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 	host = scsi_host_alloc(&nsp_driver_template, sizeof(nsp_hw_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 	if (host == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 		nsp_dbg(NSP_DEBUG_INIT, "host failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 	memcpy(host->hostdata, data_b, sizeof(nsp_hw_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 	data = (nsp_hw_data *)host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 	data->ScsiInfo->host = host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) #ifdef NSP_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 	data->CmdId = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 	nsp_dbg(NSP_DEBUG_INIT, "irq=%d,%d", data_b->IrqNumber, ((nsp_hw_data *)host->hostdata)->IrqNumber);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 	host->unique_id	  = data->BaseAddress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 	host->io_port	  = data->BaseAddress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 	host->n_io_port	  = data->NumAddress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 	host->irq	  = data->IrqNumber;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 	host->base        = data->MmioAddress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 	spin_lock_init(&(data->Lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 	snprintf(data->nspinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 		 sizeof(data->nspinfo),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 		 "NinjaSCSI-3/32Bi Driver $Revision: 1.23 $ IO:0x%04lx-0x%04lx MMIO(virt addr):0x%04lx IRQ:%02d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 		 host->io_port, host->io_port + host->n_io_port - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 		 host->base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 		 host->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 	sht->name	  = data->nspinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 	nsp_dbg(NSP_DEBUG_INIT, "end");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 	return host; /* detect done. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) /*----------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) /* return info string						  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) /*----------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) static const char *nsp_info(struct Scsi_Host *shpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 	nsp_hw_data *data = (nsp_hw_data *)shpnt->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 	return data->nspinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) static int nsp_show_info(struct seq_file *m, struct Scsi_Host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 	int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 	int speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 	nsp_hw_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 	int hostno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 	hostno = host->host_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 	data = (nsp_hw_data *)host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 	seq_puts(m, "NinjaSCSI status\n\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 		"Driver version:        $Revision: 1.23 $\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 	seq_printf(m, "SCSI host No.:         %d\n",          hostno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 	seq_printf(m, "IRQ:                   %d\n",          host->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 	seq_printf(m, "IO:                    0x%lx-0x%lx\n", host->io_port, host->io_port + host->n_io_port - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 	seq_printf(m, "MMIO(virtual address): 0x%lx-0x%lx\n", host->base, host->base + data->MmioLength - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 	seq_printf(m, "sg_tablesize:          %d\n",          host->sg_tablesize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 	seq_puts(m, "burst transfer mode:   ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 	switch (nsp_burst_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 	case BURST_IO8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 		seq_puts(m, "io8");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 	case BURST_IO32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 		seq_puts(m, "io32");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 	case BURST_MEM32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 		seq_puts(m, "mem32");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 		seq_puts(m, "???");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 	seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 	spin_lock_irqsave(&(data->Lock), flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 	seq_printf(m, "CurrentSC:             0x%p\n\n",      data->CurrentSC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 	spin_unlock_irqrestore(&(data->Lock), flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 	seq_puts(m, "SDTR status\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 	for(id = 0; id < ARRAY_SIZE(data->Sync); id++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 		seq_printf(m, "id %d: ", id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 		if (id == host->this_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 			seq_puts(m, "----- NinjaSCSI-3 host adapter\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 		switch(data->Sync[id].SyncNegotiation) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 		case SYNC_OK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 			seq_puts(m, " sync");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 		case SYNC_NG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 			seq_puts(m, "async");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 		case SYNC_NOT_YET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 			seq_puts(m, " none");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 			seq_puts(m, "?????");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 		if (data->Sync[id].SyncPeriod != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 			speed = 1000000 / (data->Sync[id].SyncPeriod * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 			seq_printf(m, " transfer %d.%dMB/s, offset %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 				speed / 1000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 				speed % 1000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 				data->Sync[id].SyncOffset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 				);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 		seq_putc(m, '\n');
^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) /*---------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) /* error handler                                                 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) /*---------------------------------------------------------------*/
^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) static int nsp_eh_abort(struct scsi_cmnd *SCpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 	nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 	return nsp_eh_bus_reset(SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) }*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) static int nsp_bus_reset(nsp_hw_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 	unsigned int base = data->BaseAddress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 	int	     i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 	nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 	nsp_index_write(base, SCSIBUSCTRL, SCSI_RST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 	mdelay(100); /* 100ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 	nsp_index_write(base, SCSIBUSCTRL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 	for(i = 0; i < 5; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 		nsp_index_read(base, IRQPHASESENCE); /* dummy read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 	nsphw_init_sync(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 	nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 	return SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) static int nsp_eh_bus_reset(struct scsi_cmnd *SCpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 	nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 	return nsp_bus_reset(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) static int nsp_eh_host_reset(struct scsi_cmnd *SCpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 	nsp_dbg(NSP_DEBUG_BUSRESET, "in");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 	nsphw_init(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 	return SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) /**********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501)   PCMCIA functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) **********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) static int nsp_cs_probe(struct pcmcia_device *link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 	scsi_info_t  *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 	nsp_hw_data  *data = &nsp_data_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 	nsp_dbg(NSP_DEBUG_INIT, "in");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 	/* Create new SCSI device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 	info = kzalloc(sizeof(*info), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 	if (info == NULL) { return -ENOMEM; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 	info->p_dev = link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 	link->priv = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 	data->ScsiInfo = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 	nsp_dbg(NSP_DEBUG_INIT, "info=0x%p", info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 	ret = nsp_cs_config(link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 	nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) } /* nsp_cs_attach */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) static void nsp_cs_detach(struct pcmcia_device *link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 	nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 	((scsi_info_t *)link->priv)->stop = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 	nsp_cs_release(link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 	kfree(link->priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 	link->priv = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) } /* nsp_cs_detach */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) static int nsp_cs_config_check(struct pcmcia_device *p_dev, void *priv_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 	nsp_hw_data		*data = priv_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 	if (p_dev->config_index == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 	/* This reserves IO space but doesn't actually enable it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 	if (pcmcia_request_io(p_dev) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 		goto next_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 	if (resource_size(p_dev->resource[2])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 		p_dev->resource[2]->flags |= (WIN_DATA_WIDTH_16 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 					WIN_MEMORY_TYPE_CM |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 					WIN_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 		if (p_dev->resource[2]->end < 0x1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 			p_dev->resource[2]->end = 0x1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 		if (pcmcia_request_window(p_dev, p_dev->resource[2], 0) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 			goto next_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 		if (pcmcia_map_mem_page(p_dev, p_dev->resource[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 						p_dev->card_addr) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 			goto next_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 		data->MmioAddress = (unsigned long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 			ioremap(p_dev->resource[2]->start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 					resource_size(p_dev->resource[2]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 		data->MmioLength  = resource_size(p_dev->resource[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 	/* If we got this far, we're cool! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) next_entry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 	nsp_dbg(NSP_DEBUG_INIT, "next");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 	pcmcia_disable_device(p_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 	return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) static int nsp_cs_config(struct pcmcia_device *link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 	int		  ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 	scsi_info_t	 *info	 = link->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 	struct Scsi_Host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 	nsp_hw_data      *data = &nsp_data_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 	nsp_dbg(NSP_DEBUG_INIT, "in");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 	link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_CHECK_VCC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 		CONF_AUTO_SET_VPP | CONF_AUTO_AUDIO | CONF_AUTO_SET_IOMEM |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 		CONF_AUTO_SET_IO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 	ret = pcmcia_loop_config(link, nsp_cs_config_check, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 		goto cs_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 	if (pcmcia_request_irq(link, nspintr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 		goto cs_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 	ret = pcmcia_enable_device(link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 		goto cs_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 	if (free_ports) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 		if (link->resource[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 			release_region(link->resource[0]->start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 					resource_size(link->resource[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 		if (link->resource[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 			release_region(link->resource[1]->start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 					resource_size(link->resource[1]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 	/* Set port and IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 	data->BaseAddress = link->resource[0]->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 	data->NumAddress  = resource_size(link->resource[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 	data->IrqNumber   = link->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 	nsp_dbg(NSP_DEBUG_INIT, "I/O[0x%x+0x%x] IRQ %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 		data->BaseAddress, data->NumAddress, data->IrqNumber);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 	if(nsphw_init(data) == FALSE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) 		goto cs_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 	host = nsp_detect(&nsp_driver_template);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 	if (host == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 		nsp_dbg(NSP_DEBUG_INIT, "detect failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 		goto cs_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 	ret = scsi_add_host (host, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 		goto cs_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 	scsi_scan_host(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 	info->host = host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642)  cs_failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 	nsp_dbg(NSP_DEBUG_INIT, "config fail");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 	nsp_cs_release(link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 	return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) } /* nsp_cs_config */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) static void nsp_cs_release(struct pcmcia_device *link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 	scsi_info_t *info = link->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 	nsp_hw_data *data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 	if (info->host == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 		nsp_msg(KERN_DEBUG, "unexpected card release call.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 		data = (nsp_hw_data *)info->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 	nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 	/* Unlink the device chain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) 	if (info->host != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) 		scsi_remove_host(info->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 	if (resource_size(link->resource[2])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 		if (data != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 			iounmap((void *)(data->MmioAddress));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) 	pcmcia_disable_device(link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 	if (info->host != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 		scsi_host_put(info->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) } /* nsp_cs_release */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) static int nsp_cs_suspend(struct pcmcia_device *link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 	scsi_info_t *info = link->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 	nsp_hw_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 	nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 	if (info->host != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 		nsp_msg(KERN_INFO, "clear SDTR status");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 		data = (nsp_hw_data *)info->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 		nsphw_init_sync(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) 	info->stop = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) static int nsp_cs_resume(struct pcmcia_device *link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 	scsi_info_t *info = link->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 	nsp_hw_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 	nsp_dbg(NSP_DEBUG_INIT, "event: resume");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) 	info->stop = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 	if (info->host != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 		nsp_msg(KERN_INFO, "reset host and bus");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 		data = (nsp_hw_data *)info->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 		nsphw_init   (data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 		nsp_bus_reset(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) /*======================================================================*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722)  *	module entry point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723)  *====================================================================*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) static const struct pcmcia_device_id nsp_cs_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 	PCMCIA_DEVICE_PROD_ID123("IO DATA", "CBSC16       ", "1", 0x547e66dc, 0x0d63a3fd, 0x51de003a),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 	PCMCIA_DEVICE_PROD_ID123("KME    ", "SCSI-CARD-001", "1", 0x534c02bc, 0x52008408, 0x51de003a),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 	PCMCIA_DEVICE_PROD_ID123("KME    ", "SCSI-CARD-002", "1", 0x534c02bc, 0xcb09d5b2, 0x51de003a),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 	PCMCIA_DEVICE_PROD_ID123("KME    ", "SCSI-CARD-003", "1", 0x534c02bc, 0xbc0ee524, 0x51de003a),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 	PCMCIA_DEVICE_PROD_ID123("KME    ", "SCSI-CARD-004", "1", 0x534c02bc, 0x226a7087, 0x51de003a),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 	PCMCIA_DEVICE_PROD_ID123("WBT", "NinjaSCSI-3", "R1.0", 0xc7ba805f, 0xfdc7c97d, 0x6973710e),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 	PCMCIA_DEVICE_PROD_ID123("WORKBIT", "UltraNinja-16", "1", 0x28191418, 0xb70f4b09, 0x51de003a),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 	PCMCIA_DEVICE_NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) MODULE_DEVICE_TABLE(pcmcia, nsp_cs_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) static struct pcmcia_driver nsp_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 	.owner		= THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 	.name		= "nsp_cs",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 	.probe		= nsp_cs_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 	.remove		= nsp_cs_detach,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 	.id_table	= nsp_cs_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 	.suspend	= nsp_cs_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 	.resume		= nsp_cs_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) module_pcmcia_driver(nsp_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) /* end */