[PATCH 3/3] "nsp_cs" and "nsp32" update

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



 This is 3rd part of the patch.

diff --git a/drivers/scsi/pcmcia/nsp_cs.h b/drivers/scsi/pcmcia/nsp_cs.h
index b66b140..e275ec9 100644
--- a/drivers/scsi/pcmcia/nsp_cs.h
+++ b/drivers/scsi/pcmcia/nsp_cs.h
@@ -1,6 +1,6 @@
 /*=======================================================/
   Header file for nsp_cs.c
-      By: YOKOTA Hiroshi <yokota@xxxxxxxxxxxxxxxxxxxxxxx>
+      By: YOKOTA Hiroshi <yokota (at) netlab (dot) cs (dot) tsukuba (dot) ac (dot) jp>
 
     Ver.1.0 : Cut unused lines.
     Ver 0.1 : Initial version.
@@ -10,7 +10,7 @@
 
 =========================================================*/
 
-/* $Id: nsp_cs.h,v 1.19 2003/08/18 11:09:19 elca Exp $ */
+/* $Id: nsp_cs.h,v 1.45 2006/03/27 18:04:33 elca Exp $ */
 
 #ifndef  __nsp_cs__
 #define  __nsp_cs__
@@ -26,12 +26,17 @@
 /************************************
  * Some useful macros...
  */
-#define BIT(x)      (1L << (x))
+#define BIT(x)  (1UL << (x))
 
 /* SCSI initiator must be ID 7 */
 #define NSP_INITIATOR_ID  7
 
-#define NSP_SELTIMEOUT 200
+#define NSP_SELTIMEOUT_COUNT 200
+#define NSP_RW_TIMEOUT       10000 /* 10sec  */
+#define NSP_ARBIT_TIMEOUT    3000  /*  3sec  */
+#define NSP_SIGNAL_TIMEOUT   10    /* 10msec */
+
+#define EXTENDED_SDTR_LEN 3
 
 /***************************************************************************
  * register definitions
@@ -40,16 +45,24 @@
  * base register
  ========================================================================*/
 #define	IRQCONTROL	0x00  /* R */
-#  define IRQCONTROL_RESELECT_CLEAR     BIT(0)
+#  define IRQCONTROL_RESELECT_CLEAR	BIT(0)
 #  define IRQCONTROL_PHASE_CHANGE_CLEAR BIT(1)
-#  define IRQCONTROL_TIMER_CLEAR        BIT(2)
-#  define IRQCONTROL_FIFO_CLEAR         BIT(3)
-#  define IRQCONTROL_ALLMASK            0xff
-#  define IRQCONTROL_ALLCLEAR           (IRQCONTROL_RESELECT_CLEAR     | \
+#  define IRQCONTROL_TIMER_CLEAR	BIT(2)
+#  define IRQCONTROL_FIFO_CLEAR		BIT(3)
+#  define IRQCONTROL_SCSI_IRQ_MASK	BIT(4)
+#  define IRQCONTROL_EXT_IRQ_MASK	BIT(5)
+#  define IRQCONTROL_TIMER_IRQ_MASK	BIT(6)
+#  define IRQCONTROL_FIFO_IRQ_MASK	BIT(7)
+#  define IRQCONTROL_ALL_MASK		(IRQCONTROL_SCSI_IRQ_MASK  | \
+					 IRQCONTROL_EXT_IRQ_MASK   | \
+					 IRQCONTROL_TIMER_IRQ_MASK | \
+					 IRQCONTROL_FIFO_IRQ_MASK  )
+#  define IRQCONTROL_ALL_CLEAR		(IRQCONTROL_RESELECT_CLEAR     | \
 					 IRQCONTROL_PHASE_CHANGE_CLEAR | \
-					 IRQCONTROL_TIMER_CLEAR        | \
-					 IRQCONTROL_FIFO_CLEAR          )
-#  define IRQCONTROL_IRQDISABLE         0xf0
+					 IRQCONTROL_TIMER_CLEAR	       | \
+					 IRQCONTROL_FIFO_CLEAR	       )
+#  define IRQCONTROL_ALL_CLEAR_AND_MASK	 (IRQCONTROL_ALL_MASK | \
+					  IRQCONTROL_ALL_CLEAR)
 
 #define	IRQSTATUS	0x00  /* W */
 #  define IRQSTATUS_SCSI  BIT(0)
@@ -63,8 +76,8 @@
 
 #define	FIFOSTATUS	0x01 /* R */
 #  define FIFOSTATUS_CHIP_REVISION_MASK 0x0f
-#  define FIFOSTATUS_CHIP_ID_MASK       0x70
-#  define FIFOSTATUS_FULL_EMPTY         BIT(7)
+#  define FIFOSTATUS_CHIP_ID_MASK	0x70
+#  define FIFOSTATUS_FULL_EMPTY		BIT(7)
 
 #define	INDEXREG	0x02 /* R/W */
 #define	DATAREG		0x03 /* R/W */
@@ -88,62 +101,62 @@
 
 #define SCSIIRQMODE	0x15 /* R/W */
 #  define SCSI_PHASE_CHANGE_EI BIT(0)
-#  define RESELECT_EI          BIT(4)
-#  define FIFO_IRQ_EI          BIT(5)
+#  define RESELECT_EI	       BIT(4)
+#  define FIFO_IRQ_EI	       BIT(5)
 #  define SCSI_RESET_IRQ_EI    BIT(6)
 
 #define IRQPHASESENCE	0x16 /* R */
-#  define LATCHED_MSG      BIT(0)
-#  define LATCHED_IO       BIT(1)
-#  define LATCHED_CD       BIT(2)
+#  define LATCHED_MSG	   BIT(0)
+#  define LATCHED_IO	   BIT(1)
+#  define LATCHED_CD	   BIT(2)
 #  define LATCHED_BUS_FREE BIT(3)
 #  define PHASE_CHANGE_IRQ BIT(4)
-#  define RESELECT_IRQ     BIT(5)
-#  define FIFO_IRQ         BIT(6)
+#  define RESELECT_IRQ	   BIT(5)
+#  define FIFO_IRQ	   BIT(6)
 #  define SCSI_RESET_IRQ   BIT(7)
 
 #define TIMERCOUNT	0x17 /* R/W */
 
 #define SCSIBUSCTRL	0x18 /* R/W */
-#  define SCSI_SEL         BIT(0)
-#  define SCSI_RST         BIT(1)
+#  define SCSI_SEL	   BIT(0)
+#  define SCSI_RST	   BIT(1)
 #  define SCSI_DATAOUT_ENB BIT(2)
-#  define SCSI_ATN         BIT(3)
-#  define SCSI_ACK         BIT(4)
-#  define SCSI_BSY         BIT(5)
-#  define AUTODIRECTION    BIT(6)
-#  define ACKENB           BIT(7)
+#  define SCSI_ATN	   BIT(3)
+#  define SCSI_ACK	   BIT(4)
+#  define SCSI_BSY	   BIT(5)
+#  define AUTODIRECTION	   BIT(6)
+#  define ACKENB	   BIT(7)
 
 #define SCSIBUSMON	0x19 /* R */
 
 #define SETARBIT	0x1A /* W */
-#  define ARBIT_GO         BIT(0)
+#  define ARBIT_GO	   BIT(0)
 #  define ARBIT_FLAG_CLEAR BIT(1)
 
 #define ARBITSTATUS	0x1A /* R */
-/*#  define ARBIT_GO        BIT(0)*/
-#  define ARBIT_WIN        BIT(1)
-#  define ARBIT_FAIL       BIT(2)
-#  define RESELECT_FLAG    BIT(3)
+/*#  define ARBIT_GO	    BIT(0)*/
+#  define ARBIT_WIN	   BIT(1)
+#  define ARBIT_FAIL	   BIT(2)
+#  define RESELECT_FLAG	   BIT(3)
 
 #define PARITYCTRL	0x1B  /* W */
 #define PARITYSTATUS	0x1B  /* R */
 
 #define COMMANDCTRL	0x1C  /* W */
 #  define CLEAR_COMMAND_POINTER BIT(0)
-#  define AUTO_COMMAND_GO       BIT(1)
+#  define AUTO_COMMAND_GO	BIT(1)
 
 #define RESELECTID	0x1C  /* R   */
 #define COMMANDDATA	0x1D  /* R/W */
 
 #define POINTERCLR	0x1E  /*   W */
-#  define POINTER_CLEAR      BIT(0)
+#  define POINTER_CLEAR	     BIT(0)
 #  define ACK_COUNTER_CLEAR  BIT(1)
 #  define REQ_COUNTER_CLEAR  BIT(2)
 #  define HOST_COUNTER_CLEAR BIT(3)
-#  define READ_SOURCE        (BIT(4) | BIT(5))
-#    define ACK_COUNTER        (0)
-#    define REQ_COUNTER        (BIT(4))
+#  define READ_SOURCE	     (BIT(4) | BIT(5))
+#    define ACK_COUNTER	       (0)
+#    define REQ_COUNTER	       (BIT(4))
 #    define HOST_COUNTER       (BIT(5))
 
 #define TRANSFERCOUNT	0x1E  /* R   */
@@ -163,87 +176,87 @@
 #  define SYNCREG_PERIOD_MASK  0xf0
 #  define SYNCREG_PERIOD_SHIFT 4
 
-#define SCSIDATALATCH	0x22 /*   W */
+#define SCSIDATALATCH	0x22 /*	  W */
 #define SCSIDATAIN	0x22 /* R   */
 #define SCSIDATAWITHACK	0x23 /* R/W */
-#define SCAMCONTROL	0x24 /*   W */
+#define SCAMCONTROL	0x24 /*	  W */
 #define SCAMSTATUS	0x24 /* R   */
 #define SCAMDATA	0x25 /* R/W */
 
 #define OTHERCONTROL	0x26 /* R/W */
 #  define TPL_ROM_WRITE_EN BIT(0)
-#  define TPWR_OUT         BIT(1)
-#  define TPWR_SENSE       BIT(2)
-#  define RA8_CONTROL      BIT(3)
+#  define TPWR_OUT	   BIT(1)
+#  define TPWR_SENSE	   BIT(2)
+#  define RA8_CONTROL	   BIT(3)
 
 #define ACKWIDTH	0x27 /* R/W */
-#define CLRTESTPNT	0x28 /*   W */
-#define ACKCNTLD	0x29 /*   W */
-#define REQCNTLD	0x2A /*   W */
-#define HSTCNTLD	0x2B /*   W */
+#define CLRTESTPNT	0x28 /*	  W */
+#define ACKCNTLD	0x29 /*	  W */
+#define REQCNTLD	0x2A /*	  W */
+#define HSTCNTLD	0x2B /*	  W */
 #define CHECKSUM	0x2C /* R/W */
 
 /************************************************************************
  * Input status bit definitions.
  ************************************************************************/
-#define S_MESSAGE	BIT(0)    /* Message line from SCSI bus      */
-#define S_IO		BIT(1)    /* Input/Output line from SCSI bus */
-#define S_CD		BIT(2)    /* Command/Data line from SCSI bus */
-#define S_BUSY		BIT(3)    /* Busy line from SCSI bus         */
-#define S_ACK		BIT(4)    /* Acknowlege line from SCSI bus   */
-#define S_REQUEST	BIT(5)    /* Request line from SCSI bus      */
-#define S_SELECT	BIT(6)	  /*                                 */
-#define S_ATN		BIT(7)	  /*                                 */
+#define S_MESSAGE	BIT(0)	  /* Message line from SCSI bus	     */
+#define S_IO		BIT(1)	  /* Input/Output line from SCSI bus */
+#define S_CD		BIT(2)	  /* Command/Data line from SCSI bus */
+#define S_BUSY		BIT(3)	  /* Busy line from SCSI bus	     */
+#define S_ACK		BIT(4)	  /* Acknowlege line from SCSI bus   */
+#define S_REQUEST	BIT(5)	  /* Request line from SCSI bus	     */
+#define S_SELECT	BIT(6)	  /*				     */
+#define S_ATN		BIT(7)	  /*				     */
 
 /***********************************************************************
  * Useful Bus Monitor status combinations.
  ***********************************************************************/
-#define BUSMON_SEL         S_SELECT
-#define BUSMON_BSY         S_BUSY
-#define BUSMON_REQ         S_REQUEST
-#define BUSMON_IO          S_IO
-#define BUSMON_ACK         S_ACK
-#define BUSMON_BUS_FREE    0
-#define BUSMON_COMMAND     ( S_BUSY | S_CD |                    S_REQUEST )
+#define BUSMON_SEL	   S_SELECT
+#define BUSMON_BSY	   S_BUSY
+#define BUSMON_REQ	   S_REQUEST
+#define BUSMON_IO	   S_IO
+#define BUSMON_ACK	   S_ACK
+#define BUSMON_BUS_FREE	   0
+#define BUSMON_COMMAND	   ( S_BUSY | S_CD |			S_REQUEST )
 #define BUSMON_MESSAGE_IN  ( S_BUSY | S_CD | S_IO | S_MESSAGE | S_REQUEST )
-#define BUSMON_MESSAGE_OUT ( S_BUSY | S_CD |        S_MESSAGE | S_REQUEST )
-#define BUSMON_DATA_IN     ( S_BUSY |        S_IO |             S_REQUEST )
-#define BUSMON_DATA_OUT    ( S_BUSY |                           S_REQUEST )
-#define BUSMON_STATUS      ( S_BUSY | S_CD | S_IO |             S_REQUEST )
-#define BUSMON_SELECT      (                 S_IO |                        S_SELECT )
-#define BUSMON_RESELECT    (                 S_IO |                        S_SELECT )
-#define BUSMON_PHASE_MASK  (          S_CD | S_IO | S_MESSAGE |            S_SELECT )
+#define BUSMON_MESSAGE_OUT ( S_BUSY | S_CD |	    S_MESSAGE | S_REQUEST )
+#define BUSMON_DATA_IN	   ( S_BUSY |	     S_IO |		S_REQUEST )
+#define BUSMON_DATA_OUT	   ( S_BUSY |				S_REQUEST )
+#define BUSMON_STATUS	   ( S_BUSY | S_CD | S_IO |		S_REQUEST )
+#define BUSMON_SELECT	   (		     S_IO |			   S_SELECT )
+#define BUSMON_RESELECT	   (		     S_IO |			   S_SELECT )
+#define BUSMON_PHASE_MASK  (	      S_CD | S_IO | S_MESSAGE |		   S_SELECT )
 
-#define BUSPHASE_SELECT      ( BUSMON_SELECT      & BUSMON_PHASE_MASK )
-#define BUSPHASE_COMMAND     ( BUSMON_COMMAND     & BUSMON_PHASE_MASK )
+#define BUSPHASE_SELECT	     ( BUSMON_SELECT	  & BUSMON_PHASE_MASK )
+#define BUSPHASE_COMMAND     ( BUSMON_COMMAND	  & BUSMON_PHASE_MASK )
 #define BUSPHASE_MESSAGE_IN  ( BUSMON_MESSAGE_IN  & BUSMON_PHASE_MASK )
 #define BUSPHASE_MESSAGE_OUT ( BUSMON_MESSAGE_OUT & BUSMON_PHASE_MASK )
-#define BUSPHASE_DATA_IN     ( BUSMON_DATA_IN     & BUSMON_PHASE_MASK )
-#define BUSPHASE_DATA_OUT    ( BUSMON_DATA_OUT    & BUSMON_PHASE_MASK )
-#define BUSPHASE_STATUS      ( BUSMON_STATUS      & BUSMON_PHASE_MASK )
+#define BUSPHASE_DATA_IN     ( BUSMON_DATA_IN	  & BUSMON_PHASE_MASK )
+#define BUSPHASE_DATA_OUT    ( BUSMON_DATA_OUT	  & BUSMON_PHASE_MASK )
+#define BUSPHASE_STATUS	     ( BUSMON_STATUS	  & BUSMON_PHASE_MASK )
 
 /*====================================================================*/
 
 typedef struct scsi_info_t {
-	dev_link_t             link;
+	dev_link_t	       link;
 	struct Scsi_Host      *host;
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74))
-	dev_node_t             node;
+	dev_node_t	       node;
 #else
-	int	               ndev;
-	dev_node_t             node[8];
+	int		       ndev;
+	dev_node_t	       node[8];
 	struct bus_operations *bus;
 #endif
-	int                    stop;
+	int		       stop;
 } scsi_info_t;
 
 
 /* synchronous transfer negotiation data */
 typedef struct _sync_data {
-	unsigned int SyncNegotiation;
+	unsigned int  SyncNegotiation;
 #define SYNC_NOT_YET 0
-#define SYNC_OK      1
-#define SYNC_NG      2
+#define SYNC_OK	     1
+#define SYNC_NG	     2
 
 	unsigned int  SyncPeriod;
 	unsigned int  SyncOffset;
@@ -252,118 +265,135 @@ typedef struct _sync_data {
 } sync_data;
 
 typedef struct _nsp_hw_data {
-	unsigned int  BaseAddress;
-	unsigned int  NumAddress;
-	unsigned int  IrqNumber;
+	unsigned int  BaseAddress; /* I/O base address		    */
+	size_t	      NumAddress;  /* number of allocated I/O ports */
+	int	      IrqNumber;   /* allocated IRQ number	    */
 
-	unsigned long MmioAddress;
+	unsigned long MmioAddress; /* memory mapped I/O address (virtual address) */
 #define NSP_MMIO_OFFSET 0x0800
-	unsigned long MmioLength;
+	unsigned long MmioLength;  /* number of allocated MMIO addresses */
 
 	unsigned char ScsiClockDiv;
+	unsigned char TransferMode; /* Current transfer mode	    */
+	unsigned char ChipRev;
 
-	unsigned char TransferMode;
-
-	int           TimerCount;
-	int           SelectionTimeOut;
-	Scsi_Cmnd    *CurrentSC;
-	//int           CurrnetTarget;
+	int	      TimerCount;
+	int	      SelectionTimeOut;
+	struct scsi_cmnd    *CurrentSC;
+	//int		CurrnetTarget;
 
-	int           FifoCount;
+	int	      FifoCount;
 
 #define MSGBUF_SIZE 20
-	unsigned char MsgBuffer[MSGBUF_SIZE];
-	int MsgLen;
+	unsigned char MsgInBuffer[MSGBUF_SIZE]; /* SCSI message buffer */
+	size_t	      MsgInLen;
+	unsigned char MsgOutBuffer[MSGBUF_SIZE]; /* SCSI message buffer */
+	size_t	      MsgOutLen;
 
 #define N_TARGET 8
 	sync_data     Sync[N_TARGET];
 
-	char nspinfo[110];     /* description */
-	spinlock_t Lock;
-
-	scsi_info_t   *ScsiInfo; /* attach <-> detect glue */
+	char	      nspinfo[110];  /* description string     */
+	spinlock_t    Lock;
 
+	scsi_info_t  *ScsiInfo;	     /* attach <-> detect glue */
 
 #ifdef NSP_DEBUG
-	int CmdId; /* Accepted command serial number.
-		      Used for debugging.             */
+	int CmdId;	/* Accepted command serial number.
+			   Used for debugging.		   */
 #endif
 } nsp_hw_data;
 
 
 /****************************************************************************
- *
+ * functions
  */
 
 /* Card service functions */
-static void        nsp_cs_detach (struct pcmcia_device *p_dev);
-static void        nsp_cs_release(dev_link_t *link);
-static void        nsp_cs_config (dev_link_t *link);
+static int  nsp_cs_attach (struct pcmcia_device *p_dev);
+static void nsp_cs_detach (struct pcmcia_device *p_dev);
+static void nsp_cs_release(dev_link_t *link);
+static void nsp_cs_config (dev_link_t *link);
+static int  nsp_cs_suspend(struct pcmcia_device *dev);
+static int  nsp_cs_resume (struct pcmcia_device *dev);
 
 /* Linux SCSI subsystem specific functions */
-static struct Scsi_Host *nsp_detect     (struct scsi_host_template *sht);
+static struct Scsi_Host *nsp_detect	(struct scsi_host_template *sht);
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-static        int        nsp_detect_old (struct scsi_host_template *sht);
-static        int        nsp_release_old(struct Scsi_Host *shpnt);
+static	      int	 nsp_detect_old (Scsi_Host_Template *sht);
+static	      int	 nsp_release_old(struct Scsi_Host *shpnt);
 #endif
-static const  char      *nsp_info       (struct Scsi_Host *shpnt);
-static        int        nsp_proc_info  (
+static const  char	*nsp_info	(struct Scsi_Host *shpnt);
+static	      int	 nsp_proc_info	(
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
-	                                 struct Scsi_Host *host,
+					 struct Scsi_Host *host,
 #endif
-					 char   *buffer,
+					 char	*buffer,
 					 char  **start,
-					 off_t   offset,
-					 int     length,
+					 off_t	 offset,
+					 int	 length,
 #if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
-					 int     hostno,
+					 int	 hostno,
 #endif
-					 int     inout);
-static        int        nsp_queuecommand(Scsi_Cmnd *SCpnt, void (* done)(Scsi_Cmnd *SCpnt));
+					 int	 inout);
+static	      int	 nsp_queuecommand(struct scsi_cmnd *SCpnt, void (* done)(struct scsi_cmnd *SCpnt));
 
 /* Error handler */
-/*static int nsp_eh_abort       (Scsi_Cmnd *SCpnt);*/
-/*static int nsp_eh_device_reset(Scsi_Cmnd *SCpnt);*/
-static int nsp_eh_bus_reset    (Scsi_Cmnd *SCpnt);
-static int nsp_eh_host_reset   (Scsi_Cmnd *SCpnt);
+/*static int nsp_eh_abort	(struct scsi_cmnd *SCpnt);*/
+/*static int nsp_eh_device_reset(struct scsi_cmnd *SCpnt);*/
+static int nsp_eh_bus_reset    (struct scsi_cmnd *SCpnt);
+static int nsp_eh_host_reset   (struct scsi_cmnd *SCpnt);
 static int nsp_bus_reset       (nsp_hw_data *data);
 
 /* */
-static int  nsphw_init           (nsp_hw_data *data);
-static int  nsphw_start_selection(Scsi_Cmnd *SCpnt);
-static void nsp_start_timer      (Scsi_Cmnd *SCpnt, int time);
-static int  nsp_fifo_count       (Scsi_Cmnd *SCpnt);
-static void nsp_pio_read         (Scsi_Cmnd *SCpnt);
-static void nsp_pio_write        (Scsi_Cmnd *SCpnt);
-static int  nsp_nexus            (Scsi_Cmnd *SCpnt);
-static void nsp_scsi_done        (Scsi_Cmnd *SCpnt);
-static int  nsp_analyze_sdtr     (Scsi_Cmnd *SCpnt);
-static int  nsp_negate_signal    (Scsi_Cmnd *SCpnt, unsigned char mask, char *str);
-static int  nsp_expect_signal    (Scsi_Cmnd *SCpnt, unsigned char current_phase, unsigned char  mask);
-static int  nsp_xfer             (Scsi_Cmnd *SCpnt, int phase);
-static int  nsp_dataphase_bypass (Scsi_Cmnd *SCpnt);
-static int  nsp_reselected       (Scsi_Cmnd *SCpnt);
+static int  nsphw_init		 (	nsp_hw_data *data);
+static int  nsphw_start_selection(	struct scsi_cmnd *SCpnt);
+static void nsp_start_timer	 (const struct scsi_cmnd *SCpnt, int time);
+static int  nsp_fifo_count	 (const struct scsi_cmnd *SCpnt);
+static void nsp_pio_read	 (	struct scsi_cmnd *SCpnt);
+static void nsp_pio_write	 (	struct scsi_cmnd *SCpnt);
+static int  nsp_nexus		 (const struct scsi_cmnd *SCpnt);
+static void nsp_scsi_done	 (	struct scsi_cmnd *SCpnt);
+static int  nsp_analyze_sdtr	 (const struct scsi_cmnd *SCpnt);
+static int  nsp_negate_signal	 (const struct scsi_cmnd *SCpnt, unsigned char mask, char *str);
+static int  nsp_expect_signal	 (const struct scsi_cmnd *SCpnt, unsigned char current_phase, unsigned char mask);
+static int  nsp_xfer		 (const struct scsi_cmnd *SCpnt, int phase);
+static int  nsp_dataphase_bypass (	struct scsi_cmnd *SCpnt);
+static int  nsp_reselected	 (const struct scsi_cmnd *SCpnt);
 static struct Scsi_Host *nsp_detect(struct scsi_host_template *sht);
 
 /* Interrupt handler */
-//static irqreturn_t nspintr(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t nspintr(int irq, void *dev_id, struct pt_regs *regs);
 
 /* Module entry point*/
 static int  __init nsp_cs_init(void);
 static void __exit nsp_cs_exit(void);
 
+/* sysfs attributes */
+static ssize_t nsp_show_version		   (struct class_device *, char *);
+static ssize_t nsp_show_host_no		   (struct class_device *, char *);
+static ssize_t nsp_show_irq		   (struct class_device *, char *);
+static ssize_t nsp_show_io_port		   (struct class_device *, char *);
+static ssize_t nsp_show_mmio_port	   (struct class_device *, char *);
+static ssize_t nsp_show_sg_tablesize	   (struct class_device *, char *);
+static ssize_t nsp_show_burst_transfer_mode(struct class_device *, char *);
+static ssize_t nsp_show_chip_id		   (struct class_device *, char *);
+static ssize_t nsp_show_chip_revision	   (struct class_device *, char *);
+static ssize_t nsp_show_current_sc	   (struct class_device *, char *);
+static ssize_t nsp_show_status		   (struct class_device *, char *);
 
 /* Debug */
 #ifdef NSP_DEBUG
-static void show_command (Scsi_Cmnd *SCpnt);
-static void show_phase   (Scsi_Cmnd *SCpnt);
+static void show_command (const struct scsi_cmnd *SCpnt);
+static void show_phase	 (const struct scsi_cmnd *SCpnt);
 static void show_busphase(unsigned char stat);
-static void show_message (nsp_hw_data *data);
+static void show_message (const nsp_hw_data *data);
 #else
-# define show_command(ptr)   /* */
-# define show_phase(SCpnt)   /* */
-# define show_busphase(stat) /* */
-# define show_message(data)  /* */
+# define show_command(ptr)   do {} while(0)
+# define show_phase(SCpnt)   do {} while(0)
+# define show_busphase(stat) do {} while(0)
+# define show_message(data)  do {} while(0)
+# define nsp_byte_dump(ptr, offset, num) do {} while(0)
 #endif
 
 /*
@@ -371,17 +401,17 @@ static void show_message (nsp_hw_data *d
  */
 enum _scsi_phase {
 	PH_UNDETERMINED ,
-	PH_ARBSTART     ,
-	PH_SELSTART     ,
-	PH_SELECTED     ,
-	PH_COMMAND      ,
-	PH_DATA         ,
-	PH_STATUS       ,
-	PH_MSG_IN       ,
-	PH_MSG_OUT      ,
-	PH_DISCONNECT   ,
-	PH_RESELECT     ,
-	PH_ABORT        ,
+	PH_ARBSTART	,
+	PH_SELSTART	,
+	PH_SELECTED	,
+	PH_COMMAND	,
+	PH_DATA		,
+	PH_STATUS	,
+	PH_MSG_IN	,
+	PH_MSG_OUT	,
+	PH_DISCONNECT	,
+	PH_RESELECT	,
+	PH_ABORT	,
 	PH_RESET
 };
 
@@ -399,71 +429,14 @@ enum _burst_mode {
 
 
 /**************************************************************************
- * SCSI messaage
- */
-#define MSG_COMMAND_COMPLETE 0x00
-#define MSG_EXTENDED         0x01
-#define MSG_ABORT            0x06
-#define MSG_NO_OPERATION     0x08
-#define MSG_BUS_DEVICE_RESET 0x0c
-
-#define MSG_EXT_SDTR         0x01
-
-
-/**************************************************************************
  * Compatibility functions
  */
 
-/* for Kernel 2.4 */
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
-#  define scsi_register_host(template)   scsi_register_module(MODULE_SCSI_HA, template)
-#  define scsi_unregister_host(template) scsi_unregister_module(MODULE_SCSI_HA, template)
-#  define scsi_host_put(host)            scsi_unregister(host)
-
-typedef void irqreturn_t;
-#  define IRQ_NONE      /* */
-#  define IRQ_HANDLED   /* */
-#  define IRQ_RETVAL(x) /* */
-
-/* This is ad-hoc version of scsi_host_get_next() */
-static inline struct Scsi_Host *scsi_host_get_next(struct Scsi_Host *host)
-{
-	if (host == NULL) {
-		return scsi_hostlist;
-	} else {
-		return host->next;
-	}
-}
-
-/* This is ad-hoc version of scsi_host_hn_get() */
-static inline struct Scsi_Host *scsi_host_hn_get(unsigned short hostno)
-{
-	struct Scsi_Host *host;
-
-	for (host = scsi_host_get_next(NULL); host != NULL;
-	     host = scsi_host_get_next(host)) {
-		if (host->host_no == hostno) {
-			break;
-		}
-	}
-
-	return host;
-}
-
-static void cs_error(client_handle_t handle, int func, int ret)
-{
-	error_info_t err = { func, ret };
-	pcmcia_report_error(handle, &err);
-}
-
-/* scatter-gather table */
-#  define BUFFER_ADDR (SCpnt->SCp.buffer->address)
-#endif
-
 /* for Kernel 2.6 */
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
 /* scatter-gather table */
-#  define BUFFER_ADDR ((char *)((unsigned int)(SCpnt->SCp.buffer->page) + SCpnt->SCp.buffer->offset))
+# define SG_ADDRESS(buffer) ((char *) (page_address((buffer)->page) + (buffer)->offset))
+
 #endif
 
 #endif  /*__nsp_cs__*/
diff --git a/drivers/scsi/pcmcia/nsp_debug.c b/drivers/scsi/pcmcia/nsp_debug.c
index 62e5c60..0ab4443 100644
--- a/drivers/scsi/pcmcia/nsp_debug.c
+++ b/drivers/scsi/pcmcia/nsp_debug.c
@@ -1,12 +1,12 @@
 /*========================================================================
     Debug routines for nsp_cs
-      By: YOKOTA Hiroshi <yokota@xxxxxxxxxxxxxxxxxxxxxxx>
+      By: YOKOTA Hiroshi <yokota (at) netlab (dot) cs (dot) tsukuba (dot) ac (dot) jp>
 
     This software may be used and distributed according to the terms of
     the GNU General Public License.
 =========================================================================*/
 
-/* $Id: nsp_debug.c,v 1.3 2003/07/26 14:21:09 elca Exp $ */
+/* $Id: nsp_debug.c,v 1.10 2005/10/16 05:50:36 elca Exp $ */
 
 /*
  * Show the command data of a command
@@ -17,10 +17,10 @@ static const char * group_0_commands[] =
 /* 00-03 */ "Test Unit Ready", "Rezero Unit", unknown, "Request Sense",
 /* 04-07 */ "Format Unit", "Read Block Limits", unknown, "Reasssign Blocks",
 /* 08-0d */ "Read (6)", unknown, "Write (6)", "Seek (6)", unknown, unknown,
-/* 0e-12 */ unknown, "Read Reverse", "Write Filemarks", "Space", "Inquiry",  
+/* 0e-12 */ unknown, "Read Reverse", "Write Filemarks", "Space", "Inquiry",
 /* 13-16 */ unknown, "Recover Buffered Data", "Mode Select", "Reserve",
 /* 17-1b */ "Release", "Copy", "Erase", "Mode Sense", "Start/Stop Unit",
-/* 1c-1d */ "Receive Diagnostic", "Send Diagnostic", 
+/* 1c-1d */ "Receive Diagnostic", "Send Diagnostic",
 /* 1e-1f */ "Prevent/Allow Medium Removal", unknown,
 };
 
@@ -30,7 +30,7 @@ static const char *group_1_commands[] = 
 /* 23-28 */ unknown, unknown, "Read Capacity", unknown, unknown, "Read (10)",
 /* 29-2d */ unknown, "Write (10)", "Seek (10)", unknown, unknown,
 /* 2e-31 */ "Write Verify","Verify", "Search High", "Search Equal",
-/* 32-34 */ "Search Low", "Set Limits", "Prefetch or Read Position", 
+/* 32-34 */ "Search Low", "Set Limits", "Prefetch or Read Position",
 /* 35-37 */ "Synchronize Cache","Lock/Unlock Cache", "Read Defect Data",
 /* 38-3c */ "Medium Scan", "Compare","Copy Verify", "Write Buffer", "Read Buffer",
 /* 3d-3f */ "Update Block", "Read Long",  "Write Long",
@@ -38,8 +38,8 @@ static const char *group_1_commands[] = 
 
 
 static const char *group_2_commands[] = {
-/* 40-41 */ "Change Definition", "Write Same", 
-/* 42-48 */ "Read Sub-Ch(cd)", "Read TOC", "Read Header(cd)", "Play Audio(cd)", unknown, "Play Audio MSF(cd)", "Play Audio Track/Index(cd)", 
+/* 40-41 */ "Change Definition", "Write Same",
+/* 42-48 */ "Read Sub-Ch(cd)", "Read TOC", "Read Header(cd)", "Play Audio(cd)", unknown, "Play Audio MSF(cd)", "Play Audio Track/Index(cd)",
 /* 49-4f */ "Play Track Relative(10)(cd)", unknown, "Pause/Resume(cd)", "Log Select", "Log Sense", unknown, unknown,
 /* 50-55 */ unknown, unknown, unknown, unknown, unknown, "Mode Select (10)",
 /* 56-5b */ unknown, unknown, unknown, unknown, "Mode Sense (10)", unknown,
@@ -53,9 +53,9 @@ static const char *group_2_commands[] = 
 #define NOTEXT_GROUP    2
 
 static const char **commands[] = {
-    group_0_commands, group_1_commands, group_2_commands, 
-    (const char **) RESERVED_GROUP, (const char **) RESERVED_GROUP, 
-    (const char **) NOTEXT_GROUP, (const char **) VENDOR_GROUP, 
+    group_0_commands, group_1_commands, group_2_commands,
+    (const char **) RESERVED_GROUP, (const char **) RESERVED_GROUP,
+    (const char **) NOTEXT_GROUP, (const char **) VENDOR_GROUP,
     (const char **) VENDOR_GROUP
 };
 
@@ -68,13 +68,13 @@ static void print_opcodek(unsigned char 
 
 	switch ((unsigned long) table) {
 	case RESERVED_GROUP:
-		printk("%s[%02x] ", reserved, opcode); 
+		printk("%s[%02x] ", reserved, opcode);
 		break;
 	case NOTEXT_GROUP:
-		printk("%s(notext)[%02x] ", unknown, opcode); 
+		printk("%s(notext)[%02x] ", unknown, opcode);
 		break;
 	case VENDOR_GROUP:
-		printk("%s[%02x] ", vendor, opcode); 
+		printk("%s[%02x] ", vendor, opcode);
 		break;
 	default:
 		if (table[opcode & 0x1f] != unknown)
@@ -85,23 +85,23 @@ static void print_opcodek(unsigned char 
 	}
 }
 
-static void print_commandk (unsigned char *command)
+static void print_commandk (const unsigned char *command)
 {
-	int i, s;
+	int i, size;
 	printk(KERN_DEBUG);
 	print_opcodek(command[0]);
-	/*printk(KERN_DEBUG "%s ", __FUNCTION__);*/
+	/*printk(KERN_DEBUG __FUNCTION__ " ");*/
 	if ((command[0] >> 5) == 6 ||
 	    (command[0] >> 5) == 7 ) {
-		s = 12; /* vender specific */
+		size = 12; /* vender specific */
 	} else {
-		s = COMMAND_SIZE(command[0]);
+		size = COMMAND_SIZE(command[0]);
 	}
-	for ( i = 1; i < s; ++i) {
+	for ( i = 1; i < size; ++i) {
 		printk("%02x ", command[i]);
 	}
 
-	switch (s) {
+	switch (size) {
 	case 6:
 		printk("LBA=%d len=%d",
 		       (((unsigned int)command[1] & 0x0f) << 16) |
@@ -138,12 +138,12 @@ static void print_commandk (unsigned cha
 	printk("\n");
 }
 
-static void show_command(Scsi_Cmnd *SCpnt)
+static void show_command(const struct scsi_cmnd *SCpnt)
 {
 	print_commandk(SCpnt->cmnd);
 }
 
-static void show_phase(Scsi_Cmnd *SCpnt)
+static void show_phase(const struct scsi_cmnd *SCpnt)
 {
 	int i = SCpnt->SCp.phase;
 
@@ -201,13 +201,72 @@ static void show_busphase(unsigned char 
 	}
 }
 
-static void show_message(nsp_hw_data *data)
+static void show_message(const nsp_hw_data *data)
 {
 	int i;
 
-	printk(KERN_DEBUG "msg:");
-	for(i=0; i < data->MsgLen; i++) {
-		printk(" %02x", data->MsgBuffer[i]);
+	switch (data->CurrentSC->SCp.phase) {
+	case PH_MSG_IN:
+		printk(KERN_DEBUG "msgi:");
+
+		for(i=0; i < data->MsgInLen; i++) {
+			printk(" %02x", data->MsgInBuffer[i]);
+		}
+		break;
+	case PH_MSG_OUT:
+		printk(KERN_DEBUG "msgo:");
+
+		for(i=0; i < data->MsgOutLen; i++) {
+			printk(" %02x", data->MsgOutBuffer[i]);
+		}
+		break;
+	default:
+		printk("???\n");
+		return;
+		break;
+	}
+
+
+	printk("\n");
+}
+
+/*
+ * Byte dumper
+ *
+ * ptr:    start address
+ * offset: offset value for address section
+ * size:   dump size in byte
+ */
+static void nsp_byte_dump(const void *ptr, int offset, int size)
+{
+	const unsigned char *tmp = ptr;
+	int pos;
+
+	if (size == 0) {
+		return;
+	}
+
+	pos = 0;
+	while(pos < size) {
+		/* address */
+		if (pos % 16 == 0) {
+			printk(/*KERN_DEBUG*/ "%08x:", pos + offset);
+		}
+
+		/* half separator */
+		if (pos % 16 == 8) {
+			printk(" -");
+		}
+
+		printk(" %02x", tmp[pos]);
+
+		/* Don't print "\n" at last line.
+		   Because we can get one more "\n". */
+		if ((pos % 16 == 15) && (pos + 1 != size)) {
+			printk("\n");
+		}
+
+		pos ++;
 	}
 	printk("\n");
 }
diff --git a/drivers/scsi/pcmcia/nsp_io.h b/drivers/scsi/pcmcia/nsp_io.h
index 3b8746f..650f767 100644
--- a/drivers/scsi/pcmcia/nsp_io.h
+++ b/drivers/scsi/pcmcia/nsp_io.h
@@ -1,40 +1,39 @@
-/*
+/***********************************************************************
   NinjaSCSI I/O funtions 
-      By: YOKOTA Hiroshi <yokota@xxxxxxxxxxxxxxxxxxxxxxx>
+      By: YOKOTA Hiroshi <yokota (at) netlab (dot) is (dot) tsukuba (dot) ac (dot) jp>
  
   This software may be used and distributed according to the terms of
   the GNU General Public License.
+************************************************************************/
 
-  */
-
-/* $Id: nsp_io.h,v 1.3 2003/08/04 21:15:26 elca Exp $ */
+/* $Id: nsp_io.h,v 1.5 2004/07/26 15:24:21 elca Exp $ */
 
 #ifndef __NSP_IO_H__
 #define __NSP_IO_H__
 
-static inline          void nsp_write(unsigned int base,
+inline static          void nsp_write(unsigned int base,
 				      unsigned int index,
 				      unsigned char val);
-static inline unsigned char nsp_read(unsigned int base,
+inline static unsigned char nsp_read(unsigned int base,
 				     unsigned int index);
-static inline          void nsp_index_write(unsigned int BaseAddr,
+inline static          void nsp_index_write(unsigned int BaseAddr,
 					    unsigned int Register,
 					    unsigned char Value);
-static inline unsigned char nsp_index_read(unsigned int BaseAddr,
+inline static unsigned char nsp_index_read(unsigned int BaseAddr,
 					   unsigned int Register);
 
 /*******************************************************************
  * Basic IO
  */
 
-static inline void nsp_write(unsigned int  base,
+inline static void nsp_write(unsigned int  base,
 			     unsigned int  index,
 			     unsigned char val)
 {
 	outb(val, (base + index));
 }
 
-static inline unsigned char nsp_read(unsigned int base,
+inline static unsigned char nsp_read(unsigned int base,
 				     unsigned int index)
 {
 	return inb(base + index);
@@ -44,14 +43,14 @@ static inline unsigned char nsp_read(uns
 /**********************************************************************
  * Indexed IO
  */
-static inline unsigned char nsp_index_read(unsigned int BaseAddr,
+inline static unsigned char nsp_index_read(unsigned int BaseAddr,
 					   unsigned int Register)
 {
 	outb(Register, BaseAddr + INDEXREG);
 	return inb(BaseAddr + DATAREG);
 }
 
-static inline void nsp_index_write(unsigned int  BaseAddr,
+inline static void nsp_index_write(unsigned int  BaseAddr,
 				   unsigned int  Register,
 				   unsigned char Value)
 {
@@ -64,7 +63,7 @@ static inline void nsp_index_write(unsig
  */
 
 /* read 8 bit FIFO */
-static inline void nsp_multi_read_1(unsigned int   BaseAddr,
+inline static void nsp_multi_read_1(unsigned int   BaseAddr,
 				    unsigned int   Register,
 				    void          *buf,
 				    unsigned long  count)
@@ -72,7 +71,7 @@ static inline void nsp_multi_read_1(unsi
 	insb(BaseAddr + Register, buf, count);
 }
 
-static inline void nsp_fifo8_read(unsigned int   base,
+inline static void nsp_fifo8_read(unsigned int   base,
 				  void          *buf,
 				  unsigned long  count)
 {
@@ -83,7 +82,7 @@ static inline void nsp_fifo8_read(unsign
 /*--------------------------------------------------------------*/
 
 /* read 16 bit FIFO */
-static inline void nsp_multi_read_2(unsigned int   BaseAddr,
+inline static void nsp_multi_read_2(unsigned int   BaseAddr,
 				    unsigned int   Register,
 				    void          *buf,
 				    unsigned long  count)
@@ -91,7 +90,7 @@ static inline void nsp_multi_read_2(unsi
 	insw(BaseAddr + Register, buf, count);
 }
 
-static inline void nsp_fifo16_read(unsigned int   base,
+inline static void nsp_fifo16_read(unsigned int   base,
 				   void          *buf,
 				   unsigned long  count)
 {
@@ -102,7 +101,7 @@ static inline void nsp_fifo16_read(unsig
 /*--------------------------------------------------------------*/
 
 /* read 32bit FIFO */
-static inline void nsp_multi_read_4(unsigned int   BaseAddr,
+inline static void nsp_multi_read_4(unsigned int   BaseAddr,
 				    unsigned int   Register,
 				    void          *buf,
 				    unsigned long  count)
@@ -110,7 +109,7 @@ static inline void nsp_multi_read_4(unsi
 	insl(BaseAddr + Register, buf, count);
 }
 
-static inline void nsp_fifo32_read(unsigned int   base,
+inline static void nsp_fifo32_read(unsigned int   base,
 				   void          *buf,
 				   unsigned long  count)
 {
@@ -121,7 +120,7 @@ static inline void nsp_fifo32_read(unsig
 /*----------------------------------------------------------*/
 
 /* write 8bit FIFO */
-static inline void nsp_multi_write_1(unsigned int   BaseAddr,
+inline static void nsp_multi_write_1(unsigned int   BaseAddr,
 				     unsigned int   Register,
 				     void          *buf,
 				     unsigned long  count)
@@ -129,7 +128,7 @@ static inline void nsp_multi_write_1(uns
 	outsb(BaseAddr + Register, buf, count);
 }
 
-static inline void nsp_fifo8_write(unsigned int   base,
+inline static void nsp_fifo8_write(unsigned int   base,
 				   void          *buf,
 				   unsigned long  count)
 {
@@ -139,7 +138,7 @@ static inline void nsp_fifo8_write(unsig
 /*---------------------------------------------------------*/
 
 /* write 16bit FIFO */
-static inline void nsp_multi_write_2(unsigned int   BaseAddr,
+inline static void nsp_multi_write_2(unsigned int   BaseAddr,
 				     unsigned int   Register,
 				     void          *buf,
 				     unsigned long  count)
@@ -147,7 +146,7 @@ static inline void nsp_multi_write_2(uns
 	outsw(BaseAddr + Register, buf, count);
 }
 
-static inline void nsp_fifo16_write(unsigned int   base,
+inline static void nsp_fifo16_write(unsigned int   base,
 				    void          *buf,
 				    unsigned long  count)
 {
@@ -157,7 +156,7 @@ static inline void nsp_fifo16_write(unsi
 /*---------------------------------------------------------*/
 
 /* write 32bit FIFO */
-static inline void nsp_multi_write_4(unsigned int   BaseAddr,
+inline static void nsp_multi_write_4(unsigned int   BaseAddr,
 				     unsigned int   Register,
 				     void          *buf,
 				     unsigned long  count)
@@ -165,7 +164,7 @@ static inline void nsp_multi_write_4(uns
 	outsl(BaseAddr + Register, buf, count);
 }
 
-static inline void nsp_fifo32_write(unsigned int   base,
+inline static void nsp_fifo32_write(unsigned int   base,
 				    void          *buf,
 				    unsigned long  count)
 {
@@ -175,7 +174,7 @@ static inline void nsp_fifo32_write(unsi
 
 /*====================================================================*/
 
-static inline void nsp_mmio_write(unsigned long base,
+inline static void nsp_mmio_write(unsigned long base,
 				  unsigned int  index,
 				  unsigned char val)
 {
@@ -184,7 +183,7 @@ static inline void nsp_mmio_write(unsign
 	writeb(val, ptr);
 }
 
-static inline unsigned char nsp_mmio_read(unsigned long base,
+inline static unsigned char nsp_mmio_read(unsigned long base,
 					  unsigned int  index)
 {
 	unsigned char *ptr = (unsigned char *)(base + NSP_MMIO_OFFSET + index);
@@ -194,7 +193,7 @@ static inline unsigned char nsp_mmio_rea
 
 /*-----------*/
 
-static inline unsigned char nsp_mmio_index_read(unsigned long base,
+inline static unsigned char nsp_mmio_index_read(unsigned long base,
 						unsigned int  reg)
 {
 	unsigned char *index_ptr = (unsigned char *)(base + NSP_MMIO_OFFSET + INDEXREG);
@@ -204,7 +203,7 @@ static inline unsigned char nsp_mmio_ind
 	return readb(data_ptr);
 }
 
-static inline void nsp_mmio_index_write(unsigned long base,
+inline static void nsp_mmio_index_write(unsigned long base,
 					unsigned int  reg,
 					unsigned char val)
 {
@@ -216,7 +215,7 @@ static inline void nsp_mmio_index_write(
 }
 
 /* read 32bit FIFO */
-static inline void nsp_mmio_multi_read_4(unsigned long  base,
+inline static void nsp_mmio_multi_read_4(unsigned long  base,
 					 unsigned int   Register,
 					 void          *buf,
 					 unsigned long  count)
@@ -234,7 +233,7 @@ static inline void nsp_mmio_multi_read_4
 	}
 }
 
-static inline void nsp_mmio_fifo32_read(unsigned int   base,
+inline static void nsp_mmio_fifo32_read(unsigned int   base,
 					void          *buf,
 					unsigned long  count)
 {
@@ -242,7 +241,7 @@ static inline void nsp_mmio_fifo32_read(
 	nsp_mmio_multi_read_4(base, FIFODATA, buf, count);
 }
 
-static inline void nsp_mmio_multi_write_4(unsigned long  base,
+inline static void nsp_mmio_multi_write_4(unsigned long  base,
 					  unsigned int   Register,
 					  void          *buf,
 					  unsigned long  count)
@@ -260,7 +259,7 @@ static inline void nsp_mmio_multi_write_
 	}
 }
 
-static inline void nsp_mmio_fifo32_write(unsigned int   base,
+inline static void nsp_mmio_fifo32_write(unsigned int   base,
 					 void          *buf,
 					 unsigned long  count)
 {
diff --git a/drivers/scsi/pcmcia/nsp_message.c b/drivers/scsi/pcmcia/nsp_message.c
index d705773..8d073d9 100644
--- a/drivers/scsi/pcmcia/nsp_message.c
+++ b/drivers/scsi/pcmcia/nsp_message.c
@@ -1,31 +1,138 @@
 /*==========================================================================
   NinjaSCSI-3 message handler
-      By: YOKOTA Hiroshi <yokota@xxxxxxxxxxxxxxxxxxxxxxx>
+      By: YOKOTA Hiroshi <yokota<at>netlab.cs.tsukuba.ac.jp>
 
    This software may be used and distributed according to the terms of
    the GNU General Public License.
  */
 
-/* $Id: nsp_message.c,v 1.6 2003/07/26 14:21:09 elca Exp $ */
+/* $Id: nsp_message.c,v 1.14 2005/10/16 05:50:36 elca Exp $ */
 
-static void nsp_message_in(Scsi_Cmnd *SCpnt)
+
+/*
+ * IDENTIFY Message
+ */
+static void nsp_build_identify(const Scsi_Cmnd *SCpnt)
+{
+	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
+	int	     pos  = data->MsgOutLen;
+
+	data->MsgOutBuffer[pos] = IDENTIFY(TRUE, SCpnt->device->lun); pos++;
+	data->MsgOutLen = pos;
+}
+
+/*
+ * SDTR Message Routine
+ */
+static void nsp_build_sdtr(const Scsi_Cmnd *SCpnt,
+				  unsigned char period,
+				  unsigned char offset)
+{
+	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
+	int	     pos  = data->MsgOutLen;
+
+	data->MsgOutBuffer[pos] = EXTENDED_MESSAGE;  pos++;
+	data->MsgOutBuffer[pos] = EXTENDED_SDTR_LEN; pos++;
+	data->MsgOutBuffer[pos] = EXTENDED_SDTR;     pos++;
+	data->MsgOutBuffer[pos] = period;	     pos++;
+	data->MsgOutBuffer[pos] = offset;	     pos++;
+
+	data->MsgOutLen = pos;
+}
+
+/*
+ * No Operation Message
+ */
+static void nsp_build_nop(const Scsi_Cmnd *SCpnt)
 {
-	unsigned int  base = SCpnt->device->host->io_port;
+	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
+	int	     pos  = data->MsgOutLen;
+
+	/*
+	if (pos != 0) {
+		nsp_msg(KERN_WARNING,
+			"Some messages are already contained!");
+		return;
+	}
+	*/
+
+	data->MsgOutBuffer[pos] = NOP; pos++;
+	data->MsgOutLen = pos;
+}
+
+
+/*
+ * transfer SCSI message
+ */
+static int nsp_xfer(const Scsi_Cmnd *SCpnt, int phase)
+{
+	const unsigned int base = SCpnt->device->host->io_port;
+	nsp_hw_data   *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
+	unsigned char *buf;
+	int	       ptr, ret;
+	size_t	       len;
+
+	//nsp_dbg(NSP_DEBUG_DATA_IO, "in");
+
+	if (phase & BUSMON_IO ||
+	    SCpnt->SCp.phase != PH_MSG_OUT) {
+		nsp_msg(KERN_DEBUG, "xfer: read");
+		ret = 0;
+		goto err;
+	} else {
+		len = min(sizeof(data->MsgOutBuffer), data->MsgOutLen);
+		buf = data->MsgOutBuffer;
+	}
+
+	for (ptr = 0; len > 0; len--, ptr++) {
+		int sig;
+
+		sig = nsp_expect_signal(SCpnt, phase, BUSMON_REQ);
+		if (sig <= 0) {
+			nsp_msg(KERN_DEBUG, "xfer quit");
+			ret = 0;
+			goto out;
+		}
+
+		/* if last byte, negate ATN */
+		if (len == 1 && SCpnt->SCp.phase == PH_MSG_OUT) {
+			nsp_index_write(base, SCSIBUSCTRL, AUTODIRECTION | ACKENB);
+			ndelay(90); /* 90ns */
+		}
+
+		/* write message */
+		nsp_dbg(NSP_DEBUG_DATA_IO, "write msg");
+		nsp_index_write(base, SCSIDATAWITHACK, buf[ptr]);
+
+		nsp_negate_signal(SCpnt, BUSMON_ACK, "xfer<ack>");
+	}
+	ret = 1;
+
+ out:
+	data->MsgOutLen = len;
+
+ err:
+	return ret;
+}
+
+static void nsp_message_in(const Scsi_Cmnd *SCpnt)
+{
+	const unsigned int base = SCpnt->device->host->io_port;
 	nsp_hw_data  *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
-	unsigned char data_reg, control_reg;
-	int           ret, len;
+	int	      sig = 1;
+	size_t	      len = 0;
 
 	/*
 	 * XXX: NSP QUIRK
 	 * NSP invoke interrupts only in the case of scsi phase changes,
-	 * therefore we should poll the scsi phase here to catch 
+	 * therefore we should poll the scsi phase here to catch
 	 * the next "msg in" if exists (no scsi phase changes).
 	 */
-	ret = 16;
-	len = 0;
 
 	nsp_dbg(NSP_DEBUG_MSGINOCCUR, "msgin loop");
 	do {
+		unsigned char data_reg, control_reg;
+
 		/* read data */
 		data_reg = nsp_index_read(base, SCSIDATAIN);
 
@@ -35,7 +142,7 @@ static void nsp_message_in(Scsi_Cmnd *SC
 		nsp_index_write(base, SCSIBUSCTRL, control_reg);
 		nsp_negate_signal(SCpnt, BUSMON_REQ, "msgin<REQ>");
 
-		data->MsgBuffer[len] = data_reg; len++;
+		data->MsgInBuffer[len] = data_reg; len++;
 
 		/* deassert ACK */
 		control_reg =  nsp_index_read(base, SCSIBUSCTRL);
@@ -43,36 +150,41 @@ static void nsp_message_in(Scsi_Cmnd *SC
 		nsp_index_write(base, SCSIBUSCTRL, control_reg);
 
 		/* catch a next signal */
-		ret = nsp_expect_signal(SCpnt, BUSPHASE_MESSAGE_IN, BUSMON_REQ);
-	} while (ret > 0 && MSGBUF_SIZE > len);
-
-	data->MsgLen = len;
+		sig = nsp_expect_signal(SCpnt, BUSPHASE_MESSAGE_IN, BUSMON_REQ);
+	} while (sig > 0 && sizeof(data->MsgInBuffer) > len);
 
+	data->MsgInLen = len;
 }
 
-static void nsp_message_out(Scsi_Cmnd *SCpnt)
+static void nsp_message_out(const Scsi_Cmnd *SCpnt)
 {
-	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
-	int ret = 1;
-	int len = data->MsgLen;
+	const nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
+	int sig = 1;
+	int tmp;
 
 	/*
 	 * XXX: NSP QUIRK
 	 * NSP invoke interrupts only in the case of scsi phase changes,
-	 * therefore we should poll the scsi phase here to catch 
+	 * therefore we should poll the scsi phase here to catch
 	 * the next "msg out" if exists (no scsi phase changes).
 	 */
 
+	if (data->MsgOutLen <= 0) {
+		nsp_dbg(NSP_DEBUG_MSGOUTOCCUR, "add nop");
+		nsp_build_nop(SCpnt);
+	}
+
 	nsp_dbg(NSP_DEBUG_MSGOUTOCCUR, "msgout loop");
 	do {
-		if (nsp_xfer(SCpnt, BUSPHASE_MESSAGE_OUT)) {
-			nsp_msg(KERN_DEBUG, "msgout: xfer short");
+		tmp = nsp_xfer(SCpnt, BUSPHASE_MESSAGE_OUT);
+
+		if (tmp == 0) {
+			nsp_msg(KERN_DEBUG, "msgout: xfer short, tmp=%d, len=%d", tmp, data->MsgOutLen);
 		}
 
 		/* catch a next signal */
-		ret = nsp_expect_signal(SCpnt, BUSPHASE_MESSAGE_OUT, BUSMON_REQ);
-	} while (ret > 0 && len-- > 0);
-
+		sig = nsp_expect_signal(SCpnt, BUSPHASE_MESSAGE_OUT, BUSMON_REQ);
+	} while (sig > 0 && data->MsgOutLen > 0);
 }
 
 /* end */
-- 
1.2.6

-
: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux