diff --git a/debian/patches/features/all/drivers/cciss-support-for-gt-2TB-volumes.patch b/debian/patches/features/all/drivers/cciss-support-for-gt-2TB-volumes.patch deleted file mode 100644 index 659970932..000000000 --- a/debian/patches/features/all/drivers/cciss-support-for-gt-2TB-volumes.patch +++ /dev/null @@ -1,500 +0,0 @@ -From: Mike Miller (OS Dev) -Date: Sun, 1 Oct 2006 06:27:23 +0000 (-0700) -Subject: [PATCH] cciss: support for >2TB logical volumes -X-Git-Tag: v2.6.19-rc1 -X-Git-Url: http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=00988a3514bbc0cce781c067cf52559741d88b80 - -[PATCH] cciss: support for >2TB logical volumes - -Add support for logical volumes >2TB. All SAS/SATA controllers support -large volumes. - -Signed-off-by: Mike Miller -Cc: Jens Axboe -Signed-off-by: Andrew Morton -Signed-off-by: Linus Torvalds ---- - ---- a/drivers/block/cciss.c -+++ b/drivers/block/cciss.c -@@ -144,13 +144,13 @@ static int rebuild_lun_table(ctlr_info_t - static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, - int clear_all); - --static void cciss_read_capacity(int ctlr, int logvol, ReadCapdata_struct *buf, -- int withirq, unsigned int *total_size, -- unsigned int *block_size); --static void cciss_geometry_inquiry(int ctlr, int logvol, int withirq, -- unsigned int total_size, -- unsigned int block_size, -- InquiryData_struct *inq_buff, -+static void cciss_read_capacity(int ctlr, int logvol, int withirq, -+ sector_t *total_size, unsigned int *block_size); -+static void cciss_read_capacity_16(int ctlr, int logvol, int withirq, -+ sector_t *total_size, unsigned int *block_size); -+static void cciss_geometry_inquiry(int ctlr, int logvol, -+ int withirq, sector_t total_size, -+ unsigned int block_size, InquiryData_struct *inq_buff, - drive_info_struct *drv); - static void cciss_getgeometry(int cntl_num); - static void __devinit cciss_interrupt_mode(ctlr_info_t *, struct pci_dev *, -@@ -1325,10 +1325,9 @@ static void cciss_update_drive_info(int - { - ctlr_info_t *h = hba[ctlr]; - struct gendisk *disk; -- ReadCapdata_struct *size_buff = NULL; - InquiryData_struct *inq_buff = NULL; - unsigned int block_size; -- unsigned int total_size; -+ sector_t total_size; - unsigned long flags = 0; - int ret = 0; - -@@ -1347,15 +1346,25 @@ static void cciss_update_drive_info(int - return; - - /* Get information about the disk and modify the driver structure */ -- size_buff = kmalloc(sizeof(ReadCapdata_struct), GFP_KERNEL); -- if (size_buff == NULL) -- goto mem_msg; - inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); - if (inq_buff == NULL) - goto mem_msg; - -- cciss_read_capacity(ctlr, drv_index, size_buff, 1, -+ cciss_read_capacity(ctlr, drv_index, 1, - &total_size, &block_size); -+ -+ /* total size = last LBA + 1 */ -+ /* FFFFFFFF + 1 = 0, cannot have a logical volume of size 0 */ -+ /* so we assume this volume this must be >2TB in size */ -+ if (total_size == (__u32) 0) { -+ cciss_read_capacity_16(ctlr, drv_index, 1, -+ &total_size, &block_size); -+ h->cciss_read = CCISS_READ_16; -+ h->cciss_write = CCISS_WRITE_16; -+ } else { -+ h->cciss_read = CCISS_READ_10; -+ h->cciss_write = CCISS_WRITE_10; -+ } - cciss_geometry_inquiry(ctlr, drv_index, 1, total_size, block_size, - inq_buff, &h->drv[drv_index]); - -@@ -1391,7 +1400,6 @@ static void cciss_update_drive_info(int - } - - freeret: -- kfree(size_buff); - kfree(inq_buff); - return; - mem_msg: -@@ -1716,6 +1724,22 @@ static int fill_cmd(CommandList_struct * - c->Request.Timeout = 0; - c->Request.CDB[0] = cmd; - break; -+ case CCISS_READ_CAPACITY_16: -+ c->Header.LUN.LogDev.VolId = h->drv[log_unit].LunID; -+ c->Header.LUN.LogDev.Mode = 1; -+ c->Request.CDBLen = 16; -+ c->Request.Type.Attribute = ATTR_SIMPLE; -+ c->Request.Type.Direction = XFER_READ; -+ c->Request.Timeout = 0; -+ c->Request.CDB[0] = cmd; -+ c->Request.CDB[1] = 0x10; -+ c->Request.CDB[10] = (size >> 24) & 0xFF; -+ c->Request.CDB[11] = (size >> 16) & 0xFF; -+ c->Request.CDB[12] = (size >> 8) & 0xFF; -+ c->Request.CDB[13] = size & 0xFF; -+ c->Request.Timeout = 0; -+ c->Request.CDB[0] = cmd; -+ break; - case CCISS_CACHE_FLUSH: - c->Request.CDBLen = 12; - c->Request.Type.Attribute = ATTR_SIMPLE; -@@ -1749,6 +1773,7 @@ static int fill_cmd(CommandList_struct * - memset(&c->Request.CDB[0], 0, sizeof(c->Request.CDB)); - c->Request.CDB[0] = cmd; /* reset */ - c->Request.CDB[1] = 0x04; /* reset a LUN */ -+ break; - case 3: /* No-Op message */ - c->Request.CDBLen = 1; - c->Request.Type.Attribute = ATTR_SIMPLE; -@@ -1892,12 +1917,15 @@ static int sendcmd_withirq(__u8 cmd, - } - - static void cciss_geometry_inquiry(int ctlr, int logvol, -- int withirq, unsigned int total_size, -+ int withirq, sector_t total_size, - unsigned int block_size, - InquiryData_struct *inq_buff, - drive_info_struct *drv) - { - int return_code; -+ unsigned long t; -+ unsigned long rem; -+ - memset(inq_buff, 0, sizeof(InquiryData_struct)); - if (withirq) - return_code = sendcmd_withirq(CISS_INQUIRY, ctlr, -@@ -1916,10 +1944,10 @@ static void cciss_geometry_inquiry(int c - drv->nr_blocks = total_size; - drv->heads = 255; - drv->sectors = 32; // Sectors per track -- drv->cylinders = total_size / 255 / 32; -+ t = drv->heads * drv->sectors; -+ drv->cylinders = total_size; -+ rem = do_div(drv->cylinders, t); - } else { -- unsigned int t; -- - drv->block_size = block_size; - drv->nr_blocks = total_size; - drv->heads = inq_buff->data_byte[6]; -@@ -1929,7 +1957,8 @@ static void cciss_geometry_inquiry(int c - drv->raid_level = inq_buff->data_byte[8]; - t = drv->heads * drv->sectors; - if (t > 1) { -- drv->cylinders = total_size / t; -+ drv->cylinders = total_size; -+ rem = do_div(drv->cylinders, t); - } - } - } else { /* Get geometry failed */ -@@ -1940,31 +1969,72 @@ static void cciss_geometry_inquiry(int c - } - - static void --cciss_read_capacity(int ctlr, int logvol, ReadCapdata_struct *buf, -- int withirq, unsigned int *total_size, -+cciss_read_capacity(int ctlr, int logvol, int withirq, sector_t *total_size, - unsigned int *block_size) - { -+ ReadCapdata_struct *buf; - int return_code; -- memset(buf, 0, sizeof(*buf)); -+ buf = kmalloc(sizeof(ReadCapdata_struct), GFP_KERNEL); -+ if (buf == NULL) { -+ printk(KERN_WARNING "cciss: out of memory\n"); -+ return; -+ } -+ memset(buf, 0, sizeof(ReadCapdata_struct)); - if (withirq) - return_code = sendcmd_withirq(CCISS_READ_CAPACITY, -- ctlr, buf, sizeof(*buf), 1, -- logvol, 0, TYPE_CMD); -+ ctlr, buf, sizeof(ReadCapdata_struct), -+ 1, logvol, 0, TYPE_CMD); - else - return_code = sendcmd(CCISS_READ_CAPACITY, -- ctlr, buf, sizeof(*buf), 1, logvol, 0, -- NULL, TYPE_CMD); -+ ctlr, buf, sizeof(ReadCapdata_struct), -+ 1, logvol, 0, NULL, TYPE_CMD); -+ if (return_code == IO_OK) { -+ *total_size = be32_to_cpu(*(__u32 *) buf->total_size)+1; -+ *block_size = be32_to_cpu(*(__u32 *) buf->block_size); -+ } else { /* read capacity command failed */ -+ printk(KERN_WARNING "cciss: read capacity failed\n"); -+ *total_size = 0; -+ *block_size = BLOCK_SIZE; -+ } -+ if (*total_size != (__u32) 0) -+ printk(KERN_INFO " blocks= %lld block_size= %d\n", -+ *total_size, *block_size); -+ kfree(buf); -+ return; -+} -+ -+static void -+cciss_read_capacity_16(int ctlr, int logvol, int withirq, sector_t *total_size, unsigned int *block_size) -+{ -+ ReadCapdata_struct_16 *buf; -+ int return_code; -+ buf = kmalloc(sizeof(ReadCapdata_struct_16), GFP_KERNEL); -+ if (buf == NULL) { -+ printk(KERN_WARNING "cciss: out of memory\n"); -+ return; -+ } -+ memset(buf, 0, sizeof(ReadCapdata_struct_16)); -+ if (withirq) { -+ return_code = sendcmd_withirq(CCISS_READ_CAPACITY_16, -+ ctlr, buf, sizeof(ReadCapdata_struct_16), -+ 1, logvol, 0, TYPE_CMD); -+ } -+ else { -+ return_code = sendcmd(CCISS_READ_CAPACITY_16, -+ ctlr, buf, sizeof(ReadCapdata_struct_16), -+ 1, logvol, 0, NULL, TYPE_CMD); -+ } - if (return_code == IO_OK) { -- *total_size = -- be32_to_cpu(*((__be32 *) & buf->total_size[0])) + 1; -- *block_size = be32_to_cpu(*((__be32 *) & buf->block_size[0])); -+ *total_size = be64_to_cpu(*(__u64 *) buf->total_size)+1; -+ *block_size = be32_to_cpu(*(__u32 *) buf->block_size); - } else { /* read capacity command failed */ - printk(KERN_WARNING "cciss: read capacity failed\n"); - *total_size = 0; - *block_size = BLOCK_SIZE; - } -- printk(KERN_INFO " blocks= %u block_size= %d\n", -+ printk(KERN_INFO " blocks= %lld block_size= %d\n", - *total_size, *block_size); -+ kfree(buf); - return; - } - -@@ -1975,8 +2045,7 @@ static int cciss_revalidate(struct gendi - int logvol; - int FOUND = 0; - unsigned int block_size; -- unsigned int total_size; -- ReadCapdata_struct *size_buff = NULL; -+ sector_t total_size; - InquiryData_struct *inq_buff = NULL; - - for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) { -@@ -1989,27 +2058,24 @@ static int cciss_revalidate(struct gendi - if (!FOUND) - return 1; - -- size_buff = kmalloc(sizeof(ReadCapdata_struct), GFP_KERNEL); -- if (size_buff == NULL) { -- printk(KERN_WARNING "cciss: out of memory\n"); -- return 1; -- } - inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); - if (inq_buff == NULL) { - printk(KERN_WARNING "cciss: out of memory\n"); -- kfree(size_buff); - return 1; - } -- -- cciss_read_capacity(h->ctlr, logvol, size_buff, 1, &total_size, -- &block_size); -+ if (h->cciss_read == CCISS_READ_10) { -+ cciss_read_capacity(h->ctlr, logvol, 1, -+ &total_size, &block_size); -+ } else { -+ cciss_read_capacity_16(h->ctlr, logvol, 1, -+ &total_size, &block_size); -+ } - cciss_geometry_inquiry(h->ctlr, logvol, 1, total_size, block_size, - inq_buff, drv); - - blk_queue_hardsect_size(drv->queue, drv->block_size); - set_capacity(disk, drv->nr_blocks); - -- kfree(size_buff); - kfree(inq_buff); - return 0; - } -@@ -2418,7 +2484,8 @@ static void do_cciss_request(request_que - { - ctlr_info_t *h = q->queuedata; - CommandList_struct *c; -- int start_blk, seg; -+ sector_t start_blk; -+ int seg; - struct request *creq; - u64bit temp64; - struct scatterlist tmp_sg[MAXSGENTRIES]; -@@ -2462,10 +2529,10 @@ static void do_cciss_request(request_que - c->Request.Type.Type = TYPE_CMD; // It is a command. - c->Request.Type.Attribute = ATTR_SIMPLE; - c->Request.Type.Direction = -- (rq_data_dir(creq) == READ) ? XFER_READ : XFER_WRITE; -+ (rq_data_dir(creq) == READ) ? h->cciss_read : h->cciss_write; - c->Request.Timeout = 0; // Don't time out - c->Request.CDB[0] = -- (rq_data_dir(creq) == READ) ? CCISS_READ : CCISS_WRITE; -+ (rq_data_dir(creq) == READ) ? h->cciss_read : h->cciss_write; - start_blk = creq->sector; - #ifdef CCISS_DEBUG - printk(KERN_DEBUG "ciss: sector =%d nr_sectors=%d\n", (int)creq->sector, -@@ -2499,15 +2566,33 @@ static void do_cciss_request(request_que - #endif /* CCISS_DEBUG */ - - c->Header.SGList = c->Header.SGTotal = seg; -- c->Request.CDB[1] = 0; -- c->Request.CDB[2] = (start_blk >> 24) & 0xff; //MSB -- c->Request.CDB[3] = (start_blk >> 16) & 0xff; -- c->Request.CDB[4] = (start_blk >> 8) & 0xff; -- c->Request.CDB[5] = start_blk & 0xff; -- c->Request.CDB[6] = 0; // (sect >> 24) & 0xff; MSB -- c->Request.CDB[7] = (creq->nr_sectors >> 8) & 0xff; -- c->Request.CDB[8] = creq->nr_sectors & 0xff; -- c->Request.CDB[9] = c->Request.CDB[11] = c->Request.CDB[12] = 0; -+ if(h->cciss_read == CCISS_READ_10) { -+ c->Request.CDB[1] = 0; -+ c->Request.CDB[2] = (start_blk >> 24) & 0xff; //MSB -+ c->Request.CDB[3] = (start_blk >> 16) & 0xff; -+ c->Request.CDB[4] = (start_blk >> 8) & 0xff; -+ c->Request.CDB[5] = start_blk & 0xff; -+ c->Request.CDB[6] = 0; // (sect >> 24) & 0xff; MSB -+ c->Request.CDB[7] = (creq->nr_sectors >> 8) & 0xff; -+ c->Request.CDB[8] = creq->nr_sectors & 0xff; -+ c->Request.CDB[9] = c->Request.CDB[11] = c->Request.CDB[12] = 0; -+ } else { -+ c->Request.CDBLen = 16; -+ c->Request.CDB[1]= 0; -+ c->Request.CDB[2]= (start_blk >> 56) & 0xff; //MSB -+ c->Request.CDB[3]= (start_blk >> 48) & 0xff; -+ c->Request.CDB[4]= (start_blk >> 40) & 0xff; -+ c->Request.CDB[5]= (start_blk >> 32) & 0xff; -+ c->Request.CDB[6]= (start_blk >> 24) & 0xff; -+ c->Request.CDB[7]= (start_blk >> 16) & 0xff; -+ c->Request.CDB[8]= (start_blk >> 8) & 0xff; -+ c->Request.CDB[9]= start_blk & 0xff; -+ c->Request.CDB[10]= (creq->nr_sectors >> 24) & 0xff; -+ c->Request.CDB[11]= (creq->nr_sectors >> 16) & 0xff; -+ c->Request.CDB[12]= (creq->nr_sectors >> 8) & 0xff; -+ c->Request.CDB[13]= creq->nr_sectors & 0xff; -+ c->Request.CDB[14] = c->Request.CDB[15] = 0; -+ } - - spin_lock_irq(q->queue_lock); - -@@ -2517,9 +2602,9 @@ static void do_cciss_request(request_que - h->maxQsinceinit = h->Qdepth; - - goto queue; -- full: -+full: - blk_stop_queue(q); -- startio: -+startio: - /* We will already have the driver lock here so not need - * to lock it. - */ -@@ -2947,31 +3032,23 @@ static int cciss_pci_init(ctlr_info_t *c - static void cciss_getgeometry(int cntl_num) - { - ReportLunData_struct *ld_buff; -- ReadCapdata_struct *size_buff; - InquiryData_struct *inq_buff; - int return_code; - int i; - int listlength = 0; - __u32 lunid = 0; - int block_size; -- int total_size; -+ sector_t total_size; - - ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL); - if (ld_buff == NULL) { - printk(KERN_ERR "cciss: out of memory\n"); - return; - } -- size_buff = kmalloc(sizeof(ReadCapdata_struct), GFP_KERNEL); -- if (size_buff == NULL) { -- printk(KERN_ERR "cciss: out of memory\n"); -- kfree(ld_buff); -- return; -- } - inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); - if (inq_buff == NULL) { - printk(KERN_ERR "cciss: out of memory\n"); - kfree(ld_buff); -- kfree(size_buff); - return; - } - /* Get the firmware version */ -@@ -3026,7 +3103,6 @@ static void cciss_getgeometry(int cntl_n - #endif /* CCISS_DEBUG */ - - hba[cntl_num]->highest_lun = hba[cntl_num]->num_luns - 1; --// for(i=0; i< hba[cntl_num]->num_luns; i++) - for (i = 0; i < CISS_MAX_LUN; i++) { - if (i < hba[cntl_num]->num_luns) { - lunid = (0xff & (unsigned int)(ld_buff->LUN[i][3])) -@@ -3045,8 +3121,26 @@ static void cciss_getgeometry(int cntl_n - ld_buff->LUN[i][2], ld_buff->LUN[i][3], - hba[cntl_num]->drv[i].LunID); - #endif /* CCISS_DEBUG */ -- cciss_read_capacity(cntl_num, i, size_buff, 0, -+ -+ /* testing to see if 16-byte CDBs are already being used */ -+ if(hba[cntl_num]->cciss_read == CCISS_READ_16) { -+ cciss_read_capacity_16(cntl_num, i, 0, - &total_size, &block_size); -+ goto geo_inq; -+ } -+ cciss_read_capacity(cntl_num, i, 0, &total_size, &block_size); -+ -+ /* total_size = last LBA + 1 */ -+ if(total_size == (__u32) 0) { -+ cciss_read_capacity_16(cntl_num, i, 0, -+ &total_size, &block_size); -+ hba[cntl_num]->cciss_read = CCISS_READ_16; -+ hba[cntl_num]->cciss_write = CCISS_WRITE_16; -+ } else { -+ hba[cntl_num]->cciss_read = CCISS_READ_10; -+ hba[cntl_num]->cciss_write = CCISS_WRITE_10; -+ } -+geo_inq: - cciss_geometry_inquiry(cntl_num, i, 0, total_size, - block_size, inq_buff, - &hba[cntl_num]->drv[i]); -@@ -3056,7 +3150,6 @@ static void cciss_getgeometry(int cntl_n - } - } - kfree(ld_buff); -- kfree(size_buff); - kfree(inq_buff); - } - ---- a/drivers/block/cciss.h -+++ b/drivers/block/cciss.h -@@ -76,6 +76,9 @@ struct ctlr_info - unsigned int intr[4]; - unsigned int msix_vector; - unsigned int msi_vector; -+ BYTE cciss_read; -+ BYTE cciss_write; -+ BYTE cciss_read_capacity; - - // information about each logical volume - drive_info_struct drv[CISS_MAX_LUN]; ---- a/drivers/block/cciss_cmd.h -+++ b/drivers/block/cciss_cmd.h -@@ -118,11 +118,34 @@ typedef struct _ReadCapdata_struct - BYTE block_size[4]; // Size of blocks in bytes - } ReadCapdata_struct; - --// 12 byte commands not implemented in firmware yet. --// #define CCISS_READ 0xa8 // Read(12) --// #define CCISS_WRITE 0xaa // Write(12) -- #define CCISS_READ 0x28 // Read(10) -- #define CCISS_WRITE 0x2a // Write(10) -+#define CCISS_READ_CAPACITY_16 0x9e /* Read Capacity 16 */ -+ -+/* service action to differentiate a 16 byte read capacity from -+ other commands that use the 0x9e SCSI op code */ -+ -+#define CCISS_READ_CAPACITY_16_SERVICE_ACT 0x10 -+ -+typedef struct _ReadCapdata_struct_16 -+{ -+ BYTE total_size[8]; /* Total size in blocks */ -+ BYTE block_size[4]; /* Size of blocks in bytes */ -+ BYTE prot_en:1; /* protection enable bit */ -+ BYTE rto_en:1; /* reference tag own enable bit */ -+ BYTE reserved:6; /* reserved bits */ -+ BYTE reserved2[18]; /* reserved bytes per spec */ -+} ReadCapdata_struct_16; -+ -+/* Define the supported read/write commands for cciss based controllers */ -+ -+#define CCISS_READ_10 0x28 /* Read(10) */ -+#define CCISS_WRITE_10 0x2a /* Write(10) */ -+#define CCISS_READ_16 0x88 /* Read(16) */ -+#define CCISS_WRITE_16 0x8a /* Write(16) */ -+ -+/* Define the CDB lengths supported by cciss based controllers */ -+ -+#define CDB_LEN10 10 -+#define CDB_LEN16 16 - - // BMIC commands - #define BMIC_READ 0x26 diff --git a/debian/patches/features/all/drivers/net-r8169-1.patch b/debian/patches/features/all/drivers/net-r8169-1.patch deleted file mode 100644 index c74ae9cc9..000000000 --- a/debian/patches/features/all/drivers/net-r8169-1.patch +++ /dev/null @@ -1,1208 +0,0 @@ -diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c -index 5722a56..ebb948b 100644 ---- a/drivers/net/r8169.c -+++ b/drivers/net/r8169.c -@@ -6,26 +6,26 @@ - History: - Feb 4 2002 - created initially by ShuChen . - May 20 2002 - Add link status force-mode and TBI mode support. -- 2004 - Massive updates. See kernel SCM system for details. -+ 2004 - Massive updates. See kernel SCM system for details. - ========================================================================= - 1. [DEPRECATED: use ethtool instead] The media can be forced in 5 modes. - Command: 'insmod r8169 media = SET_MEDIA' - Ex: 'insmod r8169 media = 0x04' will force PHY to operate in 100Mpbs Half-duplex. -- -+ - SET_MEDIA can be: - _10_Half = 0x01 - _10_Full = 0x02 - _100_Half = 0x04 - _100_Full = 0x08 - _1000_Full = 0x10 -- -+ - 2. Support TBI mode. - ========================================================================= - VERSION 1.1 <2002/10/4> - - The bit4:0 of MII register 4 is called "selector field", and have to be - 00001b to indicate support of IEEE std 802.3 during NWay process of -- exchanging Link Code Word (FLP). -+ exchanging Link Code Word (FLP). - - VERSION 1.2 <2002/11/30> - -@@ -81,10 +81,10 @@ #define PFX MODULENAME ": " - - #ifdef RTL8169_DEBUG - #define assert(expr) \ -- if(!(expr)) { \ -- printk( "Assertion failed! %s,%s,%s,line=%d\n", \ -- #expr,__FILE__,__FUNCTION__,__LINE__); \ -- } -+ if (!(expr)) { \ -+ printk( "Assertion failed! %s,%s,%s,line=%d\n", \ -+ #expr,__FILE__,__FUNCTION__,__LINE__); \ -+ } - #define dprintk(fmt, args...) do { printk(PFX fmt, ## args); } while (0) - #else - #define assert(expr) do {} while (0) -@@ -150,11 +150,16 @@ #define RTL_R16(reg) readw (ioaddr + (r - #define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg))) - - enum mac_version { -- RTL_GIGA_MAC_VER_B = 0x00, -- /* RTL_GIGA_MAC_VER_C = 0x03, */ -- RTL_GIGA_MAC_VER_D = 0x01, -- RTL_GIGA_MAC_VER_E = 0x02, -- RTL_GIGA_MAC_VER_X = 0x04 /* Greater than RTL_GIGA_MAC_VER_E */ -+ RTL_GIGA_MAC_VER_01 = 0x00, -+ RTL_GIGA_MAC_VER_02 = 0x01, -+ RTL_GIGA_MAC_VER_03 = 0x02, -+ RTL_GIGA_MAC_VER_04 = 0x03, -+ RTL_GIGA_MAC_VER_05 = 0x04, -+ RTL_GIGA_MAC_VER_11 = 0x0b, -+ RTL_GIGA_MAC_VER_12 = 0x0c, -+ RTL_GIGA_MAC_VER_13 = 0x0d, -+ RTL_GIGA_MAC_VER_14 = 0x0e, -+ RTL_GIGA_MAC_VER_15 = 0x0f - }; - - enum phy_version { -@@ -166,7 +171,6 @@ enum phy_version { - RTL_GIGA_PHY_VER_H = 0x08, /* PHY Reg 0x03 bit0-3 == 0x0003 */ - }; - -- - #define _R(NAME,MAC,MASK) \ - { .name = NAME, .mac_version = MAC, .RxConfigMask = MASK } - -@@ -175,19 +179,44 @@ static const struct { - u8 mac_version; - u32 RxConfigMask; /* Clears the bits supported by this chip */ - } rtl_chip_info[] = { -- _R("RTL8169", RTL_GIGA_MAC_VER_B, 0xff7e1880), -- _R("RTL8169s/8110s", RTL_GIGA_MAC_VER_D, 0xff7e1880), -- _R("RTL8169s/8110s", RTL_GIGA_MAC_VER_E, 0xff7e1880), -- _R("RTL8169s/8110s", RTL_GIGA_MAC_VER_X, 0xff7e1880), -+ _R("RTL8169", RTL_GIGA_MAC_VER_01, 0xff7e1880), -+ _R("RTL8169s/8110s", RTL_GIGA_MAC_VER_02, 0xff7e1880), -+ _R("RTL8169s/8110s", RTL_GIGA_MAC_VER_03, 0xff7e1880), -+ _R("RTL8169sb/8110sb", RTL_GIGA_MAC_VER_04, 0xff7e1880), -+ _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_05, 0xff7e1880), -+ _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_11, 0xff7e1880), // PCI-E -+ _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_12, 0xff7e1880), // PCI-E -+ _R("RTL8101e", RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139 -+ _R("RTL8100e", RTL_GIGA_MAC_VER_14, 0xff7e1880), // PCI-E 8139 -+ _R("RTL8100e", RTL_GIGA_MAC_VER_15, 0xff7e1880) // PCI-E 8139 - }; - #undef _R - -+enum cfg_version { -+ RTL_CFG_0 = 0x00, -+ RTL_CFG_1, -+ RTL_CFG_2 -+}; -+ -+static const struct { -+ unsigned int region; -+ unsigned int align; -+} rtl_cfg_info[] = { -+ [RTL_CFG_0] = { 1, NET_IP_ALIGN }, -+ [RTL_CFG_1] = { 2, NET_IP_ALIGN }, -+ [RTL_CFG_2] = { 2, 8 } -+}; -+ - static struct pci_device_id rtl8169_pci_tbl[] = { -- { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), }, -- { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8129), }, -- { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), }, -- { PCI_DEVICE(0x16ec, 0x0116), }, -- { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0024, }, -+ { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8129), 0, 0, RTL_CFG_0 }, -+ { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8136), 0, 0, RTL_CFG_2 }, -+ { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8167), 0, 0, RTL_CFG_1 }, -+ { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168), 0, 0, RTL_CFG_2 }, -+ { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), 0, 0, RTL_CFG_0 }, -+ { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), 0, 0, RTL_CFG_0 }, -+ { PCI_DEVICE(0x16ec, 0x0116), 0, 0, RTL_CFG_0 }, -+ { PCI_VENDOR_ID_LINKSYS, 0x1032, -+ PCI_ANY_ID, 0x0024, 0, 0, RTL_CFG_0 }, - {0,}, - }; - -@@ -257,10 +286,11 @@ enum RTL8169_register_content { - RxOK = 0x01, - - /* RxStatusDesc */ -- RxRES = 0x00200000, -- RxCRC = 0x00080000, -- RxRUNT = 0x00100000, -- RxRWT = 0x00400000, -+ RxFOVF = (1 << 23), -+ RxRWT = (1 << 22), -+ RxRES = (1 << 21), -+ RxRUNT = (1 << 20), -+ RxCRC = (1 << 19), - - /* ChipCmdBits */ - CmdReset = 0x10, -@@ -326,30 +356,6 @@ enum RTL8169_register_content { - LinkStatus = 0x02, - FullDup = 0x01, - -- /* GIGABIT_PHY_registers */ -- PHY_CTRL_REG = 0, -- PHY_STAT_REG = 1, -- PHY_AUTO_NEGO_REG = 4, -- PHY_1000_CTRL_REG = 9, -- -- /* GIGABIT_PHY_REG_BIT */ -- PHY_Restart_Auto_Nego = 0x0200, -- PHY_Enable_Auto_Nego = 0x1000, -- -- /* PHY_STAT_REG = 1 */ -- PHY_Auto_Neco_Comp = 0x0020, -- -- /* PHY_AUTO_NEGO_REG = 4 */ -- PHY_Cap_10_Half = 0x0020, -- PHY_Cap_10_Full = 0x0040, -- PHY_Cap_100_Half = 0x0080, -- PHY_Cap_100_Full = 0x0100, -- -- /* PHY_1000_CTRL_REG = 9 */ -- PHY_Cap_1000_Full = 0x0200, -- -- PHY_Cap_Null = 0x0, -- - /* _MediaType */ - _10_Half = 0x01, - _10_Full = 0x02, -@@ -433,6 +439,7 @@ struct rtl8169_private { - dma_addr_t RxPhyAddr; - struct sk_buff *Rx_skbuff[NUM_RX_DESC]; /* Rx data buffers */ - struct ring_info tx_skb[NUM_TX_DESC]; /* Tx data buffers */ -+ unsigned align; - unsigned rx_buf_sz; - struct timer_list timer; - u16 cp_cmd; -@@ -488,12 +495,7 @@ static const u16 rtl8169_intr_mask = - static const u16 rtl8169_napi_event = - RxOK | RxOverflow | RxFIFOOver | TxOK | TxErr; - static const unsigned int rtl8169_rx_config = -- (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift); -- --#define PHY_Cap_10_Half_Or_Less PHY_Cap_10_Half --#define PHY_Cap_10_Full_Or_Less PHY_Cap_10_Full | PHY_Cap_10_Half_Or_Less --#define PHY_Cap_100_Half_Or_Less PHY_Cap_100_Half | PHY_Cap_10_Full_Or_Less --#define PHY_Cap_100_Full_Or_Less PHY_Cap_100_Full | PHY_Cap_100_Half_Or_Less -+ (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift); - - static void mdio_write(void __iomem *ioaddr, int RegAddr, int value) - { -@@ -503,7 +505,7 @@ static void mdio_write(void __iomem *ioa - - for (i = 20; i > 0; i--) { - /* Check if the RTL8169 has completed writing to the specified MII register */ -- if (!(RTL_R32(PHYAR) & 0x80000000)) -+ if (!(RTL_R32(PHYAR) & 0x80000000)) - break; - udelay(25); - } -@@ -547,7 +549,7 @@ static unsigned int rtl8169_tbi_reset_pe - - static unsigned int rtl8169_xmii_reset_pending(void __iomem *ioaddr) - { -- return mdio_read(ioaddr, 0) & 0x8000; -+ return mdio_read(ioaddr, MII_BMCR) & BMCR_RESET; - } - - static unsigned int rtl8169_tbi_link_ok(void __iomem *ioaddr) -@@ -569,8 +571,8 @@ static void rtl8169_xmii_reset_enable(vo - { - unsigned int val; - -- val = (mdio_read(ioaddr, PHY_CTRL_REG) | 0x8000) & 0xffff; -- mdio_write(ioaddr, PHY_CTRL_REG, val); -+ val = (mdio_read(ioaddr, MII_BMCR) | BMCR_RESET) & 0xffff; -+ mdio_write(ioaddr, MII_BMCR, val); - } - - static void rtl8169_check_link_status(struct net_device *dev, -@@ -608,7 +610,7 @@ static void rtl8169_link_option(int idx, - { SPEED_1000, DUPLEX_FULL, AUTONEG_ENABLE, 0xff } - }, *p; - unsigned char option; -- -+ - option = ((idx < MAX_UNITS) && (idx >= 0)) ? media[idx] : 0xff; - - if ((option != 0xff) && !idx && netif_msg_drv(&debug)) -@@ -650,9 +652,9 @@ #define WAKE_ANY (WAKE_PHY | WAKE_MAGIC - if (options & UWF) - wol->wolopts |= WAKE_UCAST; - if (options & BWF) -- wol->wolopts |= WAKE_BCAST; -+ wol->wolopts |= WAKE_BCAST; - if (options & MWF) -- wol->wolopts |= WAKE_MCAST; -+ wol->wolopts |= WAKE_MCAST; - - out_unlock: - spin_unlock_irq(&tp->lock); -@@ -745,38 +747,57 @@ static int rtl8169_set_speed_xmii(struct - void __iomem *ioaddr = tp->mmio_addr; - int auto_nego, giga_ctrl; - -- auto_nego = mdio_read(ioaddr, PHY_AUTO_NEGO_REG); -- auto_nego &= ~(PHY_Cap_10_Half | PHY_Cap_10_Full | -- PHY_Cap_100_Half | PHY_Cap_100_Full); -- giga_ctrl = mdio_read(ioaddr, PHY_1000_CTRL_REG); -- giga_ctrl &= ~(PHY_Cap_1000_Full | PHY_Cap_Null); -+ auto_nego = mdio_read(ioaddr, MII_ADVERTISE); -+ auto_nego &= ~(ADVERTISE_10HALF | ADVERTISE_10FULL | -+ ADVERTISE_100HALF | ADVERTISE_100FULL); -+ giga_ctrl = mdio_read(ioaddr, MII_CTRL1000); -+ giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); - - if (autoneg == AUTONEG_ENABLE) { -- auto_nego |= (PHY_Cap_10_Half | PHY_Cap_10_Full | -- PHY_Cap_100_Half | PHY_Cap_100_Full); -- giga_ctrl |= PHY_Cap_1000_Full; -+ auto_nego |= (ADVERTISE_10HALF | ADVERTISE_10FULL | -+ ADVERTISE_100HALF | ADVERTISE_100FULL); -+ giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF; - } else { - if (speed == SPEED_10) -- auto_nego |= PHY_Cap_10_Half | PHY_Cap_10_Full; -+ auto_nego |= ADVERTISE_10HALF | ADVERTISE_10FULL; - else if (speed == SPEED_100) -- auto_nego |= PHY_Cap_100_Half | PHY_Cap_100_Full; -+ auto_nego |= ADVERTISE_100HALF | ADVERTISE_100FULL; - else if (speed == SPEED_1000) -- giga_ctrl |= PHY_Cap_1000_Full; -+ giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF; - - if (duplex == DUPLEX_HALF) -- auto_nego &= ~(PHY_Cap_10_Full | PHY_Cap_100_Full); -+ auto_nego &= ~(ADVERTISE_10FULL | ADVERTISE_100FULL); - - if (duplex == DUPLEX_FULL) -- auto_nego &= ~(PHY_Cap_10_Half | PHY_Cap_100_Half); -+ auto_nego &= ~(ADVERTISE_10HALF | ADVERTISE_100HALF); -+ -+ /* This tweak comes straight from Realtek's driver. */ -+ if ((speed == SPEED_100) && (duplex == DUPLEX_HALF) && -+ (tp->mac_version == RTL_GIGA_MAC_VER_13)) { -+ auto_nego = ADVERTISE_100HALF | ADVERTISE_CSMA; -+ } -+ } -+ -+ /* The 8100e/8101e do Fast Ethernet only. */ -+ if ((tp->mac_version == RTL_GIGA_MAC_VER_13) || -+ (tp->mac_version == RTL_GIGA_MAC_VER_14) || -+ (tp->mac_version == RTL_GIGA_MAC_VER_15)) { -+ if ((giga_ctrl & (ADVERTISE_1000FULL | ADVERTISE_1000HALF)) && -+ netif_msg_link(tp)) { -+ printk(KERN_INFO "%s: PHY does not support 1000Mbps.\n", -+ dev->name); -+ } -+ giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); - } - -+ auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; -+ - tp->phy_auto_nego_reg = auto_nego; - tp->phy_1000_ctrl_reg = giga_ctrl; - -- mdio_write(ioaddr, PHY_AUTO_NEGO_REG, auto_nego); -- mdio_write(ioaddr, PHY_1000_CTRL_REG, giga_ctrl); -- mdio_write(ioaddr, PHY_CTRL_REG, PHY_Enable_Auto_Nego | -- PHY_Restart_Auto_Nego); -+ mdio_write(ioaddr, MII_ADVERTISE, auto_nego); -+ mdio_write(ioaddr, MII_CTRL1000, giga_ctrl); -+ mdio_write(ioaddr, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART); - return 0; - } - -@@ -788,7 +809,7 @@ static int rtl8169_set_speed(struct net_ - - ret = tp->set_speed(dev, autoneg, speed, duplex); - -- if (netif_running(dev) && (tp->phy_1000_ctrl_reg & PHY_Cap_1000_Full)) -+ if (netif_running(dev) && (tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL)) - mod_timer(&tp->timer, jiffies + RTL8169_PHY_TIMEOUT); - - return ret; -@@ -803,7 +824,7 @@ static int rtl8169_set_settings(struct n - spin_lock_irqsave(&tp->lock, flags); - ret = rtl8169_set_speed(dev, cmd->autoneg, cmd->speed, cmd->duplex); - spin_unlock_irqrestore(&tp->lock, flags); -- -+ - return ret; - } - -@@ -936,20 +957,20 @@ static void rtl8169_gset_xmii(struct net - SUPPORTED_100baseT_Full | - SUPPORTED_1000baseT_Full | - SUPPORTED_Autoneg | -- SUPPORTED_TP; -+ SUPPORTED_TP; - - cmd->autoneg = 1; - cmd->advertising = ADVERTISED_TP | ADVERTISED_Autoneg; - -- if (tp->phy_auto_nego_reg & PHY_Cap_10_Half) -+ if (tp->phy_auto_nego_reg & ADVERTISE_10HALF) - cmd->advertising |= ADVERTISED_10baseT_Half; -- if (tp->phy_auto_nego_reg & PHY_Cap_10_Full) -+ if (tp->phy_auto_nego_reg & ADVERTISE_10FULL) - cmd->advertising |= ADVERTISED_10baseT_Full; -- if (tp->phy_auto_nego_reg & PHY_Cap_100_Half) -+ if (tp->phy_auto_nego_reg & ADVERTISE_100HALF) - cmd->advertising |= ADVERTISED_100baseT_Half; -- if (tp->phy_auto_nego_reg & PHY_Cap_100_Full) -+ if (tp->phy_auto_nego_reg & ADVERTISE_100FULL) - cmd->advertising |= ADVERTISED_100baseT_Full; -- if (tp->phy_1000_ctrl_reg & PHY_Cap_1000_Full) -+ if (tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL) - cmd->advertising |= ADVERTISED_1000baseT_Full; - - status = RTL_R8(PHYstatus); -@@ -961,6 +982,11 @@ static void rtl8169_gset_xmii(struct net - else if (status & _10bps) - cmd->speed = SPEED_10; - -+ if (status & TxFlowCtrl) -+ cmd->advertising |= ADVERTISED_Asym_Pause; -+ if (status & RxFlowCtrl) -+ cmd->advertising |= ADVERTISED_Pause; -+ - cmd->duplex = ((status & _1000bpsF) || (status & FullDup)) ? - DUPLEX_FULL : DUPLEX_HALF; - } -@@ -981,15 +1007,15 @@ static int rtl8169_get_settings(struct n - static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs *regs, - void *p) - { -- struct rtl8169_private *tp = netdev_priv(dev); -- unsigned long flags; -+ struct rtl8169_private *tp = netdev_priv(dev); -+ unsigned long flags; - -- if (regs->len > R8169_REGS_SIZE) -- regs->len = R8169_REGS_SIZE; -+ if (regs->len > R8169_REGS_SIZE) -+ regs->len = R8169_REGS_SIZE; - -- spin_lock_irqsave(&tp->lock, flags); -- memcpy_fromio(p, tp->mmio_addr, regs->len); -- spin_unlock_irqrestore(&tp->lock, flags); -+ spin_lock_irqsave(&tp->lock, flags); -+ memcpy_fromio(p, tp->mmio_addr, regs->len); -+ spin_unlock_irqrestore(&tp->lock, flags); - } - - static u32 rtl8169_get_msglevel(struct net_device *dev) -@@ -1071,7 +1097,7 @@ static void rtl8169_get_ethtool_stats(st - RTL_W32(CounterAddrLow, 0); - RTL_W32(CounterAddrHigh, 0); - -- data[0] = le64_to_cpu(counters->tx_packets); -+ data[0] = le64_to_cpu(counters->tx_packets); - data[1] = le64_to_cpu(counters->rx_packets); - data[2] = le64_to_cpu(counters->tx_errors); - data[3] = le32_to_cpu(counters->rx_errors); -@@ -1131,7 +1157,7 @@ static void rtl8169_write_gmii_reg_bit(v - val = mdio_read(ioaddr, reg); - val = (bitval == 1) ? - val | (bitval << bitnum) : val & ~(0x0001 << bitnum); -- mdio_write(ioaddr, reg, val & 0xffff); -+ mdio_write(ioaddr, reg, val & 0xffff); - } - - static void rtl8169_get_mac_version(struct rtl8169_private *tp, void __iomem *ioaddr) -@@ -1140,10 +1166,16 @@ static void rtl8169_get_mac_version(stru - u32 mask; - int mac_version; - } mac_info[] = { -- { 0x1 << 28, RTL_GIGA_MAC_VER_X }, -- { 0x1 << 26, RTL_GIGA_MAC_VER_E }, -- { 0x1 << 23, RTL_GIGA_MAC_VER_D }, -- { 0x00000000, RTL_GIGA_MAC_VER_B } /* Catch-all */ -+ { 0x38800000, RTL_GIGA_MAC_VER_15 }, -+ { 0x38000000, RTL_GIGA_MAC_VER_12 }, -+ { 0x34000000, RTL_GIGA_MAC_VER_13 }, -+ { 0x30800000, RTL_GIGA_MAC_VER_14 }, -+ { 0x30000000, RTL_GIGA_MAC_VER_11 }, -+ { 0x18000000, RTL_GIGA_MAC_VER_05 }, -+ { 0x10000000, RTL_GIGA_MAC_VER_04 }, -+ { 0x04000000, RTL_GIGA_MAC_VER_03 }, -+ { 0x00800000, RTL_GIGA_MAC_VER_02 }, -+ { 0x00000000, RTL_GIGA_MAC_VER_01 } /* Catch-all */ - }, *p = mac_info; - u32 reg; - -@@ -1155,24 +1187,7 @@ static void rtl8169_get_mac_version(stru - - static void rtl8169_print_mac_version(struct rtl8169_private *tp) - { -- struct { -- int version; -- char *msg; -- } mac_print[] = { -- { RTL_GIGA_MAC_VER_E, "RTL_GIGA_MAC_VER_E" }, -- { RTL_GIGA_MAC_VER_D, "RTL_GIGA_MAC_VER_D" }, -- { RTL_GIGA_MAC_VER_B, "RTL_GIGA_MAC_VER_B" }, -- { 0, NULL } -- }, *p; -- -- for (p = mac_print; p->msg; p++) { -- if (tp->mac_version == p->version) { -- dprintk("mac_version == %s (%04d)\n", p->msg, -- p->version); -- return; -- } -- } -- dprintk("mac_version == Unknown\n"); -+ dprintk("mac_version = 0x%02x\n", tp->mac_version); - } - - static void rtl8169_get_phy_version(struct rtl8169_private *tp, void __iomem *ioaddr) -@@ -1189,7 +1204,7 @@ static void rtl8169_get_phy_version(stru - }, *p = phy_info; - u16 reg; - -- reg = mdio_read(ioaddr, 3) & 0xffff; -+ reg = mdio_read(ioaddr, MII_PHYSID2) & 0xffff; - while ((reg & p->mask) != p->set) - p++; - tp->phy_version = p->phy_version; -@@ -1257,7 +1272,7 @@ static void rtl8169_hw_phy_config(struct - rtl8169_print_mac_version(tp); - rtl8169_print_phy_version(tp); - -- if (tp->mac_version <= RTL_GIGA_MAC_VER_B) -+ if (tp->mac_version <= RTL_GIGA_MAC_VER_01) - return; - if (tp->phy_version >= RTL_GIGA_PHY_VER_H) - return; -@@ -1267,7 +1282,7 @@ static void rtl8169_hw_phy_config(struct - - /* Shazam ! */ - -- if (tp->mac_version == RTL_GIGA_MAC_VER_X) { -+ if (tp->mac_version == RTL_GIGA_MAC_VER_04) { - mdio_write(ioaddr, 31, 0x0001); - mdio_write(ioaddr, 9, 0x273a); - mdio_write(ioaddr, 14, 0x7bfb); -@@ -1306,16 +1321,16 @@ static void rtl8169_phy_timer(unsigned l - void __iomem *ioaddr = tp->mmio_addr; - unsigned long timeout = RTL8169_PHY_TIMEOUT; - -- assert(tp->mac_version > RTL_GIGA_MAC_VER_B); -+ assert(tp->mac_version > RTL_GIGA_MAC_VER_01); - assert(tp->phy_version < RTL_GIGA_PHY_VER_H); - -- if (!(tp->phy_1000_ctrl_reg & PHY_Cap_1000_Full)) -+ if (!(tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL)) - return; - - spin_lock_irq(&tp->lock); - - if (tp->phy_reset_pending(ioaddr)) { -- /* -+ /* - * A busy loop could burn quite a few cycles on nowadays CPU. - * Let's delay the execution of the timer for a few ticks. - */ -@@ -1342,7 +1357,7 @@ static inline void rtl8169_delete_timer( - struct rtl8169_private *tp = netdev_priv(dev); - struct timer_list *timer = &tp->timer; - -- if ((tp->mac_version <= RTL_GIGA_MAC_VER_B) || -+ if ((tp->mac_version <= RTL_GIGA_MAC_VER_01) || - (tp->phy_version >= RTL_GIGA_PHY_VER_H)) - return; - -@@ -1354,7 +1369,7 @@ static inline void rtl8169_request_timer - struct rtl8169_private *tp = netdev_priv(dev); - struct timer_list *timer = &tp->timer; - -- if ((tp->mac_version <= RTL_GIGA_MAC_VER_B) || -+ if ((tp->mac_version <= RTL_GIGA_MAC_VER_01) || - (tp->phy_version >= RTL_GIGA_PHY_VER_H)) - return; - -@@ -1382,6 +1397,41 @@ static void rtl8169_netpoll(struct net_d - } - #endif - -+static void __rtl8169_set_mac_addr(struct net_device *dev, void __iomem *ioaddr) -+{ -+ unsigned int i, j; -+ -+ RTL_W8(Cfg9346, Cfg9346_Unlock); -+ for (i = 0; i < 2; i++) { -+ __le32 l = 0; -+ -+ for (j = 0; j < 4; j++) { -+ l <<= 8; -+ l |= dev->dev_addr[4*i + j]; -+ } -+ RTL_W32(MAC0 + 4*i, cpu_to_be32(l)); -+ } -+ RTL_W8(Cfg9346, Cfg9346_Lock); -+} -+ -+static int rtl8169_set_mac_addr(struct net_device *dev, void *p) -+{ -+ struct rtl8169_private *tp = netdev_priv(dev); -+ struct sockaddr *addr = p; -+ -+ if (!is_valid_ether_addr(addr->sa_data)) -+ return -EINVAL; -+ -+ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); -+ -+ if (netif_running(dev)) { -+ spin_lock_irq(&tp->lock); -+ __rtl8169_set_mac_addr(dev, tp->mmio_addr); -+ spin_unlock_irq(&tp->lock); -+ } -+ return 0; -+} -+ - static void rtl8169_release_board(struct pci_dev *pdev, struct net_device *dev, - void __iomem *ioaddr) - { -@@ -1391,23 +1441,87 @@ static void rtl8169_release_board(struct - free_netdev(dev); - } - -+static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp) -+{ -+ void __iomem *ioaddr = tp->mmio_addr; -+ static int board_idx = -1; -+ u8 autoneg, duplex; -+ u16 speed; -+ -+ board_idx++; -+ -+ rtl8169_hw_phy_config(dev); -+ -+ dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n"); -+ RTL_W8(0x82, 0x01); -+ -+ if (tp->mac_version < RTL_GIGA_MAC_VER_03) { -+ dprintk("Set PCI Latency=0x40\n"); -+ pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40); -+ } -+ -+ if (tp->mac_version == RTL_GIGA_MAC_VER_02) { -+ dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n"); -+ RTL_W8(0x82, 0x01); -+ dprintk("Set PHY Reg 0x0bh = 0x00h\n"); -+ mdio_write(ioaddr, 0x0b, 0x0000); //w 0x0b 15 0 0 -+ } -+ -+ rtl8169_link_option(board_idx, &autoneg, &speed, &duplex); -+ -+ rtl8169_set_speed(dev, autoneg, speed, duplex); -+ -+ if ((RTL_R8(PHYstatus) & TBI_Enable) && netif_msg_link(tp)) -+ printk(KERN_INFO PFX "%s: TBI auto-negotiating\n", dev->name); -+} -+ -+static int rtl8169_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -+{ -+ struct rtl8169_private *tp = netdev_priv(dev); -+ struct mii_ioctl_data *data = if_mii(ifr); -+ -+ if (!netif_running(dev)) -+ return -ENODEV; -+ -+ switch (cmd) { -+ case SIOCGMIIPHY: -+ data->phy_id = 32; /* Internal PHY */ -+ return 0; -+ -+ case SIOCGMIIREG: -+ data->val_out = mdio_read(tp->mmio_addr, data->reg_num & 0x1f); -+ return 0; -+ -+ case SIOCSMIIREG: -+ if (!capable(CAP_NET_ADMIN)) -+ return -EPERM; -+ mdio_write(tp->mmio_addr, data->reg_num & 0x1f, data->val_in); -+ return 0; -+ } -+ return -EOPNOTSUPP; -+} -+ - static int __devinit --rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out, -- void __iomem **ioaddr_out) -+rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) - { -- void __iomem *ioaddr; -- struct net_device *dev; -+ const unsigned int region = rtl_cfg_info[ent->driver_data].region; - struct rtl8169_private *tp; -- int rc = -ENOMEM, i, acpi_idle_state = 0, pm_cap; -+ struct net_device *dev; -+ void __iomem *ioaddr; -+ unsigned int i, pm_cap; -+ int rc; - -- assert(ioaddr_out != NULL); -+ if (netif_msg_drv(&debug)) { -+ printk(KERN_INFO "%s Gigabit Ethernet driver %s loaded\n", -+ MODULENAME, RTL8169_VERSION); -+ } - -- /* dev zeroed in alloc_etherdev */ - dev = alloc_etherdev(sizeof (*tp)); -- if (dev == NULL) { -+ if (!dev) { - if (netif_msg_drv(&debug)) - dev_err(&pdev->dev, "unable to alloc new ethernet\n"); -- goto err_out; -+ rc = -ENOMEM; -+ goto out; - } - - SET_MODULE_OWNER(dev); -@@ -1420,48 +1534,53 @@ rtl8169_init_board(struct pci_dev *pdev, - if (rc < 0) { - if (netif_msg_probe(tp)) - dev_err(&pdev->dev, "enable failure\n"); -- goto err_out_free_dev; -+ goto err_out_free_dev_1; - } - - rc = pci_set_mwi(pdev); - if (rc < 0) -- goto err_out_disable; -+ goto err_out_disable_2; - - /* save power state before pci_enable_device overwrites it */ - pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM); - if (pm_cap) { -- u16 pwr_command; -+ u16 pwr_command, acpi_idle_state; - - pci_read_config_word(pdev, pm_cap + PCI_PM_CTRL, &pwr_command); - acpi_idle_state = pwr_command & PCI_PM_CTRL_STATE_MASK; - } else { -- if (netif_msg_probe(tp)) -+ if (netif_msg_probe(tp)) { - dev_err(&pdev->dev, -- "PowerManagement capability not found.\n"); -+ "PowerManagement capability not found.\n"); -+ } - } - - /* make sure PCI base addr 1 is MMIO */ -- if (!(pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) { -- if (netif_msg_probe(tp)) -+ if (!(pci_resource_flags(pdev, region) & IORESOURCE_MEM)) { -+ if (netif_msg_probe(tp)) { - dev_err(&pdev->dev, -- "region #1 not an MMIO resource, aborting\n"); -+ "region #%d not an MMIO resource, aborting\n", -+ region); -+ } - rc = -ENODEV; -- goto err_out_mwi; -+ goto err_out_mwi_3; - } -+ - /* check for weird/broken PCI region reporting */ -- if (pci_resource_len(pdev, 1) < R8169_REGS_SIZE) { -- if (netif_msg_probe(tp)) -+ if (pci_resource_len(pdev, region) < R8169_REGS_SIZE) { -+ if (netif_msg_probe(tp)) { - dev_err(&pdev->dev, -- "Invalid PCI region size(s), aborting\n"); -+ "Invalid PCI region size(s), aborting\n"); -+ } - rc = -ENODEV; -- goto err_out_mwi; -+ goto err_out_mwi_3; - } - - rc = pci_request_regions(pdev, MODULENAME); - if (rc < 0) { - if (netif_msg_probe(tp)) - dev_err(&pdev->dev, "could not request regions.\n"); -- goto err_out_mwi; -+ goto err_out_mwi_3; - } - - tp->cp_cmd = PCIMulRW | RxChkSum; -@@ -1473,22 +1592,23 @@ rtl8169_init_board(struct pci_dev *pdev, - } else { - rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK); - if (rc < 0) { -- if (netif_msg_probe(tp)) -+ if (netif_msg_probe(tp)) { - dev_err(&pdev->dev, -- "DMA configuration failed.\n"); -- goto err_out_free_res; -+ "DMA configuration failed.\n"); -+ } -+ goto err_out_free_res_4; - } - } - - pci_set_master(pdev); - - /* ioremap MMIO region */ -- ioaddr = ioremap(pci_resource_start(pdev, 1), R8169_REGS_SIZE); -- if (ioaddr == NULL) { -+ ioaddr = ioremap(pci_resource_start(pdev, region), R8169_REGS_SIZE); -+ if (!ioaddr) { - if (netif_msg_probe(tp)) - dev_err(&pdev->dev, "cannot remap MMIO, aborting\n"); - rc = -EIO; -- goto err_out_free_res; -+ goto err_out_free_res_4; - } - - /* Unneeded ? Don't mess with Mrs. Murphy. */ -@@ -1498,10 +1618,10 @@ rtl8169_init_board(struct pci_dev *pdev, - RTL_W8(ChipCmd, CmdReset); - - /* Check that the chip has finished the reset. */ -- for (i = 1000; i > 0; i--) { -+ for (i = 100; i > 0; i--) { - if ((RTL_R8(ChipCmd) & CmdReset) == 0) - break; -- udelay(10); -+ msleep_interruptible(1); - } - - /* Identify chip attached to board */ -@@ -1519,8 +1639,8 @@ rtl8169_init_board(struct pci_dev *pdev, - /* Unknown chip: assume array element #0, original RTL-8169 */ - if (netif_msg_probe(tp)) { - dev_printk(KERN_DEBUG, &pdev->dev, -- "unknown chip version, assuming %s\n", -- rtl_chip_info[0].name); -+ "unknown chip version, assuming %s\n", -+ rtl_chip_info[0].name); - } - i++; - } -@@ -1531,56 +1651,6 @@ rtl8169_init_board(struct pci_dev *pdev, - RTL_W8(Config5, RTL_R8(Config5) & PMEStatus); - RTL_W8(Cfg9346, Cfg9346_Lock); - -- *ioaddr_out = ioaddr; -- *dev_out = dev; --out: -- return rc; -- --err_out_free_res: -- pci_release_regions(pdev); -- --err_out_mwi: -- pci_clear_mwi(pdev); -- --err_out_disable: -- pci_disable_device(pdev); -- --err_out_free_dev: -- free_netdev(dev); --err_out: -- *ioaddr_out = NULL; -- *dev_out = NULL; -- goto out; --} -- --static int __devinit --rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) --{ -- struct net_device *dev = NULL; -- struct rtl8169_private *tp; -- void __iomem *ioaddr = NULL; -- static int board_idx = -1; -- u8 autoneg, duplex; -- u16 speed; -- int i, rc; -- -- assert(pdev != NULL); -- assert(ent != NULL); -- -- board_idx++; -- -- if (netif_msg_drv(&debug)) { -- printk(KERN_INFO "%s Gigabit Ethernet driver %s loaded\n", -- MODULENAME, RTL8169_VERSION); -- } -- -- rc = rtl8169_init_board(pdev, &dev, &ioaddr); -- if (rc) -- return rc; -- -- tp = netdev_priv(dev); -- assert(ioaddr != NULL); -- - if (RTL_R8(PHYstatus) & TBI_Enable) { - tp->set_speed = rtl8169_set_speed_tbi; - tp->get_settings = rtl8169_gset_tbi; -@@ -1588,13 +1658,15 @@ rtl8169_init_one(struct pci_dev *pdev, c - tp->phy_reset_pending = rtl8169_tbi_reset_pending; - tp->link_ok = rtl8169_tbi_link_ok; - -- tp->phy_1000_ctrl_reg = PHY_Cap_1000_Full; /* Implied by TBI */ -+ tp->phy_1000_ctrl_reg = ADVERTISE_1000FULL; /* Implied by TBI */ - } else { - tp->set_speed = rtl8169_set_speed_xmii; - tp->get_settings = rtl8169_gset_xmii; - tp->phy_reset_enable = rtl8169_xmii_reset_enable; - tp->phy_reset_pending = rtl8169_xmii_reset_pending; - tp->link_ok = rtl8169_xmii_link_ok; -+ -+ dev->do_ioctl = rtl8169_ioctl; - } - - /* Get MAC address. FIXME: read EEPROM */ -@@ -1609,6 +1681,7 @@ rtl8169_init_one(struct pci_dev *pdev, c - dev->stop = rtl8169_close; - dev->tx_timeout = rtl8169_tx_timeout; - dev->set_multicast_list = rtl8169_set_rx_mode; -+ dev->set_mac_address = rtl8169_set_mac_addr; - dev->watchdog_timeo = RTL8169_TX_TIMEOUT; - dev->irq = pdev->irq; - dev->base_addr = (unsigned long) ioaddr; -@@ -1632,19 +1705,13 @@ #endif - tp->intr_mask = 0xffff; - tp->pci_dev = pdev; - tp->mmio_addr = ioaddr; -+ tp->align = rtl_cfg_info[ent->driver_data].align; - - spin_lock_init(&tp->lock); - - rc = register_netdev(dev); -- if (rc) { -- rtl8169_release_board(pdev, dev, ioaddr); -- return rc; -- } -- -- if (netif_msg_probe(tp)) { -- printk(KERN_DEBUG "%s: Identified chip type is '%s'.\n", -- dev->name, rtl_chip_info[tp->chipset].name); -- } -+ if (rc < 0) -+ goto err_out_unmap_5; - - pci_set_drvdata(pdev, dev); - -@@ -1653,38 +1720,29 @@ #endif - "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, " - "IRQ %d\n", - dev->name, -- rtl_chip_info[ent->driver_data].name, -+ rtl_chip_info[tp->chipset].name, - dev->base_addr, - dev->dev_addr[0], dev->dev_addr[1], - dev->dev_addr[2], dev->dev_addr[3], - dev->dev_addr[4], dev->dev_addr[5], dev->irq); - } - -- rtl8169_hw_phy_config(dev); -- -- dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n"); -- RTL_W8(0x82, 0x01); -+ rtl8169_init_phy(dev, tp); - -- if (tp->mac_version < RTL_GIGA_MAC_VER_E) { -- dprintk("Set PCI Latency=0x40\n"); -- pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40); -- } -- -- if (tp->mac_version == RTL_GIGA_MAC_VER_D) { -- dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n"); -- RTL_W8(0x82, 0x01); -- dprintk("Set PHY Reg 0x0bh = 0x00h\n"); -- mdio_write(ioaddr, 0x0b, 0x0000); //w 0x0b 15 0 0 -- } -- -- rtl8169_link_option(board_idx, &autoneg, &speed, &duplex); -- -- rtl8169_set_speed(dev, autoneg, speed, duplex); -- -- if ((RTL_R8(PHYstatus) & TBI_Enable) && netif_msg_link(tp)) -- printk(KERN_INFO PFX "%s: TBI auto-negotiating\n", dev->name); -+out: -+ return rc; - -- return 0; -+err_out_unmap_5: -+ iounmap(ioaddr); -+err_out_free_res_4: -+ pci_release_regions(pdev); -+err_out_mwi_3: -+ pci_clear_mwi(pdev); -+err_out_disable_2: -+ pci_disable_device(pdev); -+err_out_free_dev_1: -+ free_netdev(dev); -+ goto out; - } - - static void __devexit -@@ -1780,20 +1838,41 @@ rtl8169_hw_start(struct net_device *dev) - { - struct rtl8169_private *tp = netdev_priv(dev); - void __iomem *ioaddr = tp->mmio_addr; -+ struct pci_dev *pdev = tp->pci_dev; - u32 i; - - /* Soft reset the chip. */ - RTL_W8(ChipCmd, CmdReset); - - /* Check that the chip has finished the reset. */ -- for (i = 1000; i > 0; i--) { -+ for (i = 100; i > 0; i--) { - if ((RTL_R8(ChipCmd) & CmdReset) == 0) - break; -- udelay(10); -+ msleep_interruptible(1); -+ } -+ -+ if (tp->mac_version == RTL_GIGA_MAC_VER_13) { -+ pci_write_config_word(pdev, 0x68, 0x00); -+ pci_write_config_word(pdev, 0x69, 0x08); -+ } -+ -+ /* Undocumented stuff. */ -+ if (tp->mac_version == RTL_GIGA_MAC_VER_05) { -+ u16 cmd; -+ -+ /* Realtek's r1000_n.c driver uses '&& 0x01' here. Well... */ -+ if ((RTL_R8(Config2) & 0x07) & 0x01) -+ RTL_W32(0x7c, 0x0007ffff); -+ -+ RTL_W32(0x7c, 0x0007ff00); -+ -+ pci_read_config_word(pdev, PCI_COMMAND, &cmd); -+ cmd = cmd & 0xef; -+ pci_write_config_word(pdev, PCI_COMMAND, cmd); - } - -+ - RTL_W8(Cfg9346, Cfg9346_Unlock); -- RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); - RTL_W8(EarlyTxThres, EarlyTxThld); - - /* Low hurts. Let's disable the filtering. */ -@@ -1805,32 +1884,40 @@ rtl8169_hw_start(struct net_device *dev) - RTL_W32(RxConfig, i); - - /* Set DMA burst size and Interframe Gap Time */ -- RTL_W32(TxConfig, -- (TX_DMA_BURST << TxDMAShift) | (InterFrameGap << -- TxInterFrameGapShift)); -- tp->cp_cmd |= RTL_R16(CPlusCmd); -- RTL_W16(CPlusCmd, tp->cp_cmd); -+ RTL_W32(TxConfig, (TX_DMA_BURST << TxDMAShift) | -+ (InterFrameGap << TxInterFrameGapShift)); -+ -+ tp->cp_cmd |= RTL_R16(CPlusCmd) | PCIMulRW; - -- if ((tp->mac_version == RTL_GIGA_MAC_VER_D) || -- (tp->mac_version == RTL_GIGA_MAC_VER_E)) { -+ if ((tp->mac_version == RTL_GIGA_MAC_VER_02) || -+ (tp->mac_version == RTL_GIGA_MAC_VER_03)) { - dprintk(KERN_INFO PFX "Set MAC Reg C+CR Offset 0xE0. " - "Bit-3 and bit-14 MUST be 1\n"); -- tp->cp_cmd |= (1 << 14) | PCIMulRW; -- RTL_W16(CPlusCmd, tp->cp_cmd); -+ tp->cp_cmd |= (1 << 14); - } - -+ RTL_W16(CPlusCmd, tp->cp_cmd); -+ - /* - * Undocumented corner. Supposedly: - * (TxTimer << 12) | (TxPackets << 8) | (RxTimer << 4) | RxPackets - */ - RTL_W16(IntrMitigate, 0x0000); - -- RTL_W32(TxDescStartAddrLow, ((u64) tp->TxPhyAddr & DMA_32BIT_MASK)); -+ /* -+ * Magic spell: some iop3xx ARM board needs the TxDescAddrHigh -+ * register to be written before TxDescAddrLow to work. -+ * Switching from MMIO to I/O access fixes the issue as well. -+ */ - RTL_W32(TxDescStartAddrHigh, ((u64) tp->TxPhyAddr >> 32)); -- RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr & DMA_32BIT_MASK)); -+ RTL_W32(TxDescStartAddrLow, ((u64) tp->TxPhyAddr & DMA_32BIT_MASK)); - RTL_W32(RxDescAddrHigh, ((u64) tp->RxPhyAddr >> 32)); -+ RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr & DMA_32BIT_MASK)); -+ RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); - RTL_W8(Cfg9346, Cfg9346_Lock); -- udelay(10); -+ -+ /* Initially a 10 us delay. Turned it into a PCI commit. - FR */ -+ RTL_R8(IntrMask); - - RTL_W32(RxMissed, 0); - -@@ -1842,6 +1929,8 @@ rtl8169_hw_start(struct net_device *dev) - /* Enable all known interrupts by setting the interrupt mask. */ - RTL_W16(IntrMask, rtl8169_intr_mask); - -+ __rtl8169_set_mac_addr(dev, ioaddr); -+ - netif_start_queue(dev); - } - -@@ -1910,17 +1999,18 @@ static inline void rtl8169_map_to_asic(s - } - - static int rtl8169_alloc_rx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff, -- struct RxDesc *desc, int rx_buf_sz) -+ struct RxDesc *desc, int rx_buf_sz, -+ unsigned int align) - { - struct sk_buff *skb; - dma_addr_t mapping; - int ret = 0; - -- skb = dev_alloc_skb(rx_buf_sz + NET_IP_ALIGN); -+ skb = dev_alloc_skb(rx_buf_sz + align); - if (!skb) - goto err_out; - -- skb_reserve(skb, NET_IP_ALIGN); -+ skb_reserve(skb, align); - *sk_buff = skb; - - mapping = pci_map_single(pdev, skb->data, rx_buf_sz, -@@ -1953,15 +2043,15 @@ static u32 rtl8169_rx_fill(struct rtl816 - u32 start, u32 end) - { - u32 cur; -- -+ - for (cur = start; end - cur > 0; cur++) { - int ret, i = cur % NUM_RX_DESC; - - if (tp->Rx_skbuff[i]) - continue; -- -+ - ret = rtl8169_alloc_rx_skb(tp->pci_dev, tp->Rx_skbuff + i, -- tp->RxDescArray + i, tp->rx_buf_sz); -+ tp->RxDescArray + i, tp->rx_buf_sz, tp->align); - if (ret < 0) - break; - } -@@ -2190,8 +2280,8 @@ static int rtl8169_start_xmit(struct sk_ - dma_addr_t mapping; - u32 status, len; - u32 opts1; -- int ret = 0; -- -+ int ret = NETDEV_TX_OK; -+ - if (unlikely(TX_BUFFS_AVAIL(tp) < skb_shinfo(skb)->nr_frags)) { - if (netif_msg_drv(tp)) { - printk(KERN_ERR -@@ -2255,7 +2345,7 @@ out: - - err_stop: - netif_stop_queue(dev); -- ret = 1; -+ ret = NETDEV_TX_BUSY; - err_update_stats: - tp->stats.tx_dropped++; - goto out; -@@ -2372,16 +2462,17 @@ static inline void rtl8169_rx_csum(struc - } - - static inline int rtl8169_try_rx_copy(struct sk_buff **sk_buff, int pkt_size, -- struct RxDesc *desc, int rx_buf_sz) -+ struct RxDesc *desc, int rx_buf_sz, -+ unsigned int align) - { - int ret = -1; - - if (pkt_size < rx_copybreak) { - struct sk_buff *skb; - -- skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN); -+ skb = dev_alloc_skb(pkt_size + align); - if (skb) { -- skb_reserve(skb, NET_IP_ALIGN); -+ skb_reserve(skb, align); - eth_copy_and_sum(skb, sk_buff[0]->data, pkt_size, 0); - *sk_buff = skb; - rtl8169_mark_to_asic(desc, rx_buf_sz); -@@ -2427,6 +2518,10 @@ rtl8169_rx_interrupt(struct net_device * - tp->stats.rx_length_errors++; - if (status & RxCRC) - tp->stats.rx_crc_errors++; -+ if (status & RxFOVF) { -+ rtl8169_schedule_work(dev, rtl8169_reset_task); -+ tp->stats.rx_fifo_errors++; -+ } - rtl8169_mark_to_asic(desc, tp->rx_buf_sz); - } else { - struct sk_buff *skb = tp->Rx_skbuff[entry]; -@@ -2447,13 +2542,13 @@ rtl8169_rx_interrupt(struct net_device * - } - - rtl8169_rx_csum(skb, desc); -- -+ - pci_dma_sync_single_for_cpu(tp->pci_dev, - le64_to_cpu(desc->addr), tp->rx_buf_sz, - PCI_DMA_FROMDEVICE); - - if (rtl8169_try_rx_copy(&skb, pkt_size, desc, -- tp->rx_buf_sz)) { -+ tp->rx_buf_sz, tp->align)) { - pci_action = pci_unmap_single; - tp->Rx_skbuff[entry] = NULL; - } -@@ -2543,7 +2638,7 @@ #ifdef CONFIG_R8169_NAPI - __netif_rx_schedule(dev); - else if (netif_msg_intr(tp)) { - printk(KERN_INFO "%s: interrupt %04x taken in poll\n", -- dev->name, status); -+ dev->name, status); - } - break; - #else -@@ -2716,6 +2811,15 @@ rtl8169_set_rx_mode(struct net_device *d - tmp = rtl8169_rx_config | rx_mode | - (RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask); - -+ if ((tp->mac_version == RTL_GIGA_MAC_VER_11) || -+ (tp->mac_version == RTL_GIGA_MAC_VER_12) || -+ (tp->mac_version == RTL_GIGA_MAC_VER_13) || -+ (tp->mac_version == RTL_GIGA_MAC_VER_14) || -+ (tp->mac_version == RTL_GIGA_MAC_VER_15)) { -+ mc_filter[0] = 0xffffffff; -+ mc_filter[1] = 0xffffffff; -+ } -+ - RTL_W32(RxConfig, tmp); - RTL_W32(MAR0 + 0, mc_filter[0]); - RTL_W32(MAR0 + 4, mc_filter[1]); -@@ -2741,7 +2845,7 @@ static struct net_device_stats *rtl8169_ - RTL_W32(RxMissed, 0); - spin_unlock_irqrestore(&tp->lock, flags); - } -- -+ - return &tp->stats; - } - diff --git a/debian/patches/features/all/drivers/scsi-ahci-cleanup-1.patch b/debian/patches/features/all/drivers/scsi-ahci-cleanup-1.patch deleted file mode 100644 index 823f3a79b..000000000 --- a/debian/patches/features/all/drivers/scsi-ahci-cleanup-1.patch +++ /dev/null @@ -1,183 +0,0 @@ -# [PATCH] The redefinition of ahci_start_engine() and ahci_stop_engine() -# 5457f2194ad198a0aba4190ec99a6a81846fdca5 - -diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c -index 77e7202..f1516ca 100644 ---- a/drivers/scsi/ahci.c -+++ b/drivers/scsi/ahci.c -@@ -205,6 +205,8 @@ static irqreturn_t ahci_interrupt (int i - static void ahci_irq_clear(struct ata_port *ap); - static int ahci_port_start(struct ata_port *ap); - static void ahci_port_stop(struct ata_port *ap); -+static int ahci_start_engine(void __iomem *port_mmio); -+static int ahci_stop_engine(void __iomem *port_mmio); - static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf); - static void ahci_qc_prep(struct ata_queued_cmd *qc); - static u8 ahci_check_status(struct ata_port *ap); -@@ -508,41 +510,64 @@ static void ahci_scr_write (struct ata_p - writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4)); - } - --static int ahci_stop_engine(struct ata_port *ap) -+static int ahci_stop_engine(void __iomem *port_mmio) - { -- void __iomem *mmio = ap->host_set->mmio_base; -- void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); -- int work; - u32 tmp; - - tmp = readl(port_mmio + PORT_CMD); -+ -+ /* Check if the HBA is idle */ -+ if ((tmp & (PORT_CMD_START | PORT_CMD_LIST_ON)) == 0) -+ return 0; -+ -+ /* Setting HBA to idle */ - tmp &= ~PORT_CMD_START; - writel(tmp, port_mmio + PORT_CMD); - -- /* wait for engine to stop. TODO: this could be -+ /* wait for engine to stop. This could be - * as long as 500 msec - */ -- work = 1000; -- while (work-- > 0) { -- tmp = readl(port_mmio + PORT_CMD); -- if ((tmp & PORT_CMD_LIST_ON) == 0) -- return 0; -- udelay(10); -- } -+ tmp = ata_wait_register(port_mmio + PORT_CMD, -+ PORT_CMD_LIST_ON, PORT_CMD_LIST_ON, 1, 500); -+ if(tmp & PORT_CMD_LIST_ON) -+ return -EIO; - -- return -EIO; -+ return 0; - } - --static void ahci_start_engine(struct ata_port *ap) -+static int ahci_start_engine(void __iomem *port_mmio) - { -- void __iomem *mmio = ap->host_set->mmio_base; -- void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); - u32 tmp; - -+ /* -+ * Get current status -+ */ - tmp = readl(port_mmio + PORT_CMD); -+ -+ /* -+ * AHCI rev 1.1 section 10.3.1: -+ * Software shall not set PxCMD.ST to '1' until it verifies -+ * that PxCMD.CR is '0' and has set PxCMD.FRE to '1' -+ */ -+ if ((tmp & PORT_CMD_FIS_RX) == 0) -+ return -EPERM; -+ -+ /* -+ * wait for engine to become idle. -+ */ -+ tmp = ata_wait_register(port_mmio + PORT_CMD, -+ PORT_CMD_LIST_ON, PORT_CMD_LIST_ON, 1,500); -+ if(tmp & PORT_CMD_LIST_ON) -+ return -EBUSY; -+ -+ /* -+ * Start DMA -+ */ - tmp |= PORT_CMD_START; - writel(tmp, port_mmio + PORT_CMD); - readl(port_mmio + PORT_CMD); /* flush */ -+ -+ return 0; - } - - static unsigned int ahci_dev_classify(struct ata_port *ap) -@@ -626,7 +651,7 @@ static int ahci_softreset(struct ata_por - } - - /* prepare for SRST (AHCI-1.1 10.4.1) */ -- rc = ahci_stop_engine(ap); -+ rc = ahci_stop_engine(port_mmio); - if (rc) { - reason = "failed to stop engine"; - goto fail_restart; -@@ -647,7 +672,7 @@ static int ahci_softreset(struct ata_por - } - - /* restart engine */ -- ahci_start_engine(ap); -+ ahci_start_engine(port_mmio); - - ata_tf_init(ap->device, &tf); - fis = pp->cmd_tbl; -@@ -706,7 +731,7 @@ static int ahci_softreset(struct ata_por - return 0; - - fail_restart: -- ahci_start_engine(ap); -+ ahci_start_engine(port_mmio); - fail: - ata_port_printk(ap, KERN_ERR, "softreset failed (%s)\n", reason); - return rc; -@@ -717,11 +742,13 @@ static int ahci_hardreset(struct ata_por - struct ahci_port_priv *pp = ap->private_data; - u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; - struct ata_taskfile tf; -+ void __iomem *mmio = ap->host_set->mmio_base; -+ void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); - int rc; - - DPRINTK("ENTER\n"); - -- ahci_stop_engine(ap); -+ ahci_stop_engine(port_mmio); - - /* clear D2H reception area to properly wait for D2H FIS */ - ata_tf_init(ap->device, &tf); -@@ -730,7 +757,7 @@ static int ahci_hardreset(struct ata_por - - rc = sata_std_hardreset(ap, class); - -- ahci_start_engine(ap); -+ ahci_start_engine(port_mmio); - - if (rc == 0 && ata_port_online(ap)) - *class = ahci_dev_classify(ap); -@@ -1052,10 +1079,13 @@ static void ahci_thaw(struct ata_port *a - - static void ahci_error_handler(struct ata_port *ap) - { -+ void __iomem *mmio = ap->host_set->mmio_base; -+ void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); -+ - if (!(ap->pflags & ATA_PFLAG_FROZEN)) { - /* restart engine */ -- ahci_stop_engine(ap); -- ahci_start_engine(ap); -+ ahci_stop_engine(port_mmio); -+ ahci_start_engine(port_mmio); - } - - /* perform recovery */ -@@ -1066,14 +1096,16 @@ static void ahci_error_handler(struct at - static void ahci_post_internal_cmd(struct ata_queued_cmd *qc) - { - struct ata_port *ap = qc->ap; -+ void __iomem *mmio = ap->host_set->mmio_base; -+ void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); - - if (qc->flags & ATA_QCFLAG_FAILED) - qc->err_mask |= AC_ERR_OTHER; - - if (qc->err_mask) { - /* make DMA engine forget about the failed command */ -- ahci_stop_engine(ap); -- ahci_start_engine(ap); -+ ahci_stop_engine(port_mmio); -+ ahci_start_engine(port_mmio); - } - } - diff --git a/debian/patches/features/all/drivers/scsi-ahci-cleanup-2.patch b/debian/patches/features/all/drivers/scsi-ahci-cleanup-2.patch deleted file mode 100644 index ca4937930..000000000 --- a/debian/patches/features/all/drivers/scsi-ahci-cleanup-2.patch +++ /dev/null @@ -1,297 +0,0 @@ -# [PATCH] ahci: relocate several internal functions -# 254950cd56fee220c9d548f3e57211b95976ba64 - -diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c -index f1516ca..92e2b95 100644 ---- a/drivers/scsi/ahci.c -+++ b/drivers/scsi/ahci.c -@@ -205,8 +205,6 @@ static irqreturn_t ahci_interrupt (int i - static void ahci_irq_clear(struct ata_port *ap); - static int ahci_port_start(struct ata_port *ap); - static void ahci_port_stop(struct ata_port *ap); --static int ahci_start_engine(void __iomem *port_mmio); --static int ahci_stop_engine(void __iomem *port_mmio); - static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf); - static void ahci_qc_prep(struct ata_queued_cmd *qc); - static u8 ahci_check_status(struct ata_port *ap); -@@ -374,108 +372,6 @@ static inline void __iomem *ahci_port_ba - return (void __iomem *) ahci_port_base_ul((unsigned long)base, port); - } - --static int ahci_port_start(struct ata_port *ap) --{ -- struct device *dev = ap->host_set->dev; -- struct ahci_host_priv *hpriv = ap->host_set->private_data; -- struct ahci_port_priv *pp; -- void __iomem *mmio = ap->host_set->mmio_base; -- void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); -- void *mem; -- dma_addr_t mem_dma; -- int rc; -- -- pp = kmalloc(sizeof(*pp), GFP_KERNEL); -- if (!pp) -- return -ENOMEM; -- memset(pp, 0, sizeof(*pp)); -- -- rc = ata_pad_alloc(ap, dev); -- if (rc) { -- kfree(pp); -- return rc; -- } -- -- mem = dma_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL); -- if (!mem) { -- ata_pad_free(ap, dev); -- kfree(pp); -- return -ENOMEM; -- } -- memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ); -- -- /* -- * First item in chunk of DMA memory: 32-slot command table, -- * 32 bytes each in size -- */ -- pp->cmd_slot = mem; -- pp->cmd_slot_dma = mem_dma; -- -- mem += AHCI_CMD_SLOT_SZ; -- mem_dma += AHCI_CMD_SLOT_SZ; -- -- /* -- * Second item: Received-FIS area -- */ -- pp->rx_fis = mem; -- pp->rx_fis_dma = mem_dma; -- -- mem += AHCI_RX_FIS_SZ; -- mem_dma += AHCI_RX_FIS_SZ; -- -- /* -- * Third item: data area for storing a single command -- * and its scatter-gather table -- */ -- pp->cmd_tbl = mem; -- pp->cmd_tbl_dma = mem_dma; -- -- ap->private_data = pp; -- -- if (hpriv->cap & HOST_CAP_64) -- writel((pp->cmd_slot_dma >> 16) >> 16, port_mmio + PORT_LST_ADDR_HI); -- writel(pp->cmd_slot_dma & 0xffffffff, port_mmio + PORT_LST_ADDR); -- readl(port_mmio + PORT_LST_ADDR); /* flush */ -- -- if (hpriv->cap & HOST_CAP_64) -- writel((pp->rx_fis_dma >> 16) >> 16, port_mmio + PORT_FIS_ADDR_HI); -- writel(pp->rx_fis_dma & 0xffffffff, port_mmio + PORT_FIS_ADDR); -- readl(port_mmio + PORT_FIS_ADDR); /* flush */ -- -- writel(PORT_CMD_ICC_ACTIVE | PORT_CMD_FIS_RX | -- PORT_CMD_POWER_ON | PORT_CMD_SPIN_UP | -- PORT_CMD_START, port_mmio + PORT_CMD); -- readl(port_mmio + PORT_CMD); /* flush */ -- -- return 0; --} -- -- --static void ahci_port_stop(struct ata_port *ap) --{ -- struct device *dev = ap->host_set->dev; -- struct ahci_port_priv *pp = ap->private_data; -- void __iomem *mmio = ap->host_set->mmio_base; -- void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); -- u32 tmp; -- -- tmp = readl(port_mmio + PORT_CMD); -- tmp &= ~(PORT_CMD_START | PORT_CMD_FIS_RX); -- writel(tmp, port_mmio + PORT_CMD); -- readl(port_mmio + PORT_CMD); /* flush */ -- -- /* spec says 500 msecs for each PORT_CMD_{START,FIS_RX} bit, so -- * this is slightly incorrect. -- */ -- msleep(500); -- -- ap->private_data = NULL; -- dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, -- pp->cmd_slot, pp->cmd_slot_dma); -- ata_pad_free(ap, dev); -- kfree(pp); --} -- - static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in) - { - unsigned int sc_reg; -@@ -510,31 +406,6 @@ static void ahci_scr_write (struct ata_p - writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4)); - } - --static int ahci_stop_engine(void __iomem *port_mmio) --{ -- u32 tmp; -- -- tmp = readl(port_mmio + PORT_CMD); -- -- /* Check if the HBA is idle */ -- if ((tmp & (PORT_CMD_START | PORT_CMD_LIST_ON)) == 0) -- return 0; -- -- /* Setting HBA to idle */ -- tmp &= ~PORT_CMD_START; -- writel(tmp, port_mmio + PORT_CMD); -- -- /* wait for engine to stop. This could be -- * as long as 500 msec -- */ -- tmp = ata_wait_register(port_mmio + PORT_CMD, -- PORT_CMD_LIST_ON, PORT_CMD_LIST_ON, 1, 500); -- if(tmp & PORT_CMD_LIST_ON) -- return -EIO; -- -- return 0; --} -- - static int ahci_start_engine(void __iomem *port_mmio) - { - u32 tmp; -@@ -570,6 +441,31 @@ static int ahci_start_engine(void __iome - return 0; - } - -+static int ahci_stop_engine(void __iomem *port_mmio) -+{ -+ u32 tmp; -+ -+ tmp = readl(port_mmio + PORT_CMD); -+ -+ /* Check if the HBA is idle */ -+ if ((tmp & (PORT_CMD_START | PORT_CMD_LIST_ON)) == 0) -+ return 0; -+ -+ /* Setting HBA to idle */ -+ tmp &= ~PORT_CMD_START; -+ writel(tmp, port_mmio + PORT_CMD); -+ -+ /* wait for engine to stop. This could be -+ * as long as 500 msec -+ */ -+ tmp = ata_wait_register(port_mmio + PORT_CMD, -+ PORT_CMD_LIST_ON, PORT_CMD_LIST_ON, 1, 500); -+ if(tmp & PORT_CMD_LIST_ON) -+ return -EIO; -+ -+ return 0; -+} -+ - static unsigned int ahci_dev_classify(struct ata_port *ap) - { - void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; -@@ -1109,6 +1005,107 @@ static void ahci_post_internal_cmd(struc - } - } - -+static int ahci_port_start(struct ata_port *ap) -+{ -+ struct device *dev = ap->host_set->dev; -+ struct ahci_host_priv *hpriv = ap->host_set->private_data; -+ struct ahci_port_priv *pp; -+ void __iomem *mmio = ap->host_set->mmio_base; -+ void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); -+ void *mem; -+ dma_addr_t mem_dma; -+ int rc; -+ -+ pp = kmalloc(sizeof(*pp), GFP_KERNEL); -+ if (!pp) -+ return -ENOMEM; -+ memset(pp, 0, sizeof(*pp)); -+ -+ rc = ata_pad_alloc(ap, dev); -+ if (rc) { -+ kfree(pp); -+ return rc; -+ } -+ -+ mem = dma_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL); -+ if (!mem) { -+ ata_pad_free(ap, dev); -+ kfree(pp); -+ return -ENOMEM; -+ } -+ memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ); -+ -+ /* -+ * First item in chunk of DMA memory: 32-slot command table, -+ * 32 bytes each in size -+ */ -+ pp->cmd_slot = mem; -+ pp->cmd_slot_dma = mem_dma; -+ -+ mem += AHCI_CMD_SLOT_SZ; -+ mem_dma += AHCI_CMD_SLOT_SZ; -+ -+ /* -+ * Second item: Received-FIS area -+ */ -+ pp->rx_fis = mem; -+ pp->rx_fis_dma = mem_dma; -+ -+ mem += AHCI_RX_FIS_SZ; -+ mem_dma += AHCI_RX_FIS_SZ; -+ -+ /* -+ * Third item: data area for storing a single command -+ * and its scatter-gather table -+ */ -+ pp->cmd_tbl = mem; -+ pp->cmd_tbl_dma = mem_dma; -+ -+ ap->private_data = pp; -+ -+ if (hpriv->cap & HOST_CAP_64) -+ writel((pp->cmd_slot_dma >> 16) >> 16, port_mmio + PORT_LST_ADDR_HI); -+ writel(pp->cmd_slot_dma & 0xffffffff, port_mmio + PORT_LST_ADDR); -+ readl(port_mmio + PORT_LST_ADDR); /* flush */ -+ -+ if (hpriv->cap & HOST_CAP_64) -+ writel((pp->rx_fis_dma >> 16) >> 16, port_mmio + PORT_FIS_ADDR_HI); -+ writel(pp->rx_fis_dma & 0xffffffff, port_mmio + PORT_FIS_ADDR); -+ readl(port_mmio + PORT_FIS_ADDR); /* flush */ -+ -+ writel(PORT_CMD_ICC_ACTIVE | PORT_CMD_FIS_RX | -+ PORT_CMD_POWER_ON | PORT_CMD_SPIN_UP | -+ PORT_CMD_START, port_mmio + PORT_CMD); -+ readl(port_mmio + PORT_CMD); /* flush */ -+ -+ return 0; -+} -+ -+static void ahci_port_stop(struct ata_port *ap) -+{ -+ struct device *dev = ap->host_set->dev; -+ struct ahci_port_priv *pp = ap->private_data; -+ void __iomem *mmio = ap->host_set->mmio_base; -+ void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); -+ u32 tmp; -+ -+ tmp = readl(port_mmio + PORT_CMD); -+ tmp &= ~(PORT_CMD_START | PORT_CMD_FIS_RX); -+ writel(tmp, port_mmio + PORT_CMD); -+ readl(port_mmio + PORT_CMD); /* flush */ -+ -+ /* spec says 500 msecs for each PORT_CMD_{START,FIS_RX} bit, so -+ * this is slightly incorrect. -+ */ -+ msleep(500); -+ -+ ap->private_data = NULL; -+ dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, -+ pp->cmd_slot, pp->cmd_slot_dma); -+ ata_pad_free(ap, dev); -+ kfree(pp); -+} -+ - static void ahci_setup_port(struct ata_ioports *port, unsigned long base, - unsigned int port_idx) - { diff --git a/debian/patches/features/all/drivers/scsi-ahci-cleanup-3.patch b/debian/patches/features/all/drivers/scsi-ahci-cleanup-3.patch deleted file mode 100644 index b78223d59..000000000 --- a/debian/patches/features/all/drivers/scsi-ahci-cleanup-3.patch +++ /dev/null @@ -1,68 +0,0 @@ -# [PATCH] ahci: cosmetic changes to ahci_start/stop_engine() -# d8fcd116d203dfe2f6c272d0cd67724b172f1bc2 - -diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c -index 92e2b95..ee00aed 100644 ---- a/drivers/scsi/ahci.c -+++ b/drivers/scsi/ahci.c -@@ -410,30 +410,23 @@ static int ahci_start_engine(void __iome - { - u32 tmp; - -- /* -- * Get current status -- */ -+ /* get current status */ - tmp = readl(port_mmio + PORT_CMD); - -- /* -- * AHCI rev 1.1 section 10.3.1: -+ /* AHCI rev 1.1 section 10.3.1: - * Software shall not set PxCMD.ST to '1' until it verifies - * that PxCMD.CR is '0' and has set PxCMD.FRE to '1' - */ - if ((tmp & PORT_CMD_FIS_RX) == 0) - return -EPERM; - -- /* -- * wait for engine to become idle. -- */ -+ /* wait for engine to become idle */ - tmp = ata_wait_register(port_mmio + PORT_CMD, - PORT_CMD_LIST_ON, PORT_CMD_LIST_ON, 1,500); -- if(tmp & PORT_CMD_LIST_ON) -+ if (tmp & PORT_CMD_LIST_ON) - return -EBUSY; - -- /* -- * Start DMA -- */ -+ /* start DMA */ - tmp |= PORT_CMD_START; - writel(tmp, port_mmio + PORT_CMD); - readl(port_mmio + PORT_CMD); /* flush */ -@@ -447,20 +440,18 @@ static int ahci_stop_engine(void __iomem - - tmp = readl(port_mmio + PORT_CMD); - -- /* Check if the HBA is idle */ -+ /* check if the HBA is idle */ - if ((tmp & (PORT_CMD_START | PORT_CMD_LIST_ON)) == 0) - return 0; - -- /* Setting HBA to idle */ -+ /* setting HBA to idle */ - tmp &= ~PORT_CMD_START; - writel(tmp, port_mmio + PORT_CMD); - -- /* wait for engine to stop. This could be -- * as long as 500 msec -- */ -+ /* wait for engine to stop. This could be as long as 500 msec */ - tmp = ata_wait_register(port_mmio + PORT_CMD, - PORT_CMD_LIST_ON, PORT_CMD_LIST_ON, 1, 500); -- if(tmp & PORT_CMD_LIST_ON) -+ if (tmp & PORT_CMD_LIST_ON) - return -EIO; - - return 0; diff --git a/debian/patches/features/all/drivers/scsi-ahci-cleanup-4.patch b/debian/patches/features/all/drivers/scsi-ahci-cleanup-4.patch deleted file mode 100644 index 41440f9ab..000000000 --- a/debian/patches/features/all/drivers/scsi-ahci-cleanup-4.patch +++ /dev/null @@ -1,42 +0,0 @@ -# [PATCH] ahci: simplify ahci_start_engine() -# 9f5920567bfabbd1be26112a31c44652b6587394 - -diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c -index ee00aed..e02b9c6 100644 ---- a/drivers/scsi/ahci.c -+++ b/drivers/scsi/ahci.c -@@ -406,32 +406,15 @@ static void ahci_scr_write (struct ata_p - writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4)); - } - --static int ahci_start_engine(void __iomem *port_mmio) -+static void ahci_start_engine(void __iomem *port_mmio) - { - u32 tmp; - -- /* get current status */ -- tmp = readl(port_mmio + PORT_CMD); -- -- /* AHCI rev 1.1 section 10.3.1: -- * Software shall not set PxCMD.ST to '1' until it verifies -- * that PxCMD.CR is '0' and has set PxCMD.FRE to '1' -- */ -- if ((tmp & PORT_CMD_FIS_RX) == 0) -- return -EPERM; -- -- /* wait for engine to become idle */ -- tmp = ata_wait_register(port_mmio + PORT_CMD, -- PORT_CMD_LIST_ON, PORT_CMD_LIST_ON, 1,500); -- if (tmp & PORT_CMD_LIST_ON) -- return -EBUSY; -- - /* start DMA */ -+ tmp = readl(port_mmio + PORT_CMD); - tmp |= PORT_CMD_START; - writel(tmp, port_mmio + PORT_CMD); - readl(port_mmio + PORT_CMD); /* flush */ -- -- return 0; - } - - static int ahci_stop_engine(void __iomem *port_mmio) diff --git a/debian/patches/features/all/drivers/scsi-ahci-suspend-1.patch b/debian/patches/features/all/drivers/scsi-ahci-suspend-1.patch deleted file mode 100644 index 325c15710..000000000 --- a/debian/patches/features/all/drivers/scsi-ahci-suspend-1.patch +++ /dev/null @@ -1,281 +0,0 @@ -# [PATCH] libata: improve driver initialization and deinitialization -# 0be0aa98985dfec42502c0d0af2a1baff9bdb19f - -diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c -index e02b9c6..fb71fa7 100644 ---- a/drivers/scsi/ahci.c -+++ b/drivers/scsi/ahci.c -@@ -92,7 +92,9 @@ enum { - HOST_AHCI_EN = (1 << 31), /* AHCI enabled */ - - /* HOST_CAP bits */ -+ HOST_CAP_SSC = (1 << 14), /* Slumber capable */ - HOST_CAP_CLO = (1 << 24), /* Command List Override support */ -+ HOST_CAP_SSS = (1 << 27), /* Staggered Spin-up */ - HOST_CAP_NCQ = (1 << 30), /* Native Command Queueing */ - HOST_CAP_64 = (1 << 31), /* PCI DAC (64-bit DMA) support */ - -@@ -155,6 +157,7 @@ enum { - PORT_CMD_SPIN_UP = (1 << 1), /* Spin up device */ - PORT_CMD_START = (1 << 0), /* Enable port DMA engine */ - -+ PORT_CMD_ICC_MASK = (0xf << 28), /* i/f ICC state mask */ - PORT_CMD_ICC_ACTIVE = (0x1 << 28), /* Put i/f in active state */ - PORT_CMD_ICC_PARTIAL = (0x2 << 28), /* Put i/f in partial state */ - PORT_CMD_ICC_SLUMBER = (0x6 << 28), /* Put i/f in slumber state */ -@@ -440,6 +443,135 @@ static int ahci_stop_engine(void __iomem - return 0; - } - -+static void ahci_start_fis_rx(void __iomem *port_mmio, u32 cap, -+ dma_addr_t cmd_slot_dma, dma_addr_t rx_fis_dma) -+{ -+ u32 tmp; -+ -+ /* set FIS registers */ -+ if (cap & HOST_CAP_64) -+ writel((cmd_slot_dma >> 16) >> 16, port_mmio + PORT_LST_ADDR_HI); -+ writel(cmd_slot_dma & 0xffffffff, port_mmio + PORT_LST_ADDR); -+ -+ if (cap & HOST_CAP_64) -+ writel((rx_fis_dma >> 16) >> 16, port_mmio + PORT_FIS_ADDR_HI); -+ writel(rx_fis_dma & 0xffffffff, port_mmio + PORT_FIS_ADDR); -+ -+ /* enable FIS reception */ -+ tmp = readl(port_mmio + PORT_CMD); -+ tmp |= PORT_CMD_FIS_RX; -+ writel(tmp, port_mmio + PORT_CMD); -+ -+ /* flush */ -+ readl(port_mmio + PORT_CMD); -+} -+ -+static int ahci_stop_fis_rx(void __iomem *port_mmio) -+{ -+ u32 tmp; -+ -+ /* disable FIS reception */ -+ tmp = readl(port_mmio + PORT_CMD); -+ tmp &= ~PORT_CMD_FIS_RX; -+ writel(tmp, port_mmio + PORT_CMD); -+ -+ /* wait for completion, spec says 500ms, give it 1000 */ -+ tmp = ata_wait_register(port_mmio + PORT_CMD, PORT_CMD_FIS_ON, -+ PORT_CMD_FIS_ON, 10, 1000); -+ if (tmp & PORT_CMD_FIS_ON) -+ return -EBUSY; -+ -+ return 0; -+} -+ -+static void ahci_power_up(void __iomem *port_mmio, u32 cap) -+{ -+ u32 cmd; -+ -+ cmd = readl(port_mmio + PORT_CMD) & ~PORT_CMD_ICC_MASK; -+ -+ /* spin up device */ -+ if (cap & HOST_CAP_SSS) { -+ cmd |= PORT_CMD_SPIN_UP; -+ writel(cmd, port_mmio + PORT_CMD); -+ } -+ -+ /* wake up link */ -+ writel(cmd | PORT_CMD_ICC_ACTIVE, port_mmio + PORT_CMD); -+} -+ -+static void ahci_power_down(void __iomem *port_mmio, u32 cap) -+{ -+ u32 cmd, scontrol; -+ -+ cmd = readl(port_mmio + PORT_CMD) & ~PORT_CMD_ICC_MASK; -+ -+ if (cap & HOST_CAP_SSC) { -+ /* enable transitions to slumber mode */ -+ scontrol = readl(port_mmio + PORT_SCR_CTL); -+ if ((scontrol & 0x0f00) > 0x100) { -+ scontrol &= ~0xf00; -+ writel(scontrol, port_mmio + PORT_SCR_CTL); -+ } -+ -+ /* put device into slumber mode */ -+ writel(cmd | PORT_CMD_ICC_SLUMBER, port_mmio + PORT_CMD); -+ -+ /* wait for the transition to complete */ -+ ata_wait_register(port_mmio + PORT_CMD, PORT_CMD_ICC_SLUMBER, -+ PORT_CMD_ICC_SLUMBER, 1, 50); -+ } -+ -+ /* put device into listen mode */ -+ if (cap & HOST_CAP_SSS) { -+ /* first set PxSCTL.DET to 0 */ -+ scontrol = readl(port_mmio + PORT_SCR_CTL); -+ scontrol &= ~0xf; -+ writel(scontrol, port_mmio + PORT_SCR_CTL); -+ -+ /* then set PxCMD.SUD to 0 */ -+ cmd &= ~PORT_CMD_SPIN_UP; -+ writel(cmd, port_mmio + PORT_CMD); -+ } -+} -+ -+static void ahci_init_port(void __iomem *port_mmio, u32 cap, -+ dma_addr_t cmd_slot_dma, dma_addr_t rx_fis_dma) -+{ -+ /* power up */ -+ ahci_power_up(port_mmio, cap); -+ -+ /* enable FIS reception */ -+ ahci_start_fis_rx(port_mmio, cap, cmd_slot_dma, rx_fis_dma); -+ -+ /* enable DMA */ -+ ahci_start_engine(port_mmio); -+} -+ -+static int ahci_deinit_port(void __iomem *port_mmio, u32 cap, const char **emsg) -+{ -+ int rc; -+ -+ /* disable DMA */ -+ rc = ahci_stop_engine(port_mmio); -+ if (rc) { -+ *emsg = "failed to stop engine"; -+ return rc; -+ } -+ -+ /* disable FIS reception */ -+ rc = ahci_stop_fis_rx(port_mmio); -+ if (rc) { -+ *emsg = "failed stop FIS RX"; -+ return rc; -+ } -+ -+ /* put device into slumber mode */ -+ ahci_power_down(port_mmio, cap); -+ -+ return 0; -+} -+ - static unsigned int ahci_dev_classify(struct ata_port *ap) - { - void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; -@@ -1037,20 +1169,8 @@ static int ahci_port_start(struct ata_po - - ap->private_data = pp; - -- if (hpriv->cap & HOST_CAP_64) -- writel((pp->cmd_slot_dma >> 16) >> 16, port_mmio + PORT_LST_ADDR_HI); -- writel(pp->cmd_slot_dma & 0xffffffff, port_mmio + PORT_LST_ADDR); -- readl(port_mmio + PORT_LST_ADDR); /* flush */ -- -- if (hpriv->cap & HOST_CAP_64) -- writel((pp->rx_fis_dma >> 16) >> 16, port_mmio + PORT_FIS_ADDR_HI); -- writel(pp->rx_fis_dma & 0xffffffff, port_mmio + PORT_FIS_ADDR); -- readl(port_mmio + PORT_FIS_ADDR); /* flush */ -- -- writel(PORT_CMD_ICC_ACTIVE | PORT_CMD_FIS_RX | -- PORT_CMD_POWER_ON | PORT_CMD_SPIN_UP | -- PORT_CMD_START, port_mmio + PORT_CMD); -- readl(port_mmio + PORT_CMD); /* flush */ -+ /* initialize port */ -+ ahci_init_port(port_mmio, hpriv->cap, pp->cmd_slot_dma, pp->rx_fis_dma); - - return 0; - } -@@ -1058,20 +1178,17 @@ static int ahci_port_start(struct ata_po - static void ahci_port_stop(struct ata_port *ap) - { - struct device *dev = ap->host_set->dev; -+ struct ahci_host_priv *hpriv = ap->host_set->private_data; - struct ahci_port_priv *pp = ap->private_data; - void __iomem *mmio = ap->host_set->mmio_base; - void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); -- u32 tmp; -- -- tmp = readl(port_mmio + PORT_CMD); -- tmp &= ~(PORT_CMD_START | PORT_CMD_FIS_RX); -- writel(tmp, port_mmio + PORT_CMD); -- readl(port_mmio + PORT_CMD); /* flush */ -+ const char *emsg = NULL; -+ int rc; - -- /* spec says 500 msecs for each PORT_CMD_{START,FIS_RX} bit, so -- * this is slightly incorrect. -- */ -- msleep(500); -+ /* de-initialize port */ -+ rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg); -+ if (rc) -+ ata_port_printk(ap, KERN_WARNING, "%s (%d)\n", emsg, rc); - - ap->private_data = NULL; - dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, -@@ -1099,7 +1216,7 @@ static int ahci_host_init(struct ata_pro - struct pci_dev *pdev = to_pci_dev(probe_ent->dev); - void __iomem *mmio = probe_ent->mmio_base; - u32 tmp, cap_save; -- unsigned int i, j, using_dac; -+ unsigned int i, using_dac; - int rc; - void __iomem *port_mmio; - -@@ -1175,6 +1292,8 @@ static int ahci_host_init(struct ata_pro - } - - for (i = 0; i < probe_ent->n_ports; i++) { -+ const char *emsg = NULL; -+ - #if 0 /* BIOSen initialize this incorrectly */ - if (!(hpriv->port_map & (1 << i))) - continue; -@@ -1187,43 +1306,24 @@ #endif - (unsigned long) mmio, i); - - /* make sure port is not active */ -- tmp = readl(port_mmio + PORT_CMD); -- VPRINTK("PORT_CMD 0x%x\n", tmp); -- if (tmp & (PORT_CMD_LIST_ON | PORT_CMD_FIS_ON | -- PORT_CMD_FIS_RX | PORT_CMD_START)) { -- tmp &= ~(PORT_CMD_LIST_ON | PORT_CMD_FIS_ON | -- PORT_CMD_FIS_RX | PORT_CMD_START); -- writel(tmp, port_mmio + PORT_CMD); -- readl(port_mmio + PORT_CMD); /* flush */ -- -- /* spec says 500 msecs for each bit, so -- * this is slightly incorrect. -- */ -- msleep(500); -- } -- -- writel(PORT_CMD_SPIN_UP, port_mmio + PORT_CMD); -- -- j = 0; -- while (j < 100) { -- msleep(10); -- tmp = readl(port_mmio + PORT_SCR_STAT); -- if ((tmp & 0xf) == 0x3) -- break; -- j++; -- } -+ rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg); -+ if (rc) -+ dev_printk(KERN_WARNING, &pdev->dev, -+ "%s (%d)\n", emsg, rc); - -+ /* clear SError */ - tmp = readl(port_mmio + PORT_SCR_ERR); - VPRINTK("PORT_SCR_ERR 0x%x\n", tmp); - writel(tmp, port_mmio + PORT_SCR_ERR); - -- /* ack any pending irq events for this port */ -+ /* clear & turn off port IRQ */ - tmp = readl(port_mmio + PORT_IRQ_STAT); - VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp); - if (tmp) - writel(tmp, port_mmio + PORT_IRQ_STAT); - - writel(1 << i, mmio + HOST_IRQ_STAT); -+ writel(0, port_mmio + PORT_IRQ_MASK); - } - - tmp = readl(mmio + HOST_CTL); diff --git a/debian/patches/features/all/drivers/scsi-ahci-suspend-2.patch b/debian/patches/features/all/drivers/scsi-ahci-suspend-2.patch deleted file mode 100644 index 15f05295b..000000000 --- a/debian/patches/features/all/drivers/scsi-ahci-suspend-2.patch +++ /dev/null @@ -1,203 +0,0 @@ -# [PATCH] ahci: separate out ahci_reset_controller() and ahci_init_controller() -# d91542c11f3981768367815cf087ad36e792ea4a - -diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c -index fb71fa7..a9e0c5f 100644 ---- a/drivers/scsi/ahci.c -+++ b/drivers/scsi/ahci.c -@@ -572,6 +572,94 @@ static int ahci_deinit_port(void __iomem - return 0; - } - -+static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev) -+{ -+ u32 cap_save, tmp; -+ -+ cap_save = readl(mmio + HOST_CAP); -+ cap_save &= ( (1<<28) | (1<<17) ); -+ cap_save |= (1 << 27); -+ -+ /* global controller reset */ -+ tmp = readl(mmio + HOST_CTL); -+ if ((tmp & HOST_RESET) == 0) { -+ writel(tmp | HOST_RESET, mmio + HOST_CTL); -+ readl(mmio + HOST_CTL); /* flush */ -+ } -+ -+ /* reset must complete within 1 second, or -+ * the hardware should be considered fried. -+ */ -+ ssleep(1); -+ -+ tmp = readl(mmio + HOST_CTL); -+ if (tmp & HOST_RESET) { -+ dev_printk(KERN_ERR, &pdev->dev, -+ "controller reset failed (0x%x)\n", tmp); -+ return -EIO; -+ } -+ -+ writel(HOST_AHCI_EN, mmio + HOST_CTL); -+ (void) readl(mmio + HOST_CTL); /* flush */ -+ writel(cap_save, mmio + HOST_CAP); -+ writel(0xf, mmio + HOST_PORTS_IMPL); -+ (void) readl(mmio + HOST_PORTS_IMPL); /* flush */ -+ -+ if (pdev->vendor == PCI_VENDOR_ID_INTEL) { -+ u16 tmp16; -+ -+ /* configure PCS */ -+ pci_read_config_word(pdev, 0x92, &tmp16); -+ tmp16 |= 0xf; -+ pci_write_config_word(pdev, 0x92, tmp16); -+ } -+ -+ return 0; -+} -+ -+static void ahci_init_controller(void __iomem *mmio, struct pci_dev *pdev, -+ int n_ports, u32 cap) -+{ -+ int i, rc; -+ u32 tmp; -+ -+ for (i = 0; i < n_ports; i++) { -+ void __iomem *port_mmio = ahci_port_base(mmio, i); -+ const char *emsg = NULL; -+ -+#if 0 /* BIOSen initialize this incorrectly */ -+ if (!(hpriv->port_map & (1 << i))) -+ continue; -+#endif -+ -+ /* make sure port is not active */ -+ rc = ahci_deinit_port(port_mmio, cap, &emsg); -+ if (rc) -+ dev_printk(KERN_WARNING, &pdev->dev, -+ "%s (%d)\n", emsg, rc); -+ -+ /* clear SError */ -+ tmp = readl(port_mmio + PORT_SCR_ERR); -+ VPRINTK("PORT_SCR_ERR 0x%x\n", tmp); -+ writel(tmp, port_mmio + PORT_SCR_ERR); -+ -+ /* clear & turn off port IRQ */ -+ tmp = readl(port_mmio + PORT_IRQ_STAT); -+ VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp); -+ if (tmp) -+ writel(tmp, port_mmio + PORT_IRQ_STAT); -+ -+ writel(1 << i, mmio + HOST_IRQ_STAT); -+ writel(0, port_mmio + PORT_IRQ_MASK); -+ } -+ -+ tmp = readl(mmio + HOST_CTL); -+ VPRINTK("HOST_CTL 0x%x\n", tmp); -+ writel(tmp | HOST_IRQ_EN, mmio + HOST_CTL); -+ tmp = readl(mmio + HOST_CTL); -+ VPRINTK("HOST_CTL 0x%x\n", tmp); -+} -+ - static unsigned int ahci_dev_classify(struct ata_port *ap) - { - void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; -@@ -1215,47 +1303,12 @@ static int ahci_host_init(struct ata_pro - struct ahci_host_priv *hpriv = probe_ent->private_data; - struct pci_dev *pdev = to_pci_dev(probe_ent->dev); - void __iomem *mmio = probe_ent->mmio_base; -- u32 tmp, cap_save; - unsigned int i, using_dac; - int rc; -- void __iomem *port_mmio; -- -- cap_save = readl(mmio + HOST_CAP); -- cap_save &= ( (1<<28) | (1<<17) ); -- cap_save |= (1 << 27); -- -- /* global controller reset */ -- tmp = readl(mmio + HOST_CTL); -- if ((tmp & HOST_RESET) == 0) { -- writel(tmp | HOST_RESET, mmio + HOST_CTL); -- readl(mmio + HOST_CTL); /* flush */ -- } -- -- /* reset must complete within 1 second, or -- * the hardware should be considered fried. -- */ -- ssleep(1); -- -- tmp = readl(mmio + HOST_CTL); -- if (tmp & HOST_RESET) { -- dev_printk(KERN_ERR, &pdev->dev, -- "controller reset failed (0x%x)\n", tmp); -- return -EIO; -- } - -- writel(HOST_AHCI_EN, mmio + HOST_CTL); -- (void) readl(mmio + HOST_CTL); /* flush */ -- writel(cap_save, mmio + HOST_CAP); -- writel(0xf, mmio + HOST_PORTS_IMPL); -- (void) readl(mmio + HOST_PORTS_IMPL); /* flush */ -- -- if (pdev->vendor == PCI_VENDOR_ID_INTEL) { -- u16 tmp16; -- -- pci_read_config_word(pdev, 0x92, &tmp16); -- tmp16 |= 0xf; -- pci_write_config_word(pdev, 0x92, tmp16); -- } -+ rc = ahci_reset_controller(mmio, pdev); -+ if (rc) -+ return rc; - - hpriv->cap = readl(mmio + HOST_CAP); - hpriv->port_map = readl(mmio + HOST_PORTS_IMPL); -@@ -1291,46 +1344,10 @@ static int ahci_host_init(struct ata_pro - } - } - -- for (i = 0; i < probe_ent->n_ports; i++) { -- const char *emsg = NULL; -- --#if 0 /* BIOSen initialize this incorrectly */ -- if (!(hpriv->port_map & (1 << i))) -- continue; --#endif -+ for (i = 0; i < probe_ent->n_ports; i++) -+ ahci_setup_port(&probe_ent->port[i], (unsigned long) mmio, i); - -- port_mmio = ahci_port_base(mmio, i); -- VPRINTK("mmio %p port_mmio %p\n", mmio, port_mmio); -- -- ahci_setup_port(&probe_ent->port[i], -- (unsigned long) mmio, i); -- -- /* make sure port is not active */ -- rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg); -- if (rc) -- dev_printk(KERN_WARNING, &pdev->dev, -- "%s (%d)\n", emsg, rc); -- -- /* clear SError */ -- tmp = readl(port_mmio + PORT_SCR_ERR); -- VPRINTK("PORT_SCR_ERR 0x%x\n", tmp); -- writel(tmp, port_mmio + PORT_SCR_ERR); -- -- /* clear & turn off port IRQ */ -- tmp = readl(port_mmio + PORT_IRQ_STAT); -- VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp); -- if (tmp) -- writel(tmp, port_mmio + PORT_IRQ_STAT); -- -- writel(1 << i, mmio + HOST_IRQ_STAT); -- writel(0, port_mmio + PORT_IRQ_MASK); -- } -- -- tmp = readl(mmio + HOST_CTL); -- VPRINTK("HOST_CTL 0x%x\n", tmp); -- writel(tmp | HOST_IRQ_EN, mmio + HOST_CTL); -- tmp = readl(mmio + HOST_CTL); -- VPRINTK("HOST_CTL 0x%x\n", tmp); -+ ahci_init_controller(mmio, pdev, probe_ent->n_ports, hpriv->cap); - - pci_set_master(pdev); - diff --git a/debian/patches/features/all/drivers/scsi-ahci-suspend-3.patch b/debian/patches/features/all/drivers/scsi-ahci-suspend-3.patch deleted file mode 100644 index 00b574102..000000000 --- a/debian/patches/features/all/drivers/scsi-ahci-suspend-3.patch +++ /dev/null @@ -1,126 +0,0 @@ -# [PATCH] ahci: implement Power Management support -# c1332875cbe0c148c7f200d4f9b36b64e34d9872 - -diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c -index a9e0c5f..909a4dc 100644 ---- a/drivers/scsi/ahci.c -+++ b/drivers/scsi/ahci.c -@@ -215,6 +215,10 @@ static void ahci_freeze(struct ata_port - static void ahci_thaw(struct ata_port *ap); - static void ahci_error_handler(struct ata_port *ap); - static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); -+static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg); -+static int ahci_port_resume(struct ata_port *ap); -+static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); -+static int ahci_pci_device_resume(struct pci_dev *pdev); - static void ahci_remove_one (struct pci_dev *pdev); - - static struct scsi_host_template ahci_sht = { -@@ -234,6 +238,8 @@ static struct scsi_host_template ahci_sh - .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, - .bios_param = ata_std_bios_param, -+ .suspend = ata_scsi_device_suspend, -+ .resume = ata_scsi_device_resume, - }; - - static const struct ata_port_operations ahci_ops = { -@@ -260,6 +266,9 @@ static const struct ata_port_operations - .error_handler = ahci_error_handler, - .post_internal_cmd = ahci_post_internal_cmd, - -+ .port_suspend = ahci_port_suspend, -+ .port_resume = ahci_port_resume, -+ - .port_start = ahci_port_start, - .port_stop = ahci_port_stop, - }; -@@ -361,6 +370,8 @@ static struct pci_driver ahci_pci_driver - .name = DRV_NAME, - .id_table = ahci_pci_tbl, - .probe = ahci_init_one, -+ .suspend = ahci_pci_device_suspend, -+ .resume = ahci_pci_device_resume, - .remove = ahci_remove_one, - }; - -@@ -1199,6 +1210,79 @@ static void ahci_post_internal_cmd(struc - } - } - -+static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg) -+{ -+ struct ahci_host_priv *hpriv = ap->host_set->private_data; -+ struct ahci_port_priv *pp = ap->private_data; -+ void __iomem *mmio = ap->host_set->mmio_base; -+ void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); -+ const char *emsg = NULL; -+ int rc; -+ -+ rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg); -+ if (rc) { -+ ata_port_printk(ap, KERN_ERR, "%s (%d)\n", emsg, rc); -+ ahci_init_port(port_mmio, hpriv->cap, -+ pp->cmd_slot_dma, pp->rx_fis_dma); -+ } -+ -+ return rc; -+} -+ -+static int ahci_port_resume(struct ata_port *ap) -+{ -+ struct ahci_port_priv *pp = ap->private_data; -+ struct ahci_host_priv *hpriv = ap->host_set->private_data; -+ void __iomem *mmio = ap->host_set->mmio_base; -+ void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); -+ -+ ahci_init_port(port_mmio, hpriv->cap, pp->cmd_slot_dma, pp->rx_fis_dma); -+ -+ return 0; -+} -+ -+static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) -+{ -+ struct ata_host_set *host_set = dev_get_drvdata(&pdev->dev); -+ void __iomem *mmio = host_set->mmio_base; -+ u32 ctl; -+ -+ if (mesg.event == PM_EVENT_SUSPEND) { -+ /* AHCI spec rev1.1 section 8.3.3: -+ * Software must disable interrupts prior to requesting a -+ * transition of the HBA to D3 state. -+ */ -+ ctl = readl(mmio + HOST_CTL); -+ ctl &= ~HOST_IRQ_EN; -+ writel(ctl, mmio + HOST_CTL); -+ readl(mmio + HOST_CTL); /* flush */ -+ } -+ -+ return ata_pci_device_suspend(pdev, mesg); -+} -+ -+static int ahci_pci_device_resume(struct pci_dev *pdev) -+{ -+ struct ata_host_set *host_set = dev_get_drvdata(&pdev->dev); -+ struct ahci_host_priv *hpriv = host_set->private_data; -+ void __iomem *mmio = host_set->mmio_base; -+ int rc; -+ -+ ata_pci_device_do_resume(pdev); -+ -+ if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) { -+ rc = ahci_reset_controller(mmio, pdev); -+ if (rc) -+ return rc; -+ -+ ahci_init_controller(mmio, pdev, host_set->n_ports, hpriv->cap); -+ } -+ -+ ata_host_set_resume(host_set); -+ -+ return 0; -+} -+ - static int ahci_port_start(struct ata_port *ap) - { - struct device *dev = ap->host_set->dev; diff --git a/debian/patches/features/all/drivers/scsi-arcmsr-1.patch b/debian/patches/features/all/drivers/scsi-arcmsr-1.patch deleted file mode 100644 index 7a2ad8c72..000000000 --- a/debian/patches/features/all/drivers/scsi-arcmsr-1.patch +++ /dev/null @@ -1,3101 +0,0 @@ -# [SCSI] arcmsr: initial driver, version 1.20.00.13 -# 1c57e86d75cf162bdadb3a5fe0cd3f65aa1a9ca3 - -diff --git a/Documentation/scsi/ChangeLog.arcmsr b/Documentation/scsi/ChangeLog.arcmsr -new file mode 100644 -index 0000000..162c47f ---- /dev/null -+++ b/Documentation/scsi/ChangeLog.arcmsr -@@ -0,0 +1,56 @@ -+************************************************************************** -+** History -+** -+** REV# DATE NAME DESCRIPTION -+** 1.00.00.00 3/31/2004 Erich Chen First release -+** 1.10.00.04 7/28/2004 Erich Chen modify for ioctl -+** 1.10.00.06 8/28/2004 Erich Chen modify for 2.6.x -+** 1.10.00.08 9/28/2004 Erich Chen modify for x86_64 -+** 1.10.00.10 10/10/2004 Erich Chen bug fix for SMP & ioctl -+** 1.20.00.00 11/29/2004 Erich Chen bug fix with arcmsr_bus_reset when PHY error -+** 1.20.00.02 12/09/2004 Erich Chen bug fix with over 2T bytes RAID Volume -+** 1.20.00.04 1/09/2005 Erich Chen fits for Debian linux kernel version 2.2.xx -+** 1.20.00.05 2/20/2005 Erich Chen cleanly as look like a Linux driver at 2.6.x -+** thanks for peoples kindness comment -+** Kornel Wieliczek -+** Christoph Hellwig -+** Adrian Bunk -+** Andrew Morton -+** Christoph Hellwig -+** James Bottomley -+** Arjan van de Ven -+** 1.20.00.06 3/12/2005 Erich Chen fix with arcmsr_pci_unmap_dma "unsigned long" cast, -+** modify PCCB POOL allocated by "dma_alloc_coherent" -+** (Kornel Wieliczek's comment) -+** 1.20.00.07 3/23/2005 Erich Chen bug fix with arcmsr_scsi_host_template_init -+** occur segmentation fault, -+** if RAID adapter does not on PCI slot -+** and modprobe/rmmod this driver twice. -+** bug fix enormous stack usage (Adrian Bunk's comment) -+** 1.20.00.08 6/23/2005 Erich Chen bug fix with abort command, -+** in case of heavy loading when sata cable -+** working on low quality connection -+** 1.20.00.09 9/12/2005 Erich Chen bug fix with abort command handling, firmware version check -+** and firmware update notify for hardware bug fix -+** 1.20.00.10 9/23/2005 Erich Chen enhance sysfs function for change driver's max tag Q number. -+** add DMA_64BIT_MASK for backward compatible with all 2.6.x -+** add some useful message for abort command -+** add ioctl code 'ARCMSR_IOCTL_FLUSH_ADAPTER_CACHE' -+** customer can send this command for sync raid volume data -+** 1.20.00.11 9/29/2005 Erich Chen by comment of Arjan van de Ven fix incorrect msleep redefine -+** cast off sizeof(dma_addr_t) condition for 64bit pci_set_dma_mask -+** 1.20.00.12 9/30/2005 Erich Chen bug fix with 64bit platform's ccbs using if over 4G system memory -+** change 64bit pci_set_consistent_dma_mask into 32bit -+** increcct adapter count if adapter initialize fail. -+** miss edit at arcmsr_build_ccb.... -+** psge += sizeof(struct _SG64ENTRY *) => -+** psge += sizeof(struct _SG64ENTRY) -+** 64 bits sg entry would be incorrectly calculated -+** thanks Kornel Wieliczek give me kindly notify -+** and detail description -+** 1.20.00.13 11/15/2005 Erich Chen scheduling pending ccb with FIFO -+** change the architecture of arcmsr command queue list -+** for linux standard list -+** enable usage of pci message signal interrupt -+** follow Randy.Danlup kindness suggestion cleanup this code -+************************************************************************** -\ No newline at end of file -diff --git a/Documentation/scsi/arcmsr_spec.txt b/Documentation/scsi/arcmsr_spec.txt -new file mode 100644 -index 0000000..5e00423 ---- /dev/null -+++ b/Documentation/scsi/arcmsr_spec.txt -@@ -0,0 +1,574 @@ -+******************************************************************************* -+** ARECA FIRMWARE SPEC -+******************************************************************************* -+** Usage of IOP331 adapter -+** (All In/Out is in IOP331's view) -+** 1. Message 0 --> InitThread message and retrun code -+** 2. Doorbell is used for RS-232 emulation -+** inDoorBell : bit0 -- data in ready -+** (DRIVER DATA WRITE OK) -+** bit1 -- data out has been read -+** (DRIVER DATA READ OK) -+** outDooeBell: bit0 -- data out ready -+** (IOP331 DATA WRITE OK) -+** bit1 -- data in has been read -+** (IOP331 DATA READ OK) -+** 3. Index Memory Usage -+** offset 0xf00 : for RS232 out (request buffer) -+** offset 0xe00 : for RS232 in (scratch buffer) -+** offset 0xa00 : for inbound message code message_rwbuffer -+** (driver send to IOP331) -+** offset 0xa00 : for outbound message code message_rwbuffer -+** (IOP331 send to driver) -+** 4. RS-232 emulation -+** Currently 128 byte buffer is used -+** 1st uint32_t : Data length (1--124) -+** Byte 4--127 : Max 124 bytes of data -+** 5. PostQ -+** All SCSI Command must be sent through postQ: -+** (inbound queue port) Request frame must be 32 bytes aligned -+** #bit27--bit31 => flag for post ccb -+** #bit0--bit26 => real address (bit27--bit31) of post arcmsr_cdb -+** bit31 : -+** 0 : 256 bytes frame -+** 1 : 512 bytes frame -+** bit30 : -+** 0 : normal request -+** 1 : BIOS request -+** bit29 : reserved -+** bit28 : reserved -+** bit27 : reserved -+** --------------------------------------------------------------------------- -+** (outbount queue port) Request reply -+** #bit27--bit31 -+** => flag for reply -+** #bit0--bit26 -+** => real address (bit27--bit31) of reply arcmsr_cdb -+** bit31 : must be 0 (for this type of reply) -+** bit30 : reserved for BIOS handshake -+** bit29 : reserved -+** bit28 : -+** 0 : no error, ignore AdapStatus/DevStatus/SenseData -+** 1 : Error, error code in AdapStatus/DevStatus/SenseData -+** bit27 : reserved -+** 6. BIOS request -+** All BIOS request is the same with request from PostQ -+** Except : -+** Request frame is sent from configuration space -+** offset: 0x78 : Request Frame (bit30 == 1) -+** offset: 0x18 : writeonly to generate -+** IRQ to IOP331 -+** Completion of request: -+** (bit30 == 0, bit28==err flag) -+** 7. Definition of SGL entry (structure) -+** 8. Message1 Out - Diag Status Code (????) -+** 9. Message0 message code : -+** 0x00 : NOP -+** 0x01 : Get Config -+** ->offset 0xa00 :for outbound message code message_rwbuffer -+** (IOP331 send to driver) -+** Signature 0x87974060(4) -+** Request len 0x00000200(4) -+** numbers of queue 0x00000100(4) -+** SDRAM Size 0x00000100(4)-->256 MB -+** IDE Channels 0x00000008(4) -+** vendor 40 bytes char -+** model 8 bytes char -+** FirmVer 16 bytes char -+** Device Map 16 bytes char -+** FirmwareVersion DWORD <== Added for checking of -+** new firmware capability -+** 0x02 : Set Config -+** ->offset 0xa00 :for inbound message code message_rwbuffer -+** (driver send to IOP331) -+** Signature 0x87974063(4) -+** UPPER32 of Request Frame (4)-->Driver Only -+** 0x03 : Reset (Abort all queued Command) -+** 0x04 : Stop Background Activity -+** 0x05 : Flush Cache -+** 0x06 : Start Background Activity -+** (re-start if background is halted) -+** 0x07 : Check If Host Command Pending -+** (Novell May Need This Function) -+** 0x08 : Set controller time -+** ->offset 0xa00 : for inbound message code message_rwbuffer -+** (driver to IOP331) -+** byte 0 : 0xaa <-- signature -+** byte 1 : 0x55 <-- signature -+** byte 2 : year (04) -+** byte 3 : month (1..12) -+** byte 4 : date (1..31) -+** byte 5 : hour (0..23) -+** byte 6 : minute (0..59) -+** byte 7 : second (0..59) -+******************************************************************************* -+******************************************************************************* -+** RS-232 Interface for Areca Raid Controller -+** The low level command interface is exclusive with VT100 terminal -+** -------------------------------------------------------------------- -+** 1. Sequence of command execution -+** -------------------------------------------------------------------- -+** (A) Header : 3 bytes sequence (0x5E, 0x01, 0x61) -+** (B) Command block : variable length of data including length, -+** command code, data and checksum byte -+** (C) Return data : variable length of data -+** -------------------------------------------------------------------- -+** 2. Command block -+** -------------------------------------------------------------------- -+** (A) 1st byte : command block length (low byte) -+** (B) 2nd byte : command block length (high byte) -+** note ..command block length shouldn't > 2040 bytes, -+** length excludes these two bytes -+** (C) 3rd byte : command code -+** (D) 4th and following bytes : variable length data bytes -+** depends on command code -+** (E) last byte : checksum byte (sum of 1st byte until last data byte) -+** -------------------------------------------------------------------- -+** 3. Command code and associated data -+** -------------------------------------------------------------------- -+** The following are command code defined in raid controller Command -+** code 0x10--0x1? are used for system level management, -+** no password checking is needed and should be implemented in separate -+** well controlled utility and not for end user access. -+** Command code 0x20--0x?? always check the password, -+** password must be entered to enable these command. -+** enum -+** { -+** GUI_SET_SERIAL=0x10, -+** GUI_SET_VENDOR, -+** GUI_SET_MODEL, -+** GUI_IDENTIFY, -+** GUI_CHECK_PASSWORD, -+** GUI_LOGOUT, -+** GUI_HTTP, -+** GUI_SET_ETHERNET_ADDR, -+** GUI_SET_LOGO, -+** GUI_POLL_EVENT, -+** GUI_GET_EVENT, -+** GUI_GET_HW_MONITOR, -+** // GUI_QUICK_CREATE=0x20, (function removed) -+** GUI_GET_INFO_R=0x20, -+** GUI_GET_INFO_V, -+** GUI_GET_INFO_P, -+** GUI_GET_INFO_S, -+** GUI_CLEAR_EVENT, -+** GUI_MUTE_BEEPER=0x30, -+** GUI_BEEPER_SETTING, -+** GUI_SET_PASSWORD, -+** GUI_HOST_INTERFACE_MODE, -+** GUI_REBUILD_PRIORITY, -+** GUI_MAX_ATA_MODE, -+** GUI_RESET_CONTROLLER, -+** GUI_COM_PORT_SETTING, -+** GUI_NO_OPERATION, -+** GUI_DHCP_IP, -+** GUI_CREATE_PASS_THROUGH=0x40, -+** GUI_MODIFY_PASS_THROUGH, -+** GUI_DELETE_PASS_THROUGH, -+** GUI_IDENTIFY_DEVICE, -+** GUI_CREATE_RAIDSET=0x50, -+** GUI_DELETE_RAIDSET, -+** GUI_EXPAND_RAIDSET, -+** GUI_ACTIVATE_RAIDSET, -+** GUI_CREATE_HOT_SPARE, -+** GUI_DELETE_HOT_SPARE, -+** GUI_CREATE_VOLUME=0x60, -+** GUI_MODIFY_VOLUME, -+** GUI_DELETE_VOLUME, -+** GUI_START_CHECK_VOLUME, -+** GUI_STOP_CHECK_VOLUME -+** }; -+** Command description : -+** GUI_SET_SERIAL : Set the controller serial# -+** byte 0,1 : length -+** byte 2 : command code 0x10 -+** byte 3 : password length (should be 0x0f) -+** byte 4-0x13 : should be "ArEcATecHnoLogY" -+** byte 0x14--0x23 : Serial number string (must be 16 bytes) -+** GUI_SET_VENDOR : Set vendor string for the controller -+** byte 0,1 : length -+** byte 2 : command code 0x11 -+** byte 3 : password length (should be 0x08) -+** byte 4-0x13 : should be "ArEcAvAr" -+** byte 0x14--0x3B : vendor string (must be 40 bytes) -+** GUI_SET_MODEL : Set the model name of the controller -+** byte 0,1 : length -+** byte 2 : command code 0x12 -+** byte 3 : password length (should be 0x08) -+** byte 4-0x13 : should be "ArEcAvAr" -+** byte 0x14--0x1B : model string (must be 8 bytes) -+** GUI_IDENTIFY : Identify device -+** byte 0,1 : length -+** byte 2 : command code 0x13 -+** return "Areca RAID Subsystem " -+** GUI_CHECK_PASSWORD : Verify password -+** byte 0,1 : length -+** byte 2 : command code 0x14 -+** byte 3 : password length -+** byte 4-0x?? : user password to be checked -+** GUI_LOGOUT : Logout GUI (force password checking on next command) -+** byte 0,1 : length -+** byte 2 : command code 0x15 -+** GUI_HTTP : HTTP interface (reserved for Http proxy service)(0x16) -+** -+** GUI_SET_ETHERNET_ADDR : Set the ethernet MAC address -+** byte 0,1 : length -+** byte 2 : command code 0x17 -+** byte 3 : password length (should be 0x08) -+** byte 4-0x13 : should be "ArEcAvAr" -+** byte 0x14--0x19 : Ethernet MAC address (must be 6 bytes) -+** GUI_SET_LOGO : Set logo in HTTP -+** byte 0,1 : length -+** byte 2 : command code 0x18 -+** byte 3 : Page# (0/1/2/3) (0xff --> clear OEM logo) -+** byte 4/5/6/7 : 0x55/0xaa/0xa5/0x5a -+** byte 8 : TITLE.JPG data (each page must be 2000 bytes) -+** note page0 1st 2 byte must be -+** actual length of the JPG file -+** GUI_POLL_EVENT : Poll If Event Log Changed -+** byte 0,1 : length -+** byte 2 : command code 0x19 -+** GUI_GET_EVENT : Read Event -+** byte 0,1 : length -+** byte 2 : command code 0x1a -+** byte 3 : Event Page (0:1st page/1/2/3:last page) -+** GUI_GET_HW_MONITOR : Get HW monitor data -+** byte 0,1 : length -+** byte 2 : command code 0x1b -+** byte 3 : # of FANs(example 2) -+** byte 4 : # of Voltage sensor(example 3) -+** byte 5 : # of temperature sensor(example 2) -+** byte 6 : # of power -+** byte 7/8 : Fan#0 (RPM) -+** byte 9/10 : Fan#1 -+** byte 11/12 : Voltage#0 original value in *1000 -+** byte 13/14 : Voltage#0 value -+** byte 15/16 : Voltage#1 org -+** byte 17/18 : Voltage#1 -+** byte 19/20 : Voltage#2 org -+** byte 21/22 : Voltage#2 -+** byte 23 : Temp#0 -+** byte 24 : Temp#1 -+** byte 25 : Power indicator (bit0 : power#0, -+** bit1 : power#1) -+** byte 26 : UPS indicator -+** GUI_QUICK_CREATE : Quick create raid/volume set -+** byte 0,1 : length -+** byte 2 : command code 0x20 -+** byte 3/4/5/6 : raw capacity -+** byte 7 : raid level -+** byte 8 : stripe size -+** byte 9 : spare -+** byte 10/11/12/13: device mask (the devices to create raid/volume) -+** This function is removed, application like -+** to implement quick create function -+** need to use GUI_CREATE_RAIDSET and GUI_CREATE_VOLUMESET function. -+** GUI_GET_INFO_R : Get Raid Set Information -+** byte 0,1 : length -+** byte 2 : command code 0x20 -+** byte 3 : raidset# -+** typedef struct sGUI_RAIDSET -+** { -+** BYTE grsRaidSetName[16]; -+** DWORD grsCapacity; -+** DWORD grsCapacityX; -+** DWORD grsFailMask; -+** BYTE grsDevArray[32]; -+** BYTE grsMemberDevices; -+** BYTE grsNewMemberDevices; -+** BYTE grsRaidState; -+** BYTE grsVolumes; -+** BYTE grsVolumeList[16]; -+** BYTE grsRes1; -+** BYTE grsRes2; -+** BYTE grsRes3; -+** BYTE grsFreeSegments; -+** DWORD grsRawStripes[8]; -+** DWORD grsRes4; -+** DWORD grsRes5; // Total to 128 bytes -+** DWORD grsRes6; // Total to 128 bytes -+** } sGUI_RAIDSET, *pGUI_RAIDSET; -+** GUI_GET_INFO_V : Get Volume Set Information -+** byte 0,1 : length -+** byte 2 : command code 0x21 -+** byte 3 : volumeset# -+** typedef struct sGUI_VOLUMESET -+** { -+** BYTE gvsVolumeName[16]; // 16 -+** DWORD gvsCapacity; -+** DWORD gvsCapacityX; -+** DWORD gvsFailMask; -+** DWORD gvsStripeSize; -+** DWORD gvsNewFailMask; -+** DWORD gvsNewStripeSize; -+** DWORD gvsVolumeStatus; -+** DWORD gvsProgress; // 32 -+** sSCSI_ATTR gvsScsi; -+** BYTE gvsMemberDisks; -+** BYTE gvsRaidLevel; // 8 -+** BYTE gvsNewMemberDisks; -+** BYTE gvsNewRaidLevel; -+** BYTE gvsRaidSetNumber; -+** BYTE gvsRes0; // 4 -+** BYTE gvsRes1[4]; // 64 bytes -+** } sGUI_VOLUMESET, *pGUI_VOLUMESET; -+** GUI_GET_INFO_P : Get Physical Drive Information -+** byte 0,1 : length -+** byte 2 : command code 0x22 -+** byte 3 : drive # (from 0 to max-channels - 1) -+** typedef struct sGUI_PHY_DRV -+** { -+** BYTE gpdModelName[40]; -+** BYTE gpdSerialNumber[20]; -+** BYTE gpdFirmRev[8]; -+** DWORD gpdCapacity; -+** DWORD gpdCapacityX; // Reserved for expansion -+** BYTE gpdDeviceState; -+** BYTE gpdPioMode; -+** BYTE gpdCurrentUdmaMode; -+** BYTE gpdUdmaMode; -+** BYTE gpdDriveSelect; -+** BYTE gpdRaidNumber; // 0xff if not belongs to a raid set -+** sSCSI_ATTR gpdScsi; -+** BYTE gpdReserved[40]; // Total to 128 bytes -+** } sGUI_PHY_DRV, *pGUI_PHY_DRV; -+** GUI_GET_INFO_S : Get System Information -+** byte 0,1 : length -+** byte 2 : command code 0x23 -+** typedef struct sCOM_ATTR -+** { -+** BYTE comBaudRate; -+** BYTE comDataBits; -+** BYTE comStopBits; -+** BYTE comParity; -+** BYTE comFlowControl; -+** } sCOM_ATTR, *pCOM_ATTR; -+** typedef struct sSYSTEM_INFO -+** { -+** BYTE gsiVendorName[40]; -+** BYTE gsiSerialNumber[16]; -+** BYTE gsiFirmVersion[16]; -+** BYTE gsiBootVersion[16]; -+** BYTE gsiMbVersion[16]; -+** BYTE gsiModelName[8]; -+** BYTE gsiLocalIp[4]; -+** BYTE gsiCurrentIp[4]; -+** DWORD gsiTimeTick; -+** DWORD gsiCpuSpeed; -+** DWORD gsiICache; -+** DWORD gsiDCache; -+** DWORD gsiScache; -+** DWORD gsiMemorySize; -+** DWORD gsiMemorySpeed; -+** DWORD gsiEvents; -+** BYTE gsiMacAddress[6]; -+** BYTE gsiDhcp; -+** BYTE gsiBeeper; -+** BYTE gsiChannelUsage; -+** BYTE gsiMaxAtaMode; -+** BYTE gsiSdramEcc; // 1:if ECC enabled -+** BYTE gsiRebuildPriority; -+** sCOM_ATTR gsiComA; // 5 bytes -+** sCOM_ATTR gsiComB; // 5 bytes -+** BYTE gsiIdeChannels; -+** BYTE gsiScsiHostChannels; -+** BYTE gsiIdeHostChannels; -+** BYTE gsiMaxVolumeSet; -+** BYTE gsiMaxRaidSet; -+** BYTE gsiEtherPort; // 1:if ether net port supported -+** BYTE gsiRaid6Engine; // 1:Raid6 engine supported -+** BYTE gsiRes[75]; -+** } sSYSTEM_INFO, *pSYSTEM_INFO; -+** GUI_CLEAR_EVENT : Clear System Event -+** byte 0,1 : length -+** byte 2 : command code 0x24 -+** GUI_MUTE_BEEPER : Mute current beeper -+** byte 0,1 : length -+** byte 2 : command code 0x30 -+** GUI_BEEPER_SETTING : Disable beeper -+** byte 0,1 : length -+** byte 2 : command code 0x31 -+** byte 3 : 0->disable, 1->enable -+** GUI_SET_PASSWORD : Change password -+** byte 0,1 : length -+** byte 2 : command code 0x32 -+** byte 3 : pass word length ( must <= 15 ) -+** byte 4 : password (must be alpha-numerical) -+** GUI_HOST_INTERFACE_MODE : Set host interface mode -+** byte 0,1 : length -+** byte 2 : command code 0x33 -+** byte 3 : 0->Independent, 1->cluster -+** GUI_REBUILD_PRIORITY : Set rebuild priority -+** byte 0,1 : length -+** byte 2 : command code 0x34 -+** byte 3 : 0/1/2/3 (low->high) -+** GUI_MAX_ATA_MODE : Set maximum ATA mode to be used -+** byte 0,1 : length -+** byte 2 : command code 0x35 -+** byte 3 : 0/1/2/3 (133/100/66/33) -+** GUI_RESET_CONTROLLER : Reset Controller -+** byte 0,1 : length -+** byte 2 : command code 0x36 -+** *Response with VT100 screen (discard it) -+** GUI_COM_PORT_SETTING : COM port setting -+** byte 0,1 : length -+** byte 2 : command code 0x37 -+** byte 3 : 0->COMA (term port), -+** 1->COMB (debug port) -+** byte 4 : 0/1/2/3/4/5/6/7 -+** (1200/2400/4800/9600/19200/38400/57600/115200) -+** byte 5 : data bit -+** (0:7 bit, 1:8 bit : must be 8 bit) -+** byte 6 : stop bit (0:1, 1:2 stop bits) -+** byte 7 : parity (0:none, 1:off, 2:even) -+** byte 8 : flow control -+** (0:none, 1:xon/xoff, 2:hardware => must use none) -+** GUI_NO_OPERATION : No operation -+** byte 0,1 : length -+** byte 2 : command code 0x38 -+** GUI_DHCP_IP : Set DHCP option and local IP address -+** byte 0,1 : length -+** byte 2 : command code 0x39 -+** byte 3 : 0:dhcp disabled, 1:dhcp enabled -+** byte 4/5/6/7 : IP address -+** GUI_CREATE_PASS_THROUGH : Create pass through disk -+** byte 0,1 : length -+** byte 2 : command code 0x40 -+** byte 3 : device # -+** byte 4 : scsi channel (0/1) -+** byte 5 : scsi id (0-->15) -+** byte 6 : scsi lun (0-->7) -+** byte 7 : tagged queue (1 : enabled) -+** byte 8 : cache mode (1 : enabled) -+** byte 9 : max speed (0/1/2/3/4, -+** async/20/40/80/160 for scsi) -+** (0/1/2/3/4, 33/66/100/133/150 for ide ) -+** GUI_MODIFY_PASS_THROUGH : Modify pass through disk -+** byte 0,1 : length -+** byte 2 : command code 0x41 -+** byte 3 : device # -+** byte 4 : scsi channel (0/1) -+** byte 5 : scsi id (0-->15) -+** byte 6 : scsi lun (0-->7) -+** byte 7 : tagged queue (1 : enabled) -+** byte 8 : cache mode (1 : enabled) -+** byte 9 : max speed (0/1/2/3/4, -+** async/20/40/80/160 for scsi) -+** (0/1/2/3/4, 33/66/100/133/150 for ide ) -+** GUI_DELETE_PASS_THROUGH : Delete pass through disk -+** byte 0,1 : length -+** byte 2 : command code 0x42 -+** byte 3 : device# to be deleted -+** GUI_IDENTIFY_DEVICE : Identify Device -+** byte 0,1 : length -+** byte 2 : command code 0x43 -+** byte 3 : Flash Method -+** (0:flash selected, 1:flash not selected) -+** byte 4/5/6/7 : IDE device mask to be flashed -+** note .... no response data available -+** GUI_CREATE_RAIDSET : Create Raid Set -+** byte 0,1 : length -+** byte 2 : command code 0x50 -+** byte 3/4/5/6 : device mask -+** byte 7-22 : raidset name (if byte 7 == 0:use default) -+** GUI_DELETE_RAIDSET : Delete Raid Set -+** byte 0,1 : length -+** byte 2 : command code 0x51 -+** byte 3 : raidset# -+** GUI_EXPAND_RAIDSET : Expand Raid Set -+** byte 0,1 : length -+** byte 2 : command code 0x52 -+** byte 3 : raidset# -+** byte 4/5/6/7 : device mask for expansion -+** byte 8/9/10 : (8:0 no change, 1 change, 0xff:terminate, -+** 9:new raid level, -+** 10:new stripe size -+** 0/1/2/3/4/5->4/8/16/32/64/128K ) -+** byte 11/12/13 : repeat for each volume in the raidset -+** GUI_ACTIVATE_RAIDSET : Activate incomplete raid set -+** byte 0,1 : length -+** byte 2 : command code 0x53 -+** byte 3 : raidset# -+** GUI_CREATE_HOT_SPARE : Create hot spare disk -+** byte 0,1 : length -+** byte 2 : command code 0x54 -+** byte 3/4/5/6 : device mask for hot spare creation -+** GUI_DELETE_HOT_SPARE : Delete hot spare disk -+** byte 0,1 : length -+** byte 2 : command code 0x55 -+** byte 3/4/5/6 : device mask for hot spare deletion -+** GUI_CREATE_VOLUME : Create volume set -+** byte 0,1 : length -+** byte 2 : command code 0x60 -+** byte 3 : raidset# -+** byte 4-19 : volume set name -+** (if byte4 == 0, use default) -+** byte 20-27 : volume capacity (blocks) -+** byte 28 : raid level -+** byte 29 : stripe size -+** (0/1/2/3/4/5->4/8/16/32/64/128K) -+** byte 30 : channel -+** byte 31 : ID -+** byte 32 : LUN -+** byte 33 : 1 enable tag -+** byte 34 : 1 enable cache -+** byte 35 : speed -+** (0/1/2/3/4->async/20/40/80/160 for scsi) -+** (0/1/2/3/4->33/66/100/133/150 for IDE ) -+** byte 36 : 1 to select quick init -+** -+** GUI_MODIFY_VOLUME : Modify volume Set -+** byte 0,1 : length -+** byte 2 : command code 0x61 -+** byte 3 : volumeset# -+** byte 4-19 : new volume set name -+** (if byte4 == 0, not change) -+** byte 20-27 : new volume capacity (reserved) -+** byte 28 : new raid level -+** byte 29 : new stripe size -+** (0/1/2/3/4/5->4/8/16/32/64/128K) -+** byte 30 : new channel -+** byte 31 : new ID -+** byte 32 : new LUN -+** byte 33 : 1 enable tag -+** byte 34 : 1 enable cache -+** byte 35 : speed -+** (0/1/2/3/4->async/20/40/80/160 for scsi) -+** (0/1/2/3/4->33/66/100/133/150 for IDE ) -+** GUI_DELETE_VOLUME : Delete volume set -+** byte 0,1 : length -+** byte 2 : command code 0x62 -+** byte 3 : volumeset# -+** GUI_START_CHECK_VOLUME : Start volume consistency check -+** byte 0,1 : length -+** byte 2 : command code 0x63 -+** byte 3 : volumeset# -+** GUI_STOP_CHECK_VOLUME : Stop volume consistency check -+** byte 0,1 : length -+** byte 2 : command code 0x64 -+** --------------------------------------------------------------------- -+** 4. Returned data -+** --------------------------------------------------------------------- -+** (A) Header : 3 bytes sequence (0x5E, 0x01, 0x61) -+** (B) Length : 2 bytes -+** (low byte 1st, excludes length and checksum byte) -+** (C) status or data : -+** <1> If length == 1 ==> 1 byte status code -+** #define GUI_OK 0x41 -+** #define GUI_RAIDSET_NOT_NORMAL 0x42 -+** #define GUI_VOLUMESET_NOT_NORMAL 0x43 -+** #define GUI_NO_RAIDSET 0x44 -+** #define GUI_NO_VOLUMESET 0x45 -+** #define GUI_NO_PHYSICAL_DRIVE 0x46 -+** #define GUI_PARAMETER_ERROR 0x47 -+** #define GUI_UNSUPPORTED_COMMAND 0x48 -+** #define GUI_DISK_CONFIG_CHANGED 0x49 -+** #define GUI_INVALID_PASSWORD 0x4a -+** #define GUI_NO_DISK_SPACE 0x4b -+** #define GUI_CHECKSUM_ERROR 0x4c -+** #define GUI_PASSWORD_REQUIRED 0x4d -+** <2> If length > 1 ==> -+** data block returned from controller -+** and the contents depends on the command code -+** (E) Checksum : checksum of length and status or data byte -+************************************************************************** -diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig -index 96a81cd..d61662c 100644 ---- a/drivers/scsi/Kconfig -+++ b/drivers/scsi/Kconfig -@@ -469,6 +469,20 @@ config SCSI_IN2000 - To compile this driver as a module, choose M here: the - module will be called in2000. - -+config SCSI_ARCMSR -+ tristate "ARECA ARC11X0[PCI-X]/ARC12X0[PCI-EXPRESS] SATA-RAID support" -+ depends on PCI && SCSI -+ help -+ This driver supports all of ARECA's SATA RAID controller cards. -+ This is an ARECA-maintained driver by Erich Chen. -+ If you have any problems, please mail to: < erich@areca.com.tw > -+ Areca supports Linux RAID config tools. -+ -+ < http://www.areca.com.tw > -+ -+ To compile this driver as a module, choose M here: the -+ module will be called arcmsr (modprobe arcmsr). -+ - source "drivers/scsi/megaraid/Kconfig.megaraid" - - config SCSI_SATA -diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile -index ebd0cf0..b2de9bf 100644 ---- a/drivers/scsi/Makefile -+++ b/drivers/scsi/Makefile -@@ -59,6 +59,7 @@ obj-$(CONFIG_SCSI_PSI240I) += psi240i.o - obj-$(CONFIG_SCSI_BUSLOGIC) += BusLogic.o - obj-$(CONFIG_SCSI_DPT_I2O) += dpt_i2o.o - obj-$(CONFIG_SCSI_U14_34F) += u14-34f.o -+obj-$(CONFIG_SCSI_ARCMSR) += arcmsr/ - obj-$(CONFIG_SCSI_ULTRASTOR) += ultrastor.o - obj-$(CONFIG_SCSI_AHA152X) += aha152x.o - obj-$(CONFIG_SCSI_AHA1542) += aha1542.o -diff --git a/drivers/scsi/arcmsr/Makefile b/drivers/scsi/arcmsr/Makefile -new file mode 100644 -index 0000000..721aced ---- /dev/null -+++ b/drivers/scsi/arcmsr/Makefile -@@ -0,0 +1,6 @@ -+# File: drivers/arcmsr/Makefile -+# Makefile for the ARECA PCI-X PCI-EXPRESS SATA RAID controllers SCSI driver. -+ -+arcmsr-objs := arcmsr_attr.o arcmsr_hba.o -+ -+obj-$(CONFIG_SCSI_ARCMSR) := arcmsr.o -diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h -new file mode 100644 -index 0000000..aff96db ---- /dev/null -+++ b/drivers/scsi/arcmsr/arcmsr.h -@@ -0,0 +1,472 @@ -+/* -+******************************************************************************* -+** O.S : Linux -+** FILE NAME : arcmsr.h -+** BY : Erich Chen -+** Description: SCSI RAID Device Driver for -+** ARECA RAID Host adapter -+******************************************************************************* -+** Copyright (C) 2002 - 2005, Areca Technology Corporation All rights reserved. -+** -+** Web site: www.areca.com.tw -+** E-mail: erich@areca.com.tw -+** -+** This program is free software; you can redistribute it and/or modify -+** it under the terms of the GNU General Public License version 2 as -+** published by the Free Software Foundation. -+** This program is distributed in the hope that it will be useful, -+** but WITHOUT ANY WARRANTY; without even the implied warranty of -+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+** GNU General Public License for more details. -+******************************************************************************* -+** Redistribution and use in source and binary forms, with or without -+** modification, are permitted provided that the following conditions -+** are met: -+** 1. Redistributions of source code must retain the above copyright -+** notice, this list of conditions and the following disclaimer. -+** 2. Redistributions in binary form must reproduce the above copyright -+** notice, this list of conditions and the following disclaimer in the -+** documentation and/or other materials provided with the distribution. -+** 3. The name of the author may not be used to endorse or promote products -+** derived from this software without specific prior written permission. -+** -+** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -+** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -+** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -+** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -+** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT -+** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION)HOWEVER CAUSED AND ON ANY -+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+**(INCLUDING NEGLIGENCE OR OTHERWISE)ARISING IN ANY WAY OUT OF THE USE OF -+** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+******************************************************************************* -+*/ -+#include -+ -+struct class_device_attribute; -+ -+#define ARCMSR_MAX_OUTSTANDING_CMD 256 -+#define ARCMSR_MAX_FREECCB_NUM 288 -+#define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.13" -+#define ARCMSR_SCSI_INITIATOR_ID 255 -+#define ARCMSR_MAX_XFER_SECTORS 512 -+#define ARCMSR_MAX_TARGETID 17 -+#define ARCMSR_MAX_TARGETLUN 8 -+#define ARCMSR_MAX_CMD_PERLUN ARCMSR_MAX_OUTSTANDING_CMD -+#define ARCMSR_MAX_QBUFFER 4096 -+#define ARCMSR_MAX_SG_ENTRIES 38 -+ -+/* -+******************************************************************************* -+** split 64bits dma addressing -+******************************************************************************* -+*/ -+#define dma_addr_hi32(addr) (uint32_t) ((addr>>16)>>16) -+#define dma_addr_lo32(addr) (uint32_t) (addr & 0xffffffff) -+/* -+******************************************************************************* -+** MESSAGE CONTROL CODE -+******************************************************************************* -+*/ -+struct CMD_MESSAGE -+{ -+ uint32_t HeaderLength; -+ uint8_t Signature[8]; -+ uint32_t Timeout; -+ uint32_t ControlCode; -+ uint32_t ReturnCode; -+ uint32_t Length; -+}; -+/* -+******************************************************************************* -+** IOP Message Transfer Data for user space -+******************************************************************************* -+*/ -+struct CMD_MESSAGE_FIELD -+{ -+ struct CMD_MESSAGE cmdmessage; -+ uint8_t messagedatabuffer[1032]; -+}; -+/* IOP message transfer */ -+#define ARCMSR_MESSAGE_FAIL 0x0001 -+/* DeviceType */ -+#define ARECA_SATA_RAID 0x90000000 -+/* FunctionCode */ -+#define FUNCTION_READ_RQBUFFER 0x0801 -+#define FUNCTION_WRITE_WQBUFFER 0x0802 -+#define FUNCTION_CLEAR_RQBUFFER 0x0803 -+#define FUNCTION_CLEAR_WQBUFFER 0x0804 -+#define FUNCTION_CLEAR_ALLQBUFFER 0x0805 -+#define FUNCTION_RETURN_CODE_3F 0x0806 -+#define FUNCTION_SAY_HELLO 0x0807 -+#define FUNCTION_SAY_GOODBYE 0x0808 -+#define FUNCTION_FLUSH_ADAPTER_CACHE 0x0809 -+/* ARECA IO CONTROL CODE*/ -+#define ARCMSR_MESSAGE_READ_RQBUFFER \ -+ ARECA_SATA_RAID | FUNCTION_READ_RQBUFFER -+#define ARCMSR_MESSAGE_WRITE_WQBUFFER \ -+ ARECA_SATA_RAID | FUNCTION_WRITE_WQBUFFER -+#define ARCMSR_MESSAGE_CLEAR_RQBUFFER \ -+ ARECA_SATA_RAID | FUNCTION_CLEAR_RQBUFFER -+#define ARCMSR_MESSAGE_CLEAR_WQBUFFER \ -+ ARECA_SATA_RAID | FUNCTION_CLEAR_WQBUFFER -+#define ARCMSR_MESSAGE_CLEAR_ALLQBUFFER \ -+ ARECA_SATA_RAID | FUNCTION_CLEAR_ALLQBUFFER -+#define ARCMSR_MESSAGE_RETURN_CODE_3F \ -+ ARECA_SATA_RAID | FUNCTION_RETURN_CODE_3F -+#define ARCMSR_MESSAGE_SAY_HELLO \ -+ ARECA_SATA_RAID | FUNCTION_SAY_HELLO -+#define ARCMSR_MESSAGE_SAY_GOODBYE \ -+ ARECA_SATA_RAID | FUNCTION_SAY_GOODBYE -+#define ARCMSR_MESSAGE_FLUSH_ADAPTER_CACHE \ -+ ARECA_SATA_RAID | FUNCTION_FLUSH_ADAPTER_CACHE -+/* ARECA IOCTL ReturnCode */ -+#define ARCMSR_MESSAGE_RETURNCODE_OK 0x00000001 -+#define ARCMSR_MESSAGE_RETURNCODE_ERROR 0x00000006 -+#define ARCMSR_MESSAGE_RETURNCODE_3F 0x0000003F -+/* -+************************************************************* -+** structure for holding DMA address data -+************************************************************* -+*/ -+#define IS_SG64_ADDR 0x01000000 /* bit24 */ -+struct SG32ENTRY -+{ -+ uint32_t length; -+ uint32_t address; -+}; -+struct SG64ENTRY -+{ -+ uint32_t length; -+ uint32_t address; -+ uint32_t addresshigh; -+}; -+struct SGENTRY_UNION -+{ -+ union -+ { -+ struct SG32ENTRY sg32entry; -+ struct SG64ENTRY sg64entry; -+ }u; -+}; -+/* -+******************************************************************** -+** Q Buffer of IOP Message Transfer -+******************************************************************** -+*/ -+struct QBUFFER -+{ -+ uint32_t data_len; -+ uint8_t data[124]; -+}; -+/* -+******************************************************************************* -+** FIRMWARE INFO -+******************************************************************************* -+*/ -+struct FIRMWARE_INFO -+{ -+ uint32_t signature; /*0, 00-03*/ -+ uint32_t request_len; /*1, 04-07*/ -+ uint32_t numbers_queue; /*2, 08-11*/ -+ uint32_t sdram_size; /*3, 12-15*/ -+ uint32_t ide_channels; /*4, 16-19*/ -+ char vendor[40]; /*5, 20-59*/ -+ char model[8]; /*15, 60-67*/ -+ char firmware_ver[16]; /*17, 68-83*/ -+ char device_map[16]; /*21, 84-99*/ -+}; -+/* signature of set and get firmware config */ -+#define ARCMSR_SIGNATURE_GET_CONFIG 0x87974060 -+#define ARCMSR_SIGNATURE_SET_CONFIG 0x87974063 -+/* message code of inbound message register */ -+#define ARCMSR_INBOUND_MESG0_NOP 0x00000000 -+#define ARCMSR_INBOUND_MESG0_GET_CONFIG 0x00000001 -+#define ARCMSR_INBOUND_MESG0_SET_CONFIG 0x00000002 -+#define ARCMSR_INBOUND_MESG0_ABORT_CMD 0x00000003 -+#define ARCMSR_INBOUND_MESG0_STOP_BGRB 0x00000004 -+#define ARCMSR_INBOUND_MESG0_FLUSH_CACHE 0x00000005 -+#define ARCMSR_INBOUND_MESG0_START_BGRB 0x00000006 -+#define ARCMSR_INBOUND_MESG0_CHK331PENDING 0x00000007 -+#define ARCMSR_INBOUND_MESG0_SYNC_TIMER 0x00000008 -+/* doorbell interrupt generator */ -+#define ARCMSR_INBOUND_DRIVER_DATA_WRITE_OK 0x00000001 -+#define ARCMSR_INBOUND_DRIVER_DATA_READ_OK 0x00000002 -+#define ARCMSR_OUTBOUND_IOP331_DATA_WRITE_OK 0x00000001 -+#define ARCMSR_OUTBOUND_IOP331_DATA_READ_OK 0x00000002 -+/* ccb areca cdb flag */ -+#define ARCMSR_CCBPOST_FLAG_SGL_BSIZE 0x80000000 -+#define ARCMSR_CCBPOST_FLAG_IAM_BIOS 0x40000000 -+#define ARCMSR_CCBREPLY_FLAG_IAM_BIOS 0x40000000 -+#define ARCMSR_CCBREPLY_FLAG_ERROR 0x10000000 -+/* outbound firmware ok */ -+#define ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK 0x80000000 -+/* -+******************************************************************************* -+** ARECA SCSI COMMAND DESCRIPTOR BLOCK size 0x1F8 (504) -+******************************************************************************* -+*/ -+struct ARCMSR_CDB -+{ -+ uint8_t Bus; -+ uint8_t TargetID; -+ uint8_t LUN; -+ uint8_t Function; -+ -+ uint8_t CdbLength; -+ uint8_t sgcount; -+ uint8_t Flags; -+#define ARCMSR_CDB_FLAG_SGL_BSIZE 0x01 -+#define ARCMSR_CDB_FLAG_BIOS 0x02 -+#define ARCMSR_CDB_FLAG_WRITE 0x04 -+#define ARCMSR_CDB_FLAG_SIMPLEQ 0x00 -+#define ARCMSR_CDB_FLAG_HEADQ 0x08 -+#define ARCMSR_CDB_FLAG_ORDEREDQ 0x10 -+ uint8_t Reserved1; -+ -+ uint32_t Context; -+ uint32_t DataLength; -+ -+ uint8_t Cdb[16]; -+ -+ uint8_t DeviceStatus; -+#define ARCMSR_DEV_CHECK_CONDITION 0x02 -+#define ARCMSR_DEV_SELECT_TIMEOUT 0xF0 -+#define ARCMSR_DEV_ABORTED 0xF1 -+#define ARCMSR_DEV_INIT_FAIL 0xF2 -+ uint8_t SenseData[15]; -+ -+ union -+ { -+ struct SG32ENTRY sg32entry[ARCMSR_MAX_SG_ENTRIES]; -+ struct SG64ENTRY sg64entry[ARCMSR_MAX_SG_ENTRIES]; -+ } u; -+}; -+/* -+******************************************************************************* -+** Messaging Unit (MU) of the Intel R 80331 I/O processor (80331) -+******************************************************************************* -+*/ -+struct MessageUnit -+{ -+ uint32_t resrved0[4]; /*0000 000F*/ -+ uint32_t inbound_msgaddr0; /*0010 0013*/ -+ uint32_t inbound_msgaddr1; /*0014 0017*/ -+ uint32_t outbound_msgaddr0; /*0018 001B*/ -+ uint32_t outbound_msgaddr1; /*001C 001F*/ -+ uint32_t inbound_doorbell; /*0020 0023*/ -+ uint32_t inbound_intstatus; /*0024 0027*/ -+ uint32_t inbound_intmask; /*0028 002B*/ -+ uint32_t outbound_doorbell; /*002C 002F*/ -+ uint32_t outbound_intstatus; /*0030 0033*/ -+ uint32_t outbound_intmask; /*0034 0037*/ -+ uint32_t reserved1[2]; /*0038 003F*/ -+ uint32_t inbound_queueport; /*0040 0043*/ -+ uint32_t outbound_queueport; /*0044 0047*/ -+ uint32_t reserved2[2]; /*0048 004F*/ -+ uint32_t reserved3[492]; /*0050 07FF 492*/ -+ uint32_t reserved4[128]; /*0800 09FF 128*/ -+ uint32_t message_rwbuffer[256]; /*0a00 0DFF 256*/ -+ uint32_t message_wbuffer[32]; /*0E00 0E7F 32*/ -+ uint32_t reserved5[32]; /*0E80 0EFF 32*/ -+ uint32_t message_rbuffer[32]; /*0F00 0F7F 32*/ -+ uint32_t reserved6[32]; /*0F80 0FFF 32*/ -+}; -+/* -+******************************************************************************* -+** Adapter Control Block -+******************************************************************************* -+*/ -+struct AdapterControlBlock -+{ -+ struct pci_dev * pdev; -+ struct Scsi_Host * host; -+ unsigned long vir2phy_offset; -+ /* Offset is used in making arc cdb physical to virtual calculations */ -+ uint32_t outbound_int_enable; -+ -+ struct MessageUnit __iomem * pmu; -+ /* message unit ATU inbound base address0 */ -+ -+ uint32_t acb_flags; -+#define ACB_F_SCSISTOPADAPTER 0x0001 -+#define ACB_F_MSG_STOP_BGRB 0x0002 -+ /* stop RAID background rebuild */ -+#define ACB_F_MSG_START_BGRB 0x0004 -+ /* stop RAID background rebuild */ -+#define ACB_F_IOPDATA_OVERFLOW 0x0008 -+ /* iop message data rqbuffer overflow */ -+#define ACB_F_MESSAGE_WQBUFFER_CLEARED 0x0010 -+ /* message clear wqbuffer */ -+#define ACB_F_MESSAGE_RQBUFFER_CLEARED 0x0020 -+ /* message clear rqbuffer */ -+#define ACB_F_MESSAGE_WQBUFFER_READED 0x0040 -+#define ACB_F_BUS_RESET 0x0080 -+#define ACB_F_IOP_INITED 0x0100 -+ /* iop init */ -+ -+ struct CommandControlBlock * pccb_pool[ARCMSR_MAX_FREECCB_NUM]; -+ /* used for memory free */ -+ struct list_head ccb_free_list; -+ /* head of free ccb list */ -+ atomic_t ccboutstandingcount; -+ -+ void * dma_coherent; -+ /* dma_coherent used for memory free */ -+ dma_addr_t dma_coherent_handle; -+ /* dma_coherent_handle used for memory free */ -+ -+ uint8_t rqbuffer[ARCMSR_MAX_QBUFFER]; -+ /* data collection buffer for read from 80331 */ -+ int32_t rqbuf_firstindex; -+ /* first of read buffer */ -+ int32_t rqbuf_lastindex; -+ /* last of read buffer */ -+ uint8_t wqbuffer[ARCMSR_MAX_QBUFFER]; -+ /* data collection buffer for write to 80331 */ -+ int32_t wqbuf_firstindex; -+ /* first of write buffer */ -+ int32_t wqbuf_lastindex; -+ /* last of write buffer */ -+ uint8_t devstate[ARCMSR_MAX_TARGETID][ARCMSR_MAX_TARGETLUN]; -+ /* id0 ..... id15, lun0...lun7 */ -+#define ARECA_RAID_GONE 0x55 -+#define ARECA_RAID_GOOD 0xaa -+ uint32_t num_resets; -+ uint32_t num_aborts; -+ uint32_t firm_request_len; -+ uint32_t firm_numbers_queue; -+ uint32_t firm_sdram_size; -+ uint32_t firm_hd_channels; -+ char firm_model[12]; -+ char firm_version[20]; -+};/* HW_DEVICE_EXTENSION */ -+/* -+******************************************************************************* -+** Command Control Block -+** this CCB length must be 32 bytes boundary -+******************************************************************************* -+*/ -+struct CommandControlBlock -+{ -+ struct ARCMSR_CDB arcmsr_cdb; -+ /* -+ ** 0-503 (size of CDB=504): -+ ** arcmsr messenger scsi command descriptor size 504 bytes -+ */ -+ uint32_t cdb_shifted_phyaddr; -+ /* 504-507 */ -+ uint32_t reserved1; -+ /* 508-511 */ -+#if BITS_PER_LONG == 64 -+ /* ======================512+64 bytes======================== */ -+ struct list_head list; -+ /* 512-527 16 bytes next/prev ptrs for ccb lists */ -+ struct scsi_cmnd * pcmd; -+ /* 528-535 8 bytes pointer of linux scsi command */ -+ struct AdapterControlBlock * acb; -+ /* 536-543 8 bytes pointer of acb */ -+ -+ uint16_t ccb_flags; -+ /* 544-545 */ -+ #define CCB_FLAG_READ 0x0000 -+ #define CCB_FLAG_WRITE 0x0001 -+ #define CCB_FLAG_ERROR 0x0002 -+ #define CCB_FLAG_FLUSHCACHE 0x0004 -+ #define CCB_FLAG_MASTER_ABORTED 0x0008 -+ uint16_t startdone; -+ /* 546-547 */ -+ #define ARCMSR_CCB_DONE 0x0000 -+ #define ARCMSR_CCB_START 0x55AA -+ #define ARCMSR_CCB_ABORTED 0xAA55 -+ #define ARCMSR_CCB_ILLEGAL 0xFFFF -+ uint32_t reserved2[7]; -+ /* 548-551 552-555 556-559 560-563 564-567 568-571 572-575 */ -+#else -+ /* ======================512+32 bytes======================== */ -+ struct list_head list; -+ /* 512-519 8 bytes next/prev ptrs for ccb lists */ -+ struct scsi_cmnd * pcmd; -+ /* 520-523 4 bytes pointer of linux scsi command */ -+ struct AdapterControlBlock * acb; -+ /* 524-527 4 bytes pointer of acb */ -+ -+ uint16_t ccb_flags; -+ /* 528-529 */ -+ #define CCB_FLAG_READ 0x0000 -+ #define CCB_FLAG_WRITE 0x0001 -+ #define CCB_FLAG_ERROR 0x0002 -+ #define CCB_FLAG_FLUSHCACHE 0x0004 -+ #define CCB_FLAG_MASTER_ABORTED 0x0008 -+ uint16_t startdone; -+ /* 530-531 */ -+ #define ARCMSR_CCB_DONE 0x0000 -+ #define ARCMSR_CCB_START 0x55AA -+ #define ARCMSR_CCB_ABORTED 0xAA55 -+ #define ARCMSR_CCB_ILLEGAL 0xFFFF -+ uint32_t reserved2[3]; -+ /* 532-535 536-539 540-543 */ -+#endif -+ /* ========================================================== */ -+}; -+/* -+******************************************************************************* -+** ARECA SCSI sense data -+******************************************************************************* -+*/ -+struct SENSE_DATA -+{ -+ uint8_t ErrorCode:7; -+#define SCSI_SENSE_CURRENT_ERRORS 0x70 -+#define SCSI_SENSE_DEFERRED_ERRORS 0x71 -+ uint8_t Valid:1; -+ uint8_t SegmentNumber; -+ uint8_t SenseKey:4; -+ uint8_t Reserved:1; -+ uint8_t IncorrectLength:1; -+ uint8_t EndOfMedia:1; -+ uint8_t FileMark:1; -+ uint8_t Information[4]; -+ uint8_t AdditionalSenseLength; -+ uint8_t CommandSpecificInformation[4]; -+ uint8_t AdditionalSenseCode; -+ uint8_t AdditionalSenseCodeQualifier; -+ uint8_t FieldReplaceableUnitCode; -+ uint8_t SenseKeySpecific[3]; -+}; -+/* -+******************************************************************************* -+** Outbound Interrupt Status Register - OISR -+******************************************************************************* -+*/ -+#define ARCMSR_MU_OUTBOUND_INTERRUPT_STATUS_REG 0x30 -+#define ARCMSR_MU_OUTBOUND_PCI_INT 0x10 -+#define ARCMSR_MU_OUTBOUND_POSTQUEUE_INT 0x08 -+#define ARCMSR_MU_OUTBOUND_DOORBELL_INT 0x04 -+#define ARCMSR_MU_OUTBOUND_MESSAGE1_INT 0x02 -+#define ARCMSR_MU_OUTBOUND_MESSAGE0_INT 0x01 -+#define ARCMSR_MU_OUTBOUND_HANDLE_INT \ -+ (ARCMSR_MU_OUTBOUND_MESSAGE0_INT \ -+ |ARCMSR_MU_OUTBOUND_MESSAGE1_INT \ -+ |ARCMSR_MU_OUTBOUND_DOORBELL_INT \ -+ |ARCMSR_MU_OUTBOUND_POSTQUEUE_INT \ -+ |ARCMSR_MU_OUTBOUND_PCI_INT) -+/* -+******************************************************************************* -+** Outbound Interrupt Mask Register - OIMR -+******************************************************************************* -+*/ -+#define ARCMSR_MU_OUTBOUND_INTERRUPT_MASK_REG 0x34 -+#define ARCMSR_MU_OUTBOUND_PCI_INTMASKENABLE 0x10 -+#define ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE 0x08 -+#define ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE 0x04 -+#define ARCMSR_MU_OUTBOUND_MESSAGE1_INTMASKENABLE 0x02 -+#define ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE 0x01 -+#define ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE 0x1F -+ -+extern void arcmsr_post_Qbuffer(struct AdapterControlBlock *acb); -+extern struct class_device_attribute *arcmsr_host_attrs[]; -+extern int arcmsr_alloc_sysfs_attr(struct AdapterControlBlock *acb); -+void arcmsr_free_sysfs_attr(struct AdapterControlBlock *acb); -+ -diff --git a/drivers/scsi/arcmsr/arcmsr_attr.c b/drivers/scsi/arcmsr/arcmsr_attr.c -new file mode 100644 -index 0000000..0459f41 ---- /dev/null -+++ b/drivers/scsi/arcmsr/arcmsr_attr.c -@@ -0,0 +1,392 @@ -+/* -+******************************************************************************* -+** O.S : Linux -+** FILE NAME : arcmsr_attr.c -+** BY : Erich Chen -+** Description: attributes exported to sysfs and device host -+******************************************************************************* -+** Copyright (C) 2002 - 2005, Areca Technology Corporation All rights reserved -+** -+** Web site: www.areca.com.tw -+** E-mail: erich@areca.com.tw -+** -+** This program is free software; you can redistribute it and/or modify -+** it under the terms of the GNU General Public License version 2 as -+** published by the Free Software Foundation. -+** This program is distributed in the hope that it will be useful, -+** but WITHOUT ANY WARRANTY; without even the implied warranty of -+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+** GNU General Public License for more details. -+******************************************************************************* -+** Redistribution and use in source and binary forms, with or without -+** modification, are permitted provided that the following conditions -+** are met: -+** 1. Redistributions of source code must retain the above copyright -+** notice, this list of conditions and the following disclaimer. -+** 2. Redistributions in binary form must reproduce the above copyright -+** notice, this list of conditions and the following disclaimer in the -+** documentation and/or other materials provided with the distribution. -+** 3. The name of the author may not be used to endorse or promote products -+** derived from this software without specific prior written permission. -+** -+** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -+** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -+** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -+** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -+** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING,BUT -+** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION)HOWEVER CAUSED AND ON ANY -+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+** (INCLUDING NEGLIGENCE OR OTHERWISE)ARISING IN ANY WAY OUT OF THE USE OF -+** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+******************************************************************************* -+** For history of changes, see Documentation/scsi/ChangeLog.arcmsr -+** Firmware Specification, see Documentation/scsi/arcmsr_spec.txt -+******************************************************************************* -+*/ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include "arcmsr.h" -+ -+struct class_device_attribute *arcmsr_host_attrs[]; -+ -+static ssize_t -+arcmsr_sysfs_iop_message_read(struct kobject *kobj, char *buf, loff_t off, -+ size_t count) -+{ -+ struct class_device *cdev = container_of(kobj,struct class_device,kobj); -+ struct Scsi_Host *host = class_to_shost(cdev); -+ struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; -+ struct MessageUnit __iomem *reg = acb->pmu; -+ uint8_t *pQbuffer,*ptmpQbuffer; -+ int32_t allxfer_len = 0; -+ -+ if (!capable(CAP_SYS_ADMIN)) -+ return -EACCES; -+ -+ /* do message unit read. */ -+ ptmpQbuffer = (uint8_t *)buf; -+ while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex) -+ && (allxfer_len < 1031)) { -+ pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex]; -+ memcpy(ptmpQbuffer, pQbuffer, 1); -+ acb->rqbuf_firstindex++; -+ acb->rqbuf_firstindex %= ARCMSR_MAX_QBUFFER; -+ ptmpQbuffer++; -+ allxfer_len++; -+ } -+ if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { -+ struct QBUFFER __iomem * prbuffer = (struct QBUFFER __iomem *) -+ ®->message_rbuffer; -+ uint8_t __iomem * iop_data = (uint8_t __iomem *)prbuffer->data; -+ int32_t iop_len; -+ -+ acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; -+ iop_len = readl(&prbuffer->data_len); -+ while (iop_len > 0) { -+ acb->rqbuffer[acb->rqbuf_lastindex] = readb(iop_data); -+ acb->rqbuf_lastindex++; -+ acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER; -+ iop_data++; -+ iop_len--; -+ } -+ writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, -+ ®->inbound_doorbell); -+ } -+ return (allxfer_len); -+} -+ -+static ssize_t -+arcmsr_sysfs_iop_message_write(struct kobject *kobj, char *buf, loff_t off, -+ size_t count) -+{ -+ struct class_device *cdev = container_of(kobj,struct class_device,kobj); -+ struct Scsi_Host *host = class_to_shost(cdev); -+ struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; -+ int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex; -+ uint8_t *pQbuffer, *ptmpuserbuffer; -+ -+ if (!capable(CAP_SYS_ADMIN)) -+ return -EACCES; -+ if (count > 1032) -+ return -EINVAL; -+ /* do message unit write. */ -+ ptmpuserbuffer = (uint8_t *)buf; -+ user_len = (int32_t)count; -+ wqbuf_lastindex = acb->wqbuf_lastindex; -+ wqbuf_firstindex = acb->wqbuf_firstindex; -+ if (wqbuf_lastindex != wqbuf_firstindex) { -+ arcmsr_post_Qbuffer(acb); -+ return 0; /*need retry*/ -+ } else { -+ my_empty_len = (wqbuf_firstindex-wqbuf_lastindex - 1) -+ &(ARCMSR_MAX_QBUFFER - 1); -+ if (my_empty_len >= user_len) { -+ while (user_len > 0) { -+ pQbuffer = -+ &acb->wqbuffer[acb->wqbuf_lastindex]; -+ memcpy(pQbuffer, ptmpuserbuffer, 1); -+ acb->wqbuf_lastindex++; -+ acb->wqbuf_lastindex %= ARCMSR_MAX_QBUFFER; -+ ptmpuserbuffer++; -+ user_len--; -+ } -+ if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_CLEARED) { -+ acb->acb_flags &= -+ ~ACB_F_MESSAGE_WQBUFFER_CLEARED; -+ arcmsr_post_Qbuffer(acb); -+ } -+ return count; -+ } else { -+ return 0; /*need retry*/ -+ } -+ } -+} -+ -+static ssize_t -+arcmsr_sysfs_iop_message_clear(struct kobject *kobj, char *buf, loff_t off, -+ size_t count) -+{ -+ struct class_device *cdev = container_of(kobj,struct class_device,kobj); -+ struct Scsi_Host *host = class_to_shost(cdev); -+ struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; -+ struct MessageUnit __iomem *reg = acb->pmu; -+ uint8_t *pQbuffer; -+ -+ if (!capable(CAP_SYS_ADMIN)) -+ return -EACCES; -+ -+ if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { -+ acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; -+ writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK -+ , ®->inbound_doorbell); -+ } -+ acb->acb_flags |= -+ (ACB_F_MESSAGE_WQBUFFER_CLEARED -+ | ACB_F_MESSAGE_RQBUFFER_CLEARED -+ | ACB_F_MESSAGE_WQBUFFER_READED); -+ acb->rqbuf_firstindex = 0; -+ acb->rqbuf_lastindex = 0; -+ acb->wqbuf_firstindex = 0; -+ acb->wqbuf_lastindex = 0; -+ pQbuffer = acb->rqbuffer; -+ memset(pQbuffer, 0, sizeof (struct QBUFFER)); -+ pQbuffer = acb->wqbuffer; -+ memset(pQbuffer, 0, sizeof (struct QBUFFER)); -+ return 1; -+} -+ -+static struct bin_attribute arcmsr_sysfs_message_read_attr = { -+ .attr = { -+ .name = "mu_read", -+ .mode = S_IRUSR , -+ .owner = THIS_MODULE, -+ }, -+ .size = 1032, -+ .read = arcmsr_sysfs_iop_message_read, -+}; -+ -+static struct bin_attribute arcmsr_sysfs_message_write_attr = { -+ .attr = { -+ .name = "mu_write", -+ .mode = S_IWUSR, -+ .owner = THIS_MODULE, -+ }, -+ .size = 1032, -+ .write = arcmsr_sysfs_iop_message_write, -+}; -+ -+static struct bin_attribute arcmsr_sysfs_message_clear_attr = { -+ .attr = { -+ .name = "mu_clear", -+ .mode = S_IWUSR, -+ .owner = THIS_MODULE, -+ }, -+ .size = 1, -+ .write = arcmsr_sysfs_iop_message_clear, -+}; -+ -+int arcmsr_alloc_sysfs_attr(struct AdapterControlBlock *acb) -+{ -+ struct Scsi_Host *host = acb->host; -+ int error; -+ -+ error = sysfs_create_bin_file(&host->shost_classdev.kobj, -+ &arcmsr_sysfs_message_read_attr); -+ if (error) { -+ printk(KERN_ERR "arcmsr: alloc sysfs mu_read failed\n"); -+ goto error_bin_file_message_read; -+ } -+ error = sysfs_create_bin_file(&host->shost_classdev.kobj, -+ &arcmsr_sysfs_message_write_attr); -+ if (error) { -+ printk(KERN_ERR "arcmsr: alloc sysfs mu_write failed\n"); -+ goto error_bin_file_message_write; -+ } -+ error = sysfs_create_bin_file(&host->shost_classdev.kobj, -+ &arcmsr_sysfs_message_clear_attr); -+ if (error) { -+ printk(KERN_ERR "arcmsr: alloc sysfs mu_clear failed\n"); -+ goto error_bin_file_message_clear; -+ } -+ return 0; -+error_bin_file_message_clear: -+ error = sysfs_remove_bin_file(&host->shost_classdev.kobj, -+ &arcmsr_sysfs_message_write_attr); -+ if (error) -+ printk(KERN_ERR "arcmsr: sysfs_remove_bin_file mu_write failed\n"); -+error_bin_file_message_write: -+ error = sysfs_remove_bin_file(&host->shost_classdev.kobj, -+ &arcmsr_sysfs_message_read_attr); -+ if (error) -+ printk(KERN_ERR "arcmsr: sysfs_remove_bin_file mu_read failed\n"); -+error_bin_file_message_read: -+ return error; -+} -+ -+void -+arcmsr_free_sysfs_attr(struct AdapterControlBlock *acb) { -+ struct Scsi_Host *host = acb->host; -+ int error; -+ -+ error = sysfs_remove_bin_file(&host->shost_classdev.kobj, -+ &arcmsr_sysfs_message_clear_attr); -+ if (error) -+ printk(KERN_ERR "arcmsr: free sysfs mu_clear failed\n"); -+ error = sysfs_remove_bin_file(&host->shost_classdev.kobj, -+ &arcmsr_sysfs_message_write_attr); -+ if (error) -+ printk(KERN_ERR "arcmsr: free sysfs mu_write failed\n"); -+ error = sysfs_remove_bin_file(&host->shost_classdev.kobj, -+ &arcmsr_sysfs_message_read_attr); -+ if (error) -+ printk(KERN_ERR "arcmsr: free sysfss mu_read failed\n"); -+} -+ -+ -+static ssize_t -+arcmsr_attr_host_driver_version(struct class_device *cdev, char *buf) { -+ return snprintf(buf, PAGE_SIZE, -+ "ARCMSR: %s\n", -+ ARCMSR_DRIVER_VERSION); -+} -+ -+static ssize_t -+arcmsr_attr_host_driver_posted_cmd(struct class_device *cdev, char *buf) { -+ struct Scsi_Host *host = class_to_shost(cdev); -+ struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; -+ return snprintf(buf, PAGE_SIZE, -+ "Current commands posted: %4d\n", -+ atomic_read(&acb->ccboutstandingcount)); -+} -+ -+static ssize_t -+arcmsr_attr_host_driver_reset(struct class_device *cdev, char *buf) { -+ struct Scsi_Host *host = class_to_shost(cdev); -+ struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; -+ return snprintf(buf, PAGE_SIZE, -+ "SCSI Host Resets: %4d\n", -+ acb->num_resets); -+} -+ -+static ssize_t -+arcmsr_attr_host_driver_abort(struct class_device *cdev, char *buf) { -+ struct Scsi_Host *host = class_to_shost(cdev); -+ struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; -+ return snprintf(buf, PAGE_SIZE, -+ "SCSI Aborts/Timeouts: %4d\n", -+ acb->num_aborts); -+} -+ -+static ssize_t -+arcmsr_attr_host_fw_model(struct class_device *cdev, char *buf) { -+ struct Scsi_Host *host = class_to_shost(cdev); -+ struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; -+ return snprintf(buf, PAGE_SIZE, -+ "Adapter Model: %s\n", -+ acb->firm_model); -+} -+ -+static ssize_t -+arcmsr_attr_host_fw_version(struct class_device *cdev, char *buf) { -+ struct Scsi_Host *host = class_to_shost(cdev); -+ struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; -+ -+ return snprintf(buf, PAGE_SIZE, -+ "Firmware Version: %s\n", -+ acb->firm_version); -+} -+ -+static ssize_t -+arcmsr_attr_host_fw_request_len(struct class_device *cdev, char *buf) { -+ struct Scsi_Host *host = class_to_shost(cdev); -+ struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; -+ -+ return snprintf(buf, PAGE_SIZE, -+ "Reguest Lenth: %4d\n", -+ acb->firm_request_len); -+} -+ -+static ssize_t -+arcmsr_attr_host_fw_numbers_queue(struct class_device *cdev, char *buf) { -+ struct Scsi_Host *host = class_to_shost(cdev); -+ struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; -+ -+ return snprintf(buf, PAGE_SIZE, -+ "Numbers of Queue: %4d\n", -+ acb->firm_numbers_queue); -+} -+ -+static ssize_t -+arcmsr_attr_host_fw_sdram_size(struct class_device *cdev, char *buf) { -+ struct Scsi_Host *host = class_to_shost(cdev); -+ struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; -+ -+ return snprintf(buf, PAGE_SIZE, -+ "SDRAM Size: %4d\n", -+ acb->firm_sdram_size); -+} -+ -+static ssize_t -+arcmsr_attr_host_fw_hd_channels(struct class_device *cdev, char *buf) { -+ struct Scsi_Host *host = class_to_shost(cdev); -+ struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; -+ -+ return snprintf(buf, PAGE_SIZE, -+ "Hard Disk Channels: %4d\n", -+ acb->firm_hd_channels); -+} -+ -+static CLASS_DEVICE_ATTR(host_driver_version, S_IRUGO, arcmsr_attr_host_driver_version, NULL); -+static CLASS_DEVICE_ATTR(host_driver_posted_cmd, S_IRUGO, arcmsr_attr_host_driver_posted_cmd, NULL); -+static CLASS_DEVICE_ATTR(host_driver_reset, S_IRUGO, arcmsr_attr_host_driver_reset, NULL); -+static CLASS_DEVICE_ATTR(host_driver_abort, S_IRUGO, arcmsr_attr_host_driver_abort, NULL); -+static CLASS_DEVICE_ATTR(host_fw_model, S_IRUGO, arcmsr_attr_host_fw_model, NULL); -+static CLASS_DEVICE_ATTR(host_fw_version, S_IRUGO, arcmsr_attr_host_fw_version, NULL); -+static CLASS_DEVICE_ATTR(host_fw_request_len, S_IRUGO, arcmsr_attr_host_fw_request_len, NULL); -+static CLASS_DEVICE_ATTR(host_fw_numbers_queue, S_IRUGO, arcmsr_attr_host_fw_numbers_queue, NULL); -+static CLASS_DEVICE_ATTR(host_fw_sdram_size, S_IRUGO, arcmsr_attr_host_fw_sdram_size, NULL); -+static CLASS_DEVICE_ATTR(host_fw_hd_channels, S_IRUGO, arcmsr_attr_host_fw_hd_channels, NULL); -+ -+struct class_device_attribute *arcmsr_host_attrs[] = { -+ &class_device_attr_host_driver_version, -+ &class_device_attr_host_driver_posted_cmd, -+ &class_device_attr_host_driver_reset, -+ &class_device_attr_host_driver_abort, -+ &class_device_attr_host_fw_model, -+ &class_device_attr_host_fw_version, -+ &class_device_attr_host_fw_request_len, -+ &class_device_attr_host_fw_numbers_queue, -+ &class_device_attr_host_fw_sdram_size, -+ &class_device_attr_host_fw_hd_channels, -+ NULL, -+}; -diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c -new file mode 100644 -index 0000000..475f978 ---- /dev/null -+++ b/drivers/scsi/arcmsr/arcmsr_hba.c -@@ -0,0 +1,1496 @@ -+/* -+******************************************************************************* -+** O.S : Linux -+** FILE NAME : arcmsr_hba.c -+** BY : Erich Chen -+** Description: SCSI RAID Device Driver for -+** ARECA RAID Host adapter -+******************************************************************************* -+** Copyright (C) 2002 - 2005, Areca Technology Corporation All rights reserved -+** -+** Web site: www.areca.com.tw -+** E-mail: erich@areca.com.tw -+** -+** This program is free software; you can redistribute it and/or modify -+** it under the terms of the GNU General Public License version 2 as -+** published by the Free Software Foundation. -+** This program is distributed in the hope that it will be useful, -+** but WITHOUT ANY WARRANTY; without even the implied warranty of -+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+** GNU General Public License for more details. -+******************************************************************************* -+** Redistribution and use in source and binary forms, with or without -+** modification, are permitted provided that the following conditions -+** are met: -+** 1. Redistributions of source code must retain the above copyright -+** notice, this list of conditions and the following disclaimer. -+** 2. Redistributions in binary form must reproduce the above copyright -+** notice, this list of conditions and the following disclaimer in the -+** documentation and/or other materials provided with the distribution. -+** 3. The name of the author may not be used to endorse or promote products -+** derived from this software without specific prior written permission. -+** -+** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -+** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -+** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -+** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -+** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING,BUT -+** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION)HOWEVER CAUSED AND ON ANY -+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+** (INCLUDING NEGLIGENCE OR OTHERWISE)ARISING IN ANY WAY OUT OF THE USE OF -+** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+******************************************************************************* -+** For history of changes, see Documentation/scsi/ChangeLog.arcmsr -+** Firmware Specification, see Documentation/scsi/arcmsr_spec.txt -+******************************************************************************* -+*/ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "arcmsr.h" -+ -+MODULE_AUTHOR("Erich Chen "); -+MODULE_DESCRIPTION("ARECA (ARC11xx/12xx) SATA RAID HOST Adapter"); -+MODULE_LICENSE("Dual BSD/GPL"); -+MODULE_VERSION(ARCMSR_DRIVER_VERSION); -+ -+static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, struct scsi_cmnd *cmd); -+static int arcmsr_abort(struct scsi_cmnd *); -+static int arcmsr_bus_reset(struct scsi_cmnd *); -+static int arcmsr_bios_param(struct scsi_device *sdev, -+ struct block_device *bdev, sector_t capacity, int *info); -+static int arcmsr_queue_command(struct scsi_cmnd * cmd, -+ void (*done) (struct scsi_cmnd *)); -+static int arcmsr_probe(struct pci_dev *pdev, -+ const struct pci_device_id *id); -+static void arcmsr_remove(struct pci_dev *pdev); -+static void arcmsr_shutdown(struct pci_dev *pdev); -+static void arcmsr_iop_init(struct AdapterControlBlock *acb); -+static void arcmsr_free_ccb_pool(struct AdapterControlBlock *acb); -+static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb); -+static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb); -+static uint8_t arcmsr_wait_msgint_ready(struct AdapterControlBlock *acb); -+static const char *arcmsr_info(struct Scsi_Host *); -+static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb); -+ -+static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev, int queue_depth) -+{ -+ if (queue_depth > ARCMSR_MAX_CMD_PERLUN) -+ queue_depth = ARCMSR_MAX_CMD_PERLUN; -+ scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth); -+ return queue_depth; -+} -+ -+static struct scsi_host_template arcmsr_scsi_host_template = { -+ .module = THIS_MODULE, -+ .name = "ARCMSR ARECA SATA RAID HOST Adapter" ARCMSR_DRIVER_VERSION, -+ .info = arcmsr_info, -+ .queuecommand = arcmsr_queue_command, -+ .eh_abort_handler = arcmsr_abort, -+ .eh_bus_reset_handler = arcmsr_bus_reset, -+ .bios_param = arcmsr_bios_param, -+ .change_queue_depth = arcmsr_adjust_disk_queue_depth, -+ .can_queue = ARCMSR_MAX_OUTSTANDING_CMD, -+ .this_id = ARCMSR_SCSI_INITIATOR_ID, -+ .sg_tablesize = ARCMSR_MAX_SG_ENTRIES, -+ .max_sectors = ARCMSR_MAX_XFER_SECTORS, -+ .cmd_per_lun = ARCMSR_MAX_CMD_PERLUN, -+ .use_clustering = ENABLE_CLUSTERING, -+ .shost_attrs = arcmsr_host_attrs, -+}; -+ -+static struct pci_device_id arcmsr_device_id_table[] = { -+ {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1110)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1120)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1130)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1160)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1170)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1210)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1220)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1230)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1260)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1270)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1280)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1380)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1381)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1680)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1681)}, -+ {0, 0}, /* Terminating entry */ -+}; -+MODULE_DEVICE_TABLE(pci, arcmsr_device_id_table); -+static struct pci_driver arcmsr_pci_driver = { -+ .name = "arcmsr", -+ .id_table = arcmsr_device_id_table, -+ .probe = arcmsr_probe, -+ .remove = arcmsr_remove, -+ .shutdown = arcmsr_shutdown -+}; -+ -+static irqreturn_t arcmsr_do_interrupt(int irq, void *dev_id, -+ struct pt_regs *regs) -+{ -+ irqreturn_t handle_state; -+ struct AdapterControlBlock *acb; -+ unsigned long flags; -+ -+ acb = (struct AdapterControlBlock *)dev_id; -+ -+ spin_lock_irqsave(acb->host->host_lock, flags); -+ handle_state = arcmsr_interrupt(acb); -+ spin_unlock_irqrestore(acb->host->host_lock, flags); -+ return handle_state; -+} -+ -+static int arcmsr_bios_param(struct scsi_device *sdev, -+ struct block_device *bdev, sector_t capacity, int *geom) -+{ -+ int ret, heads, sectors, cylinders, total_capacity; -+ unsigned char *buffer;/* return copy of block device's partition table */ -+ -+ buffer = scsi_bios_ptable(bdev); -+ if (buffer) { -+ ret = scsi_partsize(buffer, capacity, &geom[2], &geom[0], &geom[1]); -+ kfree(buffer); -+ if (ret != -1) -+ return ret; -+ } -+ total_capacity = capacity; -+ heads = 64; -+ sectors = 32; -+ cylinders = total_capacity / (heads * sectors); -+ if (cylinders > 1024) { -+ heads = 255; -+ sectors = 63; -+ cylinders = total_capacity / (heads * sectors); -+ } -+ geom[0] = heads; -+ geom[1] = sectors; -+ geom[2] = cylinders; -+ return 0; -+} -+ -+static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb) -+{ -+ struct pci_dev *pdev = acb->pdev; -+ struct MessageUnit __iomem *reg = acb->pmu; -+ u32 ccb_phyaddr_hi32; -+ void *dma_coherent; -+ dma_addr_t dma_coherent_handle, dma_addr; -+ struct CommandControlBlock *ccb_tmp; -+ int i, j; -+ -+ dma_coherent = dma_alloc_coherent(&pdev->dev, -+ ARCMSR_MAX_FREECCB_NUM * -+ sizeof (struct CommandControlBlock) + 0x20, -+ &dma_coherent_handle, GFP_KERNEL); -+ if (!dma_coherent) -+ return -ENOMEM; -+ -+ acb->dma_coherent = dma_coherent; -+ acb->dma_coherent_handle = dma_coherent_handle; -+ -+ if (((unsigned long)dma_coherent & 0x1F)) { -+ dma_coherent = dma_coherent + -+ (0x20 - ((unsigned long)dma_coherent & 0x1F)); -+ dma_coherent_handle = dma_coherent_handle + -+ (0x20 - ((unsigned long)dma_coherent_handle & 0x1F)); -+ } -+ -+ dma_addr = dma_coherent_handle; -+ ccb_tmp = (struct CommandControlBlock *)dma_coherent; -+ for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { -+ ccb_tmp->cdb_shifted_phyaddr = dma_addr >> 5; -+ ccb_tmp->acb = acb; -+ acb->pccb_pool[i] = ccb_tmp; -+ list_add_tail(&ccb_tmp->list, &acb->ccb_free_list); -+ dma_addr = dma_addr + sizeof (struct CommandControlBlock); -+ ccb_tmp++; -+ } -+ -+ acb->vir2phy_offset = (unsigned long)ccb_tmp - -+ (unsigned long)dma_addr; -+ for (i = 0; i < ARCMSR_MAX_TARGETID; i++) -+ for (j = 0; j < ARCMSR_MAX_TARGETLUN; j++) -+ acb->devstate[i][j] = ARECA_RAID_GOOD; -+ -+ /* -+ ** here we need to tell iop 331 our ccb_tmp.HighPart -+ ** if ccb_tmp.HighPart is not zero -+ */ -+ ccb_phyaddr_hi32 = (uint32_t) ((dma_coherent_handle >> 16) >> 16); -+ if (ccb_phyaddr_hi32 != 0) { -+ writel(ARCMSR_SIGNATURE_SET_CONFIG, ®->message_rwbuffer[0]); -+ writel(ccb_phyaddr_hi32, ®->message_rwbuffer[1]); -+ writel(ARCMSR_INBOUND_MESG0_SET_CONFIG, ®->inbound_msgaddr0); -+ if (arcmsr_wait_msgint_ready(acb)) -+ printk(KERN_NOTICE "arcmsr%d: " -+ "'set ccb high part physical address' timeout\n", -+ acb->host->host_no); -+ } -+ -+ writel(readl(®->outbound_intmask) | -+ ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE, -+ ®->outbound_intmask); -+ return 0; -+} -+ -+static int arcmsr_probe(struct pci_dev *pdev, -+ const struct pci_device_id *id) -+{ -+ struct Scsi_Host *host; -+ struct AdapterControlBlock *acb; -+ uint8_t bus, dev_fun; -+ int error; -+ -+ error = pci_enable_device(pdev); -+ if (error) -+ goto out; -+ pci_set_master(pdev); -+ -+ host = scsi_host_alloc(&arcmsr_scsi_host_template, -+ sizeof(struct AdapterControlBlock)); -+ if (!host) { -+ error = -ENOMEM; -+ goto out_disable_device; -+ } -+ acb = (struct AdapterControlBlock *)host->hostdata; -+ memset(acb, 0, sizeof (struct AdapterControlBlock)); -+ -+ error = pci_set_dma_mask(pdev, DMA_64BIT_MASK); -+ if (error) { -+ error = pci_set_dma_mask(pdev, DMA_32BIT_MASK); -+ if (error) { -+ printk(KERN_WARNING -+ "scsi%d: No suitable DMA mask available\n", -+ host->host_no); -+ goto out_host_put; -+ } -+ } -+ bus = pdev->bus->number; -+ dev_fun = pdev->devfn; -+ acb->host = host; -+ acb->pdev = pdev; -+ host->max_sectors = ARCMSR_MAX_XFER_SECTORS; -+ host->max_lun = ARCMSR_MAX_TARGETLUN; -+ host->max_id = ARCMSR_MAX_TARGETID;/*16:8*/ -+ host->max_cmd_len = 16; /*this is issue of 64bit LBA, over 2T byte*/ -+ host->sg_tablesize = ARCMSR_MAX_SG_ENTRIES; -+ host->can_queue = ARCMSR_MAX_FREECCB_NUM; /* max simultaneous cmds */ -+ host->cmd_per_lun = ARCMSR_MAX_CMD_PERLUN; -+ host->this_id = ARCMSR_SCSI_INITIATOR_ID; -+ host->unique_id = (bus << 8) | dev_fun; -+ host->irq = pdev->irq; -+ error = pci_request_regions(pdev, "arcmsr"); -+ if (error) -+ goto out_host_put; -+ -+ acb->pmu = ioremap(pci_resource_start(pdev, 0), -+ pci_resource_len(pdev, 0)); -+ if (!acb->pmu) { -+ printk(KERN_NOTICE "arcmsr%d: memory" -+ " mapping region fail \n", acb->host->host_no); -+ goto out_release_regions; -+ } -+ acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED | -+ ACB_F_MESSAGE_RQBUFFER_CLEARED | -+ ACB_F_MESSAGE_WQBUFFER_READED); -+ acb->acb_flags &= ~ACB_F_SCSISTOPADAPTER; -+ INIT_LIST_HEAD(&acb->ccb_free_list); -+ -+ error = arcmsr_alloc_ccb_pool(acb); -+ if (error) -+ goto out_iounmap; -+ -+ error = request_irq(pdev->irq, arcmsr_do_interrupt, -+ SA_INTERRUPT | SA_SHIRQ, "arcmsr", acb); -+ if (error) -+ goto out_free_ccb_pool; -+ -+ arcmsr_iop_init(acb); -+ pci_set_drvdata(pdev, host); -+ -+ error = scsi_add_host(host, &pdev->dev); -+ if (error) -+ goto out_free_irq; -+ -+ error = arcmsr_alloc_sysfs_attr(acb); -+ if (error) -+ goto out_free_sysfs; -+ -+ scsi_scan_host(host); -+ return 0; -+ out_free_sysfs: -+ out_free_irq: -+ free_irq(pdev->irq, acb); -+ out_free_ccb_pool: -+ arcmsr_free_ccb_pool(acb); -+ out_iounmap: -+ iounmap(acb->pmu); -+ out_release_regions: -+ pci_release_regions(pdev); -+ out_host_put: -+ scsi_host_put(host); -+ out_disable_device: -+ pci_disable_device(pdev); -+ out: -+ return error; -+} -+ -+static void arcmsr_abort_allcmd(struct AdapterControlBlock *acb) -+{ -+ struct MessageUnit __iomem *reg = acb->pmu; -+ -+ writel(ARCMSR_INBOUND_MESG0_ABORT_CMD, ®->inbound_msgaddr0); -+ if (arcmsr_wait_msgint_ready(acb)) -+ printk(KERN_NOTICE -+ "arcmsr%d: wait 'abort all outstanding command' timeout \n" -+ , acb->host->host_no); -+} -+ -+static void arcmsr_pci_unmap_dma(struct CommandControlBlock *ccb) -+{ -+ struct AdapterControlBlock *acb = ccb->acb; -+ struct scsi_cmnd *pcmd = ccb->pcmd; -+ -+ if (pcmd->use_sg != 0) { -+ struct scatterlist *sl; -+ -+ sl = (struct scatterlist *)pcmd->request_buffer; -+ pci_unmap_sg(acb->pdev, sl, pcmd->use_sg, pcmd->sc_data_direction); -+ } -+ else if (pcmd->request_bufflen != 0) -+ pci_unmap_single(acb->pdev, -+ pcmd->SCp.dma_handle, -+ pcmd->request_bufflen, pcmd->sc_data_direction); -+} -+ -+static void arcmsr_ccb_complete(struct CommandControlBlock *ccb, int stand_flag) -+{ -+ struct AdapterControlBlock *acb = ccb->acb; -+ struct scsi_cmnd *pcmd = ccb->pcmd; -+ -+ arcmsr_pci_unmap_dma(ccb); -+ if (stand_flag == 1) -+ atomic_dec(&acb->ccboutstandingcount); -+ ccb->startdone = ARCMSR_CCB_DONE; -+ ccb->ccb_flags = 0; -+ list_add_tail(&ccb->list, &acb->ccb_free_list); -+ pcmd->scsi_done(pcmd); -+} -+ -+static void arcmsr_remove(struct pci_dev *pdev) -+{ -+ struct Scsi_Host *host = pci_get_drvdata(pdev); -+ struct AdapterControlBlock *acb = -+ (struct AdapterControlBlock *) host->hostdata; -+ struct MessageUnit __iomem *reg = acb->pmu; -+ int poll_count = 0; -+ -+ arcmsr_free_sysfs_attr(acb); -+ scsi_remove_host(host); -+ arcmsr_stop_adapter_bgrb(acb); -+ arcmsr_flush_adapter_cache(acb); -+ writel(readl(®->outbound_intmask) | -+ ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE, -+ ®->outbound_intmask); -+ acb->acb_flags |= ACB_F_SCSISTOPADAPTER; -+ acb->acb_flags &= ~ACB_F_IOP_INITED; -+ -+ for (poll_count = 0; poll_count < 256; poll_count++) { -+ if (!atomic_read(&acb->ccboutstandingcount)) -+ break; -+ arcmsr_interrupt(acb); -+ msleep(25); -+ } -+ -+ if (atomic_read(&acb->ccboutstandingcount)) { -+ int i; -+ -+ arcmsr_abort_allcmd(acb); -+ for (i = 0; i < ARCMSR_MAX_OUTSTANDING_CMD; i++) -+ readl(®->outbound_queueport); -+ for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { -+ struct CommandControlBlock *ccb = acb->pccb_pool[i]; -+ if (ccb->startdone == ARCMSR_CCB_START) { -+ ccb->startdone = ARCMSR_CCB_ABORTED; -+ ccb->pcmd->result = DID_ABORT << 16; -+ arcmsr_ccb_complete(ccb, 1); -+ } -+ } -+ } -+ -+ free_irq(pdev->irq, acb); -+ iounmap(acb->pmu); -+ arcmsr_free_ccb_pool(acb); -+ pci_release_regions(pdev); -+ -+ scsi_host_put(host); -+ -+ pci_disable_device(pdev); -+ pci_set_drvdata(pdev, NULL); -+} -+ -+static void arcmsr_shutdown(struct pci_dev *pdev) -+{ -+ struct Scsi_Host *host = pci_get_drvdata(pdev); -+ struct AdapterControlBlock *acb = -+ (struct AdapterControlBlock *)host->hostdata; -+ -+ arcmsr_stop_adapter_bgrb(acb); -+ arcmsr_flush_adapter_cache(acb); -+} -+ -+static int arcmsr_module_init(void) -+{ -+ int error = 0; -+ -+ error = pci_register_driver(&arcmsr_pci_driver); -+ return error; -+} -+ -+static void arcmsr_module_exit(void) -+{ -+ pci_unregister_driver(&arcmsr_pci_driver); -+} -+module_init(arcmsr_module_init); -+module_exit(arcmsr_module_exit); -+ -+static u32 arcmsr_disable_outbound_ints(struct AdapterControlBlock *acb) -+{ -+ struct MessageUnit __iomem *reg = acb->pmu; -+ u32 orig_mask = readl(®->outbound_intmask); -+ -+ writel(orig_mask | ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE, -+ ®->outbound_intmask); -+ return orig_mask; -+} -+ -+static void arcmsr_enable_outbound_ints(struct AdapterControlBlock *acb, -+ u32 orig_mask) -+{ -+ struct MessageUnit __iomem *reg = acb->pmu; -+ u32 mask; -+ -+ mask = orig_mask & ~(ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE | -+ ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE); -+ writel(mask, ®->outbound_intmask); -+} -+ -+static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb) -+{ -+ struct MessageUnit __iomem *reg=acb->pmu; -+ -+ writel(ARCMSR_INBOUND_MESG0_FLUSH_CACHE, ®->inbound_msgaddr0); -+ if (arcmsr_wait_msgint_ready(acb)) -+ printk(KERN_NOTICE -+ "arcmsr%d: wait 'flush adapter cache' timeout \n" -+ , acb->host->host_no); -+} -+ -+static void arcmsr_report_sense_info(struct CommandControlBlock *ccb) -+{ -+ struct scsi_cmnd *pcmd = ccb->pcmd; -+ struct SENSE_DATA *sensebuffer = (struct SENSE_DATA *)pcmd->sense_buffer; -+ -+ pcmd->result = DID_OK << 16; -+ if (sensebuffer) { -+ int sense_data_length = -+ sizeof (struct SENSE_DATA) < sizeof (pcmd->sense_buffer) -+ ? sizeof (struct SENSE_DATA) : sizeof (pcmd->sense_buffer); -+ memset(sensebuffer, 0, sizeof (pcmd->sense_buffer)); -+ memcpy(sensebuffer, ccb->arcmsr_cdb.SenseData, sense_data_length); -+ sensebuffer->ErrorCode = SCSI_SENSE_CURRENT_ERRORS; -+ sensebuffer->Valid = 1; -+ } -+} -+ -+static uint8_t arcmsr_wait_msgint_ready(struct AdapterControlBlock *acb) -+{ -+ struct MessageUnit __iomem *reg = acb->pmu; -+ uint32_t Index; -+ uint8_t Retries = 0x00; -+ -+ do { -+ for (Index = 0; Index < 100; Index++) { -+ if (readl(®->outbound_intstatus) -+ & ARCMSR_MU_OUTBOUND_MESSAGE0_INT) { -+ writel(ARCMSR_MU_OUTBOUND_MESSAGE0_INT -+ , ®->outbound_intstatus); -+ return 0x00; -+ } -+ msleep_interruptible(10); -+ }/*max 1 seconds*/ -+ } while (Retries++ < 20);/*max 20 sec*/ -+ return 0xff; -+} -+ -+static void arcmsr_build_ccb(struct AdapterControlBlock *acb, -+ struct CommandControlBlock *ccb, struct scsi_cmnd *pcmd) -+{ -+ struct ARCMSR_CDB *arcmsr_cdb = (struct ARCMSR_CDB *)&ccb->arcmsr_cdb; -+ int8_t *psge = (int8_t *)&arcmsr_cdb->u; -+ uint32_t address_lo, address_hi; -+ int arccdbsize = 0x30; -+ -+ ccb->pcmd = pcmd; -+ memset(arcmsr_cdb, 0, sizeof (struct ARCMSR_CDB)); -+ arcmsr_cdb->Bus = 0; -+ arcmsr_cdb->TargetID = pcmd->device->id; -+ arcmsr_cdb->LUN = pcmd->device->lun; -+ arcmsr_cdb->Function = 1; -+ arcmsr_cdb->CdbLength = (uint8_t)pcmd->cmd_len; -+ arcmsr_cdb->Context = (unsigned long)arcmsr_cdb; -+ memcpy(arcmsr_cdb->Cdb, pcmd->cmnd, pcmd->cmd_len); -+ if (pcmd->use_sg) { -+ int length, sgcount, i, cdb_sgcount = 0; -+ struct scatterlist *sl; -+ -+ /* Get Scatter Gather List from scsiport. */ -+ sl = (struct scatterlist *) pcmd->request_buffer; -+ sgcount = pci_map_sg(acb->pdev, sl, pcmd->use_sg, -+ pcmd->sc_data_direction); -+ /* map stor port SG list to our iop SG List. */ -+ for (i = 0; i < sgcount; i++) { -+ /* Get the physical address of the current data pointer */ -+ length = cpu_to_le32(sg_dma_len(sl)); -+ address_lo = cpu_to_le32(dma_addr_lo32(sg_dma_address(sl))); -+ address_hi = cpu_to_le32(dma_addr_hi32(sg_dma_address(sl))); -+ if (address_hi == 0) { -+ struct SG32ENTRY *pdma_sg = (struct SG32ENTRY *)psge; -+ -+ pdma_sg->address = address_lo; -+ pdma_sg->length = length; -+ psge += sizeof (struct SG32ENTRY); -+ arccdbsize += sizeof (struct SG32ENTRY); -+ } else { -+ struct SG64ENTRY *pdma_sg = (struct SG64ENTRY *)psge; -+ -+ pdma_sg->addresshigh = address_hi; -+ pdma_sg->address = address_lo; -+ pdma_sg->length = length|IS_SG64_ADDR; -+ psge += sizeof (struct SG64ENTRY); -+ arccdbsize += sizeof (struct SG64ENTRY); -+ } -+ sl++; -+ cdb_sgcount++; -+ } -+ arcmsr_cdb->sgcount = (uint8_t)cdb_sgcount; -+ arcmsr_cdb->DataLength = pcmd->request_bufflen; -+ if ( arccdbsize > 256) -+ arcmsr_cdb->Flags |= ARCMSR_CDB_FLAG_SGL_BSIZE; -+ } else if (pcmd->request_bufflen) { -+ dma_addr_t dma_addr; -+ dma_addr = pci_map_single(acb->pdev, pcmd->request_buffer, -+ pcmd->request_bufflen, pcmd->sc_data_direction); -+ pcmd->SCp.dma_handle = dma_addr; -+ address_lo = cpu_to_le32(dma_addr_lo32(dma_addr)); -+ address_hi = cpu_to_le32(dma_addr_hi32(dma_addr)); -+ if (address_hi == 0) { -+ struct SG32ENTRY *pdma_sg = (struct SG32ENTRY *)psge; -+ pdma_sg->address = address_lo; -+ pdma_sg->length = pcmd->request_bufflen; -+ } else { -+ struct SG64ENTRY *pdma_sg = (struct SG64ENTRY *)psge; -+ pdma_sg->addresshigh = address_hi; -+ pdma_sg->address = address_lo; -+ pdma_sg->length = pcmd->request_bufflen|IS_SG64_ADDR; -+ } -+ arcmsr_cdb->sgcount = 1; -+ arcmsr_cdb->DataLength = pcmd->request_bufflen; -+ } -+ if (pcmd->sc_data_direction == DMA_TO_DEVICE ) { -+ arcmsr_cdb->Flags |= ARCMSR_CDB_FLAG_WRITE; -+ ccb->ccb_flags |= CCB_FLAG_WRITE; -+ } -+} -+ -+static void arcmsr_post_ccb(struct AdapterControlBlock *acb, struct CommandControlBlock *ccb) -+{ -+ struct MessageUnit __iomem *reg = acb->pmu; -+ uint32_t cdb_shifted_phyaddr = ccb->cdb_shifted_phyaddr; -+ struct ARCMSR_CDB *arcmsr_cdb = (struct ARCMSR_CDB *)&ccb->arcmsr_cdb; -+ -+ atomic_inc(&acb->ccboutstandingcount); -+ ccb->startdone = ARCMSR_CCB_START; -+ if (arcmsr_cdb->Flags & ARCMSR_CDB_FLAG_SGL_BSIZE) -+ writel(cdb_shifted_phyaddr | ARCMSR_CCBPOST_FLAG_SGL_BSIZE, -+ ®->inbound_queueport); -+ else -+ writel(cdb_shifted_phyaddr, ®->inbound_queueport); -+} -+ -+void arcmsr_post_Qbuffer(struct AdapterControlBlock *acb) -+{ -+ struct MessageUnit __iomem *reg = acb->pmu; -+ struct QBUFFER __iomem *pwbuffer = (struct QBUFFER __iomem *) ®->message_wbuffer; -+ uint8_t __iomem *iop_data = (uint8_t __iomem *) pwbuffer->data; -+ int32_t allxfer_len = 0; -+ -+ if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_READED) { -+ acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READED); -+ while ((acb->wqbuf_firstindex != acb->wqbuf_lastindex) -+ && (allxfer_len < 124)) { -+ writeb(acb->wqbuffer[acb->wqbuf_firstindex], iop_data); -+ acb->wqbuf_firstindex++; -+ acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER; -+ iop_data++; -+ allxfer_len++; -+ } -+ writel(allxfer_len, &pwbuffer->data_len); -+ writel(ARCMSR_INBOUND_DRIVER_DATA_WRITE_OK -+ , ®->inbound_doorbell); -+ } -+} -+ -+static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb) -+{ -+ struct MessageUnit __iomem *reg = acb->pmu; -+ -+ acb->acb_flags &= ~ACB_F_MSG_START_BGRB; -+ writel(ARCMSR_INBOUND_MESG0_STOP_BGRB, ®->inbound_msgaddr0); -+ if (arcmsr_wait_msgint_ready(acb)) -+ printk(KERN_NOTICE -+ "arcmsr%d: wait 'stop adapter background rebulid' timeout \n" -+ , acb->host->host_no); -+} -+ -+static void arcmsr_free_ccb_pool(struct AdapterControlBlock *acb) -+{ -+ dma_free_coherent(&acb->pdev->dev, -+ ARCMSR_MAX_FREECCB_NUM * sizeof (struct CommandControlBlock) + 0x20, -+ acb->dma_coherent, -+ acb->dma_coherent_handle); -+} -+ -+static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb) -+{ -+ struct MessageUnit __iomem *reg = acb->pmu; -+ struct CommandControlBlock *ccb; -+ uint32_t flag_ccb, outbound_intstatus, outbound_doorbell; -+ -+ outbound_intstatus = readl(®->outbound_intstatus) -+ & acb->outbound_int_enable; -+ writel(outbound_intstatus, ®->outbound_intstatus); -+ if (outbound_intstatus & ARCMSR_MU_OUTBOUND_DOORBELL_INT) { -+ outbound_doorbell = readl(®->outbound_doorbell); -+ writel(outbound_doorbell, ®->outbound_doorbell); -+ if (outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_WRITE_OK) { -+ struct QBUFFER __iomem * prbuffer = -+ (struct QBUFFER __iomem *) ®->message_rbuffer; -+ uint8_t __iomem * iop_data = (uint8_t __iomem *)prbuffer->data; -+ int32_t my_empty_len, iop_len, rqbuf_firstindex, rqbuf_lastindex; -+ -+ rqbuf_lastindex = acb->rqbuf_lastindex; -+ rqbuf_firstindex = acb->rqbuf_firstindex; -+ iop_len = readl(&prbuffer->data_len); -+ my_empty_len = (rqbuf_firstindex - rqbuf_lastindex - 1) -+ &(ARCMSR_MAX_QBUFFER - 1); -+ if (my_empty_len >= iop_len) { -+ while (iop_len > 0) { -+ acb->rqbuffer[acb->rqbuf_lastindex] = readb(iop_data); -+ acb->rqbuf_lastindex++; -+ acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER; -+ iop_data++; -+ iop_len--; -+ } -+ writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, -+ ®->inbound_doorbell); -+ } else -+ acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW; -+ } -+ if (outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_READ_OK) { -+ acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_READED; -+ if (acb->wqbuf_firstindex != acb->wqbuf_lastindex) { -+ struct QBUFFER __iomem * pwbuffer = -+ (struct QBUFFER __iomem *) ®->message_wbuffer; -+ uint8_t __iomem * iop_data = (uint8_t __iomem *) pwbuffer->data; -+ int32_t allxfer_len = 0; -+ -+ acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READED); -+ while ((acb->wqbuf_firstindex != acb->wqbuf_lastindex) -+ && (allxfer_len < 124)) { -+ writeb(acb->wqbuffer[acb->wqbuf_firstindex], iop_data); -+ acb->wqbuf_firstindex++; -+ acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER; -+ iop_data++; -+ allxfer_len++; -+ } -+ writel(allxfer_len, &pwbuffer->data_len); -+ writel(ARCMSR_INBOUND_DRIVER_DATA_WRITE_OK, -+ ®->inbound_doorbell); -+ } -+ if (acb->wqbuf_firstindex == acb->wqbuf_lastindex) -+ acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_CLEARED; -+ } -+ } -+ if (outbound_intstatus & ARCMSR_MU_OUTBOUND_POSTQUEUE_INT) { -+ int id, lun; -+ /* -+ **************************************************************** -+ ** areca cdb command done -+ **************************************************************** -+ */ -+ while (1) { -+ if ((flag_ccb = readl(®->outbound_queueport)) == 0xFFFFFFFF) -+ break;/*chip FIFO no ccb for completion already*/ -+ /* check if command done with no error*/ -+ ccb = (struct CommandControlBlock *)(acb->vir2phy_offset + -+ (flag_ccb << 5)); -+ if ((ccb->acb != acb) || (ccb->startdone != ARCMSR_CCB_START)) { -+ if (ccb->startdone == ARCMSR_CCB_ABORTED) { -+ struct scsi_cmnd *abortcmd=ccb->pcmd; -+ if (abortcmd) { -+ abortcmd->result |= DID_ABORT >> 16; -+ arcmsr_ccb_complete(ccb, 1); -+ printk(KERN_NOTICE -+ "arcmsr%d: ccb='0x%p' isr got aborted command \n" -+ , acb->host->host_no, ccb); -+ } -+ continue; -+ } -+ printk(KERN_NOTICE -+ "arcmsr%d: isr get an illegal ccb command done acb='0x%p'" -+ "ccb='0x%p' ccbacb='0x%p' startdone = 0x%x" -+ " ccboutstandingcount=%d \n" -+ , acb->host->host_no -+ , acb -+ , ccb -+ , ccb->acb -+ , ccb->startdone -+ , atomic_read(&acb->ccboutstandingcount)); -+ continue; -+ } -+ id = ccb->pcmd->device->id; -+ lun = ccb->pcmd->device->lun; -+ if (!(flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR)) { -+ if (acb->devstate[id][lun] == ARECA_RAID_GONE) -+ acb->devstate[id][lun] = ARECA_RAID_GOOD; -+ ccb->pcmd->result = DID_OK << 16; -+ arcmsr_ccb_complete(ccb, 1); -+ } else { -+ switch(ccb->arcmsr_cdb.DeviceStatus) { -+ case ARCMSR_DEV_SELECT_TIMEOUT: { -+ acb->devstate[id][lun] = ARECA_RAID_GONE; -+ ccb->pcmd->result = DID_TIME_OUT << 16; -+ arcmsr_ccb_complete(ccb, 1); -+ } -+ break; -+ case ARCMSR_DEV_ABORTED: -+ case ARCMSR_DEV_INIT_FAIL: { -+ acb->devstate[id][lun] = ARECA_RAID_GONE; -+ ccb->pcmd->result = DID_BAD_TARGET << 16; -+ arcmsr_ccb_complete(ccb, 1); -+ } -+ break; -+ case ARCMSR_DEV_CHECK_CONDITION: { -+ acb->devstate[id][lun] = ARECA_RAID_GOOD; -+ arcmsr_report_sense_info(ccb); -+ arcmsr_ccb_complete(ccb, 1); -+ } -+ break; -+ default: -+ printk(KERN_NOTICE -+ "arcmsr%d: scsi id=%d lun=%d" -+ " isr get command error done," -+ "but got unknown DeviceStatus = 0x%x \n" -+ , acb->host->host_no -+ , id -+ , lun -+ , ccb->arcmsr_cdb.DeviceStatus); -+ acb->devstate[id][lun] = ARECA_RAID_GONE; -+ ccb->pcmd->result = DID_NO_CONNECT << 16; -+ arcmsr_ccb_complete(ccb, 1); -+ break; -+ } -+ } -+ }/*drain reply FIFO*/ -+ } -+ if (!(outbound_intstatus & ARCMSR_MU_OUTBOUND_HANDLE_INT)) -+ return IRQ_NONE; -+ return IRQ_HANDLED; -+} -+ -+static void arcmsr_iop_parking(struct AdapterControlBlock *acb) -+{ -+ if (acb) { -+ /* stop adapter background rebuild */ -+ if (acb->acb_flags & ACB_F_MSG_START_BGRB) { -+ acb->acb_flags &= ~ACB_F_MSG_START_BGRB; -+ arcmsr_stop_adapter_bgrb(acb); -+ arcmsr_flush_adapter_cache(acb); -+ } -+ } -+} -+ -+static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, struct scsi_cmnd *cmd) -+{ -+ struct MessageUnit __iomem *reg = acb->pmu; -+ struct CMD_MESSAGE_FIELD *pcmdmessagefld; -+ int retvalue = 0, transfer_len = 0; -+ char *buffer; -+ uint32_t controlcode = (uint32_t ) cmd->cmnd[5] << 24 | -+ (uint32_t ) cmd->cmnd[6] << 16 | -+ (uint32_t ) cmd->cmnd[7] << 8 | -+ (uint32_t ) cmd->cmnd[8]; -+ /* 4 bytes: Areca io control code */ -+ if (cmd->use_sg) { -+ struct scatterlist *sg = (struct scatterlist *)cmd->request_buffer; -+ -+ buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset; -+ if (cmd->use_sg > 1) { -+ retvalue = ARCMSR_MESSAGE_FAIL; -+ goto message_out; -+ } -+ transfer_len += sg->length; -+ } else { -+ buffer = cmd->request_buffer; -+ transfer_len = cmd->request_bufflen; -+ } -+ if (transfer_len > sizeof(struct CMD_MESSAGE_FIELD)) { -+ retvalue = ARCMSR_MESSAGE_FAIL; -+ goto message_out; -+ } -+ pcmdmessagefld = (struct CMD_MESSAGE_FIELD *) buffer; -+ switch(controlcode) { -+ case ARCMSR_MESSAGE_READ_RQBUFFER: { -+ unsigned long *ver_addr; -+ dma_addr_t buf_handle; -+ uint8_t *pQbuffer, *ptmpQbuffer; -+ int32_t allxfer_len = 0; -+ -+ ver_addr = pci_alloc_consistent(acb->pdev, 1032, &buf_handle); -+ if (!ver_addr) { -+ retvalue = ARCMSR_MESSAGE_FAIL; -+ goto message_out; -+ } -+ ptmpQbuffer = (uint8_t *) ver_addr; -+ while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex) -+ && (allxfer_len < 1031)) { -+ pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex]; -+ memcpy(ptmpQbuffer, pQbuffer, 1); -+ acb->rqbuf_firstindex++; -+ acb->rqbuf_firstindex %= ARCMSR_MAX_QBUFFER; -+ ptmpQbuffer++; -+ allxfer_len++; -+ } -+ if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { -+ struct QBUFFER __iomem * prbuffer = (struct QBUFFER __iomem *) -+ ®->message_rbuffer; -+ uint8_t __iomem * iop_data = (uint8_t __iomem *)prbuffer->data; -+ int32_t iop_len; -+ -+ acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; -+ iop_len = readl(&prbuffer->data_len); -+ while (iop_len > 0) { -+ acb->rqbuffer[acb->rqbuf_lastindex] = readb(iop_data); -+ acb->rqbuf_lastindex++; -+ acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER; -+ iop_data++; -+ iop_len--; -+ } -+ writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, -+ ®->inbound_doorbell); -+ } -+ memcpy(pcmdmessagefld->messagedatabuffer, -+ (uint8_t *)ver_addr, allxfer_len); -+ pcmdmessagefld->cmdmessage.Length = allxfer_len; -+ pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; -+ pci_free_consistent(acb->pdev, 1032, ver_addr, buf_handle); -+ } -+ break; -+ case ARCMSR_MESSAGE_WRITE_WQBUFFER: { -+ unsigned long *ver_addr; -+ dma_addr_t buf_handle; -+ int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex; -+ uint8_t *pQbuffer, *ptmpuserbuffer; -+ -+ ver_addr = pci_alloc_consistent(acb->pdev, 1032, &buf_handle); -+ if (!ver_addr) { -+ retvalue = ARCMSR_MESSAGE_FAIL; -+ goto message_out; -+ } -+ ptmpuserbuffer = (uint8_t *)ver_addr; -+ user_len = pcmdmessagefld->cmdmessage.Length; -+ memcpy(ptmpuserbuffer, pcmdmessagefld->messagedatabuffer, user_len); -+ wqbuf_lastindex = acb->wqbuf_lastindex; -+ wqbuf_firstindex = acb->wqbuf_firstindex; -+ if (wqbuf_lastindex != wqbuf_firstindex) { -+ struct SENSE_DATA *sensebuffer = -+ (struct SENSE_DATA *)cmd->sense_buffer; -+ arcmsr_post_Qbuffer(acb); -+ /* has error report sensedata */ -+ sensebuffer->ErrorCode = 0x70; -+ sensebuffer->SenseKey = ILLEGAL_REQUEST; -+ sensebuffer->AdditionalSenseLength = 0x0A; -+ sensebuffer->AdditionalSenseCode = 0x20; -+ sensebuffer->Valid = 1; -+ retvalue = ARCMSR_MESSAGE_FAIL; -+ } else { -+ my_empty_len = (wqbuf_firstindex-wqbuf_lastindex - 1) -+ &(ARCMSR_MAX_QBUFFER - 1); -+ if (my_empty_len >= user_len) { -+ while (user_len > 0) { -+ pQbuffer = -+ &acb->wqbuffer[acb->wqbuf_lastindex]; -+ memcpy(pQbuffer, ptmpuserbuffer, 1); -+ acb->wqbuf_lastindex++; -+ acb->wqbuf_lastindex %= ARCMSR_MAX_QBUFFER; -+ ptmpuserbuffer++; -+ user_len--; -+ } -+ if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_CLEARED) { -+ acb->acb_flags &= -+ ~ACB_F_MESSAGE_WQBUFFER_CLEARED; -+ arcmsr_post_Qbuffer(acb); -+ } -+ } else { -+ /* has error report sensedata */ -+ struct SENSE_DATA *sensebuffer = -+ (struct SENSE_DATA *)cmd->sense_buffer; -+ sensebuffer->ErrorCode = 0x70; -+ sensebuffer->SenseKey = ILLEGAL_REQUEST; -+ sensebuffer->AdditionalSenseLength = 0x0A; -+ sensebuffer->AdditionalSenseCode = 0x20; -+ sensebuffer->Valid = 1; -+ retvalue = ARCMSR_MESSAGE_FAIL; -+ } -+ } -+ pci_free_consistent(acb->pdev, 1032, ver_addr, buf_handle); -+ } -+ break; -+ case ARCMSR_MESSAGE_CLEAR_RQBUFFER: { -+ uint8_t *pQbuffer = acb->rqbuffer; -+ -+ if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { -+ acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; -+ writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, -+ ®->inbound_doorbell); -+ } -+ acb->acb_flags |= ACB_F_MESSAGE_RQBUFFER_CLEARED; -+ acb->rqbuf_firstindex = 0; -+ acb->rqbuf_lastindex = 0; -+ memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); -+ pcmdmessagefld->cmdmessage.ReturnCode = -+ ARCMSR_MESSAGE_RETURNCODE_OK; -+ } -+ break; -+ case ARCMSR_MESSAGE_CLEAR_WQBUFFER: { -+ uint8_t *pQbuffer = acb->wqbuffer; -+ -+ if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { -+ acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; -+ writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK -+ , ®->inbound_doorbell); -+ } -+ acb->acb_flags |= -+ (ACB_F_MESSAGE_WQBUFFER_CLEARED | -+ ACB_F_MESSAGE_WQBUFFER_READED); -+ acb->wqbuf_firstindex = 0; -+ acb->wqbuf_lastindex = 0; -+ memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); -+ pcmdmessagefld->cmdmessage.ReturnCode = -+ ARCMSR_MESSAGE_RETURNCODE_OK; -+ } -+ break; -+ case ARCMSR_MESSAGE_CLEAR_ALLQBUFFER: { -+ uint8_t *pQbuffer; -+ -+ if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { -+ acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; -+ writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK -+ , ®->inbound_doorbell); -+ } -+ acb->acb_flags |= -+ (ACB_F_MESSAGE_WQBUFFER_CLEARED -+ | ACB_F_MESSAGE_RQBUFFER_CLEARED -+ | ACB_F_MESSAGE_WQBUFFER_READED); -+ acb->rqbuf_firstindex = 0; -+ acb->rqbuf_lastindex = 0; -+ acb->wqbuf_firstindex = 0; -+ acb->wqbuf_lastindex = 0; -+ pQbuffer = acb->rqbuffer; -+ memset(pQbuffer, 0, sizeof (struct QBUFFER)); -+ pQbuffer = acb->wqbuffer; -+ memset(pQbuffer, 0, sizeof (struct QBUFFER)); -+ pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; -+ } -+ break; -+ case ARCMSR_MESSAGE_RETURN_CODE_3F: { -+ pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_3F; -+ } -+ break; -+ case ARCMSR_MESSAGE_SAY_HELLO: { -+ int8_t * hello_string = "Hello! I am ARCMSR"; -+ -+ memcpy(pcmdmessagefld->messagedatabuffer, hello_string -+ , (int16_t)strlen(hello_string)); -+ pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; -+ } -+ break; -+ case ARCMSR_MESSAGE_SAY_GOODBYE: -+ arcmsr_iop_parking(acb); -+ break; -+ case ARCMSR_MESSAGE_FLUSH_ADAPTER_CACHE: -+ arcmsr_flush_adapter_cache(acb); -+ break; -+ default: -+ retvalue = ARCMSR_MESSAGE_FAIL; -+ } -+ message_out: -+ if (cmd->use_sg) { -+ struct scatterlist *sg; -+ -+ sg = (struct scatterlist *) cmd->request_buffer; -+ kunmap_atomic(buffer - sg->offset, KM_IRQ0); -+ } -+ return retvalue; -+} -+ -+static struct CommandControlBlock *arcmsr_get_freeccb(struct AdapterControlBlock *acb) -+{ -+ struct list_head *head = &acb->ccb_free_list; -+ struct CommandControlBlock *ccb = NULL; -+ -+ if (!list_empty(head)) { -+ ccb = list_entry(head->next, struct CommandControlBlock, list); -+ list_del(head->next); -+ } -+ return ccb; -+} -+ -+static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb, -+ struct scsi_cmnd *cmd) -+{ -+ switch (cmd->cmnd[0]) { -+ case INQUIRY: { -+ unsigned char inqdata[36]; -+ char *buffer; -+ -+ if (cmd->device->lun) { -+ cmd->result = (DID_TIME_OUT << 16); -+ cmd->scsi_done(cmd); -+ return; -+ } -+ inqdata[0] = TYPE_PROCESSOR; -+ /* Periph Qualifier & Periph Dev Type */ -+ inqdata[1] = 0; -+ /* rem media bit & Dev Type Modifier */ -+ inqdata[2] = 0; -+ /* ISO,ECMA,& ANSI versions */ -+ inqdata[4] = 31; -+ /* length of additional data */ -+ strncpy(&inqdata[8], "Areca ", 8); -+ /* Vendor Identification */ -+ strncpy(&inqdata[16], "RAID controller ", 16); -+ /* Product Identification */ -+ strncpy(&inqdata[32], "R001", 4); /* Product Revision */ -+ if (cmd->use_sg) { -+ struct scatterlist *sg; -+ -+ sg = (struct scatterlist *) cmd->request_buffer; -+ buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset; -+ } else { -+ buffer = cmd->request_buffer; -+ } -+ memcpy(buffer, inqdata, sizeof(inqdata)); -+ if (cmd->use_sg) { -+ struct scatterlist *sg; -+ -+ sg = (struct scatterlist *) cmd->request_buffer; -+ kunmap_atomic(buffer - sg->offset, KM_IRQ0); -+ } -+ cmd->scsi_done(cmd); -+ } -+ break; -+ case WRITE_BUFFER: -+ case READ_BUFFER: { -+ if (arcmsr_iop_message_xfer(acb, cmd)) -+ cmd->result = (DID_ERROR << 16); -+ cmd->scsi_done(cmd); -+ } -+ break; -+ default: -+ cmd->scsi_done(cmd); -+ } -+} -+ -+static int arcmsr_queue_command(struct scsi_cmnd *cmd, -+ void (* done)(struct scsi_cmnd *)) -+{ -+ struct Scsi_Host *host = cmd->device->host; -+ struct AdapterControlBlock *acb = -+ (struct AdapterControlBlock *) host->hostdata; -+ struct CommandControlBlock *ccb; -+ int target = cmd->device->id; -+ int lun = cmd->device->lun; -+ -+ cmd->scsi_done = done; -+ cmd->host_scribble = NULL; -+ cmd->result = 0; -+ if (acb->acb_flags & ACB_F_BUS_RESET) { -+ printk(KERN_NOTICE "arcmsr%d: bus reset" -+ " and return busy \n" -+ , acb->host->host_no); -+ return SCSI_MLQUEUE_HOST_BUSY; -+ } -+ if(target == 16) { -+ /* virtual device for iop message transfer */ -+ arcmsr_handle_virtual_command(acb, cmd); -+ return 0; -+ } -+ if (acb->devstate[target][lun] == ARECA_RAID_GONE) { -+ uint8_t block_cmd; -+ -+ block_cmd = cmd->cmnd[0] & 0x0f; -+ if (block_cmd == 0x08 || block_cmd == 0x0a) { -+ printk(KERN_NOTICE -+ "arcmsr%d: block 'read/write'" -+ "command with gone raid volume" -+ " Cmd=%2x, TargetId=%d, Lun=%d \n" -+ , acb->host->host_no -+ , cmd->cmnd[0] -+ , target, lun); -+ cmd->result = (DID_NO_CONNECT << 16); -+ cmd->scsi_done(cmd); -+ return 0; -+ } -+ } -+ if (atomic_read(&acb->ccboutstandingcount) >= -+ ARCMSR_MAX_OUTSTANDING_CMD) -+ return SCSI_MLQUEUE_HOST_BUSY; -+ -+ ccb = arcmsr_get_freeccb(acb); -+ if (!ccb) -+ return SCSI_MLQUEUE_HOST_BUSY; -+ arcmsr_build_ccb(acb, ccb, cmd); -+ arcmsr_post_ccb(acb, ccb); -+ return 0; -+} -+ -+static void arcmsr_get_firmware_spec(struct AdapterControlBlock *acb) -+{ -+ struct MessageUnit __iomem *reg = acb->pmu; -+ char *acb_firm_model = acb->firm_model; -+ char *acb_firm_version = acb->firm_version; -+ char __iomem *iop_firm_model = (char __iomem *) ®->message_rwbuffer[15]; -+ char __iomem *iop_firm_version = (char __iomem *) ®->message_rwbuffer[17]; -+ int count; -+ -+ writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, ®->inbound_msgaddr0); -+ if (arcmsr_wait_msgint_ready(acb)) -+ printk(KERN_NOTICE -+ "arcmsr%d: wait " -+ "'get adapter firmware miscellaneous data' timeout \n" -+ , acb->host->host_no); -+ count = 8; -+ while (count) { -+ *acb_firm_model = readb(iop_firm_model); -+ acb_firm_model++; -+ iop_firm_model++; -+ count--; -+ } -+ count = 16; -+ while (count) { -+ *acb_firm_version = readb(iop_firm_version); -+ acb_firm_version++; -+ iop_firm_version++; -+ count--; -+ } -+ printk(KERN_INFO -+ "ARECA RAID ADAPTER%d: FIRMWARE VERSION %s \n" -+ , acb->host->host_no -+ , acb->firm_version); -+ acb->firm_request_len = readl(®->message_rwbuffer[1]); -+ acb->firm_numbers_queue = readl(®->message_rwbuffer[2]); -+ acb->firm_sdram_size = readl(®->message_rwbuffer[3]); -+ acb->firm_hd_channels = readl(®->message_rwbuffer[4]); -+} -+ -+static void arcmsr_polling_ccbdone(struct AdapterControlBlock *acb, -+ struct CommandControlBlock *poll_ccb) -+{ -+ struct MessageUnit __iomem *reg = acb->pmu; -+ struct CommandControlBlock *ccb; -+ uint32_t flag_ccb, outbound_intstatus, poll_ccb_done = 0, poll_count = 0; -+ int id, lun; -+ -+ polling_ccb_retry: -+ poll_count++; -+ outbound_intstatus = readl(®->outbound_intstatus) -+ & acb->outbound_int_enable; -+ writel(outbound_intstatus, ®->outbound_intstatus);/*clear interrupt*/ -+ while (1) { -+ if ((flag_ccb = readl(®->outbound_queueport)) == 0xFFFFFFFF) { -+ if (poll_ccb_done) -+ break; -+ else { -+ msleep(25); -+ if (poll_count > 100) -+ break; -+ goto polling_ccb_retry; -+ } -+ } -+ ccb = (struct CommandControlBlock *) -+ (acb->vir2phy_offset + (flag_ccb << 5)); -+ if ((ccb->acb != acb) || -+ (ccb->startdone != ARCMSR_CCB_START)) { -+ if ((ccb->startdone == ARCMSR_CCB_ABORTED) || -+ (ccb == poll_ccb)) { -+ printk(KERN_NOTICE -+ "arcmsr%d: scsi id=%d lun=%d ccb='0x%p'" -+ " poll command abort successfully \n" -+ , acb->host->host_no -+ , ccb->pcmd->device->id -+ , ccb->pcmd->device->lun -+ , ccb); -+ ccb->pcmd->result = DID_ABORT << 16; -+ arcmsr_ccb_complete(ccb, 1); -+ poll_ccb_done = 1; -+ continue; -+ } -+ printk(KERN_NOTICE -+ "arcmsr%d: polling get an illegal ccb" -+ " command done ccb='0x%p'" -+ "ccboutstandingcount=%d \n" -+ , acb->host->host_no -+ , ccb -+ , atomic_read(&acb->ccboutstandingcount)); -+ continue; -+ } -+ id = ccb->pcmd->device->id; -+ lun = ccb->pcmd->device->lun; -+ if (!(flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR)) { -+ if (acb->devstate[id][lun] == ARECA_RAID_GONE) -+ acb->devstate[id][lun] = ARECA_RAID_GOOD; -+ ccb->pcmd->result = DID_OK << 16; -+ arcmsr_ccb_complete(ccb, 1); -+ } else { -+ switch(ccb->arcmsr_cdb.DeviceStatus) { -+ case ARCMSR_DEV_SELECT_TIMEOUT: { -+ acb->devstate[id][lun] = ARECA_RAID_GONE; -+ ccb->pcmd->result = DID_TIME_OUT << 16; -+ arcmsr_ccb_complete(ccb, 1); -+ } -+ break; -+ case ARCMSR_DEV_ABORTED: -+ case ARCMSR_DEV_INIT_FAIL: { -+ acb->devstate[id][lun] = ARECA_RAID_GONE; -+ ccb->pcmd->result = DID_BAD_TARGET << 16; -+ arcmsr_ccb_complete(ccb, 1); -+ } -+ break; -+ case ARCMSR_DEV_CHECK_CONDITION: { -+ acb->devstate[id][lun] = ARECA_RAID_GOOD; -+ arcmsr_report_sense_info(ccb); -+ arcmsr_ccb_complete(ccb, 1); -+ } -+ break; -+ default: -+ printk(KERN_NOTICE -+ "arcmsr%d: scsi id=%d lun=%d" -+ " polling and getting command error done" -+ "but got unknown DeviceStatus = 0x%x \n" -+ , acb->host->host_no -+ , id -+ , lun -+ , ccb->arcmsr_cdb.DeviceStatus); -+ acb->devstate[id][lun] = ARECA_RAID_GONE; -+ ccb->pcmd->result = DID_BAD_TARGET << 16; -+ arcmsr_ccb_complete(ccb, 1); -+ break; -+ } -+ } -+ } -+} -+ -+static void arcmsr_iop_init(struct AdapterControlBlock *acb) -+{ -+ struct MessageUnit __iomem *reg = acb->pmu; -+ uint32_t intmask_org, mask, outbound_doorbell, firmware_state = 0; -+ -+ do { -+ firmware_state = readl(®->outbound_msgaddr1); -+ } while (!(firmware_state & ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK)); -+ intmask_org = readl(®->outbound_intmask) -+ | ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE; -+ arcmsr_get_firmware_spec(acb); -+ -+ acb->acb_flags |= ACB_F_MSG_START_BGRB; -+ writel(ARCMSR_INBOUND_MESG0_START_BGRB, ®->inbound_msgaddr0); -+ if (arcmsr_wait_msgint_ready(acb)) { -+ printk(KERN_NOTICE "arcmsr%d: " -+ "wait 'start adapter background rebulid' timeout\n", -+ acb->host->host_no); -+ } -+ -+ outbound_doorbell = readl(®->outbound_doorbell); -+ writel(outbound_doorbell, ®->outbound_doorbell); -+ writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, ®->inbound_doorbell); -+ mask = ~(ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE -+ | ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE); -+ writel(intmask_org & mask, ®->outbound_intmask); -+ acb->outbound_int_enable = ~(intmask_org & mask) & 0x000000ff; -+ acb->acb_flags |= ACB_F_IOP_INITED; -+} -+ -+static void arcmsr_iop_reset(struct AdapterControlBlock *acb) -+{ -+ struct MessageUnit __iomem *reg = acb->pmu; -+ struct CommandControlBlock *ccb; -+ uint32_t intmask_org; -+ int i = 0; -+ -+ if (atomic_read(&acb->ccboutstandingcount) != 0) { -+ /* talk to iop 331 outstanding command aborted */ -+ arcmsr_abort_allcmd(acb); -+ /* wait for 3 sec for all command aborted*/ -+ msleep_interruptible(3000); -+ /* disable all outbound interrupt */ -+ intmask_org = arcmsr_disable_outbound_ints(acb); -+ /* clear all outbound posted Q */ -+ for (i = 0; i < ARCMSR_MAX_OUTSTANDING_CMD; i++) -+ readl(®->outbound_queueport); -+ for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { -+ ccb = acb->pccb_pool[i]; -+ if ((ccb->startdone == ARCMSR_CCB_START) || -+ (ccb->startdone == ARCMSR_CCB_ABORTED)) { -+ ccb->startdone = ARCMSR_CCB_ABORTED; -+ ccb->pcmd->result = DID_ABORT << 16; -+ arcmsr_ccb_complete(ccb, 1); -+ } -+ } -+ /* enable all outbound interrupt */ -+ arcmsr_enable_outbound_ints(acb, intmask_org); -+ } -+ atomic_set(&acb->ccboutstandingcount, 0); -+} -+ -+static int arcmsr_bus_reset(struct scsi_cmnd *cmd) -+{ -+ struct AdapterControlBlock *acb = -+ (struct AdapterControlBlock *)cmd->device->host->hostdata; -+ int i; -+ -+ acb->num_resets++; -+ acb->acb_flags |= ACB_F_BUS_RESET; -+ for (i = 0; i < 400; i++) { -+ if (!atomic_read(&acb->ccboutstandingcount)) -+ break; -+ arcmsr_interrupt(acb); -+ msleep(25); -+ } -+ arcmsr_iop_reset(acb); -+ acb->acb_flags &= ~ACB_F_BUS_RESET; -+ return SUCCESS; -+} -+ -+static void arcmsr_abort_one_cmd(struct AdapterControlBlock *acb, -+ struct CommandControlBlock *ccb) -+{ -+ u32 intmask; -+ -+ ccb->startdone = ARCMSR_CCB_ABORTED; -+ -+ /* -+ ** Wait for 3 sec for all command done. -+ */ -+ msleep_interruptible(3000); -+ -+ intmask = arcmsr_disable_outbound_ints(acb); -+ arcmsr_polling_ccbdone(acb, ccb); -+ arcmsr_enable_outbound_ints(acb, intmask); -+} -+ -+static int arcmsr_abort(struct scsi_cmnd *cmd) -+{ -+ struct AdapterControlBlock *acb = -+ (struct AdapterControlBlock *)cmd->device->host->hostdata; -+ int i = 0; -+ -+ printk(KERN_NOTICE -+ "arcmsr%d: abort device command of scsi id=%d lun=%d \n", -+ acb->host->host_no, cmd->device->id, cmd->device->lun); -+ acb->num_aborts++; -+ -+ /* -+ ************************************************ -+ ** the all interrupt service routine is locked -+ ** we need to handle it as soon as possible and exit -+ ************************************************ -+ */ -+ if (!atomic_read(&acb->ccboutstandingcount)) -+ return SUCCESS; -+ -+ for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { -+ struct CommandControlBlock *ccb = acb->pccb_pool[i]; -+ if (ccb->startdone == ARCMSR_CCB_START && ccb->pcmd == cmd) { -+ arcmsr_abort_one_cmd(acb, ccb); -+ break; -+ } -+ } -+ -+ return SUCCESS; -+} -+ -+static const char *arcmsr_info(struct Scsi_Host *host) -+{ -+ struct AdapterControlBlock *acb = -+ (struct AdapterControlBlock *) host->hostdata; -+ static char buf[256]; -+ char *type; -+ int raid6 = 1; -+ -+ switch (acb->pdev->device) { -+ case PCI_DEVICE_ID_ARECA_1110: -+ case PCI_DEVICE_ID_ARECA_1210: -+ raid6 = 0; -+ /*FALLTHRU*/ -+ case PCI_DEVICE_ID_ARECA_1120: -+ case PCI_DEVICE_ID_ARECA_1130: -+ case PCI_DEVICE_ID_ARECA_1160: -+ case PCI_DEVICE_ID_ARECA_1170: -+ case PCI_DEVICE_ID_ARECA_1220: -+ case PCI_DEVICE_ID_ARECA_1230: -+ case PCI_DEVICE_ID_ARECA_1260: -+ case PCI_DEVICE_ID_ARECA_1270: -+ case PCI_DEVICE_ID_ARECA_1280: -+ type = "SATA"; -+ break; -+ case PCI_DEVICE_ID_ARECA_1380: -+ case PCI_DEVICE_ID_ARECA_1381: -+ case PCI_DEVICE_ID_ARECA_1680: -+ case PCI_DEVICE_ID_ARECA_1681: -+ type = "SAS"; -+ break; -+ default: -+ type = "X-TYPE"; -+ break; -+ } -+ sprintf(buf, "Areca %s Host Adapter RAID Controller%s\n %s", -+ type, raid6 ? "( RAID6 capable)" : "", -+ ARCMSR_DRIVER_VERSION); -+ return buf; -+} -+ -+ -diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h -index c09396d..df7b626 100644 ---- a/include/linux/pci_ids.h -+++ b/include/linux/pci_ids.h -@@ -2004,6 +2004,23 @@ #define PCI_DEVICE_ID_ALTIMA_AC1001 0x03 - #define PCI_DEVICE_ID_ALTIMA_AC9100 0x03ea - #define PCI_DEVICE_ID_ALTIMA_AC1003 0x03eb - -+#define PCI_VENDOR_ID_ARECA 0x17d3 -+#define PCI_DEVICE_ID_ARECA_1110 0x1110 -+#define PCI_DEVICE_ID_ARECA_1120 0x1120 -+#define PCI_DEVICE_ID_ARECA_1130 0x1130 -+#define PCI_DEVICE_ID_ARECA_1160 0x1160 -+#define PCI_DEVICE_ID_ARECA_1170 0x1170 -+#define PCI_DEVICE_ID_ARECA_1210 0x1210 -+#define PCI_DEVICE_ID_ARECA_1220 0x1220 -+#define PCI_DEVICE_ID_ARECA_1230 0x1230 -+#define PCI_DEVICE_ID_ARECA_1260 0x1260 -+#define PCI_DEVICE_ID_ARECA_1270 0x1270 -+#define PCI_DEVICE_ID_ARECA_1280 0x1280 -+#define PCI_DEVICE_ID_ARECA_1380 0x1380 -+#define PCI_DEVICE_ID_ARECA_1381 0x1381 -+#define PCI_DEVICE_ID_ARECA_1680 0x1680 -+#define PCI_DEVICE_ID_ARECA_1681 0x1681 -+ - #define PCI_VENDOR_ID_S2IO 0x17d5 - #define PCI_DEVICE_ID_S2IO_WIN 0x5731 - #define PCI_DEVICE_ID_S2IO_UNI 0x5831 diff --git a/debian/patches/features/all/drivers/scsi-arcmsr-2.patch b/debian/patches/features/all/drivers/scsi-arcmsr-2.patch deleted file mode 100644 index 500f170ea..000000000 --- a/debian/patches/features/all/drivers/scsi-arcmsr-2.patch +++ /dev/null @@ -1,49 +0,0 @@ -# [SCSI] areca sysfs fix -# 43d6b68dc38867e489995e21649bb82f6ee7b5d3 - -diff --git a/drivers/scsi/arcmsr/arcmsr_attr.c b/drivers/scsi/arcmsr/arcmsr_attr.c -index 0459f41..c96f714 100644 ---- a/drivers/scsi/arcmsr/arcmsr_attr.c -+++ b/drivers/scsi/arcmsr/arcmsr_attr.c -@@ -240,15 +240,11 @@ int arcmsr_alloc_sysfs_attr(struct Adapt - } - return 0; - error_bin_file_message_clear: -- error = sysfs_remove_bin_file(&host->shost_classdev.kobj, -+ sysfs_remove_bin_file(&host->shost_classdev.kobj, - &arcmsr_sysfs_message_write_attr); -- if (error) -- printk(KERN_ERR "arcmsr: sysfs_remove_bin_file mu_write failed\n"); - error_bin_file_message_write: -- error = sysfs_remove_bin_file(&host->shost_classdev.kobj, -+ sysfs_remove_bin_file(&host->shost_classdev.kobj, - &arcmsr_sysfs_message_read_attr); -- if (error) -- printk(KERN_ERR "arcmsr: sysfs_remove_bin_file mu_read failed\n"); - error_bin_file_message_read: - return error; - } -@@ -256,20 +252,13 @@ error_bin_file_message_read: - void - arcmsr_free_sysfs_attr(struct AdapterControlBlock *acb) { - struct Scsi_Host *host = acb->host; -- int error; - -- error = sysfs_remove_bin_file(&host->shost_classdev.kobj, -+ sysfs_remove_bin_file(&host->shost_classdev.kobj, - &arcmsr_sysfs_message_clear_attr); -- if (error) -- printk(KERN_ERR "arcmsr: free sysfs mu_clear failed\n"); -- error = sysfs_remove_bin_file(&host->shost_classdev.kobj, -+ sysfs_remove_bin_file(&host->shost_classdev.kobj, - &arcmsr_sysfs_message_write_attr); -- if (error) -- printk(KERN_ERR "arcmsr: free sysfs mu_write failed\n"); -- error = sysfs_remove_bin_file(&host->shost_classdev.kobj, -+ sysfs_remove_bin_file(&host->shost_classdev.kobj, - &arcmsr_sysfs_message_read_attr); -- if (error) -- printk(KERN_ERR "arcmsr: free sysfss mu_read failed\n"); - } - - diff --git a/debian/patches/features/all/drivers/scsi-arcmsr-3.patch b/debian/patches/features/all/drivers/scsi-arcmsr-3.patch deleted file mode 100644 index 6fed13597..000000000 --- a/debian/patches/features/all/drivers/scsi-arcmsr-3.patch +++ /dev/null @@ -1,97 +0,0 @@ -# [SCSI] arcmsr: fix up sysfs values -# d67a70aca200f67be42428e74eb3353f20ad1130 - -diff --git a/drivers/scsi/arcmsr/arcmsr_attr.c b/drivers/scsi/arcmsr/arcmsr_attr.c -index c96f714..12497da 100644 ---- a/drivers/scsi/arcmsr/arcmsr_attr.c -+++ b/drivers/scsi/arcmsr/arcmsr_attr.c -@@ -265,7 +265,7 @@ arcmsr_free_sysfs_attr(struct AdapterCon - static ssize_t - arcmsr_attr_host_driver_version(struct class_device *cdev, char *buf) { - return snprintf(buf, PAGE_SIZE, -- "ARCMSR: %s\n", -+ "%s\n", - ARCMSR_DRIVER_VERSION); - } - -@@ -274,7 +274,7 @@ arcmsr_attr_host_driver_posted_cmd(struc - struct Scsi_Host *host = class_to_shost(cdev); - struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; - return snprintf(buf, PAGE_SIZE, -- "Current commands posted: %4d\n", -+ "%4d\n", - atomic_read(&acb->ccboutstandingcount)); - } - -@@ -283,7 +283,7 @@ arcmsr_attr_host_driver_reset(struct cla - struct Scsi_Host *host = class_to_shost(cdev); - struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; - return snprintf(buf, PAGE_SIZE, -- "SCSI Host Resets: %4d\n", -+ "%4d\n", - acb->num_resets); - } - -@@ -292,7 +292,7 @@ arcmsr_attr_host_driver_abort(struct cla - struct Scsi_Host *host = class_to_shost(cdev); - struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; - return snprintf(buf, PAGE_SIZE, -- "SCSI Aborts/Timeouts: %4d\n", -+ "%4d\n", - acb->num_aborts); - } - -@@ -301,7 +301,7 @@ arcmsr_attr_host_fw_model(struct class_d - struct Scsi_Host *host = class_to_shost(cdev); - struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; - return snprintf(buf, PAGE_SIZE, -- "Adapter Model: %s\n", -+ "%s\n", - acb->firm_model); - } - -@@ -311,7 +311,7 @@ arcmsr_attr_host_fw_version(struct class - struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; - - return snprintf(buf, PAGE_SIZE, -- "Firmware Version: %s\n", -+ "%s\n", - acb->firm_version); - } - -@@ -321,7 +321,7 @@ arcmsr_attr_host_fw_request_len(struct c - struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; - - return snprintf(buf, PAGE_SIZE, -- "Reguest Lenth: %4d\n", -+ "%4d\n", - acb->firm_request_len); - } - -@@ -331,7 +331,7 @@ arcmsr_attr_host_fw_numbers_queue(struct - struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; - - return snprintf(buf, PAGE_SIZE, -- "Numbers of Queue: %4d\n", -+ "%4d\n", - acb->firm_numbers_queue); - } - -@@ -341,7 +341,7 @@ arcmsr_attr_host_fw_sdram_size(struct cl - struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; - - return snprintf(buf, PAGE_SIZE, -- "SDRAM Size: %4d\n", -+ "%4d\n", - acb->firm_sdram_size); - } - -@@ -351,7 +351,7 @@ arcmsr_attr_host_fw_hd_channels(struct c - struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; - - return snprintf(buf, PAGE_SIZE, -- "Hard Disk Channels: %4d\n", -+ "%4d\n", - acb->firm_hd_channels); - } -