From b2aaee33fbb354a2f08121aa1c1be55841102761 Mon Sep 17 00:00:00 2001 From: Markus Lidel Date: Thu, 23 Jun 2005 22:02:19 -0700 Subject: [PATCH] I2O: Adaptec specific SG_IO access, firmware access through sysfs and 2400A workaround Changes: - Provide SG_IO access to BLOCK and EXECUTIVE class on Adaptec controllers - Use PRIVATE messages in SCSI-OSM because on some controllers normal SCSI class commands like READ or READ CAPACITY cause errors - Use new DMA and SG list creation function - Added workaround to limit sectors per request for Adaptec 2400A controllers Signed-off-by: Markus Lidel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/i2o-dev.h | 22 ++++++++++++++++++++++ include/linux/i2o.h | 37 ++++++++++++++++++++++++++----------- include/scsi/sg_request.h | 26 ++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 11 deletions(-) create mode 100644 include/scsi/sg_request.h (limited to 'include') diff --git a/include/linux/i2o-dev.h b/include/linux/i2o-dev.h index 90c984ecd52..d4a08d29e36 100644 --- a/include/linux/i2o-dev.h +++ b/include/linux/i2o-dev.h @@ -32,6 +32,13 @@ typedef unsigned int u32; #endif /* __KERNEL__ */ +/* + * Software module types + */ +#define I2O_SOFTWARE_MODULE_IRTOS 0x11 +#define I2O_SOFTWARE_MODULE_IOP_PRIVATE 0x22 +#define I2O_SOFTWARE_MODULE_IOP_CONFIG 0x23 + /* * Vendors */ @@ -125,6 +132,10 @@ struct i2o_evt_get { int lost; }; +typedef struct i2o_sg_io_hdr { + unsigned int flags; /* see I2O_DPT_SG_IO_FLAGS */ +} i2o_sg_io_hdr_t; + /************************************************************************** * HRT related constants and structures **************************************************************************/ @@ -403,4 +414,15 @@ typedef struct _i2o_status_block { #define ADAPTER_STATE_FAILED 0x10 #define ADAPTER_STATE_FAULTED 0x11 + +/* + * DPT / Adaptec specific values for i2o_sg_io_hdr flags. + */ +#define I2O_DPT_SG_FLAG_INTERPRET 0x00010000 +#define I2O_DPT_SG_FLAG_PHYSICAL 0x00020000 + +#define I2O_DPT_FLASH_FRAG_SIZE 0x10000 +#define I2O_DPT_FLASH_READ 0x0101 +#define I2O_DPT_FLASH_WRITE 0x0102 + #endif /* _I2O_DEV_H */ diff --git a/include/linux/i2o.h b/include/linux/i2o.h index 497ea574f96..2039a87c2b9 100644 --- a/include/linux/i2o.h +++ b/include/linux/i2o.h @@ -147,10 +147,13 @@ struct i2o_controller { struct pci_dev *pdev; /* PCI device */ - unsigned int short_req:1; /* use small block sizes */ - unsigned int no_quiesce:1; /* dont quiesce before reset */ - unsigned int raptor:1; /* split bar */ unsigned int promise:1; /* Promise controller */ + unsigned int adaptec:1; /* DPT / Adaptec controller */ + unsigned int raptor:1; /* split bar */ + unsigned int no_quiesce:1; /* dont quiesce before reset */ + unsigned int short_req:1; /* use small block sizes */ + unsigned int limit_sectors:1; /* limit number of sectors / request */ + unsigned int pae_support:1; /* controller has 64-bit SGL support */ struct list_head devices; /* list of I2O devices */ struct list_head list; /* Controller list */ @@ -746,7 +749,21 @@ static inline struct i2o_message __iomem *i2o_msg_in_to_virt(struct i2o_controll static inline int i2o_dma_alloc(struct device *dev, struct i2o_dma *addr, size_t len, unsigned int gfp_mask) { + struct pci_dev *pdev = to_pci_dev(dev); + int dma_64 = 0; + + if ((sizeof(dma_addr_t) > 4) && (pdev->dma_mask == DMA_64BIT_MASK)) { + dma_64 = 1; + if(pci_set_dma_mask(pdev, DMA_32BIT_MASK)) + return -ENOMEM; + } + addr->virt = dma_alloc_coherent(dev, len, &addr->phys, gfp_mask); + + if ((sizeof(dma_addr_t) > 4) && dma_64) + if(pci_set_dma_mask(pdev, DMA_64BIT_MASK)) + printk(KERN_WARNING "i2o: unable to set 64-bit DMA"); + if (!addr->virt) return -ENOMEM; @@ -946,7 +963,7 @@ extern void i2o_debug_state(struct i2o_controller *c); #define I2O_CMD_BLOCK_MEJECT 0x43 #define I2O_CMD_BLOCK_POWER 0x70 -#define I2O_PRIVATE_MSG 0xFF +#define I2O_CMD_PRIVATE 0xFF /* Command status values */ @@ -1095,9 +1112,9 @@ extern void i2o_debug_state(struct i2o_controller *c); #define SGL_OFFSET_8 (0x0080 | I2OVERSION) #define SGL_OFFSET_9 (0x0090 | I2OVERSION) #define SGL_OFFSET_10 (0x00A0 | I2OVERSION) - -#define TRL_OFFSET_5 (0x0050 | I2OVERSION) -#define TRL_OFFSET_6 (0x0060 | I2OVERSION) +#define SGL_OFFSET_11 (0x00B0 | I2OVERSION) +#define SGL_OFFSET_12 (0x00C0 | I2OVERSION) +#define SGL_OFFSET(x) (((x)<<4) | I2OVERSION) /* Transaction Reply Lists (TRL) Control Word structure */ #define TRL_SINGLE_FIXED_LENGTH 0x00 @@ -1130,7 +1147,6 @@ extern void i2o_debug_state(struct i2o_controller *c); #define HOST_TID 1 #define MSG_FRAME_SIZE 128 /* i2o_scsi assumes >= 32 */ -#define REPLY_FRAME_SIZE 17 #define SG_TABLESIZE 30 #define NMBR_MSG_FRAMES 128 @@ -1155,11 +1171,10 @@ extern void i2o_debug_state(struct i2o_controller *c); #define I2O_HRT_GET_TRIES 3 #define I2O_LCT_GET_TRIES 3 -/* request queue sizes */ +/* defines for max_sectors and max_phys_segments */ #define I2O_MAX_SECTORS 1024 +#define I2O_MAX_SECTORS_LIMITED 256 #define I2O_MAX_PHYS_SEGMENTS MAX_PHYS_SEGMENTS -#define I2O_REQ_MEMPOOL_SIZE 32 - #endif /* __KERNEL__ */ #endif /* _I2O_H */ diff --git a/include/scsi/sg_request.h b/include/scsi/sg_request.h new file mode 100644 index 00000000000..57ff525bdd3 --- /dev/null +++ b/include/scsi/sg_request.h @@ -0,0 +1,26 @@ +typedef struct scsi_request Scsi_Request; + +static Scsi_Request *dummy_cmdp; /* only used for sizeof */ + +typedef struct sg_scatter_hold { /* holding area for scsi scatter gather info */ + unsigned short k_use_sg; /* Count of kernel scatter-gather pieces */ + unsigned short sglist_len; /* size of malloc'd scatter-gather list ++ */ + unsigned bufflen; /* Size of (aggregate) data buffer */ + unsigned b_malloc_len; /* actual len malloc'ed in buffer */ + void *buffer; /* Data buffer or scatter list (k_use_sg>0) */ + char dio_in_use; /* 0->indirect IO (or mmap), 1->dio */ + unsigned char cmd_opcode; /* first byte of command */ +} Sg_scatter_hold; + +typedef struct sg_request { /* SG_MAX_QUEUE requests outstanding per file */ + Scsi_Request *my_cmdp; /* != 0 when request with lower levels */ + struct sg_request *nextrp; /* NULL -> tail request (slist) */ + struct sg_fd *parentfp; /* NULL -> not in use */ + Sg_scatter_hold data; /* hold buffer, perhaps scatter list */ + sg_io_hdr_t header; /* scsi command+info, see */ + unsigned char sense_b[sizeof (dummy_cmdp->sr_sense_buffer)]; + char res_used; /* 1 -> using reserve buffer, 0 -> not ... */ + char orphan; /* 1 -> drop on sight, 0 -> normal */ + char sg_io_owned; /* 1 -> packet belongs to SG_IO */ + volatile char done; /* 0->before bh, 1->before read, 2->read */ +} Sg_request; -- cgit v1.2.3