From e747cad203f2956aad460325510f0c339fac10c4 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 15 Nov 2015 12:48:33 +0100 Subject: st: Remove obsolete scsi_tape.max_pfn MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Its last user was removed 10 years ago, in commit 8b05b773b6030de5 ("[SCSI] convert st to use scsi_execute_async"). Signed-off-by: Geert Uytterhoeven Reviewed-by: Ewan D. Milne Acked-by: Kai Mäkisara Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h index b6486b5..8c732c8 100644 --- a/drivers/scsi/st.h +++ b/drivers/scsi/st.h @@ -148,8 +148,6 @@ struct scsi_tape { int tape_type; int long_timeout; /* timeout for commands known to take long time */ - unsigned long max_pfn; /* the maximum page number reachable by the HBA */ - /* Mode characteristics */ struct st_modedef modes[ST_NBR_MODES]; int current_mode; -- cgit v0.10.2 From 940a7f09ad645b6be7ff85b034499fcffdfe0ebc Mon Sep 17 00:00:00 2001 From: Himanshu Madhani Date: Tue, 17 Nov 2015 15:44:48 -0500 Subject: qla2xxx: Remove unavailable firmware files Remove firmware binary names for the ISPs, which are not submitted to linux-firmware. Signed-off-by: Himanshu Madhani Signed-off-by: Giridhar Malavali Reviewed-by: Julian Calaby Reviewed-by: Xose Vazquez Perez Cc: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/qla2xxx/Kconfig b/drivers/scsi/qla2xxx/Kconfig index a0f732b..10aa18b 100644 --- a/drivers/scsi/qla2xxx/Kconfig +++ b/drivers/scsi/qla2xxx/Kconfig @@ -18,9 +18,6 @@ config SCSI_QLA_FC 2322, 6322 ql2322_fw.bin 24xx, 54xx ql2400_fw.bin 25xx ql2500_fw.bin - 2031 ql2600_fw.bin - 8031 ql8300_fw.bin - 27xx ql2700_fw.bin Upon request, the driver caches the firmware image until the driver is unloaded. diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index bfa9a64..6be32fd 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -5843,6 +5843,3 @@ MODULE_FIRMWARE(FW_FILE_ISP2300); MODULE_FIRMWARE(FW_FILE_ISP2322); MODULE_FIRMWARE(FW_FILE_ISP24XX); MODULE_FIRMWARE(FW_FILE_ISP25XX); -MODULE_FIRMWARE(FW_FILE_ISP2031); -MODULE_FIRMWARE(FW_FILE_ISP8031); -MODULE_FIRMWARE(FW_FILE_ISP27XX); -- cgit v0.10.2 From d282e2b383e3f41a7758e8cbf3076091ef9d9447 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 19 Nov 2015 15:33:41 +0100 Subject: SCSI: initio: remove duplicate module device table The initio driver has for many years had two copies of the same module device table. One of them is also used for registering the other driver, the other one is entirely useless after the large scale cleanup that Alan Cox did back in 2007. The compiler warns about this whenever the driver is built-in: drivers/scsi/initio.c:131:29: warning: 'i91u_pci_devices' defined but not used [-Wunused-variable] This removes the extraneous table and the warning. Signed-off-by: Arnd Bergmann Fixes: 72d39fea901 ("[SCSI] initio: Convert into a real Linux driver and update to modern style") Reviewed-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/initio.c b/drivers/scsi/initio.c index 6a926ba..7a91cf3 100644 --- a/drivers/scsi/initio.c +++ b/drivers/scsi/initio.c @@ -110,11 +110,6 @@ #define i91u_MAXQUEUE 2 #define i91u_REVID "Initio INI-9X00U/UW SCSI device driver; Revision: 1.04a" -#define I950_DEVICE_ID 0x9500 /* Initio's inic-950 product ID */ -#define I940_DEVICE_ID 0x9400 /* Initio's inic-940 product ID */ -#define I935_DEVICE_ID 0x9401 /* Initio's inic-935 product ID */ -#define I920_DEVICE_ID 0x0002 /* Initio's other product ID */ - #ifdef DEBUG_i91u static unsigned int i91u_debug = DEBUG_DEFAULT; #endif @@ -127,17 +122,6 @@ static int setup_debug = 0; static void i91uSCBPost(u8 * pHcb, u8 * pScb); -/* PCI Devices supported by this driver */ -static struct pci_device_id i91u_pci_devices[] = { - { PCI_VENDOR_ID_INIT, I950_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_INIT, I940_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_INIT, I935_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_INIT, I920_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_DOMEX, I920_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { } -}; -MODULE_DEVICE_TABLE(pci, i91u_pci_devices); - #define DEBUG_INTERRUPT 0 #define DEBUG_QUEUE 0 #define DEBUG_STATE 0 -- cgit v0.10.2 From c43cd036e531ca54b885dee535f535ab58bf8a0f Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:37 +0100 Subject: atp870u: Remove workport Remove workport temporary variable to simplify the code. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 05301bc..3db9d0c 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -51,7 +51,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) unsigned char i, j, c, target_id, lun,cmdp; unsigned char *prd; struct scsi_cmnd *workreq; - unsigned int workport, tmport, tmport1; + unsigned int tmport, tmport1; unsigned long adrcnt, k; #ifdef ED_DBGP unsigned long l; @@ -76,10 +76,9 @@ ch_sel: #endif dev->in_int[c] = 1; cmdp = inb(dev->ioport[c] + 0x10); - workport = dev->ioport[c]; if (dev->working[c] != 0) { if (dev->dev_id == ATP885_DEVID) { - tmport1 = workport + 0x16; + tmport1 = dev->ioport[c] + 0x16; if ((inb(tmport1) & 0x80) == 0) outb((inb(tmport1) | 0x80), tmport1); } @@ -160,7 +159,7 @@ stop_dma: * Flip wide */ if (dev->wide_id[c] != 0) { - tmport = workport + 0x1b; + tmport = dev->ioport[c] + 0x1b; outb(0x01, tmport); while ((inb(tmport) & 0x01) != 0x01) { outb(0x01, tmport); @@ -276,9 +275,9 @@ stop_dma: if (dev->dev_id == ATP885_DEVID) { j = inb(dev->baseport + 0x29) & 0xfe; outb(j, dev->baseport + 0x29); - tmport = workport + 0x16; + tmport = dev->ioport[c] + 0x16; } else { - tmport = workport + 0x10; + tmport = dev->ioport[c] + 0x10; outb(0x45, tmport); tmport += 0x06; } @@ -293,7 +292,7 @@ stop_dma: target_id &= 0x07; } if (dev->dev_id == ATP885_DEVID) { - tmport = workport + 0x10; + tmport = dev->ioport[c] + 0x10; outb(0x45, tmport); } workreq = dev->id[c][target_id].curr_req; @@ -304,7 +303,7 @@ stop_dma: printk("\n"); #endif - tmport = workport + 0x0f; + tmport = dev->ioport[c] + 0x0f; outb(lun, tmport); tmport += 0x02; outb(dev->id[c][target_id].devsp, tmport++); @@ -338,21 +337,21 @@ stop_dma: outb(i,tmpcip); } else if ((dev->dev_id == ATP880_DEVID1) || (dev->dev_id == ATP880_DEVID2) ) { - tmport = workport - 0x05; + tmport = dev->ioport[c] - 0x05; if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { outb((unsigned char) ((inb(tmport) & 0x3f) | 0xc0), tmport); } else { outb((unsigned char) (inb(tmport) & 0x3f), tmport); } } else { - tmport = workport + 0x3a; + tmport = dev->ioport[c] + 0x3a; if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { outb((unsigned char) ((inb(tmport) & 0xf3) | 0x08), tmport); } else { outb((unsigned char) (inb(tmport) & 0xf3), tmport); } } - tmport = workport + 0x1b; + tmport = dev->ioport[c] + 0x1b; j = 0; id = 1; id = id << target_id; @@ -367,7 +366,7 @@ stop_dma: outb(j,tmport); } if (dev->id[c][target_id].last_len == 0) { - tmport = workport + 0x18; + tmport = dev->ioport[c] + 0x18; outb(0x08, tmport); dev->in_int[c] = 0; #ifdef ED_DBGP @@ -414,7 +413,7 @@ stop_dma: outb(0x00, tmpcip); tmpcip -= 0x02; } - tmport = workport + 0x18; + tmport = dev->ioport[c] + 0x18; /* * Check transfer direction */ @@ -488,7 +487,7 @@ go_42: * Take it back wide */ if (dev->wide_id[c] != 0) { - tmport = workport + 0x1b; + tmport = dev->ioport[c] + 0x1b; outb(0x01, tmport); while ((inb(tmport) & 0x01) != 0x01) { outb(0x01, tmport); @@ -523,7 +522,7 @@ go_42: outb(0x06, tmpcip); outb(0x00, tmpcip); tmpcip = tmpcip - 2; - tmport = workport + 0x10; + tmport = dev->ioport[c] + 0x10; outb(0x41, tmport); if (dev->dev_id == ATP885_DEVID) { tmport += 2; @@ -549,7 +548,7 @@ go_42: outb(0x06, tmpcip); outb(0x00, tmpcip); tmpcip = tmpcip - 2; - tmport = workport + 0x10; + tmport = dev->ioport[c] + 0x10; outb(0x41, tmport); if (dev->dev_id == ATP885_DEVID) { tmport += 2; @@ -584,7 +583,7 @@ go_42: dev->in_int[c] = 0; goto handled; } else { -// tmport = workport + 0x17; +// tmport = dev->ioport[c] + 0x17; // inb(tmport); // dev->working[c] = 0; dev->in_int[c] = 0; @@ -713,7 +712,6 @@ static void send_s870(struct atp_unit *dev,unsigned char c) unsigned char *prd; unsigned short int tmpcip, w; unsigned long l, bttl = 0; - unsigned int workport; unsigned long sg_count; if (dev->in_snd[c] != 0) { @@ -759,12 +757,11 @@ static void send_s870(struct atp_unit *dev,unsigned char c) dev->in_snd[c] = 0; return; cmd_subp: - workport = dev->ioport[c]; - tmport = workport + 0x1f; + tmport = dev->ioport[c] + 0x1f; if ((inb(tmport) & 0xb0) != 0) { goto abortsnd; } - tmport = workport + 0x1c; + tmport = dev->ioport[c] + 0x1c; if (inb(tmport) == 0) { goto oktosend; } @@ -800,7 +797,7 @@ oktosend: l = 0; } - tmport = workport + 0x1b; + tmport = dev->ioport[c] + 0x1b; j = 0; target_id = scmd_id(workreq); @@ -823,7 +820,7 @@ oktosend: * Write the command */ - tmport = workport; + tmport = dev->ioport[c]; outb(workreq->cmd_len, tmport++); outb(0x2c, tmport++); if (dev->dev_id == ATP885_DEVID) { @@ -834,7 +831,7 @@ oktosend: for (i = 0; i < workreq->cmd_len; i++) { outb(workreq->cmnd[i], tmport++); } - tmport = workport + 0x0f; + tmport = dev->ioport[c] + 0x0f; outb(workreq->device->lun, tmport); tmport += 0x02; /* @@ -874,11 +871,11 @@ oktosend: } outb((unsigned char) (inb(tmport) | 0x80), tmport); outb(0x80, tmport); - tmport = workport + 0x1c; + tmport = dev->ioport[c] + 0x1c; dev->id[c][target_id].dirct = 0; if (l == 0) { if (inb(tmport) == 0) { - tmport = workport + 0x18; + tmport = dev->ioport[c] + 0x18; #ifdef ED_DBGP printk("change SCSI_CMD_REG 0x08\n"); #endif @@ -947,7 +944,7 @@ oktosend: } else if ((dev->dev_id == ATP880_DEVID1) || (dev->dev_id == ATP880_DEVID2)) { tmpcip =tmpcip -2; - tmport = workport - 0x05; + tmport = dev->ioport[c] - 0x05; if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { outb((unsigned char) ((inb(tmport) & 0x3f) | 0xc0), tmport); } else { @@ -955,19 +952,19 @@ oktosend: } } else { tmpcip =tmpcip -2; - tmport = workport + 0x3a; + tmport = dev->ioport[c] + 0x3a; if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { outb((inb(tmport) & 0xf3) | 0x08, tmport); } else { outb(inb(tmport) & 0xf3, tmport); } } - tmport = workport + 0x1c; + tmport = dev->ioport[c] + 0x1c; if(workreq->sc_data_direction == DMA_TO_DEVICE) { dev->id[c][target_id].dirct = 0x20; if (inb(tmport) == 0) { - tmport = workport + 0x18; + tmport = dev->ioport[c] + 0x18; outb(0x08, tmport); outb(0x01, tmpcip); #ifdef ED_DBGP @@ -980,7 +977,7 @@ oktosend: return; } if (inb(tmport) == 0) { - tmport = workport + 0x18; + tmport = dev->ioport[c] + 0x18; outb(0x08, tmport); outb(0x09, tmpcip); #ifdef ED_DBGP -- cgit v0.10.2 From b4263b3ce9bac236ee9317153a735ffeb635c0d9 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:38 +0100 Subject: atp870u: Remove tmport1 Remove tmport1 temporary variable to simplify the code. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 3db9d0c..aac7d47 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -51,7 +51,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) unsigned char i, j, c, target_id, lun,cmdp; unsigned char *prd; struct scsi_cmnd *workreq; - unsigned int tmport, tmport1; + unsigned int tmport; unsigned long adrcnt, k; #ifdef ED_DBGP unsigned long l; @@ -78,9 +78,8 @@ ch_sel: cmdp = inb(dev->ioport[c] + 0x10); if (dev->working[c] != 0) { if (dev->dev_id == ATP885_DEVID) { - tmport1 = dev->ioport[c] + 0x16; - if ((inb(tmport1) & 0x80) == 0) - outb((inb(tmport1) | 0x80), tmport1); + if ((inb(dev->ioport[c] + 0x16) & 0x80) == 0) + outb((inb(dev->ioport[c] + 0x16) | 0x80), dev->ioport[c] + 0x16); } tmpcip = dev->pciport[c]; if ((inb(tmpcip) & 0x08) != 0) -- cgit v0.10.2 From 3a38e53ee6c6542410a32374a3bd5ae6c8fc9f09 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:39 +0100 Subject: atp870u: Untangle tmport Untangle the tmport crap so it becomes obvious what ports are accessed. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index aac7d47..a25a300 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -51,7 +51,6 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) unsigned char i, j, c, target_id, lun,cmdp; unsigned char *prd; struct scsi_cmnd *workreq; - unsigned int tmport; unsigned long adrcnt, k; #ifdef ED_DBGP unsigned long l; @@ -61,8 +60,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) struct atp_unit *dev = (struct atp_unit *)&host->hostdata; for (c = 0; c < 2; c++) { - tmport = dev->ioport[c] + 0x1f; - j = inb(tmport); + j = inb(dev->ioport[c] + 0x1f); if ((j & 0x80) != 0) { goto ch_sel; @@ -97,9 +95,8 @@ ch_sel: stop_dma: tmpcip = dev->pciport[c]; outb(0x00, tmpcip); - tmport -= 0x08; - i = inb(tmport); + i = inb(dev->ioport[c] + 0x17); if (dev->dev_id == ATP885_DEVID) { tmpcip += 2; @@ -107,9 +104,7 @@ stop_dma: tmpcip -= 2; } - tmport -= 0x02; - target_id = inb(tmport); - tmport += 0x02; + target_id = inb(dev->ioport[c] + 0x15); /* * Remap wide devices onto id numbers @@ -137,11 +132,10 @@ stop_dma: dev->last_cmd[c] = 0xff; } if (dev->dev_id == ATP885_DEVID) { - tmport -= 0x05; adrcnt = 0; - ((unsigned char *) &adrcnt)[2] = inb(tmport++); - ((unsigned char *) &adrcnt)[1] = inb(tmport++); - ((unsigned char *) &adrcnt)[0] = inb(tmport); + ((unsigned char *) &adrcnt)[2] = inb(dev->ioport[c] + 0x12); + ((unsigned char *) &adrcnt)[1] = inb(dev->ioport[c] + 0x13); + ((unsigned char *) &adrcnt)[0] = inb(dev->ioport[c] + 0x14); if (dev->id[c][target_id].last_len != adrcnt) { k = dev->id[c][target_id].last_len; @@ -150,7 +144,7 @@ stop_dma: dev->id[c][target_id].last_len = adrcnt; } #ifdef ED_DBGP - printk("tmport = %x dev->id[c][target_id].last_len = %d dev->id[c][target_id].tran_len = %d\n",tmport,dev->id[c][target_id].last_len,dev->id[c][target_id].tran_len); + printk("dev->id[c][target_id].last_len = %d dev->id[c][target_id].tran_len = %d\n",dev->id[c][target_id].last_len,dev->id[c][target_id].tran_len); #endif } @@ -158,10 +152,9 @@ stop_dma: * Flip wide */ if (dev->wide_id[c] != 0) { - tmport = dev->ioport[c] + 0x1b; - outb(0x01, tmport); - while ((inb(tmport) & 0x01) != 0x01) { - outb(0x01, tmport); + outb(0x01, dev->ioport[c] + 0x1b); + while ((inb(dev->ioport[c] + 0x1b) & 0x01) != 0x01) { + outb(0x01, dev->ioport[c] + 0x1b); } } /* @@ -196,19 +189,16 @@ stop_dma: if ((dev->last_cmd[c] & 0xf0) != 0x40) { dev->last_cmd[c] = 0xff; } - tmport -= 0x05; adrcnt = 0; - ((unsigned char *) &adrcnt)[2] = inb(tmport++); - ((unsigned char *) &adrcnt)[1] = inb(tmport++); - ((unsigned char *) &adrcnt)[0] = inb(tmport); + ((unsigned char *) &adrcnt)[2] = inb(dev->ioport[c] + 0x12); + ((unsigned char *) &adrcnt)[1] = inb(dev->ioport[c] + 0x13); + ((unsigned char *) &adrcnt)[0] = inb(dev->ioport[c] + 0x14); k = dev->id[c][target_id].last_len; k -= adrcnt; dev->id[c][target_id].tran_len = k; dev->id[c][target_id].last_len = adrcnt; - tmport -= 0x04; - outb(0x41, tmport); - tmport += 0x08; - outb(0x08, tmport); + outb(0x41, dev->ioport[c] + 0x10); + outb(0x08, dev->ioport[c] + 0x18); dev->in_int[c] = 0; goto handled; } @@ -227,10 +217,8 @@ stop_dma: printk(KERN_DEBUG "Device reselect\n"); #endif lun = 0; - tmport -= 0x07; if (cmdp == 0x44 || i==0x80) { - tmport += 0x0d; - lun = inb(tmport) & 0x07; + lun = inb(dev->ioport[c] + 0x1d) & 0x07; } else { if ((dev->last_cmd[c] & 0xf0) != 0x40) { dev->last_cmd[c] = 0xff; @@ -239,31 +227,27 @@ stop_dma: #ifdef ED_DBGP printk("cmdp = 0x41\n"); #endif - tmport += 0x02; adrcnt = 0; - ((unsigned char *) &adrcnt)[2] = inb(tmport++); - ((unsigned char *) &adrcnt)[1] = inb(tmport++); - ((unsigned char *) &adrcnt)[0] = inb(tmport); + ((unsigned char *) &adrcnt)[2] = inb(dev->ioport[c] + 0x12); + ((unsigned char *) &adrcnt)[1] = inb(dev->ioport[c] + 0x13); + ((unsigned char *) &adrcnt)[0] = inb(dev->ioport[c] + 0x14); k = dev->id[c][target_id].last_len; k -= adrcnt; dev->id[c][target_id].tran_len = k; dev->id[c][target_id].last_len = adrcnt; - tmport += 0x04; - outb(0x08, tmport); + outb(0x08, dev->ioport[c] + 0x18); dev->in_int[c] = 0; goto handled; } else { #ifdef ED_DBGP printk("cmdp != 0x41\n"); #endif - outb(0x46, tmport); + outb(0x46, dev->ioport[c] + 0x10); dev->id[c][target_id].dirct = 0x00; - tmport += 0x02; - outb(0x00, tmport++); - outb(0x00, tmport++); - outb(0x00, tmport++); - tmport += 0x03; - outb(0x08, tmport); + outb(0x00, dev->ioport[c] + 0x12); + outb(0x00, dev->ioport[c] + 0x13); + outb(0x00, dev->ioport[c] + 0x14); + outb(0x08, dev->ioport[c] + 0x18); dev->in_int[c] = 0; goto handled; } @@ -274,14 +258,10 @@ stop_dma: if (dev->dev_id == ATP885_DEVID) { j = inb(dev->baseport + 0x29) & 0xfe; outb(j, dev->baseport + 0x29); - tmport = dev->ioport[c] + 0x16; - } else { - tmport = dev->ioport[c] + 0x10; - outb(0x45, tmport); - tmport += 0x06; - } - - target_id = inb(tmport); + } else + outb(0x45, dev->ioport[c] + 0x10); + + target_id = inb(dev->ioport[c] + 0x16); /* * Remap wide identifiers */ @@ -290,10 +270,8 @@ stop_dma: } else { target_id &= 0x07; } - if (dev->dev_id == ATP885_DEVID) { - tmport = dev->ioport[c] + 0x10; - outb(0x45, tmport); - } + if (dev->dev_id == ATP885_DEVID) + outb(0x45, dev->ioport[c] + 0x10); workreq = dev->id[c][target_id].curr_req; #ifdef ED_DBGP scmd_printk(KERN_DEBUG, workreq, "CDB"); @@ -302,18 +280,16 @@ stop_dma: printk("\n"); #endif - tmport = dev->ioport[c] + 0x0f; - outb(lun, tmport); - tmport += 0x02; - outb(dev->id[c][target_id].devsp, tmport++); + outb(lun, dev->ioport[c] + 0x0f); + outb(dev->id[c][target_id].devsp, dev->ioport[c] + 0x11); adrcnt = dev->id[c][target_id].tran_len; k = dev->id[c][target_id].last_len; - outb(((unsigned char *) &k)[2], tmport++); - outb(((unsigned char *) &k)[1], tmport++); - outb(((unsigned char *) &k)[0], tmport++); + outb(((unsigned char *) &k)[2], dev->ioport[c] + 0x12); + outb(((unsigned char *) &k)[1], dev->ioport[c] + 0x13); + outb(((unsigned char *) &k)[0], dev->ioport[c] + 0x14); #ifdef ED_DBGP - printk("k %x, k[0] 0x%x k[1] 0x%x k[2] 0x%x\n", k, inb(tmport-1), inb(tmport-2), inb(tmport-3)); + printk("k %x, k[0] 0x%x k[1] 0x%x k[2] 0x%x\n", k, inb(dev->ioport[c] + 0x14), inb(dev->ioport[c] + 0x13), inb(dev->ioport[c] + 0x12)); #endif /* Remap wide */ j = target_id; @@ -322,8 +298,8 @@ stop_dma: } /* Add direction */ j |= dev->id[c][target_id].dirct; - outb(j, tmport++); - outb(0x80,tmport); + outb(j, dev->ioport[c] + 0x15); + outb(0x80, dev->ioport[c] + 0x16); /* enable 32 bit fifo transfer */ if (dev->dev_id == ATP885_DEVID) { @@ -336,21 +312,18 @@ stop_dma: outb(i,tmpcip); } else if ((dev->dev_id == ATP880_DEVID1) || (dev->dev_id == ATP880_DEVID2) ) { - tmport = dev->ioport[c] - 0x05; if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { - outb((unsigned char) ((inb(tmport) & 0x3f) | 0xc0), tmport); + outb((unsigned char) ((inb(dev->ioport[c] - 0x05) & 0x3f) | 0xc0), dev->ioport[c] - 0x05);///minus 0x05??? } else { - outb((unsigned char) (inb(tmport) & 0x3f), tmport); + outb((unsigned char) (inb(dev->ioport[c] - 0x05) & 0x3f), dev->ioport[c] - 0x05);///minus 0x05??? } } else { - tmport = dev->ioport[c] + 0x3a; if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { - outb((unsigned char) ((inb(tmport) & 0xf3) | 0x08), tmport); + outb((unsigned char) ((inb(dev->ioport[c] + 0x3a) & 0xf3) | 0x08), dev->ioport[c] + 0x3a); } else { - outb((unsigned char) (inb(tmport) & 0xf3), tmport); + outb((unsigned char) (inb(dev->ioport[c] + 0x3a) & 0xf3), dev->ioport[c] + 0x3a); } } - tmport = dev->ioport[c] + 0x1b; j = 0; id = 1; id = id << target_id; @@ -360,13 +333,12 @@ stop_dma: if ((id & dev->wide_id[c]) != 0) { j |= 0x01; } - outb(j, tmport); - while ((inb(tmport) & 0x01) != j) { - outb(j,tmport); + outb(j, dev->ioport[c] + 0x1b); + while ((inb(dev->ioport[c] + 0x1b) & 0x01) != j) { + outb(j,dev->ioport[c] + 0x1b); } if (dev->id[c][target_id].last_len == 0) { - tmport = dev->ioport[c] + 0x18; - outb(0x08, tmport); + outb(0x08, dev->ioport[c] + 0x18); dev->in_int[c] = 0; #ifdef ED_DBGP printk("dev->id[c][target_id].last_len = 0\n"); @@ -412,12 +384,11 @@ stop_dma: outb(0x00, tmpcip); tmpcip -= 0x02; } - tmport = dev->ioport[c] + 0x18; /* * Check transfer direction */ if (dev->id[c][target_id].dirct != 0) { - outb(0x08, tmport); + outb(0x08, dev->ioport[c] + 0x18); outb(0x01, tmpcip); dev->in_int[c] = 0; #ifdef ED_DBGP @@ -425,7 +396,7 @@ stop_dma: #endif goto handled; } - outb(0x08, tmport); + outb(0x08, dev->ioport[c] + 0x18); outb(0x09, tmpcip); dev->in_int[c] = 0; #ifdef ED_DBGP @@ -454,8 +425,7 @@ stop_dma: dev->last_cmd[c] = 0xff; } errstus = 0; - tmport -= 0x08; - errstus = inb(tmport); + errstus = inb(dev->ioport[c] + 0x0f); if (((dev->r1f[c][target_id] & 0x10) != 0)&&(dev->dev_id==ATP885_DEVID)) { printk(KERN_WARNING "AEC67162 CRC ERROR !\n"); errstus = 0x02; @@ -486,10 +456,9 @@ go_42: * Take it back wide */ if (dev->wide_id[c] != 0) { - tmport = dev->ioport[c] + 0x1b; - outb(0x01, tmport); - while ((inb(tmport) & 0x01) != 0x01) { - outb(0x01, tmport); + outb(0x01, dev->ioport[c] + 0x1b); + while ((inb(dev->ioport[c] + 0x1b) & 0x01) != 0x01) { + outb(0x01, dev->ioport[c] + 0x1b); } } /* @@ -521,21 +490,17 @@ go_42: outb(0x06, tmpcip); outb(0x00, tmpcip); tmpcip = tmpcip - 2; - tmport = dev->ioport[c] + 0x10; - outb(0x41, tmport); + outb(0x41, dev->ioport[c] + 0x10); if (dev->dev_id == ATP885_DEVID) { - tmport += 2; k = dev->id[c][target_id].last_len; - outb((unsigned char) (((unsigned char *) (&k))[2]), tmport++); - outb((unsigned char) (((unsigned char *) (&k))[1]), tmport++); - outb((unsigned char) (((unsigned char *) (&k))[0]), tmport); + outb((unsigned char) (((unsigned char *) (&k))[2]), dev->ioport[c] + 0x12); + outb((unsigned char) (((unsigned char *) (&k))[1]), dev->ioport[c] + 0x13); + outb((unsigned char) (((unsigned char *) (&k))[0]), dev->ioport[c] + 0x14); dev->id[c][target_id].dirct = 0x00; - tmport += 0x04; } else { dev->id[c][target_id].dirct = 0x00; - tmport += 0x08; } - outb(0x08, tmport); + outb(0x08, dev->ioport[c] + 0x18); outb(0x09, tmpcip); dev->in_int[c] = 0; goto handled; @@ -547,43 +512,34 @@ go_42: outb(0x06, tmpcip); outb(0x00, tmpcip); tmpcip = tmpcip - 2; - tmport = dev->ioport[c] + 0x10; - outb(0x41, tmport); + outb(0x41, dev->ioport[c] + 0x10); if (dev->dev_id == ATP885_DEVID) { - tmport += 2; k = dev->id[c][target_id].last_len; - outb((unsigned char) (((unsigned char *) (&k))[2]), tmport++); - outb((unsigned char) (((unsigned char *) (&k))[1]), tmport++); - outb((unsigned char) (((unsigned char *) (&k))[0]), tmport++); - } else { - tmport += 5; + outb((unsigned char) (((unsigned char *) (&k))[2]), dev->ioport[c] + 0x12); + outb((unsigned char) (((unsigned char *) (&k))[1]), dev->ioport[c] + 0x13); + outb((unsigned char) (((unsigned char *) (&k))[0]), dev->ioport[c] + 0x14); } - outb((unsigned char) (inb(tmport) | 0x20), tmport); + outb((unsigned char) (inb(dev->ioport[c] + 0x15) | 0x20), dev->ioport[c] + 0x15); dev->id[c][target_id].dirct = 0x20; - tmport += 0x03; - outb(0x08, tmport); + outb(0x08, dev->ioport[c] + 0x18); outb(0x01, tmpcip); dev->in_int[c] = 0; goto handled; } - tmport -= 0x07; if (i == 0x0a) { - outb(0x30, tmport); + outb(0x30, dev->ioport[c] + 0x10); } else { - outb(0x46, tmport); + outb(0x46, dev->ioport[c] + 0x10); } dev->id[c][target_id].dirct = 0x00; - tmport += 0x02; - outb(0x00, tmport++); - outb(0x00, tmport++); - outb(0x00, tmport++); - tmport += 0x03; - outb(0x08, tmport); + outb(0x00, dev->ioport[c] + 0x12); + outb(0x00, dev->ioport[c] + 0x13); + outb(0x00, dev->ioport[c] + 0x14); + outb(0x08, dev->ioport[c] + 0x18); dev->in_int[c] = 0; goto handled; } else { -// tmport = dev->ioport[c] + 0x17; -// inb(tmport); +// inb(dev->ioport[c] + 0x17); // dev->working[c] = 0; dev->in_int[c] = 0; goto handled; -- cgit v0.10.2 From 3b836464809aff2795c22ba2a97f3b148e70282e Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:40 +0100 Subject: atp870u: Untangle tmport #2 Untangle the tmport crap so it becomes obvious what ports are accessed. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index a25a300..7112337 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -562,7 +562,7 @@ static int atp870u_queuecommand_lck(struct scsi_cmnd *req_p, void (*done) (struct scsi_cmnd *)) { unsigned char c; - unsigned int tmport,m; + unsigned int m; struct atp_unit *dev; struct Scsi_Host *host; @@ -631,11 +631,10 @@ static int atp870u_queuecommand_lck(struct scsi_cmnd *req_p, return 0; } dev->quereq[c][dev->quend[c]] = req_p; - tmport = dev->ioport[c] + 0x1c; #ifdef ED_DBGP - printk("dev->ioport[c] = %x inb(tmport) = %x dev->in_int[%d] = %d dev->in_snd[%d] = %d\n",dev->ioport[c],inb(tmport),c,dev->in_int[c],c,dev->in_snd[c]); + printk("dev->ioport[c] = %x inb(dev->ioport[c] + 0x1c) = %x dev->in_int[%d] = %d dev->in_snd[%d] = %d\n",dev->ioport[c],inb(dev->ioport[c] + 0x1c),c,dev->in_int[c],c,dev->in_snd[c]); #endif - if ((inb(tmport) == 0) && (dev->in_int[c] == 0) && (dev->in_snd[c] == 0)) { + if ((inb(dev->ioport[c] + 0x1c) == 0) && (dev->in_int[c] == 0) && (dev->in_snd[c] == 0)) { #ifdef ED_DBGP printk("Call sent_s870(atp870u_queuecommand)\n"); #endif @@ -660,7 +659,6 @@ static DEF_SCSI_QCMD(atp870u_queuecommand) */ static void send_s870(struct atp_unit *dev,unsigned char c) { - unsigned int tmport; struct scsi_cmnd *workreq; unsigned int i;//,k; unsigned char j, target_id; @@ -712,12 +710,10 @@ static void send_s870(struct atp_unit *dev,unsigned char c) dev->in_snd[c] = 0; return; cmd_subp: - tmport = dev->ioport[c] + 0x1f; - if ((inb(tmport) & 0xb0) != 0) { + if ((inb(dev->ioport[c] + 0x1f) & 0xb0) != 0) { goto abortsnd; } - tmport = dev->ioport[c] + 0x1c; - if (inb(tmport) == 0) { + if (inb(dev->ioport[c] + 0x1c) == 0) { goto oktosend; } abortsnd: @@ -752,7 +748,6 @@ oktosend: l = 0; } - tmport = dev->ioport[c] + 0x1b; j = 0; target_id = scmd_id(workreq); @@ -764,9 +759,9 @@ oktosend: if ((w & dev->wide_id[c]) != 0) { j |= 0x01; } - outb(j, tmport); - while ((inb(tmport) & 0x01) != j) { - outb(j,tmport); + outb(j, dev->ioport[c] + 0x1b); + while ((inb(dev->ioport[c] + 0x1b) & 0x01) != j) { + outb(j,dev->ioport[c] + 0x1b); #ifdef ED_DBGP printk("send_s870 while loop 1\n"); #endif @@ -775,24 +770,21 @@ oktosend: * Write the command */ - tmport = dev->ioport[c]; - outb(workreq->cmd_len, tmport++); - outb(0x2c, tmport++); + outb(workreq->cmd_len, dev->ioport[c] + 0x00); + outb(0x2c, dev->ioport[c] + 0x01); if (dev->dev_id == ATP885_DEVID) { - outb(0x7f, tmport++); + outb(0x7f, dev->ioport[c] + 0x02); } else { - outb(0xcf, tmport++); + outb(0xcf, dev->ioport[c] + 0x02); } for (i = 0; i < workreq->cmd_len; i++) { - outb(workreq->cmnd[i], tmport++); + outb(workreq->cmnd[i], dev->ioport[c] + 0x03 + i); } - tmport = dev->ioport[c] + 0x0f; - outb(workreq->device->lun, tmport); - tmport += 0x02; + outb(workreq->device->lun, dev->ioport[c] + 0x0f); /* * Write the target */ - outb(dev->id[c][target_id].devsp, tmport++); + outb(dev->id[c][target_id].devsp, dev->ioport[c] + 0x11); #ifdef ED_DBGP printk("dev->id[%d][%d].devsp = %2x\n",c,target_id,dev->id[c][target_id].devsp); #endif @@ -801,9 +793,9 @@ oktosend: /* * Write transfer size */ - outb((unsigned char) (((unsigned char *) (&l))[2]), tmport++); - outb((unsigned char) (((unsigned char *) (&l))[1]), tmport++); - outb((unsigned char) (((unsigned char *) (&l))[0]), tmport++); + outb((unsigned char) (((unsigned char *) (&l))[2]), dev->ioport[c] + 0x12); + outb((unsigned char) (((unsigned char *) (&l))[1]), dev->ioport[c] + 0x13); + outb((unsigned char) (((unsigned char *) (&l))[0]), dev->ioport[c] + 0x14); j = target_id; dev->id[c][j].last_len = l; dev->id[c][j].tran_len = 0; @@ -820,21 +812,19 @@ oktosend: * Check transfer direction */ if (workreq->sc_data_direction == DMA_TO_DEVICE) { - outb((unsigned char) (j | 0x20), tmport++); + outb((unsigned char) (j | 0x20), dev->ioport[c] + 0x15); } else { - outb(j, tmport++); + outb(j, dev->ioport[c] + 0x15); } - outb((unsigned char) (inb(tmport) | 0x80), tmport); - outb(0x80, tmport); - tmport = dev->ioport[c] + 0x1c; + outb((unsigned char) (inb(dev->ioport[c] + 0x16) | 0x80), dev->ioport[c] + 0x16); + outb(0x80, dev->ioport[c] + 0x16); dev->id[c][target_id].dirct = 0; if (l == 0) { - if (inb(tmport) == 0) { - tmport = dev->ioport[c] + 0x18; + if (inb(dev->ioport[c] + 0x1c) == 0) { #ifdef ED_DBGP printk("change SCSI_CMD_REG 0x08\n"); #endif - outb(0x08, tmport); + outb(0x08, dev->ioport[c] + 0x18); } else { dev->last_cmd[c] |= 0x40; } @@ -899,28 +889,24 @@ oktosend: } else if ((dev->dev_id == ATP880_DEVID1) || (dev->dev_id == ATP880_DEVID2)) { tmpcip =tmpcip -2; - tmport = dev->ioport[c] - 0x05; if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { - outb((unsigned char) ((inb(tmport) & 0x3f) | 0xc0), tmport); + outb((unsigned char) ((inb(dev->ioport[c] - 0x05) & 0x3f) | 0xc0), dev->ioport[c] - 0x05); } else { - outb((unsigned char) (inb(tmport) & 0x3f), tmport); + outb((unsigned char) (inb(dev->ioport[c] - 0x05) & 0x3f), dev->ioport[c] - 0x05); } } else { tmpcip =tmpcip -2; - tmport = dev->ioport[c] + 0x3a; if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { - outb((inb(tmport) & 0xf3) | 0x08, tmport); + outb((inb(dev->ioport[c] + 0x3a) & 0xf3) | 0x08, dev->ioport[c] + 0x3a); } else { - outb(inb(tmport) & 0xf3, tmport); + outb(inb(dev->ioport[c] + 0x3a) & 0xf3, dev->ioport[c] + 0x3a); } } - tmport = dev->ioport[c] + 0x1c; if(workreq->sc_data_direction == DMA_TO_DEVICE) { dev->id[c][target_id].dirct = 0x20; - if (inb(tmport) == 0) { - tmport = dev->ioport[c] + 0x18; - outb(0x08, tmport); + if (inb(dev->ioport[c] + 0x1c) == 0) { + outb(0x08, dev->ioport[c] + 0x18); outb(0x01, tmpcip); #ifdef ED_DBGP printk( "start DMA(to target)\n"); @@ -931,9 +917,8 @@ oktosend: dev->in_snd[c] = 0; return; } - if (inb(tmport) == 0) { - tmport = dev->ioport[c] + 0x18; - outb(0x08, tmport); + if (inb(dev->ioport[c] + 0x1c) == 0) { + outb(0x08, dev->ioport[c] + 0x18); outb(0x09, tmpcip); #ifdef ED_DBGP printk( "start DMA(to host)\n"); -- cgit v0.10.2 From 1940ed62f9ca6d0b1f4c10afef3960f4f8a7d327 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:41 +0100 Subject: atp870u: Untangle tmport #3 Untangle the tmport crap so it becomes obvious what ports are accessed. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 7112337..a23f387 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -933,38 +933,36 @@ oktosend: static unsigned char fun_scam(struct atp_unit *dev, unsigned short int *val) { - unsigned int tmport; unsigned short int i, k; unsigned char j; - tmport = dev->ioport[0] + 0x1c; - outw(*val, tmport); + outw(*val, dev->ioport[0] + 0x1c); FUN_D7: for (i = 0; i < 10; i++) { /* stable >= bus settle delay(400 ns) */ - k = inw(tmport); + k = inw(dev->ioport[0] + 0x1c); j = (unsigned char) (k >> 8); if ((k & 0x8000) != 0) { /* DB7 all release? */ goto FUN_D7; } } *val |= 0x4000; /* assert DB6 */ - outw(*val, tmport); + outw(*val, dev->ioport[0] + 0x1c); *val &= 0xdfff; /* assert DB5 */ - outw(*val, tmport); + outw(*val, dev->ioport[0] + 0x1c); FUN_D5: for (i = 0; i < 10; i++) { /* stable >= bus settle delay(400 ns) */ - if ((inw(tmport) & 0x2000) != 0) { /* DB5 all release? */ + if ((inw(dev->ioport[0] + 0x1c) & 0x2000) != 0) { /* DB5 all release? */ goto FUN_D5; } } *val |= 0x8000; /* no DB4-0, assert DB7 */ *val &= 0xe0ff; - outw(*val, tmport); + outw(*val, dev->ioport[0] + 0x1c); *val &= 0xbfff; /* release DB6 */ - outw(*val, tmport); + outw(*val, dev->ioport[0] + 0x1c); FUN_D6: for (i = 0; i < 10; i++) { /* stable >= bus settle delay(400 ns) */ - if ((inw(tmport) & 0x4000) != 0) { /* DB6 all release? */ + if ((inw(dev->ioport[0] + 0x1c) & 0x4000) != 0) { /* DB6 all release? */ goto FUN_D6; } } @@ -975,7 +973,6 @@ FUN_D6: static void tscam(struct Scsi_Host *host) { - unsigned int tmport; unsigned char i, j, k; unsigned long n; unsigned short int m, assignid_map, val; @@ -992,11 +989,9 @@ static void tscam(struct Scsi_Host *host) } */ - tmport = dev->ioport[0] + 1; - outb(0x08, tmport++); - outb(0x7f, tmport); - tmport = dev->ioport[0] + 0x11; - outb(0x20, tmport); + outb(0x08, dev->ioport[0] + 1); + outb(0x7f, dev->ioport[0] + 2); + outb(0x20, dev->ioport[0] + 0x11); if ((dev->scam_on & 0x40) == 0) { return; @@ -1009,14 +1004,13 @@ static void tscam(struct Scsi_Host *host) j = 8; } assignid_map = m; - tmport = dev->ioport[0] + 0x02; - outb(0x02, tmport++); /* 2*2=4ms,3EH 2/32*3E=3.9ms */ - outb(0, tmport++); - outb(0, tmport++); - outb(0, tmport++); - outb(0, tmport++); - outb(0, tmport++); - outb(0, tmport++); + outb(0x02, dev->ioport[0] + 0x02); /* 2*2=4ms,3EH 2/32*3E=3.9ms */ + outb(0, dev->ioport[0] + 0x03); + outb(0, dev->ioport[0] + 0x04); + outb(0, dev->ioport[0] + 0x05); + outb(0, dev->ioport[0] + 0x06); + outb(0, dev->ioport[0] + 0x07); + outb(0, dev->ioport[0] + 0x08); for (i = 0; i < j; i++) { m = 1; @@ -1024,79 +1018,69 @@ static void tscam(struct Scsi_Host *host) if ((m & assignid_map) != 0) { continue; } - tmport = dev->ioport[0] + 0x0f; - outb(0, tmport++); - tmport += 0x02; - outb(0, tmport++); - outb(0, tmport++); - outb(0, tmport++); + outb(0, dev->ioport[0] + 0x0f); + outb(0, dev->ioport[0] + 0x12); + outb(0, dev->ioport[0] + 0x13); + outb(0, dev->ioport[0] + 0x14); if (i > 7) { k = (i & 0x07) | 0x40; } else { k = i; } - outb(k, tmport++); - tmport = dev->ioport[0] + 0x1b; + outb(k, dev->ioport[0] + 0x15); if (dev->chip_ver == 4) { - outb(0x01, tmport); + outb(0x01, dev->ioport[0] + 0x1b); } else { - outb(0x00, tmport); + outb(0x00, dev->ioport[0] + 0x1b); } wait_rdyok: - tmport = dev->ioport[0] + 0x18; - outb(0x09, tmport); - tmport += 0x07; + outb(0x09, dev->ioport[0] + 0x18); - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(dev->ioport[0] + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - k = inb(tmport); + k = inb(dev->ioport[0] + 0x17); if (k != 0x16) { if ((k == 0x85) || (k == 0x42)) { continue; } - tmport = dev->ioport[0] + 0x10; - outb(0x41, tmport); + outb(0x41, dev->ioport[0] + 0x10); goto wait_rdyok; } assignid_map |= m; } - tmport = dev->ioport[0] + 0x02; - outb(0x7f, tmport); - tmport = dev->ioport[0] + 0x1b; - outb(0x02, tmport); + outb(0x7f, dev->ioport[0] + 0x02); + outb(0x02, dev->ioport[0] + 0x1b); outb(0, 0x80); val = 0x0080; /* bsy */ - tmport = dev->ioport[0] + 0x1c; - outw(val, tmport); + outw(val, dev->ioport[0] + 0x1c); val |= 0x0040; /* sel */ - outw(val, tmport); + outw(val, dev->ioport[0] + 0x1c); val |= 0x0004; /* msg */ - outw(val, tmport); + outw(val, dev->ioport[0] + 0x1c); inb(0x80); /* 2 deskew delay(45ns*2=90ns) */ val &= 0x007f; /* no bsy */ - outw(val, tmport); + outw(val, dev->ioport[0] + 0x1c); mdelay(128); val &= 0x00fb; /* after 1ms no msg */ - outw(val, tmport); + outw(val, dev->ioport[0] + 0x1c); wait_nomsg: - if ((inb(tmport) & 0x04) != 0) { + if ((inb(dev->ioport[0] + 0x1c) & 0x04) != 0) { goto wait_nomsg; } outb(1, 0x80); udelay(100); for (n = 0; n < 0x30000; n++) { - if ((inb(tmport) & 0x80) != 0) { /* bsy ? */ + if ((inb(dev->ioport[0] + 0x1c) & 0x80) != 0) { /* bsy ? */ goto wait_io; } } goto TCM_SYNC; wait_io: for (n = 0; n < 0x30000; n++) { - if ((inb(tmport) & 0x81) == 0x0081) { + if ((inb(dev->ioport[0] + 0x1c) & 0x81) == 0x0081) { goto wait_io1; } } @@ -1104,10 +1088,10 @@ wait_io: wait_io1: inb(0x80); val |= 0x8003; /* io,cd,db7 */ - outw(val, tmport); + outw(val, dev->ioport[0] + 0x1c); inb(0x80); val &= 0x00bf; /* no sel */ - outw(val, tmport); + outw(val, dev->ioport[0] + 0x1c); outb(2, 0x80); TCM_SYNC: /* @@ -1120,18 +1104,14 @@ TCM_SYNC: */ mdelay(2); udelay(48); - if ((inb(tmport) & 0x80) == 0x00) { /* bsy ? */ - outw(0, tmport--); - outb(0, tmport); - tmport = dev->ioport[0] + 0x15; - outb(0, tmport); - tmport += 0x03; - outb(0x09, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0) + if ((inb(dev->ioport[0] + 0x1c) & 0x80) == 0x00) { /* bsy ? */ + outw(0, dev->ioport[0] + 0x1c); + outb(0, dev->ioport[0] + 0x1b); + outb(0, dev->ioport[0] + 0x15); + outb(0x09, dev->ioport[0] + 0x18); + while ((inb(dev->ioport[0] + 0x1f) & 0x80) == 0) cpu_relax(); - tmport -= 0x08; - inb(tmport); + inb(dev->ioport[0] + 0x17); return; } val &= 0x00ff; /* synchronization */ @@ -1145,7 +1125,7 @@ TCM_SYNC: i = 8; j = 0; TCM_ID: - if ((inw(tmport) & 0x2000) == 0) { + if ((inw(dev->ioport[0] + 0x1c) & 0x2000) == 0) { goto TCM_ID; } outb(5, 0x80); -- cgit v0.10.2 From ea41ed600b261fec87820c1aa2455942dcfa1ce7 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:42 +0100 Subject: atp870u: Untangle tmport #4 Untangle the tmport crap so it becomes obvious what ports are accessed. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index a23f387..3e3a68b 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1207,7 +1207,6 @@ G2Q_QUIN: /* k=binID#, */ static void is870(struct atp_unit *dev, unsigned int wkport) { - unsigned int tmport; unsigned char i, j, k, rmb, n; unsigned short int m; static unsigned char mbuf[512]; @@ -1218,8 +1217,7 @@ static void is870(struct atp_unit *dev, unsigned int wkport) static unsigned char synw[6] = { 0x80, 1, 3, 1, 0x0c, 0x07 }; static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 }; - tmport = wkport + 0x3a; - outb((unsigned char) (inb(tmport) | 0x10), tmport); + outb((unsigned char) (inb(wkport + 0x3a) | 0x10), wkport + 0x3a); for (i = 0; i < 16; i++) { if ((dev->chip_ver != 4) && (i > 7)) { @@ -1234,135 +1232,105 @@ static void is870(struct atp_unit *dev, unsigned int wkport) printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_id[0]); continue; } - tmport = wkport + 0x1b; if (dev->chip_ver == 4) { - outb(0x01, tmport); + outb(0x01, wkport + 0x1b); } else { - outb(0x00, tmport); - } - tmport = wkport + 1; - outb(0x08, tmport++); - outb(0x7f, tmport++); - outb(satn[0], tmport++); - outb(satn[1], tmport++); - outb(satn[2], tmport++); - outb(satn[3], tmport++); - outb(satn[4], tmport++); - outb(satn[5], tmport++); - tmport += 0x06; - outb(0, tmport); - tmport += 0x02; - outb(dev->id[0][i].devsp, tmport++); - outb(0, tmport++); - outb(satn[6], tmport++); - outb(satn[7], tmport++); + outb(0x00, wkport + 0x1b); + } + outb(0x08, wkport + 1); + outb(0x7f, wkport + 2); + outb(satn[0], wkport + 3); + outb(satn[1], wkport + 4); + outb(satn[2], wkport + 5); + outb(satn[3], wkport + 6); + outb(satn[4], wkport + 7); + outb(satn[5], wkport + 8); + outb(0, wkport + 0x0f); + outb(dev->id[0][i].devsp, wkport + 0x11); + outb(0, wkport + 0x12); + outb(satn[6], wkport + 0x13); + outb(satn[7], wkport + 0x14); j = i; if ((j & 0x08) != 0) { j = (j & 0x07) | 0x40; } - outb(j, tmport); - tmport += 0x03; - outb(satn[8], tmport); - tmport += 0x07; + outb(j, wkport + 0x15); + outb(satn[8], wkport + 0x18); - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - if (inb(tmport) != 0x11 && inb(tmport) != 0x8e) + if (inb(wkport + 0x17) != 0x11 && inb(wkport + 0x17) != 0x8e) continue; - while (inb(tmport) != 0x8e) + while (inb(wkport + 0x17) != 0x8e) cpu_relax(); dev->active_id[0] |= m; - tmport = wkport + 0x10; - outb(0x30, tmport); - tmport = wkport + 0x04; - outb(0x00, tmport); + outb(0x30, wkport + 0x10); + outb(0x00, wkport + 0x04); phase_cmd: - tmport = wkport + 0x18; - outb(0x08, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0x00) + outb(0x08, wkport + 0x18); + while ((inb(wkport + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - j = inb(tmport); + j = inb(wkport + 0x17); if (j != 0x16) { - tmport = wkport + 0x10; - outb(0x41, tmport); + outb(0x41, wkport + 0x10); goto phase_cmd; } sel_ok: - tmport = wkport + 3; - outb(inqd[0], tmport++); - outb(inqd[1], tmport++); - outb(inqd[2], tmport++); - outb(inqd[3], tmport++); - outb(inqd[4], tmport++); - outb(inqd[5], tmport); - tmport += 0x07; - outb(0, tmport); - tmport += 0x02; - outb(dev->id[0][i].devsp, tmport++); - outb(0, tmport++); - outb(inqd[6], tmport++); - outb(inqd[7], tmport++); - tmport += 0x03; - outb(inqd[8], tmport); - tmport += 0x07; - - while ((inb(tmport) & 0x80) == 0x00) + outb(inqd[0], wkport + 3); + outb(inqd[1], wkport + 4); + outb(inqd[2], wkport + 5); + outb(inqd[3], wkport + 6); + outb(inqd[4], wkport + 7); + outb(inqd[5], wkport + 8); + outb(0, wkport + 0x0f); + outb(dev->id[0][i].devsp, wkport + 0x11); + outb(0, wkport + 0x12); + outb(inqd[6], wkport + 0x13); + outb(inqd[7], wkport + 0x14); + outb(inqd[8], wkport + 0x18); + + while ((inb(wkport + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - if (inb(tmport) != 0x11 && inb(tmport) != 0x8e) + if (inb(wkport + 0x17) != 0x11 && inb(wkport + 0x17) != 0x8e) continue; - while (inb(tmport) != 0x8e) + while (inb(wkport + 0x17) != 0x8e) cpu_relax(); - tmport = wkport + 0x1b; if (dev->chip_ver == 4) - outb(0x00, tmport); + outb(0x00, wkport + 0x1b); - tmport = wkport + 0x18; - outb(0x08, tmport); - tmport += 0x07; + outb(0x08, wkport + 0x18); j = 0; rd_inq_data: - k = inb(tmport); + k = inb(wkport + 0x1f); if ((k & 0x01) != 0) { - tmport -= 0x06; - mbuf[j++] = inb(tmport); - tmport += 0x06; + mbuf[j++] = inb(wkport + 0x19); goto rd_inq_data; } if ((k & 0x80) == 0) { goto rd_inq_data; } - tmport -= 0x08; - j = inb(tmport); + j = inb(wkport + 0x17); if (j == 0x16) { goto inq_ok; } - tmport = wkport + 0x10; - outb(0x46, tmport); - tmport += 0x02; - outb(0, tmport++); - outb(0, tmport++); - outb(0, tmport++); - tmport += 0x03; - outb(0x08, tmport); - tmport += 0x07; + outb(0x46, wkport + 0x10); + outb(0, wkport + 0x12); + outb(0, wkport + 0x13); + outb(0, wkport + 0x14); + outb(0x08, wkport + 0x18); - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - if (inb(tmport) != 0x16) { + if (inb(wkport + 0x17) != 0x16) { goto sel_ok; } inq_ok: @@ -1380,57 +1348,43 @@ inq_ok: if ((dev->global_map[0] & 0x20) == 0) { goto not_wide; } - tmport = wkport + 0x1b; - outb(0x01, tmport); - tmport = wkport + 3; - outb(satn[0], tmport++); - outb(satn[1], tmport++); - outb(satn[2], tmport++); - outb(satn[3], tmport++); - outb(satn[4], tmport++); - outb(satn[5], tmport++); - tmport += 0x06; - outb(0, tmport); - tmport += 0x02; - outb(dev->id[0][i].devsp, tmport++); - outb(0, tmport++); - outb(satn[6], tmport++); - outb(satn[7], tmport++); - tmport += 0x03; - outb(satn[8], tmport); - tmport += 0x07; - - while ((inb(tmport) & 0x80) == 0x00) + outb(0x01, wkport + 0x1b); + outb(satn[0], wkport + 3); + outb(satn[1], wkport + 4); + outb(satn[2], wkport + 5); + outb(satn[3], wkport + 6); + outb(satn[4], wkport + 7); + outb(satn[5], wkport + 8); + outb(0, wkport + 0x0f); + outb(dev->id[0][i].devsp, wkport + 0x11); + outb(0, wkport + 0x12); + outb(satn[6], wkport + 0x13); + outb(satn[7], wkport + 0x14); + outb(satn[8], wkport + 0x18); + + while ((inb(wkport + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - if (inb(tmport) != 0x11 && inb(tmport) != 0x8e) + if (inb(wkport + 0x17) != 0x11 && inb(wkport + 0x17) != 0x8e) continue; - while (inb(tmport) != 0x8e) + while (inb(wkport + 0x17) != 0x8e) cpu_relax(); try_wide: j = 0; - tmport = wkport + 0x14; - outb(0x05, tmport); - tmport += 0x04; - outb(0x20, tmport); - tmport += 0x07; + outb(0x05, wkport + 0x14); + outb(0x20, wkport + 0x18); - while ((inb(tmport) & 0x80) == 0) { - if ((inb(tmport) & 0x01) != 0) { - tmport -= 0x06; - outb(wide[j++], tmport); - tmport += 0x06; - } + while ((inb(wkport + 0x1f) & 0x80) == 0) { + if ((inb(wkport + 0x1f) & 0x01) != 0) + outb(wide[j++], wkport + 0x19); } - tmport -= 0x08; - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x17) & 0x80) == 0x00) cpu_relax(); - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -1442,18 +1396,12 @@ try_wide: } continue; widep_out: - tmport = wkport + 0x18; - outb(0x20, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0) { - if ((inb(tmport) & 0x01) != 0) { - tmport -= 0x06; - outb(0, tmport); - tmport += 0x06; - } + outb(0x20, wkport + 0x18); + while ((inb(wkport + 0x1f) & 0x80) == 0) { + if ((inb(wkport + 0x1f) & 0x01) != 0) + outb(0, wkport + 0x19); } - tmport -= 0x08; - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -1465,25 +1413,19 @@ widep_out: } continue; widep_in: - tmport = wkport + 0x14; - outb(0xff, tmport); - tmport += 0x04; - outb(0x20, tmport); - tmport += 0x07; + outb(0xff, wkport + 0x14); + outb(0x20, wkport + 0x18); k = 0; widep_in1: - j = inb(tmport); + j = inb(wkport + 0x1f); if ((j & 0x01) != 0) { - tmport -= 0x06; - mbuf[k++] = inb(tmport); - tmport += 0x06; + mbuf[k++] = inb(wkport + 0x19); goto widep_in1; } if ((j & 0x80) == 0x00) { goto widep_in1; } - tmport -= 0x08; - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -1495,19 +1437,14 @@ widep_in1: } continue; widep_cmd: - tmport = wkport + 0x10; - outb(0x30, tmport); - tmport = wkport + 0x14; - outb(0x00, tmport); - tmport += 0x04; - outb(0x08, tmport); - tmport += 0x07; + outb(0x30, wkport + 0x10); + outb(0x00, wkport + 0x14); + outb(0x08, wkport + 0x18); - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - j = inb(tmport); + j = inb(wkport + 0x17); if (j != 0x16) { if (j == 0x4e) { goto widep_out; @@ -1535,69 +1472,56 @@ not_wide: } continue; set_sync: - tmport = wkport + 0x1b; j = 0; if ((m & dev->wide_id[0]) != 0) { j |= 0x01; } - outb(j, tmport); - tmport = wkport + 3; - outb(satn[0], tmport++); - outb(satn[1], tmport++); - outb(satn[2], tmport++); - outb(satn[3], tmport++); - outb(satn[4], tmport++); - outb(satn[5], tmport++); - tmport += 0x06; - outb(0, tmport); - tmport += 0x02; - outb(dev->id[0][i].devsp, tmport++); - outb(0, tmport++); - outb(satn[6], tmport++); - outb(satn[7], tmport++); - tmport += 0x03; - outb(satn[8], tmport); - tmport += 0x07; - - while ((inb(tmport) & 0x80) == 0x00) + outb(j, wkport + 0x1b); + outb(satn[0], wkport + 3); + outb(satn[1], wkport + 4); + outb(satn[2], wkport + 5); + outb(satn[3], wkport + 6); + outb(satn[4], wkport + 7); + outb(satn[5], wkport + 8); + outb(0, wkport + 0x0f); + outb(dev->id[0][i].devsp, wkport + 0x11); + outb(0, wkport + 0x12); + outb(satn[6], wkport + 0x13); + outb(satn[7], wkport + 0x14); + outb(satn[8], wkport + 0x18); + + while ((inb(wkport + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - if (inb(tmport) != 0x11 && inb(tmport) != 0x8e) + if (inb(wkport + 0x17) != 0x11 && inb(wkport + 0x17) != 0x8e) continue; - while (inb(tmport) != 0x8e) + while (inb(wkport + 0x17) != 0x8e) cpu_relax(); try_sync: j = 0; - tmport = wkport + 0x14; - outb(0x06, tmport); - tmport += 0x04; - outb(0x20, tmport); - tmport += 0x07; + outb(0x06, wkport + 0x14); + outb(0x20, wkport + 0x18); - while ((inb(tmport) & 0x80) == 0) { - if ((inb(tmport) & 0x01) != 0) { - tmport -= 0x06; + while ((inb(wkport + 0x1f) & 0x80) == 0) { + if ((inb(wkport + 0x1f) & 0x01) != 0) { if ((m & dev->wide_id[0]) != 0) { - outb(synw[j++], tmport); + outb(synw[j++], wkport + 0x19); } else { if ((m & dev->ultra_map[0]) != 0) { - outb(synu[j++], tmport); + outb(synu[j++], wkport + 0x19); } else { - outb(synn[j++], tmport); + outb(synn[j++], wkport + 0x19); } } - tmport += 0x06; } } - tmport -= 0x08; - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x17) & 0x80) == 0x00) cpu_relax(); - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x17) & 0x0f; if (j == 0x0f) { goto phase_ins; } @@ -1609,18 +1533,12 @@ try_sync: } continue; phase_outs: - tmport = wkport + 0x18; - outb(0x20, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0x00) { - if ((inb(tmport) & 0x01) != 0x00) { - tmport -= 0x06; - outb(0x00, tmport); - tmport += 0x06; - } + outb(0x20, wkport + 0x18); + while ((inb(wkport + 0x1f) & 0x80) == 0x00) { + if ((inb(wkport + 0x1f) & 0x01) != 0x00) + outb(0x00, wkport + 0x19); } - tmport -= 0x08; - j = inb(tmport); + j = inb(wkport + 0x17); if (j == 0x85) { goto tar_dcons; } @@ -1636,29 +1554,23 @@ phase_outs: } continue; phase_ins: - tmport = wkport + 0x14; - outb(0xff, tmport); - tmport += 0x04; - outb(0x20, tmport); - tmport += 0x07; + outb(0xff, wkport + 0x14); + outb(0x20, wkport + 0x18); k = 0; phase_ins1: - j = inb(tmport); + j = inb(wkport + 0x1f); if ((j & 0x01) != 0x00) { - tmport -= 0x06; - mbuf[k++] = inb(tmport); - tmport += 0x06; + mbuf[k++] = inb(wkport + 0x19); goto phase_ins1; } if ((j & 0x80) == 0x00) { goto phase_ins1; } - tmport -= 0x08; - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x17) & 0x80) == 0x00) cpu_relax(); - j = inb(tmport); + j = inb(wkport + 0x17); if (j == 0x85) { goto tar_dcons; } @@ -1674,20 +1586,15 @@ phase_ins1: } continue; phase_cmds: - tmport = wkport + 0x10; - outb(0x30, tmport); + outb(0x30, wkport + 0x10); tar_dcons: - tmport = wkport + 0x14; - outb(0x00, tmport); - tmport += 0x04; - outb(0x08, tmport); - tmport += 0x07; + outb(0x00, wkport + 0x14); + outb(0x08, wkport + 0x18); - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - j = inb(tmport); + j = inb(wkport + 0x17); if (j != 0x16) { continue; } @@ -1727,8 +1634,7 @@ tar_dcons: set_syn_ok: dev->id[0][i].devsp = (dev->id[0][i].devsp & 0x0f) | j; } - tmport = wkport + 0x3a; - outb((unsigned char) (inb(tmport) & 0xef), tmport); + outb((unsigned char) (inb(wkport + 0x3a) & 0xef), wkport + 0x3a); } static void is880(struct atp_unit *dev, unsigned int wkport) -- cgit v0.10.2 From 3b30acf6a8989dc1a98f959d3c7743790eab00df Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:43 +0100 Subject: atp870u: Untangle tmport #5 Untangle the tmport crap so it becomes obvious what ports are accessed. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 3e3a68b..3bf01fc 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1639,7 +1639,6 @@ set_syn_ok: static void is880(struct atp_unit *dev, unsigned int wkport) { - unsigned int tmport; unsigned char i, j, k, rmb, n, lvdmode; unsigned short int m; static unsigned char mbuf[512]; @@ -1664,130 +1663,100 @@ static void is880(struct atp_unit *dev, unsigned int wkport) printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_id[0]); continue; } - tmport = wkport + 0x5b; - outb(0x01, tmport); - tmport = wkport + 0x41; - outb(0x08, tmport++); - outb(0x7f, tmport++); - outb(satn[0], tmport++); - outb(satn[1], tmport++); - outb(satn[2], tmport++); - outb(satn[3], tmport++); - outb(satn[4], tmport++); - outb(satn[5], tmport++); - tmport += 0x06; - outb(0, tmport); - tmport += 0x02; - outb(dev->id[0][i].devsp, tmport++); - outb(0, tmport++); - outb(satn[6], tmport++); - outb(satn[7], tmport++); + outb(0x01, wkport + 0x5b); + outb(0x08, wkport + 0x41); + outb(0x7f, wkport + 0x42); + outb(satn[0], wkport + 0x43); + outb(satn[1], wkport + 0x44); + outb(satn[2], wkport + 0x45); + outb(satn[3], wkport + 0x46); + outb(satn[4], wkport + 0x47); + outb(satn[5], wkport + 0x48); + outb(0, wkport + 0x4f); + outb(dev->id[0][i].devsp, wkport + 0x51); + outb(0, wkport + 0x52); + outb(satn[6], wkport + 0x53); + outb(satn[7], wkport + 0x54); j = i; if ((j & 0x08) != 0) { j = (j & 0x07) | 0x40; } - outb(j, tmport); - tmport += 0x03; - outb(satn[8], tmport); - tmport += 0x07; + outb(j, wkport + 0x55); + outb(satn[8], wkport + 0x58); - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x5f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - if (inb(tmport) != 0x11 && inb(tmport) != 0x8e) + if (inb(wkport + 0x57) != 0x11 && inb(wkport + 0x57) != 0x8e) continue; - while (inb(tmport) != 0x8e) + while (inb(wkport + 0x57) != 0x8e) cpu_relax(); dev->active_id[0] |= m; - tmport = wkport + 0x50; - outb(0x30, tmport); - tmport = wkport + 0x54; - outb(0x00, tmport); + outb(0x30, wkport + 0x50); + outb(0x00, wkport + 0x54); phase_cmd: - tmport = wkport + 0x58; - outb(0x08, tmport); - tmport += 0x07; + outb(0x08, wkport + 0x58); - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x5f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - j = inb(tmport); + j = inb(wkport + 0x57); if (j != 0x16) { - tmport = wkport + 0x50; - outb(0x41, tmport); + outb(0x41, wkport + 0x50); goto phase_cmd; } sel_ok: - tmport = wkport + 0x43; - outb(inqd[0], tmport++); - outb(inqd[1], tmport++); - outb(inqd[2], tmport++); - outb(inqd[3], tmport++); - outb(inqd[4], tmport++); - outb(inqd[5], tmport); - tmport += 0x07; - outb(0, tmport); - tmport += 0x02; - outb(dev->id[0][i].devsp, tmport++); - outb(0, tmport++); - outb(inqd[6], tmport++); - outb(inqd[7], tmport++); - tmport += 0x03; - outb(inqd[8], tmport); - tmport += 0x07; + outb(inqd[0], wkport + 0x43); + outb(inqd[1], wkport + 0x44); + outb(inqd[2], wkport + 0x45); + outb(inqd[3], wkport + 0x46); + outb(inqd[4], wkport + 0x47); + outb(inqd[5], wkport + 0x48); + outb(0, wkport + 0x4f); + outb(dev->id[0][i].devsp, wkport + 0x51); + outb(0, wkport + 0x52); + outb(inqd[6], wkport + 0x53); + outb(inqd[7], wkport + 0x54); + outb(inqd[8], wkport + 0x58); - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x5f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - if (inb(tmport) != 0x11 && inb(tmport) != 0x8e) + if (inb(wkport + 0x57) != 0x11 && inb(wkport + 0x57) != 0x8e) continue; - while (inb(tmport) != 0x8e) + while (inb(wkport + 0x57) != 0x8e) cpu_relax(); - tmport = wkport + 0x5b; - outb(0x00, tmport); - tmport = wkport + 0x58; - outb(0x08, tmport); - tmport += 0x07; + outb(0x00, wkport + 0x5b); + outb(0x08, wkport + 0x58); j = 0; rd_inq_data: - k = inb(tmport); + k = inb(wkport + 0x5f); if ((k & 0x01) != 0) { - tmport -= 0x06; - mbuf[j++] = inb(tmport); - tmport += 0x06; + mbuf[j++] = inb(wkport + 0x59); goto rd_inq_data; } if ((k & 0x80) == 0) { goto rd_inq_data; } - tmport -= 0x08; - j = inb(tmport); + j = inb(wkport + 0x57); if (j == 0x16) { goto inq_ok; } - tmport = wkport + 0x50; - outb(0x46, tmport); - tmport += 0x02; - outb(0, tmport++); - outb(0, tmport++); - outb(0, tmport++); - tmport += 0x03; - outb(0x08, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0x00) + outb(0x46, wkport + 0x50); + outb(0, wkport + 0x52); + outb(0, wkport + 0x53); + outb(0, wkport + 0x54); + outb(0x08, wkport + 0x58); + while ((inb(wkport + 0x5f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - if (inb(tmport) != 0x16) + if (inb(wkport + 0x57) != 0x16) goto sel_ok; inq_ok: @@ -1810,58 +1779,43 @@ inq_ok: goto chg_wide; } - tmport = wkport + 0x5b; - outb(0x01, tmport); - tmport = wkport + 0x43; - outb(satn[0], tmport++); - outb(satn[1], tmport++); - outb(satn[2], tmport++); - outb(satn[3], tmport++); - outb(satn[4], tmport++); - outb(satn[5], tmport++); - tmport += 0x06; - outb(0, tmport); - tmport += 0x02; - outb(dev->id[0][i].devsp, tmport++); - outb(0, tmport++); - outb(satn[6], tmport++); - outb(satn[7], tmport++); - tmport += 0x03; - outb(satn[8], tmport); - tmport += 0x07; - - while ((inb(tmport) & 0x80) == 0x00) + outb(0x01, wkport + 0x5b); + outb(satn[0], wkport + 0x43); + outb(satn[1], wkport + 0x44); + outb(satn[2], wkport + 0x45); + outb(satn[3], wkport + 0x46); + outb(satn[4], wkport + 0x47); + outb(satn[5], wkport + 0x48); + outb(0, wkport + 0x4f); + outb(dev->id[0][i].devsp, wkport + 0x51); + outb(0, wkport + 0x52); + outb(satn[6], wkport + 0x53); + outb(satn[7], wkport + 0x54); + outb(satn[8], wkport + 0x58); + + while ((inb(wkport + 0x5f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - - if (inb(tmport) != 0x11 && inb(tmport) != 0x8e) + if (inb(wkport + 0x57) != 0x11 && inb(wkport + 0x57) != 0x8e) continue; - while (inb(tmport) != 0x8e) + while (inb(wkport + 0x57) != 0x8e) cpu_relax(); try_u3: j = 0; - tmport = wkport + 0x54; - outb(0x09, tmport); - tmport += 0x04; - outb(0x20, tmport); - tmport += 0x07; + outb(0x09, wkport + 0x54); + outb(0x20, wkport + 0x58); - while ((inb(tmport) & 0x80) == 0) { - if ((inb(tmport) & 0x01) != 0) { - tmport -= 0x06; - outb(u3[j++], tmport); - tmport += 0x06; - } + while ((inb(wkport + 0x5f) & 0x80) == 0) { + if ((inb(wkport + 0x5f) & 0x01) != 0) + outb(u3[j++], wkport + 0x59); } - tmport -= 0x08; - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x57) & 0x80) == 0x00) cpu_relax(); - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x57) & 0x0f; if (j == 0x0f) { goto u3p_in; } @@ -1873,18 +1827,12 @@ try_u3: } continue; u3p_out: - tmport = wkport + 0x58; - outb(0x20, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0) { - if ((inb(tmport) & 0x01) != 0) { - tmport -= 0x06; - outb(0, tmport); - tmport += 0x06; - } + outb(0x20, wkport + 0x58); + while ((inb(wkport + 0x5f) & 0x80) == 0) { + if ((inb(wkport + 0x5f) & 0x01) != 0) + outb(0, wkport + 0x59); } - tmport -= 0x08; - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x57) & 0x0f; if (j == 0x0f) { goto u3p_in; } @@ -1896,25 +1844,19 @@ u3p_out: } continue; u3p_in: - tmport = wkport + 0x54; - outb(0x09, tmport); - tmport += 0x04; - outb(0x20, tmport); - tmport += 0x07; + outb(0x09, wkport + 0x54); + outb(0x20, wkport + 0x58); k = 0; u3p_in1: - j = inb(tmport); + j = inb(wkport + 0x5f); if ((j & 0x01) != 0) { - tmport -= 0x06; - mbuf[k++] = inb(tmport); - tmport += 0x06; + mbuf[k++] = inb(wkport + 0x59); goto u3p_in1; } if ((j & 0x80) == 0x00) { goto u3p_in1; } - tmport -= 0x08; - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x57) & 0x0f; if (j == 0x0f) { goto u3p_in; } @@ -1926,19 +1868,14 @@ u3p_in1: } continue; u3p_cmd: - tmport = wkport + 0x50; - outb(0x30, tmport); - tmport = wkport + 0x54; - outb(0x00, tmport); - tmport += 0x04; - outb(0x08, tmport); - tmport += 0x07; + outb(0x30, wkport + 0x50); + outb(0x00, wkport + 0x54); + outb(0x08, wkport + 0x58); - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x5f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - j = inb(tmport); + j = inb(wkport + 0x57); if (j != 0x16) { if (j == 0x4e) { goto u3p_out; @@ -1962,56 +1899,42 @@ u3p_cmd: continue; } chg_wide: - tmport = wkport + 0x5b; - outb(0x01, tmport); - tmport = wkport + 0x43; - outb(satn[0], tmport++); - outb(satn[1], tmport++); - outb(satn[2], tmport++); - outb(satn[3], tmport++); - outb(satn[4], tmport++); - outb(satn[5], tmport++); - tmport += 0x06; - outb(0, tmport); - tmport += 0x02; - outb(dev->id[0][i].devsp, tmport++); - outb(0, tmport++); - outb(satn[6], tmport++); - outb(satn[7], tmport++); - tmport += 0x03; - outb(satn[8], tmport); - tmport += 0x07; - - while ((inb(tmport) & 0x80) == 0x00) + outb(0x01, wkport + 0x5b); + outb(satn[0], wkport + 0x43); + outb(satn[1], wkport + 0x44); + outb(satn[2], wkport + 0x45); + outb(satn[3], wkport + 0x46); + outb(satn[4], wkport + 0x47); + outb(satn[5], wkport + 0x48); + outb(0, wkport + 0x4f); + outb(dev->id[0][i].devsp, wkport + 0x51); + outb(0, wkport + 0x52); + outb(satn[6], wkport + 0x53); + outb(satn[7], wkport + 0x54); + outb(satn[8], wkport + 0x58); + + while ((inb(wkport + 0x5f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - if (inb(tmport) != 0x11 && inb(tmport) != 0x8e) + if (inb(wkport + 0x57) != 0x11 && inb(wkport + 0x57) != 0x8e) continue; - while (inb(tmport) != 0x8e) + while (inb(wkport + 0x57) != 0x8e) cpu_relax(); try_wide: j = 0; - tmport = wkport + 0x54; - outb(0x05, tmport); - tmport += 0x04; - outb(0x20, tmport); - tmport += 0x07; + outb(0x05, wkport + 0x54); + outb(0x20, wkport + 0x58); - while ((inb(tmport) & 0x80) == 0) { - if ((inb(tmport) & 0x01) != 0) { - tmport -= 0x06; - outb(wide[j++], tmport); - tmport += 0x06; - } + while ((inb(wkport + 0x5f) & 0x80) == 0) { + if ((inb(wkport + 0x5f) & 0x01) != 0) + outb(wide[j++], wkport + 0x59); } - tmport -= 0x08; - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x57) & 0x80) == 0x00) cpu_relax(); - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x57) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -2023,18 +1946,12 @@ try_wide: } continue; widep_out: - tmport = wkport + 0x58; - outb(0x20, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0) { - if ((inb(tmport) & 0x01) != 0) { - tmport -= 0x06; - outb(0, tmport); - tmport += 0x06; - } + outb(0x20, wkport + 0x58); + while ((inb(wkport + 0x5f) & 0x80) == 0) { + if ((inb(wkport + 0x5f) & 0x01) != 0) + outb(0, wkport + 0x59); } - tmport -= 0x08; - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x57) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -2046,25 +1963,19 @@ widep_out: } continue; widep_in: - tmport = wkport + 0x54; - outb(0xff, tmport); - tmport += 0x04; - outb(0x20, tmport); - tmport += 0x07; + outb(0xff, wkport + 0x54); + outb(0x20, wkport + 0x58); k = 0; widep_in1: - j = inb(tmport); + j = inb(wkport + 0x5f); if ((j & 0x01) != 0) { - tmport -= 0x06; - mbuf[k++] = inb(tmport); - tmport += 0x06; + mbuf[k++] = inb(wkport + 0x59); goto widep_in1; } if ((j & 0x80) == 0x00) { goto widep_in1; } - tmport -= 0x08; - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x57) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -2076,19 +1987,14 @@ widep_in1: } continue; widep_cmd: - tmport = wkport + 0x50; - outb(0x30, tmport); - tmport = wkport + 0x54; - outb(0x00, tmport); - tmport += 0x04; - outb(0x08, tmport); - tmport += 0x07; + outb(0x30, wkport + 0x50); + outb(0x00, wkport + 0x54); + outb(0x08, wkport + 0x58); - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x5f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - j = inb(tmport); + j = inb(wkport + 0x57); if (j != 0x16) { if (j == 0x4e) { goto widep_out; @@ -2129,73 +2035,60 @@ set_sync: synuw[4] = 0x0a; } } - tmport = wkport + 0x5b; j = 0; if ((m & dev->wide_id[0]) != 0) { j |= 0x01; } - outb(j, tmport); - tmport = wkport + 0x43; - outb(satn[0], tmport++); - outb(satn[1], tmport++); - outb(satn[2], tmport++); - outb(satn[3], tmport++); - outb(satn[4], tmport++); - outb(satn[5], tmport++); - tmport += 0x06; - outb(0, tmport); - tmport += 0x02; - outb(dev->id[0][i].devsp, tmport++); - outb(0, tmport++); - outb(satn[6], tmport++); - outb(satn[7], tmport++); - tmport += 0x03; - outb(satn[8], tmport); - tmport += 0x07; - - while ((inb(tmport) & 0x80) == 0x00) + outb(j, wkport + 0x5b); + outb(satn[0], wkport + 0x43); + outb(satn[1], wkport + 0x44); + outb(satn[2], wkport + 0x45); + outb(satn[3], wkport + 0x46); + outb(satn[4], wkport + 0x47); + outb(satn[5], wkport + 0x48); + outb(0, wkport + 0x4f); + outb(dev->id[0][i].devsp, wkport + 0x51); + outb(0, wkport + 0x52); + outb(satn[6], wkport + 0x53); + outb(satn[7], wkport + 0x54); + outb(satn[8], wkport + 0x58); + + while ((inb(wkport + 0x5f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) { + if ((inb(wkport + 0x57) != 0x11) && (inb(wkport + 0x57) != 0x8e)) { continue; } - while (inb(tmport) != 0x8e) + while (inb(wkport + 0x57) != 0x8e) cpu_relax(); try_sync: j = 0; - tmport = wkport + 0x54; - outb(0x06, tmport); - tmport += 0x04; - outb(0x20, tmport); - tmport += 0x07; + outb(0x06, wkport + 0x54); + outb(0x20, wkport + 0x58); - while ((inb(tmport) & 0x80) == 0) { - if ((inb(tmport) & 0x01) != 0) { - tmport -= 0x06; + while ((inb(wkport + 0x5f) & 0x80) == 0) { + if ((inb(wkport + 0x5f) & 0x01) != 0) { if ((m & dev->wide_id[0]) != 0) { if ((m & dev->ultra_map[0]) != 0) { - outb(synuw[j++], tmport); + outb(synuw[j++], wkport + 0x59); } else { - outb(synw[j++], tmport); + outb(synw[j++], wkport + 0x59); } } else { if ((m & dev->ultra_map[0]) != 0) { - outb(synu[j++], tmport); + outb(synu[j++], wkport + 0x59); } else { - outb(synn[j++], tmport); + outb(synn[j++], wkport + 0x59); } } - tmport += 0x06; } } - tmport -= 0x08; - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x57) & 0x80) == 0x00) cpu_relax(); - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x57) & 0x0f; if (j == 0x0f) { goto phase_ins; } @@ -2207,18 +2100,12 @@ try_sync: } continue; phase_outs: - tmport = wkport + 0x58; - outb(0x20, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0x00) { - if ((inb(tmport) & 0x01) != 0x00) { - tmport -= 0x06; - outb(0x00, tmport); - tmport += 0x06; - } + outb(0x20, wkport + 0x58); + while ((inb(wkport + 0x5f) & 0x80) == 0x00) { + if ((inb(wkport + 0x5f) & 0x01) != 0x00) + outb(0x00, wkport + 0x59); } - tmport -= 0x08; - j = inb(tmport); + j = inb(wkport + 0x57); if (j == 0x85) { goto tar_dcons; } @@ -2234,29 +2121,23 @@ phase_outs: } continue; phase_ins: - tmport = wkport + 0x54; - outb(0x06, tmport); - tmport += 0x04; - outb(0x20, tmport); - tmport += 0x07; + outb(0x06, wkport + 0x54); + outb(0x20, wkport + 0x58); k = 0; phase_ins1: - j = inb(tmport); + j = inb(wkport + 0x5f); if ((j & 0x01) != 0x00) { - tmport -= 0x06; - mbuf[k++] = inb(tmport); - tmport += 0x06; + mbuf[k++] = inb(wkport + 0x59); goto phase_ins1; } if ((j & 0x80) == 0x00) { goto phase_ins1; } - tmport -= 0x08; - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x57) & 0x80) == 0x00) cpu_relax(); - j = inb(tmport); + j = inb(wkport + 0x57); if (j == 0x85) { goto tar_dcons; } @@ -2272,20 +2153,15 @@ phase_ins1: } continue; phase_cmds: - tmport = wkport + 0x50; - outb(0x30, tmport); + outb(0x30, wkport + 0x50); tar_dcons: - tmport = wkport + 0x54; - outb(0x00, tmport); - tmport += 0x04; - outb(0x08, tmport); - tmport += 0x07; + outb(0x00, wkport + 0x54); + outb(0x08, wkport + 0x58); - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x5f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - j = inb(tmport); + j = inb(wkport + 0x57); if (j != 0x16) { continue; } -- cgit v0.10.2 From 493c5201933f39711569602dc938ac7054391b53 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:44 +0100 Subject: atp870u: Untangle tmport #6 Untangle the tmport crap so it becomes obvious what ports are accessed. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 3bf01fc..e398ea5 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -2264,7 +2264,7 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { unsigned char k, m, c; unsigned long flags; - unsigned int base_io, tmport, error,n; + unsigned int base_io, error,n; unsigned char host_id; struct Scsi_Host *shpnt = NULL; struct atp_unit *atpdev, *p; @@ -2322,12 +2322,9 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) atpdev->dev_id = ent->device; atpdev->host_id[0] = host_id; - tmport = base_io + 0x22; - atpdev->scam_on = inb(tmport); - tmport += 0x13; - atpdev->global_map[0] = inb(tmport); - tmport += 0x07; - atpdev->ultra_map[0] = inw(tmport); + atpdev->scam_on = inb(base_io + 0x22); + atpdev->global_map[0] = inb(base_io + 0x35); + atpdev->ultra_map[0] = inw(base_io + 0x3c); n = 0x3f09; next_fblk_880: @@ -2402,37 +2399,26 @@ flash_ok_880: } spin_lock_irqsave(shpnt->host_lock, flags); - tmport = base_io + 0x38; - k = inb(tmport) & 0x80; - outb(k, tmport); - tmport += 0x03; - outb(0x20, tmport); + k = inb(base_io + 0x38) & 0x80; + outb(k, base_io + 0x38); + outb(0x20, base_io + 0x3b); mdelay(32); - outb(0, tmport); + outb(0, base_io + 0x3b); mdelay(32); - tmport = base_io + 0x5b; - inb(tmport); - tmport -= 0x04; - inb(tmport); - tmport = base_io + 0x40; - outb((host_id | 0x08), tmport); - tmport += 0x18; - outb(0, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0) + inb(base_io + 0x5b); + inb(base_io + 0x57); + outb((host_id | 0x08), base_io + 0x40); + outb(0, base_io + 0x58); + while ((inb(base_io + 0x5f) & 0x80) == 0) mdelay(1); - tmport -= 0x08; - inb(tmport); - tmport = base_io + 0x41; - outb(8, tmport++); - outb(0x7f, tmport); - tmport = base_io + 0x51; - outb(0x20, tmport); + inb(base_io + 0x57); + outb(8, base_io + 0x41); + outb(0x7f, base_io + 0x42); + outb(0x20, base_io + 0x51); tscam(shpnt); is880(p, base_io); - tmport = base_io + 0x38; - outb(0xb0, tmport); + outb(0xb0, base_io + 0x38); shpnt->max_id = 16; shpnt->this_id = host_id; shpnt->unique_id = base_io; @@ -2546,47 +2532,35 @@ flash_ok_885: inb(base_io + 0x97); inb(base_io + 0xdb); inb(base_io + 0xd7); - tmport = base_io + 0x80; k=p->host_id[0]; if (k > 7) k = (k & 0x07) | 0x40; k |= 0x08; - outb(k, tmport); - tmport += 0x18; - outb(0, tmport); - tmport += 0x07; + outb(k, base_io + 0x80); + outb(0, base_io + 0x98); - while ((inb(tmport) & 0x80) == 0) + while ((inb(base_io + 0x9f) & 0x80) == 0) cpu_relax(); - tmport -= 0x08; - inb(tmport); - tmport = base_io + 0x81; - outb(8, tmport++); - outb(0x7f, tmport); - tmport = base_io + 0x91; - outb(0x20, tmport); + inb(base_io + 0x97); + outb(8, base_io + 0x81); + outb(0x7f, base_io + 0x82); + outb(0x20, base_io + 0x91); - tmport = base_io + 0xc0; k=p->host_id[1]; if (k > 7) k = (k & 0x07) | 0x40; k |= 0x08; - outb(k, tmport); - tmport += 0x18; - outb(0, tmport); - tmport += 0x07; + outb(k, base_io + 0xc0); + outb(0, base_io + 0xd8); - while ((inb(tmport) & 0x80) == 0) + while ((inb(base_io + 0xdf) & 0x80) == 0) cpu_relax(); - tmport -= 0x08; - inb(tmport); - tmport = base_io + 0xc1; - outb(8, tmport++); - outb(0x7f, tmport); - tmport = base_io + 0xd1; - outb(0x20, tmport); + inb(base_io + 0xd7); + outb(8, base_io + 0xc1); + outb(0x7f, base_io + 0xc2); + outb(0x20, base_io + 0xd1); tscam_885(); printk(KERN_INFO " Scanning Channel A SCSI Device ...\n"); @@ -2624,11 +2598,9 @@ flash_ok_885: atpdev->dev_id = ent->device; host_id &= 0x07; atpdev->host_id[0] = host_id; - tmport = base_io + 0x22; - atpdev->scam_on = inb(tmport); - tmport += 0x0b; - atpdev->global_map[0] = inb(tmport++); - atpdev->ultra_map[0] = inw(tmport); + atpdev->scam_on = inb(base_io + 0x22); + atpdev->global_map[0] = inb(base_io + 0x2d); + atpdev->ultra_map[0] = inw(base_io + 0x2e); if (atpdev->ultra_map[0] == 0) { atpdev->scam_on = 0x00; @@ -2656,39 +2628,29 @@ flash_ok_885: spin_lock_irqsave(shpnt->host_lock, flags); if (atpdev->chip_ver > 0x07) { /* check if atp876 chip then enable terminator */ - tmport = base_io + 0x3e; - outb(0x00, tmport); + outb(0x00, base_io + 0x3e); } - tmport = base_io + 0x3a; - k = (inb(tmport) & 0xf3) | 0x10; - outb(k, tmport); - outb((k & 0xdf), tmport); + k = (inb(base_io + 0x3a) & 0xf3) | 0x10; + outb(k, base_io + 0x3a); + outb((k & 0xdf), base_io + 0x3a); mdelay(32); - outb(k, tmport); + outb(k, base_io + 0x3a); mdelay(32); - tmport = base_io; - outb((host_id | 0x08), tmport); - tmport += 0x18; - outb(0, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0) + outb((host_id | 0x08), base_io + 0); + outb(0, base_io + 0x18); + while ((inb(base_io + 0x1f) & 0x80) == 0) mdelay(1); - tmport -= 0x08; - inb(tmport); - tmport = base_io + 1; - outb(8, tmport++); - outb(0x7f, tmport); - tmport = base_io + 0x11; - outb(0x20, tmport); + inb(base_io + 0x17); + outb(8, base_io + 1); + outb(0x7f, base_io + 2); + outb(0x20, base_io + 0x11); tscam(shpnt); is870(p, base_io); - tmport = base_io + 0x3a; - outb((inb(tmport) & 0xef), tmport); - tmport++; - outb((inb(tmport) | 0x20), tmport); + outb((inb(base_io + 0x3a) & 0xef), base_io + 0x3a); + outb((inb(base_io + 0x3b) | 0x20), base_io + 0x3b); if (atpdev->chip_ver == 4) shpnt->max_id = 16; else -- cgit v0.10.2 From 2eabdf22ad667742258ef7c55a965e56366bf74d Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:45 +0100 Subject: atp870u: Untangle tmport #7 Untangle the tmport crap so it becomes obvious what ports are accessed. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index e398ea5..f5a11f4 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -2716,7 +2716,6 @@ static int atp870u_abort(struct scsi_cmnd * SCpnt) { unsigned char j, k, c; struct scsi_cmnd *workrequ; - unsigned int tmport; struct atp_unit *dev; struct Scsi_Host *host; host = SCpnt->device->host; @@ -2726,18 +2725,13 @@ static int atp870u_abort(struct scsi_cmnd * SCpnt) printk(" atp870u: abort Channel = %x \n", c); printk("working=%x last_cmd=%x ", dev->working[c], dev->last_cmd[c]); printk(" quhdu=%x quendu=%x ", dev->quhd[c], dev->quend[c]); - tmport = dev->ioport[c]; for (j = 0; j < 0x18; j++) { - printk(" r%2x=%2x", j, inb(tmport++)); + printk(" r%2x=%2x", j, inb(dev->ioport[c] + j)); } - tmport += 0x04; - printk(" r1c=%2x", inb(tmport)); - tmport += 0x03; - printk(" r1f=%2x in_snd=%2x ", inb(tmport), dev->in_snd[c]); - tmport= dev->pciport[c]; - printk(" d00=%2x", inb(tmport)); - tmport += 0x02; - printk(" d02=%2x", inb(tmport)); + printk(" r1c=%2x", inb(dev->ioport[c] + 0x1c)); + printk(" r1f=%2x in_snd=%2x ", inb(dev->ioport[c] + 0x1f), dev->in_snd[c]); + printk(" d00=%2x", inb(dev->pciport[c])); + printk(" d02=%2x", inb(dev->pciport[c] + 0x02)); for(j=0;j<16;j++) { if (dev->id[c][j].curr_req != NULL) { workrequ = dev->id[c][j].curr_req; -- cgit v0.10.2 From e2c22b45cb8feb00f2b8296e277d98485882ed92 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:46 +0100 Subject: atp870u: Untangle tmport #8 Untangle the tmport crap so it becomes obvious what ports are accessed. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index f5a11f4..993442d 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -2870,7 +2870,6 @@ static void tscam_885(void) static void is885(struct atp_unit *dev, unsigned int wkport,unsigned char c) { - unsigned int tmport; unsigned char i, j, k, rmb, n, lvdmode; unsigned short int m; static unsigned char mbuf[512]; @@ -2895,123 +2894,93 @@ static void is885(struct atp_unit *dev, unsigned int wkport,unsigned char c) printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_id[c]); continue; } - tmport = wkport + 0x1b; - outb(0x01, tmport); - tmport = wkport + 0x01; - outb(0x08, tmport++); - outb(0x7f, tmport++); - outb(satn[0], tmport++); - outb(satn[1], tmport++); - outb(satn[2], tmport++); - outb(satn[3], tmport++); - outb(satn[4], tmport++); - outb(satn[5], tmport++); - tmport += 0x06; - outb(0, tmport); - tmport += 0x02; - outb(dev->id[c][i].devsp, tmport++); + outb(0x01, wkport + 0x1b); + outb(0x08, wkport + 0x01); + outb(0x7f, wkport + 0x02); + outb(satn[0], wkport + 0x03); + outb(satn[1], wkport + 0x04); + outb(satn[2], wkport + 0x05); + outb(satn[3], wkport + 0x06); + outb(satn[4], wkport + 0x07); + outb(satn[5], wkport + 0x08); + outb(0, wkport + 0x0f); + outb(dev->id[c][i].devsp, wkport + 0x11); - outb(0, tmport++); - outb(satn[6], tmport++); - outb(satn[7], tmport++); + outb(0, wkport + 0x12); + outb(satn[6], wkport + 0x13); + outb(satn[7], wkport + 0x14); j = i; if ((j & 0x08) != 0) { j = (j & 0x07) | 0x40; } - outb(j, tmport); - tmport += 0x03; - outb(satn[8], tmport); - tmport += 0x07; + outb(j, wkport + 0x15); + outb(satn[8], wkport + 0x18); - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) { + if ((inb(wkport + 0x17) != 0x11) && (inb(wkport + 0x17) != 0x8e)) { continue; } - while (inb(tmport) != 0x8e) + while (inb(wkport + 0x17) != 0x8e) cpu_relax(); dev->active_id[c] |= m; - tmport = wkport + 0x10; - outb(0x30, tmport); - tmport = wkport + 0x14; - outb(0x00, tmport); + outb(0x30, wkport + 0x10); + outb(0x00, wkport + 0x14); phase_cmd: - tmport = wkport + 0x18; - outb(0x08, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0x00) + outb(0x08, wkport + 0x18); + while ((inb(wkport + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - j = inb(tmport); + j = inb(wkport + 0x17); if (j != 0x16) { - tmport = wkport + 0x10; - outb(0x41, tmport); + outb(0x41, wkport + 0x10); goto phase_cmd; } sel_ok: - tmport = wkport + 0x03; - outb(inqd[0], tmport++); - outb(inqd[1], tmport++); - outb(inqd[2], tmport++); - outb(inqd[3], tmport++); - outb(inqd[4], tmport++); - outb(inqd[5], tmport); - tmport += 0x07; - outb(0, tmport); - tmport += 0x02; - outb(dev->id[c][i].devsp, tmport++); - outb(0, tmport++); - outb(inqd[6], tmport++); - outb(inqd[7], tmport++); - tmport += 0x03; - outb(inqd[8], tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0x00) + outb(inqd[0], wkport + 0x03); + outb(inqd[1], wkport + 0x04); + outb(inqd[2], wkport + 0x05); + outb(inqd[3], wkport + 0x06); + outb(inqd[4], wkport + 0x07); + outb(inqd[5], wkport + 0x08); + outb(0, wkport + 0x0f); + outb(dev->id[c][i].devsp, wkport + 0x11); + outb(0, wkport + 0x12); + outb(inqd[6], wkport + 0x13); + outb(inqd[7], wkport + 0x14); + outb(inqd[8], wkport + 0x18); + while ((inb(wkport + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) { + if ((inb(wkport + 0x17) != 0x11) && (inb(wkport + 0x17) != 0x8e)) { continue; } - while (inb(tmport) != 0x8e) + while (inb(wkport + 0x17) != 0x8e) cpu_relax(); - tmport = wkport + 0x1b; - outb(0x00, tmport); - tmport = wkport + 0x18; - outb(0x08, tmport); - tmport += 0x07; + outb(0x00, wkport + 0x1b); + outb(0x08, wkport + 0x18); j = 0; rd_inq_data: - k = inb(tmport); + k = inb(wkport + 0x1f); if ((k & 0x01) != 0) { - tmport -= 0x06; - mbuf[j++] = inb(tmport); - tmport += 0x06; + mbuf[j++] = inb(wkport + 0x19); goto rd_inq_data; } if ((k & 0x80) == 0) { goto rd_inq_data; } - tmport -= 0x08; - j = inb(tmport); + j = inb(wkport + 0x17); if (j == 0x16) { goto inq_ok; } - tmport = wkport + 0x10; - outb(0x46, tmport); - tmport += 0x02; - outb(0, tmport++); - outb(0, tmport++); - outb(0, tmport++); - tmport += 0x03; - outb(0x08, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0x00) + outb(0x46, wkport + 0x10); + outb(0, wkport + 0x12); + outb(0, wkport + 0x13); + outb(0, wkport + 0x14); + outb(0x08, wkport + 0x18); + while ((inb(wkport + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - if (inb(tmport) != 0x16) { + if (inb(wkport + 0x17) != 0x16) { goto sel_ok; } inq_ok: @@ -3033,54 +3002,40 @@ inq_ok: goto chg_wide; } - tmport = wkport + 0x1b; - outb(0x01, tmport); - tmport = wkport + 0x03; - outb(satn[0], tmport++); - outb(satn[1], tmport++); - outb(satn[2], tmport++); - outb(satn[3], tmport++); - outb(satn[4], tmport++); - outb(satn[5], tmport++); - tmport += 0x06; - outb(0, tmport); - tmport += 0x02; - outb(dev->id[c][i].devsp, tmport++); - outb(0, tmport++); - outb(satn[6], tmport++); - outb(satn[7], tmport++); - tmport += 0x03; - outb(satn[8], tmport); - tmport += 0x07; - - while ((inb(tmport) & 0x80) == 0x00) + outb(0x01, wkport + 0x1b); + outb(satn[0], wkport + 0x03); + outb(satn[1], wkport + 0x04); + outb(satn[2], wkport + 0x05); + outb(satn[3], wkport + 0x06); + outb(satn[4], wkport + 0x07); + outb(satn[5], wkport + 0x08); + outb(0, wkport + 0x0f); + outb(dev->id[c][i].devsp, wkport + 0x11); + outb(0, wkport + 0x12); + outb(satn[6], wkport + 0x13); + outb(satn[7], wkport + 0x14); + outb(satn[8], wkport + 0x18); + + while ((inb(wkport + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) { + if ((inb(wkport + 0x17) != 0x11) && (inb(wkport + 0x17) != 0x8e)) { continue; } - while (inb(tmport) != 0x8e) + while (inb(wkport + 0x17) != 0x8e) cpu_relax(); try_u3: j = 0; - tmport = wkport + 0x14; - outb(0x09, tmport); - tmport += 0x04; - outb(0x20, tmport); - tmport += 0x07; - - while ((inb(tmport) & 0x80) == 0) { - if ((inb(tmport) & 0x01) != 0) { - tmport -= 0x06; - outb(u3[j++], tmport); - tmport += 0x06; - } + outb(0x09, wkport + 0x14); + outb(0x20, wkport + 0x18); + + while ((inb(wkport + 0x1f) & 0x80) == 0) { + if ((inb(wkport + 0x1f) & 0x01) != 0) + outb(u3[j++], wkport + 0x19); cpu_relax(); } - tmport -= 0x08; - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x17) & 0x80) == 0x00) cpu_relax(); - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x17) & 0x0f; if (j == 0x0f) { goto u3p_in; } @@ -3092,19 +3047,13 @@ try_u3: } continue; u3p_out: - tmport = wkport + 0x18; - outb(0x20, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0) { - if ((inb(tmport) & 0x01) != 0) { - tmport -= 0x06; - outb(0, tmport); - tmport += 0x06; - } + outb(0x20, wkport + 0x18); + while ((inb(wkport + 0x1f) & 0x80) == 0) { + if ((inb(wkport + 0x1f) & 0x01) != 0) + outb(0, wkport + 0x19); cpu_relax(); } - tmport -= 0x08; - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x17) & 0x0f; if (j == 0x0f) { goto u3p_in; } @@ -3116,25 +3065,19 @@ u3p_out: } continue; u3p_in: - tmport = wkport + 0x14; - outb(0x09, tmport); - tmport += 0x04; - outb(0x20, tmport); - tmport += 0x07; + outb(0x09, wkport + 0x14); + outb(0x20, wkport + 0x18); k = 0; u3p_in1: - j = inb(tmport); + j = inb(wkport + 0x1f); if ((j & 0x01) != 0) { - tmport -= 0x06; - mbuf[k++] = inb(tmport); - tmport += 0x06; + mbuf[k++] = inb(wkport + 0x19); goto u3p_in1; } if ((j & 0x80) == 0x00) { goto u3p_in1; } - tmport -= 0x08; - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x17) & 0x0f; if (j == 0x0f) { goto u3p_in; } @@ -3146,16 +3089,11 @@ u3p_in1: } continue; u3p_cmd: - tmport = wkport + 0x10; - outb(0x30, tmport); - tmport = wkport + 0x14; - outb(0x00, tmport); - tmport += 0x04; - outb(0x08, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0x00); - tmport -= 0x08; - j = inb(tmport); + outb(0x30, wkport + 0x10); + outb(0x00, wkport + 0x14); + outb(0x08, wkport + 0x18); + while ((inb(wkport + 0x1f) & 0x80) == 0x00); + j = inb(wkport + 0x17); if (j != 0x16) { if (j == 0x4e) { goto u3p_out; @@ -3182,54 +3120,40 @@ u3p_cmd: continue; } chg_wide: - tmport = wkport + 0x1b; - outb(0x01, tmport); - tmport = wkport + 0x03; - outb(satn[0], tmport++); - outb(satn[1], tmport++); - outb(satn[2], tmport++); - outb(satn[3], tmport++); - outb(satn[4], tmport++); - outb(satn[5], tmport++); - tmport += 0x06; - outb(0, tmport); - tmport += 0x02; - outb(dev->id[c][i].devsp, tmport++); - outb(0, tmport++); - outb(satn[6], tmport++); - outb(satn[7], tmport++); - tmport += 0x03; - outb(satn[8], tmport); - tmport += 0x07; - - while ((inb(tmport) & 0x80) == 0x00) + outb(0x01, wkport + 0x1b); + outb(satn[0], wkport + 0x03); + outb(satn[1], wkport + 0x04); + outb(satn[2], wkport + 0x05); + outb(satn[3], wkport + 0x06); + outb(satn[4], wkport + 0x07); + outb(satn[5], wkport + 0x08); + outb(0, wkport + 0x0f); + outb(dev->id[c][i].devsp, wkport + 0x11); + outb(0, wkport + 0x12); + outb(satn[6], wkport + 0x13); + outb(satn[7], wkport + 0x14); + outb(satn[8], wkport + 0x18); + + while ((inb(wkport + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) { + if ((inb(wkport + 0x17) != 0x11) && (inb(wkport + 0x17) != 0x8e)) { continue; } - while (inb(tmport) != 0x8e) + while (inb(wkport + 0x17) != 0x8e) cpu_relax(); try_wide: j = 0; - tmport = wkport + 0x14; - outb(0x05, tmport); - tmport += 0x04; - outb(0x20, tmport); - tmport += 0x07; - - while ((inb(tmport) & 0x80) == 0) { - if ((inb(tmport) & 0x01) != 0) { - tmport -= 0x06; - outb(wide[j++], tmport); - tmport += 0x06; - } + outb(0x05, wkport + 0x14); + outb(0x20, wkport + 0x18); + + while ((inb(wkport + 0x1f) & 0x80) == 0) { + if ((inb(wkport + 0x1f) & 0x01) != 0) + outb(wide[j++], wkport + 0x19); cpu_relax(); } - tmport -= 0x08; - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x17) & 0x80) == 0x00) cpu_relax(); - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -3241,19 +3165,13 @@ try_wide: } continue; widep_out: - tmport = wkport + 0x18; - outb(0x20, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0) { - if ((inb(tmport) & 0x01) != 0) { - tmport -= 0x06; - outb(0, tmport); - tmport += 0x06; - } + outb(0x20, wkport + 0x18); + while ((inb(wkport + 0x1f) & 0x80) == 0) { + if ((inb(wkport + 0x1f) & 0x01) != 0) + outb(0, wkport + 0x19); cpu_relax(); } - tmport -= 0x08; - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -3265,25 +3183,19 @@ widep_out: } continue; widep_in: - tmport = wkport + 0x14; - outb(0xff, tmport); - tmport += 0x04; - outb(0x20, tmport); - tmport += 0x07; + outb(0xff, wkport + 0x14); + outb(0x20, wkport + 0x18); k = 0; widep_in1: - j = inb(tmport); + j = inb(wkport + 0x1f); if ((j & 0x01) != 0) { - tmport -= 0x06; - mbuf[k++] = inb(tmport); - tmport += 0x06; + mbuf[k++] = inb(wkport + 0x19); goto widep_in1; } if ((j & 0x80) == 0x00) { goto widep_in1; } - tmport -= 0x08; - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -3295,17 +3207,12 @@ widep_in1: } continue; widep_cmd: - tmport = wkport + 0x10; - outb(0x30, tmport); - tmport = wkport + 0x14; - outb(0x00, tmport); - tmport += 0x04; - outb(0x08, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0x00) + outb(0x30, wkport + 0x10); + outb(0x00, wkport + 0x14); + outb(0x08, wkport + 0x18); + while ((inb(wkport + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - j = inb(tmport); + j = inb(wkport + 0x17); if (j != 0x16) { if (j == 0x4e) { goto widep_out; @@ -3347,69 +3254,56 @@ set_sync: synuw[4]=0x0a; } } - tmport = wkport + 0x1b; j = 0; if ((m & dev->wide_id[c]) != 0) { j |= 0x01; } - outb(j, tmport); - tmport = wkport + 0x03; - outb(satn[0], tmport++); - outb(satn[1], tmport++); - outb(satn[2], tmport++); - outb(satn[3], tmport++); - outb(satn[4], tmport++); - outb(satn[5], tmport++); - tmport += 0x06; - outb(0, tmport); - tmport += 0x02; - outb(dev->id[c][i].devsp, tmport++); - outb(0, tmport++); - outb(satn[6], tmport++); - outb(satn[7], tmport++); - tmport += 0x03; - outb(satn[8], tmport); - tmport += 0x07; - - while ((inb(tmport) & 0x80) == 0x00) + outb(j, wkport + 0x1b); + outb(satn[0], wkport + 0x03); + outb(satn[1], wkport + 0x04); + outb(satn[2], wkport + 0x05); + outb(satn[3], wkport + 0x06); + outb(satn[4], wkport + 0x07); + outb(satn[5], wkport + 0x08); + outb(0, wkport + 0x0f); + outb(dev->id[c][i].devsp, wkport + 0x11); + outb(0, wkport + 0x12); + outb(satn[6], wkport + 0x13); + outb(satn[7], wkport + 0x14); + outb(satn[8], wkport + 0x18); + + while ((inb(wkport + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) { + if ((inb(wkport + 0x17) != 0x11) && (inb(wkport + 0x17) != 0x8e)) { continue; } - while (inb(tmport) != 0x8e) + while (inb(wkport + 0x17) != 0x8e) cpu_relax(); try_sync: j = 0; - tmport = wkport + 0x14; - outb(0x06, tmport); - tmport += 0x04; - outb(0x20, tmport); - tmport += 0x07; - - while ((inb(tmport) & 0x80) == 0) { - if ((inb(tmport) & 0x01) != 0) { - tmport -= 0x06; + outb(0x06, wkport + 0x14); + outb(0x20, wkport + 0x18); + + while ((inb(wkport + 0x1f) & 0x80) == 0) { + if ((inb(wkport + 0x1f) & 0x01) != 0) { if ((m & dev->wide_id[c]) != 0) { if ((m & dev->ultra_map[c]) != 0) { - outb(synuw[j++], tmport); + outb(synuw[j++], wkport + 0x19); } else { - outb(synw[j++], tmport); + outb(synw[j++], wkport + 0x19); } } else { if ((m & dev->ultra_map[c]) != 0) { - outb(synu[j++], tmport); + outb(synu[j++], wkport + 0x19); } else { - outb(synn[j++], tmport); + outb(synn[j++], wkport + 0x19); } } - tmport += 0x06; } } - tmport -= 0x08; - while ((inb(tmport) & 0x80) == 0x00) + while ((inb(wkport + 0x17) & 0x80) == 0x00) cpu_relax(); - j = inb(tmport) & 0x0f; + j = inb(wkport + 0x17) & 0x0f; if (j == 0x0f) { goto phase_ins; } @@ -3421,19 +3315,13 @@ try_sync: } continue; phase_outs: - tmport = wkport + 0x18; - outb(0x20, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0x00) { - if ((inb(tmport) & 0x01) != 0x00) { - tmport -= 0x06; - outb(0x00, tmport); - tmport += 0x06; - } + outb(0x20, wkport + 0x18); + while ((inb(wkport + 0x1f) & 0x80) == 0x00) { + if ((inb(wkport + 0x1f) & 0x01) != 0x00) + outb(0x00, wkport + 0x19); cpu_relax(); } - tmport -= 0x08; - j = inb(tmport); + j = inb(wkport + 0x17); if (j == 0x85) { goto tar_dcons; } @@ -3449,26 +3337,20 @@ phase_outs: } continue; phase_ins: - tmport = wkport + 0x14; - outb(0x06, tmport); - tmport += 0x04; - outb(0x20, tmport); - tmport += 0x07; + outb(0x06, wkport + 0x14); + outb(0x20, wkport + 0x18); k = 0; phase_ins1: - j = inb(tmport); + j = inb(wkport + 0x1f); if ((j & 0x01) != 0x00) { - tmport -= 0x06; - mbuf[k++] = inb(tmport); - tmport += 0x06; + mbuf[k++] = inb(wkport + 0x19); goto phase_ins1; } if ((j & 0x80) == 0x00) { goto phase_ins1; } - tmport -= 0x08; - while ((inb(tmport) & 0x80) == 0x00); - j = inb(tmport); + while ((inb(wkport + 0x17) & 0x80) == 0x00); + j = inb(wkport + 0x17); if (j == 0x85) { goto tar_dcons; } @@ -3484,18 +3366,13 @@ phase_ins1: } continue; phase_cmds: - tmport = wkport + 0x10; - outb(0x30, tmport); + outb(0x30, wkport + 0x10); tar_dcons: - tmport = wkport + 0x14; - outb(0x00, tmport); - tmport += 0x04; - outb(0x08, tmport); - tmport += 0x07; - while ((inb(tmport) & 0x80) == 0x00) + outb(0x00, wkport + 0x14); + outb(0x08, wkport + 0x18); + while ((inb(wkport + 0x1f) & 0x80) == 0x00) cpu_relax(); - tmport -= 0x08; - j = inb(tmport); + j = inb(wkport + 0x17); if (j != 0x16) { continue; } @@ -3542,8 +3419,7 @@ tar_dcons: printk("dev->id[%2d][%2d].devsp = %2x\n",c,i,dev->id[c][i].devsp); #endif } - tmport = wkport + 0x16; - outb(0x80, tmport); + outb(0x80, wkport + 0x16); } module_init(atp870u_init); -- cgit v0.10.2 From bc0fe4c91cdc7e211ca7dafd9039d3bf40a41e3b Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:47 +0100 Subject: atp870u: Untangle tmpcip Untangle the tmpcip crap so it becomes obvious what ports are accessed. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 993442d..32544bb 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -47,7 +47,7 @@ static void tscam_885(void); static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) { unsigned long flags; - unsigned short int tmpcip, id; + unsigned short int id; unsigned char i, j, c, target_id, lun,cmdp; unsigned char *prd; struct scsi_cmnd *workreq; @@ -79,30 +79,24 @@ ch_sel: if ((inb(dev->ioport[c] + 0x16) & 0x80) == 0) outb((inb(dev->ioport[c] + 0x16) | 0x80), dev->ioport[c] + 0x16); } - tmpcip = dev->pciport[c]; - if ((inb(tmpcip) & 0x08) != 0) + if ((inb(dev->pciport[c]) & 0x08) != 0) { - tmpcip += 0x2; for (k=0; k < 1000; k++) { - if ((inb(tmpcip) & 0x08) == 0) { + if ((inb(dev->pciport[c] + 2) & 0x08) == 0) { goto stop_dma; } - if ((inb(tmpcip) & 0x01) == 0) { + if ((inb(dev->pciport[c] + 2) & 0x01) == 0) { goto stop_dma; } } } stop_dma: - tmpcip = dev->pciport[c]; - outb(0x00, tmpcip); + outb(0x00, dev->pciport[c]); i = inb(dev->ioport[c] + 0x17); - if (dev->dev_id == ATP885_DEVID) { - tmpcip += 2; - outb(0x06, tmpcip); - tmpcip -= 2; - } + if (dev->dev_id == ATP885_DEVID) + outb(0x06, dev->pciport[c] + 2); target_id = inb(dev->ioport[c] + 0x15); @@ -303,13 +297,12 @@ stop_dma: /* enable 32 bit fifo transfer */ if (dev->dev_id == ATP885_DEVID) { - tmpcip = dev->pciport[c] + 1; - i=inb(tmpcip) & 0xf3; + i=inb(dev->pciport[c] + 1) & 0xf3; //j=workreq->cmnd[0]; if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { i |= 0x0c; } - outb(i,tmpcip); + outb(i, dev->pciport[c] + 1); } else if ((dev->dev_id == ATP880_DEVID1) || (dev->dev_id == ATP880_DEVID2) ) { if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { @@ -371,25 +364,20 @@ stop_dma: } } } - tmpcip = dev->pciport[c] + 0x04; - outl(dev->id[c][target_id].prdaddr, tmpcip); + outl(dev->id[c][target_id].prdaddr, dev->pciport[c] + 0x04); #ifdef ED_DBGP printk("dev->id[%d][%d].prdaddr 0x%8x\n", c, target_id, dev->id[c][target_id].prdaddr); #endif - if (dev->dev_id == ATP885_DEVID) { - tmpcip -= 0x04; - } else { - tmpcip -= 0x02; - outb(0x06, tmpcip); - outb(0x00, tmpcip); - tmpcip -= 0x02; + if (dev->dev_id != ATP885_DEVID) { + outb(0x06, dev->pciport[c] + 2); + outb(0x00, dev->pciport[c] + 2); } /* * Check transfer direction */ if (dev->id[c][target_id].dirct != 0) { outb(0x08, dev->ioport[c] + 0x18); - outb(0x01, tmpcip); + outb(0x01, dev->pciport[c]); dev->in_int[c] = 0; #ifdef ED_DBGP printk("status 0x80 return dirct != 0\n"); @@ -397,7 +385,7 @@ stop_dma: goto handled; } outb(0x08, dev->ioport[c] + 0x18); - outb(0x09, tmpcip); + outb(0x09, dev->pciport[c]); dev->in_int[c] = 0; #ifdef ED_DBGP printk("status 0x80 return dirct = 0\n"); @@ -484,12 +472,9 @@ go_42: } i &= 0x0f; if (i == 0x09) { - tmpcip += 4; - outl(dev->id[c][target_id].prdaddr, tmpcip); - tmpcip = tmpcip - 2; - outb(0x06, tmpcip); - outb(0x00, tmpcip); - tmpcip = tmpcip - 2; + outl(dev->id[c][target_id].prdaddr, dev->pciport[c] + 4); + outb(0x06, dev->pciport[c] + 2); + outb(0x00, dev->pciport[c] + 2); outb(0x41, dev->ioport[c] + 0x10); if (dev->dev_id == ATP885_DEVID) { k = dev->id[c][target_id].last_len; @@ -501,17 +486,14 @@ go_42: dev->id[c][target_id].dirct = 0x00; } outb(0x08, dev->ioport[c] + 0x18); - outb(0x09, tmpcip); + outb(0x09, dev->pciport[c]); dev->in_int[c] = 0; goto handled; } if (i == 0x08) { - tmpcip += 4; - outl(dev->id[c][target_id].prdaddr, tmpcip); - tmpcip = tmpcip - 2; - outb(0x06, tmpcip); - outb(0x00, tmpcip); - tmpcip = tmpcip - 2; + outl(dev->id[c][target_id].prdaddr, dev->pciport[c] + 4); + outb(0x06, dev->pciport[c] + 2); + outb(0x00, dev->pciport[c] + 2); outb(0x41, dev->ioport[c] + 0x10); if (dev->dev_id == ATP885_DEVID) { k = dev->id[c][target_id].last_len; @@ -522,7 +504,7 @@ go_42: outb((unsigned char) (inb(dev->ioport[c] + 0x15) | 0x20), dev->ioport[c] + 0x15); dev->id[c][target_id].dirct = 0x20; outb(0x08, dev->ioport[c] + 0x18); - outb(0x01, tmpcip); + outb(0x01, dev->pciport[c]); dev->in_int[c] = 0; goto handled; } -- cgit v0.10.2 From c2bab4031b528b4a5a665a499fd87c2440758b00 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:48 +0100 Subject: atp870u: Untangle tmpcip #2 Untangle the tmpcip crap so it becomes obvious what ports are accessed. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 32544bb..4d840a5 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -645,7 +645,7 @@ static void send_s870(struct atp_unit *dev,unsigned char c) unsigned int i;//,k; unsigned char j, target_id; unsigned char *prd; - unsigned short int tmpcip, w; + unsigned short int w; unsigned long l, bttl = 0; unsigned long sg_count; @@ -813,7 +813,6 @@ oktosend: dev->in_snd[c] = 0; return; } - tmpcip = dev->pciport[c]; prd = dev->id[c][target_id].prd_table; dev->id[c][target_id].prd_pos = prd; @@ -850,34 +849,28 @@ oktosend: printk("2. bttl %x, l %x\n",bttl, l); #endif } - tmpcip += 4; #ifdef ED_DBGP - printk("send_s870: prdaddr_2 0x%8x tmpcip %x target_id %d\n", dev->id[c][target_id].prdaddr,tmpcip,target_id); + printk("send_s870: prdaddr_2 0x%8x target_id %d\n", dev->id[c][target_id].prdaddr,target_id); #endif dev->id[c][target_id].prdaddr = dev->id[c][target_id].prd_bus; - outl(dev->id[c][target_id].prdaddr, tmpcip); - tmpcip = tmpcip - 2; - outb(0x06, tmpcip); - outb(0x00, tmpcip); + outl(dev->id[c][target_id].prdaddr, dev->pciport[c] + 4); + outb(0x06, dev->pciport[c] + 2); + outb(0x00, dev->pciport[c] + 2); if (dev->dev_id == ATP885_DEVID) { - tmpcip--; - j=inb(tmpcip) & 0xf3; + j = inb(dev->pciport[c] + 1) & 0xf3; if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { j |= 0x0c; } - outb(j,tmpcip); - tmpcip--; + outb(j, dev->pciport[c] + 1); } else if ((dev->dev_id == ATP880_DEVID1) || (dev->dev_id == ATP880_DEVID2)) { - tmpcip =tmpcip -2; if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { outb((unsigned char) ((inb(dev->ioport[c] - 0x05) & 0x3f) | 0xc0), dev->ioport[c] - 0x05); } else { outb((unsigned char) (inb(dev->ioport[c] - 0x05) & 0x3f), dev->ioport[c] - 0x05); } } else { - tmpcip =tmpcip -2; if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { outb((inb(dev->ioport[c] + 0x3a) & 0xf3) | 0x08, dev->ioport[c] + 0x3a); } else { @@ -889,7 +882,7 @@ oktosend: dev->id[c][target_id].dirct = 0x20; if (inb(dev->ioport[c] + 0x1c) == 0) { outb(0x08, dev->ioport[c] + 0x18); - outb(0x01, tmpcip); + outb(0x01, dev->pciport[c]); #ifdef ED_DBGP printk( "start DMA(to target)\n"); #endif @@ -901,7 +894,7 @@ oktosend: } if (inb(dev->ioport[c] + 0x1c) == 0) { outb(0x08, dev->ioport[c] + 0x18); - outb(0x09, tmpcip); + outb(0x09, dev->pciport[c]); #ifdef ED_DBGP printk( "start DMA(to host)\n"); #endif -- cgit v0.10.2 From 78614ecdda717ac4afa2764bec622b50400a1dc3 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:49 +0100 Subject: atp870u: Remove ugly gotos Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 4d840a5..886e54b 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -55,20 +55,17 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) #ifdef ED_DBGP unsigned long l; #endif - int errstus; struct Scsi_Host *host = dev_id; struct atp_unit *dev = (struct atp_unit *)&host->hostdata; for (c = 0; c < 2; c++) { j = inb(dev->ioport[c] + 0x1f); if ((j & 0x80) != 0) - { - goto ch_sel; - } + break; dev->in_int[c] = 0; } - return IRQ_NONE; -ch_sel: + if ((j & 0x80) == 0) + return IRQ_NONE; #ifdef ED_DBGP printk("atp870u_intr_handle enter\n"); #endif @@ -82,15 +79,12 @@ ch_sel: if ((inb(dev->pciport[c]) & 0x08) != 0) { for (k=0; k < 1000; k++) { - if ((inb(dev->pciport[c] + 2) & 0x08) == 0) { - goto stop_dma; - } - if ((inb(dev->pciport[c] + 2) & 0x01) == 0) { - goto stop_dma; - } + if ((inb(dev->pciport[c] + 2) & 0x08) == 0) + break; + if ((inb(dev->pciport[c] + 2) & 0x01) == 0) + break; } } -stop_dma: outb(0x00, dev->pciport[c]); i = inb(dev->ioport[c] + 0x17); @@ -170,13 +164,13 @@ stop_dma: #ifdef ED_DBGP printk("Status 0x85 return\n"); #endif - goto handled; + return IRQ_HANDLED; } if (i == 0x40) { dev->last_cmd[c] |= 0x40; dev->in_int[c] = 0; - goto handled; + return IRQ_HANDLED; } if (i == 0x21) { @@ -194,7 +188,7 @@ stop_dma: outb(0x41, dev->ioport[c] + 0x10); outb(0x08, dev->ioport[c] + 0x18); dev->in_int[c] = 0; - goto handled; + return IRQ_HANDLED; } if (dev->dev_id == ATP885_DEVID) { @@ -231,7 +225,7 @@ stop_dma: dev->id[c][target_id].last_len = adrcnt; outb(0x08, dev->ioport[c] + 0x18); dev->in_int[c] = 0; - goto handled; + return IRQ_HANDLED; } else { #ifdef ED_DBGP printk("cmdp != 0x41\n"); @@ -243,7 +237,7 @@ stop_dma: outb(0x00, dev->ioport[c] + 0x14); outb(0x08, dev->ioport[c] + 0x18); dev->in_int[c] = 0; - goto handled; + return IRQ_HANDLED; } } if (dev->last_cmd[c] != 0xff) { @@ -336,7 +330,7 @@ stop_dma: #ifdef ED_DBGP printk("dev->id[c][target_id].last_len = 0\n"); #endif - goto handled; + return IRQ_HANDLED; } #ifdef ED_DBGP printk("target_id = %d adrcnt = %d\n",target_id,adrcnt); @@ -382,7 +376,7 @@ stop_dma: #ifdef ED_DBGP printk("status 0x80 return dirct != 0\n"); #endif - goto handled; + return IRQ_HANDLED; } outb(0x08, dev->ioport[c] + 0x18); outb(0x09, dev->pciport[c]); @@ -390,7 +384,7 @@ stop_dma: #ifdef ED_DBGP printk("status 0x80 return dirct = 0\n"); #endif - goto handled; + return IRQ_HANDLED; } /* @@ -399,27 +393,19 @@ stop_dma: workreq = dev->id[c][target_id].curr_req; - if (i == 0x42) { - if ((dev->last_cmd[c] & 0xf0) != 0x40) - { - dev->last_cmd[c] = 0xff; - } - errstus = 0x02; - workreq->result = errstus; - goto go_42; - } - if (i == 0x16) { + if (i == 0x42 || i == 0x16) { if ((dev->last_cmd[c] & 0xf0) != 0x40) { dev->last_cmd[c] = 0xff; } - errstus = 0; - errstus = inb(dev->ioport[c] + 0x0f); - if (((dev->r1f[c][target_id] & 0x10) != 0)&&(dev->dev_id==ATP885_DEVID)) { - printk(KERN_WARNING "AEC67162 CRC ERROR !\n"); - errstus = 0x02; - } - workreq->result = errstus; -go_42: + if (i == 0x16) { + workreq->result = inb(dev->ioport[c] + 0x0f); + if (((dev->r1f[c][target_id] & 0x10) != 0)&&(dev->dev_id==ATP885_DEVID)) { + printk(KERN_WARNING "AEC67162 CRC ERROR !\n"); + workreq->result = 0x02; + } + } else + workreq->result = 0x02; + if (dev->dev_id == ATP885_DEVID) { j = inb(dev->baseport + 0x29) | 0x01; outb(j, dev->baseport + 0x29); @@ -462,7 +448,7 @@ go_42: } spin_unlock_irqrestore(dev->host->host_lock, flags); dev->in_int[c] = 0; - goto handled; + return IRQ_HANDLED; } if ((dev->last_cmd[c] & 0xf0) != 0x40) { dev->last_cmd[c] = 0xff; @@ -488,7 +474,7 @@ go_42: outb(0x08, dev->ioport[c] + 0x18); outb(0x09, dev->pciport[c]); dev->in_int[c] = 0; - goto handled; + return IRQ_HANDLED; } if (i == 0x08) { outl(dev->id[c][target_id].prdaddr, dev->pciport[c] + 4); @@ -506,7 +492,7 @@ go_42: outb(0x08, dev->ioport[c] + 0x18); outb(0x01, dev->pciport[c]); dev->in_int[c] = 0; - goto handled; + return IRQ_HANDLED; } if (i == 0x0a) { outb(0x30, dev->ioport[c] + 0x10); @@ -518,19 +504,9 @@ go_42: outb(0x00, dev->ioport[c] + 0x13); outb(0x00, dev->ioport[c] + 0x14); outb(0x08, dev->ioport[c] + 0x18); - dev->in_int[c] = 0; - goto handled; - } else { -// inb(dev->ioport[c] + 0x17); -// dev->working[c] = 0; - dev->in_int[c] = 0; - goto handled; } - -handled: -#ifdef ED_DBGP - printk("atp870u_intr_handle exit\n"); -#endif + dev->in_int[c] = 0; + return IRQ_HANDLED; } /** -- cgit v0.10.2 From 468b8968157466996b70c610c080c41ae517c61c Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:50 +0100 Subject: atp870u: Remove ugly gotos #2 Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 886e54b..999bf74 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -617,7 +617,7 @@ static DEF_SCSI_QCMD(atp870u_queuecommand) */ static void send_s870(struct atp_unit *dev,unsigned char c) { - struct scsi_cmnd *workreq; + struct scsi_cmnd *workreq = NULL; unsigned int i;//,k; unsigned char j, target_id; unsigned char *prd; @@ -638,50 +638,42 @@ static void send_s870(struct atp_unit *dev,unsigned char c) if ((dev->last_cmd[c] != 0xff) && ((dev->last_cmd[c] & 0x40) != 0)) { dev->last_cmd[c] &= 0x0f; workreq = dev->id[c][dev->last_cmd[c]].curr_req; - if (workreq != NULL) { /* check NULL pointer */ - goto cmd_subp; - } - dev->last_cmd[c] = 0xff; - if (dev->quhd[c] == dev->quend[c]) { - dev->in_snd[c] = 0; - return ; + if (!workreq) { + dev->last_cmd[c] = 0xff; + if (dev->quhd[c] == dev->quend[c]) { + dev->in_snd[c] = 0; + return; + } } } - if ((dev->last_cmd[c] != 0xff) && (dev->working[c] != 0)) { - dev->in_snd[c] = 0; - return ; - } - dev->working[c]++; - j = dev->quhd[c]; - dev->quhd[c]++; - if (dev->quhd[c] >= qcnt) { - dev->quhd[c] = 0; - } - workreq = dev->quereq[c][dev->quhd[c]]; - if (dev->id[c][scmd_id(workreq)].curr_req == NULL) { + if (!workreq) { + if ((dev->last_cmd[c] != 0xff) && (dev->working[c] != 0)) { + dev->in_snd[c] = 0; + return; + } + dev->working[c]++; + j = dev->quhd[c]; + dev->quhd[c]++; + if (dev->quhd[c] >= qcnt) + dev->quhd[c] = 0; + workreq = dev->quereq[c][dev->quhd[c]]; + if (dev->id[c][scmd_id(workreq)].curr_req != NULL) { + dev->quhd[c] = j; + dev->working[c]--; + dev->in_snd[c] = 0; + return; + } dev->id[c][scmd_id(workreq)].curr_req = workreq; dev->last_cmd[c] = scmd_id(workreq); - goto cmd_subp; - } - dev->quhd[c] = j; - dev->working[c]--; - dev->in_snd[c] = 0; - return; -cmd_subp: - if ((inb(dev->ioport[c] + 0x1f) & 0xb0) != 0) { - goto abortsnd; - } - if (inb(dev->ioport[c] + 0x1c) == 0) { - goto oktosend; } -abortsnd: + if ((inb(dev->ioport[c] + 0x1f) & 0xb0) != 0 || inb(dev->ioport[c] + 0x1c) != 0) { #ifdef ED_DBGP - printk("Abort to Send\n"); + printk("Abort to Send\n"); #endif - dev->last_cmd[c] |= 0x40; - dev->in_snd[c] = 0; - return; -oktosend: + dev->last_cmd[c] |= 0x40; + dev->in_snd[c] = 0; + return; + } #ifdef ED_DBGP printk("OK to Send\n"); scmd_printk(KERN_DEBUG, workreq, "CDB"); -- cgit v0.10.2 From 832e9ac6de16ea07045ab3a18d7a64bc3fb1231c Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:51 +0100 Subject: atp870u: Remove ugly gotos #3 Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 999bf74..b3d4e9d 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -880,34 +880,28 @@ static unsigned char fun_scam(struct atp_unit *dev, unsigned short int *val) unsigned char j; outw(*val, dev->ioport[0] + 0x1c); -FUN_D7: for (i = 0; i < 10; i++) { /* stable >= bus settle delay(400 ns) */ k = inw(dev->ioport[0] + 0x1c); j = (unsigned char) (k >> 8); - if ((k & 0x8000) != 0) { /* DB7 all release? */ - goto FUN_D7; - } + if ((k & 0x8000) != 0) /* DB7 all release? */ + i = 0; } *val |= 0x4000; /* assert DB6 */ outw(*val, dev->ioport[0] + 0x1c); *val &= 0xdfff; /* assert DB5 */ outw(*val, dev->ioport[0] + 0x1c); -FUN_D5: for (i = 0; i < 10; i++) { /* stable >= bus settle delay(400 ns) */ - if ((inw(dev->ioport[0] + 0x1c) & 0x2000) != 0) { /* DB5 all release? */ - goto FUN_D5; - } + if ((inw(dev->ioport[0] + 0x1c) & 0x2000) != 0) /* DB5 all release? */ + i = 0; } *val |= 0x8000; /* no DB4-0, assert DB7 */ *val &= 0xe0ff; outw(*val, dev->ioport[0] + 0x1c); *val &= 0xbfff; /* release DB6 */ outw(*val, dev->ioport[0] + 0x1c); -FUN_D6: for (i = 0; i < 10; i++) { /* stable >= bus settle delay(400 ns) */ - if ((inw(dev->ioport[0] + 0x1c) & 0x4000) != 0) { /* DB6 all release? */ - goto FUN_D6; - } + if ((inw(dev->ioport[0] + 0x1c) & 0x4000) != 0) /* DB6 all release? */ + i = 0; } return j; -- cgit v0.10.2 From 58c4d046b4d1d5b84875eb73115f3ef092abccce Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:52 +0100 Subject: atp870u: Remove ugly gotos #4 Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index b3d4e9d..68afe11 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -970,19 +970,19 @@ static void tscam(struct Scsi_Host *host) } else { outb(0x00, dev->ioport[0] + 0x1b); } -wait_rdyok: - outb(0x09, dev->ioport[0] + 0x18); - - while ((inb(dev->ioport[0] + 0x1f) & 0x80) == 0x00) - cpu_relax(); - k = inb(dev->ioport[0] + 0x17); - if (k != 0x16) { - if ((k == 0x85) || (k == 0x42)) { - continue; - } - outb(0x41, dev->ioport[0] + 0x10); - goto wait_rdyok; - } + do { + outb(0x09, dev->ioport[0] + 0x18); + + while ((inb(dev->ioport[0] + 0x1f) & 0x80) == 0x00) + cpu_relax(); + k = inb(dev->ioport[0] + 0x17); + if ((k == 0x85) || (k == 0x42)) + break; + if (k != 0x16) + outb(0x41, dev->ioport[0] + 0x10); + } while (k != 0x16); + if ((k == 0x85) || (k == 0x42)) + continue; assignid_map |= m; } @@ -1003,10 +1003,8 @@ wait_rdyok: mdelay(128); val &= 0x00fb; /* after 1ms no msg */ outw(val, dev->ioport[0] + 0x1c); -wait_nomsg: - if ((inb(dev->ioport[0] + 0x1c) & 0x04) != 0) { - goto wait_nomsg; - } + while ((inb(dev->ioport[0] + 0x1c) & 0x04) != 0) + ; outb(1, 0x80); udelay(100); for (n = 0; n < 0x30000; n++) { -- cgit v0.10.2 From c7fcc089b0e49dce9208277871f69e42d8fb1db0 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:53 +0100 Subject: atp870u: Remove ugly gotos #5 Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 68afe11..fd2bb6f 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1007,28 +1007,22 @@ static void tscam(struct Scsi_Host *host) ; outb(1, 0x80); udelay(100); - for (n = 0; n < 0x30000; n++) { - if ((inb(dev->ioport[0] + 0x1c) & 0x80) != 0) { /* bsy ? */ - goto wait_io; - } - } - goto TCM_SYNC; -wait_io: - for (n = 0; n < 0x30000; n++) { - if ((inb(dev->ioport[0] + 0x1c) & 0x81) == 0x0081) { - goto wait_io1; - } - } - goto TCM_SYNC; -wait_io1: - inb(0x80); - val |= 0x8003; /* io,cd,db7 */ - outw(val, dev->ioport[0] + 0x1c); - inb(0x80); - val &= 0x00bf; /* no sel */ - outw(val, dev->ioport[0] + 0x1c); - outb(2, 0x80); -TCM_SYNC: + for (n = 0; n < 0x30000; n++) + if ((inb(dev->ioport[0] + 0x1c) & 0x80) != 0) /* bsy ? */ + break; + if (n < 0x30000) + for (n = 0; n < 0x30000; n++) + if ((inb(dev->ioport[0] + 0x1c) & 0x81) == 0x0081) { + inb(0x80); + val |= 0x8003; /* io,cd,db7 */ + outw(val, dev->ioport[0] + 0x1c); + inb(0x80); + val &= 0x00bf; /* no sel */ + outw(val, dev->ioport[0] + 0x1c); + outb(2, 0x80); + break; + } + while (1) { /* * The funny division into multiple delays is to accomodate * arches like ARM where udelay() multiplies its argument by @@ -1059,31 +1053,28 @@ TCM_SYNC: outb(4, 0x80); i = 8; j = 0; -TCM_ID: - if ((inw(dev->ioport[0] + 0x1c) & 0x2000) == 0) { - goto TCM_ID; - } - outb(5, 0x80); - val &= 0x00ff; /* get ID_STRING */ - val |= 0x2000; - k = fun_scam(dev, &val); - if ((k & 0x03) == 0) { - goto TCM_5; - } - mbuf[j] <<= 0x01; - mbuf[j] &= 0xfe; - if ((k & 0x02) != 0) { - mbuf[j] |= 0x01; - } - i--; - if (i > 0) { - goto TCM_ID; + + while (1) { + if ((inw(dev->ioport[0] + 0x1c) & 0x2000) == 0) + continue; + outb(5, 0x80); + val &= 0x00ff; /* get ID_STRING */ + val |= 0x2000; + k = fun_scam(dev, &val); + if ((k & 0x03) == 0) + break; + mbuf[j] <<= 0x01; + mbuf[j] &= 0xfe; + if ((k & 0x02) != 0) + mbuf[j] |= 0x01; + i--; + if (i > 0) + continue; + j++; + i = 8; } - j++; - i = 8; - goto TCM_ID; -TCM_5: /* isolation complete.. */ + /* isolation complete.. */ /* mbuf[32]=0; printk(" \n%x %x %x %s\n ",assignid_map,mbuf[0],mbuf[1],&mbuf[2]); */ i = 15; @@ -1091,33 +1082,33 @@ TCM_5: /* isolation complete.. */ if ((j & 0x20) != 0) { /* bit5=1:ID up to 7 */ i = 7; } - if ((j & 0x06) == 0) { /* IDvalid? */ - goto G2Q5; - } - k = mbuf[1]; -small_id: - m = 1; - m <<= k; - if ((m & assignid_map) == 0) { - goto G2Q_QUIN; - } - if (k > 0) { - k--; - goto small_id; - } -G2Q5: /* srch from max acceptable ID# */ - k = i; /* max acceptable ID# */ -G2Q_LP: - m = 1; - m <<= k; - if ((m & assignid_map) == 0) { - goto G2Q_QUIN; + if ((j & 0x06) != 0) { /* IDvalid? */ + k = mbuf[1]; + while (1) { + m = 1; + m <<= k; + if ((m & assignid_map) == 0) + break; + if (k > 0) + k--; + else + break; + } } - if (k > 0) { - k--; - goto G2Q_LP; + if ((m & assignid_map) != 0) { /* srch from max acceptable ID# */ + k = i; /* max acceptable ID# */ + while (1) { + m = 1; + m <<= k; + if ((m & assignid_map) == 0) + break; + if (k > 0) + k--; + else + break; + } } -G2Q_QUIN: /* k=binID#, */ + /* k=binID#, */ assignid_map |= m; if (k < 8) { quintet[0] = 0x38; /* 1st dft ID<8 */ @@ -1136,8 +1127,7 @@ G2Q_QUIN: /* k=binID#, */ val |= m; fun_scam(dev, &val); - goto TCM_SYNC; - + } } static void is870(struct atp_unit *dev, unsigned int wkport) -- cgit v0.10.2 From 6a3cebb682190f878dcab60450cfdb2eddeceb69 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:54 +0100 Subject: atp870u: Introduce HW access wrappers Introduce *_read? and *_write? wrappers to improve code readability. Also make sure that baseport is always initialized, not only for ATP880. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index fd2bb6f..07b50ac 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -44,6 +44,51 @@ static void send_s870(struct atp_unit *dev,unsigned char c); static void is885(struct atp_unit *dev, unsigned int wkport,unsigned char c); static void tscam_885(void); +static inline void atp_writeb_base(struct atp_unit *atp, u8 reg, u8 val) +{ + outb(val, atp->baseport + reg); +} + +static inline void atp_writeb_io(struct atp_unit *atp, u8 channel, u8 reg, u8 val) +{ + outb(val, atp->ioport[channel] + reg); +} + +static inline void atp_writew_io(struct atp_unit *atp, u8 channel, u8 reg, u16 val) +{ + outw(val, atp->ioport[channel] + reg); +} + +static inline void atp_writeb_pci(struct atp_unit *atp, u8 channel, u8 reg, u8 val) +{ + outb(val, atp->pciport[channel] + reg); +} + +static inline void atp_writel_pci(struct atp_unit *atp, u8 channel, u8 reg, u32 val) +{ + outl(val, atp->pciport[channel] + reg); +} + +static inline u8 atp_readb_base(struct atp_unit *atp, u8 reg) +{ + return inb(atp->baseport + reg); +} + +static inline u8 atp_readb_io(struct atp_unit *atp, u8 channel, u8 reg) +{ + return inb(atp->ioport[channel] + reg); +} + +static inline u16 atp_readw_io(struct atp_unit *atp, u8 channel, u8 reg) +{ + return inw(atp->ioport[channel] + reg); +} + +static inline u8 atp_readb_pci(struct atp_unit *atp, u8 channel, u8 reg) +{ + return inb(atp->pciport[channel] + reg); +} + static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) { unsigned long flags; @@ -59,7 +104,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) struct atp_unit *dev = (struct atp_unit *)&host->hostdata; for (c = 0; c < 2; c++) { - j = inb(dev->ioport[c] + 0x1f); + j = atp_readb_io(dev, c, 0x1f); if ((j & 0x80) != 0) break; dev->in_int[c] = 0; @@ -70,29 +115,29 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) printk("atp870u_intr_handle enter\n"); #endif dev->in_int[c] = 1; - cmdp = inb(dev->ioport[c] + 0x10); + cmdp = atp_readb_io(dev, c, 0x10); if (dev->working[c] != 0) { if (dev->dev_id == ATP885_DEVID) { - if ((inb(dev->ioport[c] + 0x16) & 0x80) == 0) - outb((inb(dev->ioport[c] + 0x16) | 0x80), dev->ioport[c] + 0x16); + if ((atp_readb_io(dev, c, 0x16) & 0x80) == 0) + atp_writeb_io(dev, c, 0x16, (atp_readb_io(dev, c, 0x16) | 0x80)); } - if ((inb(dev->pciport[c]) & 0x08) != 0) + if ((atp_readb_pci(dev, c, 0x00) & 0x08) != 0) { for (k=0; k < 1000; k++) { - if ((inb(dev->pciport[c] + 2) & 0x08) == 0) + if ((atp_readb_pci(dev, c, 2) & 0x08) == 0) break; - if ((inb(dev->pciport[c] + 2) & 0x01) == 0) + if ((atp_readb_pci(dev, c, 2) & 0x01) == 0) break; } } - outb(0x00, dev->pciport[c]); + atp_writeb_pci(dev, c, 0, 0x00); - i = inb(dev->ioport[c] + 0x17); + i = atp_readb_io(dev, c, 0x17); if (dev->dev_id == ATP885_DEVID) - outb(0x06, dev->pciport[c] + 2); + atp_writeb_pci(dev, c, 2, 0x06); - target_id = inb(dev->ioport[c] + 0x15); + target_id = atp_readb_io(dev, c, 0x15); /* * Remap wide devices onto id numbers @@ -121,9 +166,9 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) } if (dev->dev_id == ATP885_DEVID) { adrcnt = 0; - ((unsigned char *) &adrcnt)[2] = inb(dev->ioport[c] + 0x12); - ((unsigned char *) &adrcnt)[1] = inb(dev->ioport[c] + 0x13); - ((unsigned char *) &adrcnt)[0] = inb(dev->ioport[c] + 0x14); + ((unsigned char *) &adrcnt)[2] = atp_readb_io(dev, c, 0x12); + ((unsigned char *) &adrcnt)[1] = atp_readb_io(dev, c, 0x13); + ((unsigned char *) &adrcnt)[0] = atp_readb_io(dev, c, 0x14); if (dev->id[c][target_id].last_len != adrcnt) { k = dev->id[c][target_id].last_len; @@ -140,10 +185,9 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) * Flip wide */ if (dev->wide_id[c] != 0) { - outb(0x01, dev->ioport[c] + 0x1b); - while ((inb(dev->ioport[c] + 0x1b) & 0x01) != 0x01) { - outb(0x01, dev->ioport[c] + 0x1b); - } + atp_writeb_io(dev, c, 0x1b, 0x01); + while ((atp_readb_io(dev, c, 0x1b) & 0x01) != 0x01) + atp_writeb_io(dev, c, 0x1b, 0x01); } /* * Issue more commands @@ -178,15 +222,15 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) dev->last_cmd[c] = 0xff; } adrcnt = 0; - ((unsigned char *) &adrcnt)[2] = inb(dev->ioport[c] + 0x12); - ((unsigned char *) &adrcnt)[1] = inb(dev->ioport[c] + 0x13); - ((unsigned char *) &adrcnt)[0] = inb(dev->ioport[c] + 0x14); + ((unsigned char *) &adrcnt)[2] = atp_readb_io(dev, c, 0x12); + ((unsigned char *) &adrcnt)[1] = atp_readb_io(dev, c, 0x13); + ((unsigned char *) &adrcnt)[0] = atp_readb_io(dev, c, 0x14); k = dev->id[c][target_id].last_len; k -= adrcnt; dev->id[c][target_id].tran_len = k; dev->id[c][target_id].last_len = adrcnt; - outb(0x41, dev->ioport[c] + 0x10); - outb(0x08, dev->ioport[c] + 0x18); + atp_writeb_io(dev, c, 0x10, 0x41); + atp_writeb_io(dev, c, 0x18, 0x08); dev->in_int[c] = 0; return IRQ_HANDLED; } @@ -205,9 +249,9 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) printk(KERN_DEBUG "Device reselect\n"); #endif lun = 0; - if (cmdp == 0x44 || i==0x80) { - lun = inb(dev->ioport[c] + 0x1d) & 0x07; - } else { + if (cmdp == 0x44 || i == 0x80) + lun = atp_readb_io(dev, c, 0x1d) & 0x07; + else { if ((dev->last_cmd[c] & 0xf0) != 0x40) { dev->last_cmd[c] = 0xff; } @@ -216,26 +260,26 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) printk("cmdp = 0x41\n"); #endif adrcnt = 0; - ((unsigned char *) &adrcnt)[2] = inb(dev->ioport[c] + 0x12); - ((unsigned char *) &adrcnt)[1] = inb(dev->ioport[c] + 0x13); - ((unsigned char *) &adrcnt)[0] = inb(dev->ioport[c] + 0x14); + ((unsigned char *) &adrcnt)[2] = atp_readb_io(dev, c, 0x12); + ((unsigned char *) &adrcnt)[1] = atp_readb_io(dev, c, 0x13); + ((unsigned char *) &adrcnt)[0] = atp_readb_io(dev, c, 0x14); k = dev->id[c][target_id].last_len; k -= adrcnt; dev->id[c][target_id].tran_len = k; dev->id[c][target_id].last_len = adrcnt; - outb(0x08, dev->ioport[c] + 0x18); + atp_writeb_io(dev, c, 0x18, 0x08); dev->in_int[c] = 0; return IRQ_HANDLED; } else { #ifdef ED_DBGP printk("cmdp != 0x41\n"); #endif - outb(0x46, dev->ioport[c] + 0x10); + atp_writeb_io(dev, c, 0x10, 0x46); dev->id[c][target_id].dirct = 0x00; - outb(0x00, dev->ioport[c] + 0x12); - outb(0x00, dev->ioport[c] + 0x13); - outb(0x00, dev->ioport[c] + 0x14); - outb(0x08, dev->ioport[c] + 0x18); + atp_writeb_io(dev, c, 0x12, 0x00); + atp_writeb_io(dev, c, 0x13, 0x00); + atp_writeb_io(dev, c, 0x14, 0x00); + atp_writeb_io(dev, c, 0x18, 0x08); dev->in_int[c] = 0; return IRQ_HANDLED; } @@ -244,12 +288,12 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) dev->last_cmd[c] |= 0x40; } if (dev->dev_id == ATP885_DEVID) { - j = inb(dev->baseport + 0x29) & 0xfe; - outb(j, dev->baseport + 0x29); + j = atp_readb_base(dev, 0x29) & 0xfe; + atp_writeb_base(dev, 0x29, j); } else - outb(0x45, dev->ioport[c] + 0x10); + atp_writeb_io(dev, c, 0x10, 0x45); - target_id = inb(dev->ioport[c] + 0x16); + target_id = atp_readb_io(dev, c, 0x16); /* * Remap wide identifiers */ @@ -259,7 +303,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) target_id &= 0x07; } if (dev->dev_id == ATP885_DEVID) - outb(0x45, dev->ioport[c] + 0x10); + atp_writeb_io(dev, c, 0x10, 0x45); workreq = dev->id[c][target_id].curr_req; #ifdef ED_DBGP scmd_printk(KERN_DEBUG, workreq, "CDB"); @@ -268,16 +312,16 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) printk("\n"); #endif - outb(lun, dev->ioport[c] + 0x0f); - outb(dev->id[c][target_id].devsp, dev->ioport[c] + 0x11); + atp_writeb_io(dev, c, 0x0f, lun); + atp_writeb_io(dev, c, 0x11, dev->id[c][target_id].devsp); adrcnt = dev->id[c][target_id].tran_len; k = dev->id[c][target_id].last_len; - outb(((unsigned char *) &k)[2], dev->ioport[c] + 0x12); - outb(((unsigned char *) &k)[1], dev->ioport[c] + 0x13); - outb(((unsigned char *) &k)[0], dev->ioport[c] + 0x14); + atp_writeb_io(dev, c, 0x12, ((unsigned char *) &k)[2]); + atp_writeb_io(dev, c, 0x13, ((unsigned char *) &k)[1]); + atp_writeb_io(dev, c, 0x14, ((unsigned char *) &k)[0]); #ifdef ED_DBGP - printk("k %x, k[0] 0x%x k[1] 0x%x k[2] 0x%x\n", k, inb(dev->ioport[c] + 0x14), inb(dev->ioport[c] + 0x13), inb(dev->ioport[c] + 0x12)); + printk("k %x, k[0] 0x%x k[1] 0x%x k[2] 0x%x\n", k, atp_readb_io(dev, c, 0x14), atp_readb_io(dev, c, 0x13), atp_readb_io(dev, c, 0x12)); #endif /* Remap wide */ j = target_id; @@ -286,30 +330,28 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) } /* Add direction */ j |= dev->id[c][target_id].dirct; - outb(j, dev->ioport[c] + 0x15); - outb(0x80, dev->ioport[c] + 0x16); + atp_writeb_io(dev, c, 0x15, j); + atp_writeb_io(dev, c, 0x16, 0x80); /* enable 32 bit fifo transfer */ if (dev->dev_id == ATP885_DEVID) { - i=inb(dev->pciport[c] + 1) & 0xf3; + i = atp_readb_pci(dev, c, 1) & 0xf3; //j=workreq->cmnd[0]; if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { i |= 0x0c; } - outb(i, dev->pciport[c] + 1); + atp_writeb_pci(dev, c, 1, i); } else if ((dev->dev_id == ATP880_DEVID1) || (dev->dev_id == ATP880_DEVID2) ) { - if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { - outb((unsigned char) ((inb(dev->ioport[c] - 0x05) & 0x3f) | 0xc0), dev->ioport[c] - 0x05);///minus 0x05??? - } else { - outb((unsigned char) (inb(dev->ioport[c] - 0x05) & 0x3f), dev->ioport[c] - 0x05);///minus 0x05??? - } + if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) + atp_writeb_base(dev, 0x3b, (atp_readb_base(dev, 0x3b) & 0x3f) | 0xc0); + else + atp_writeb_base(dev, 0x3b, atp_readb_base(dev, 0x3b) & 0x3f); } else { - if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { - outb((unsigned char) ((inb(dev->ioport[c] + 0x3a) & 0xf3) | 0x08), dev->ioport[c] + 0x3a); - } else { - outb((unsigned char) (inb(dev->ioport[c] + 0x3a) & 0xf3), dev->ioport[c] + 0x3a); - } + if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) + atp_writeb_io(dev, c, 0x3a, (atp_readb_io(dev, c, 0x3a) & 0xf3) | 0x08); + else + atp_writeb_io(dev, c, 0x3a, atp_readb_io(dev, c, 0x3a) & 0xf3); } j = 0; id = 1; @@ -320,12 +362,11 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) if ((id & dev->wide_id[c]) != 0) { j |= 0x01; } - outb(j, dev->ioport[c] + 0x1b); - while ((inb(dev->ioport[c] + 0x1b) & 0x01) != j) { - outb(j,dev->ioport[c] + 0x1b); - } + atp_writeb_io(dev, c, 0x1b, j); + while ((atp_readb_io(dev, c, 0x1b) & 0x01) != j) + atp_writeb_io(dev, c, 0x1b, j); if (dev->id[c][target_id].last_len == 0) { - outb(0x08, dev->ioport[c] + 0x18); + atp_writeb_io(dev, c, 0x18, 0x08); dev->in_int[c] = 0; #ifdef ED_DBGP printk("dev->id[c][target_id].last_len = 0\n"); @@ -358,28 +399,28 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) } } } - outl(dev->id[c][target_id].prdaddr, dev->pciport[c] + 0x04); + atp_writel_pci(dev, c, 0x04, dev->id[c][target_id].prdaddr); #ifdef ED_DBGP printk("dev->id[%d][%d].prdaddr 0x%8x\n", c, target_id, dev->id[c][target_id].prdaddr); #endif if (dev->dev_id != ATP885_DEVID) { - outb(0x06, dev->pciport[c] + 2); - outb(0x00, dev->pciport[c] + 2); + atp_writeb_pci(dev, c, 2, 0x06); + atp_writeb_pci(dev, c, 2, 0x00); } /* * Check transfer direction */ if (dev->id[c][target_id].dirct != 0) { - outb(0x08, dev->ioport[c] + 0x18); - outb(0x01, dev->pciport[c]); + atp_writeb_io(dev, c, 0x18, 0x08); + atp_writeb_pci(dev, c, 0, 0x01); dev->in_int[c] = 0; #ifdef ED_DBGP printk("status 0x80 return dirct != 0\n"); #endif return IRQ_HANDLED; } - outb(0x08, dev->ioport[c] + 0x18); - outb(0x09, dev->pciport[c]); + atp_writeb_io(dev, c, 0x18, 0x08); + atp_writeb_pci(dev, c, 0, 0x09); dev->in_int[c] = 0; #ifdef ED_DBGP printk("status 0x80 return dirct = 0\n"); @@ -398,7 +439,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) dev->last_cmd[c] = 0xff; } if (i == 0x16) { - workreq->result = inb(dev->ioport[c] + 0x0f); + workreq->result = atp_readb_io(dev, c, 0x0f); if (((dev->r1f[c][target_id] & 0x10) != 0)&&(dev->dev_id==ATP885_DEVID)) { printk(KERN_WARNING "AEC67162 CRC ERROR !\n"); workreq->result = 0x02; @@ -407,8 +448,8 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) workreq->result = 0x02; if (dev->dev_id == ATP885_DEVID) { - j = inb(dev->baseport + 0x29) | 0x01; - outb(j, dev->baseport + 0x29); + j = atp_readb_base(dev, 0x29) | 0x01; + atp_writeb_base(dev, 0x29, j); } /* * Complete the command @@ -430,10 +471,9 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) * Take it back wide */ if (dev->wide_id[c] != 0) { - outb(0x01, dev->ioport[c] + 0x1b); - while ((inb(dev->ioport[c] + 0x1b) & 0x01) != 0x01) { - outb(0x01, dev->ioport[c] + 0x1b); - } + atp_writeb_io(dev, c, 0x1b, 0x01); + while ((atp_readb_io(dev, c, 0x1b) & 0x01) != 0x01) + atp_writeb_io(dev, c, 0x1b, 0x01); } /* * If there is stuff to send and nothing going then send it @@ -458,52 +498,51 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) } i &= 0x0f; if (i == 0x09) { - outl(dev->id[c][target_id].prdaddr, dev->pciport[c] + 4); - outb(0x06, dev->pciport[c] + 2); - outb(0x00, dev->pciport[c] + 2); - outb(0x41, dev->ioport[c] + 0x10); + atp_writel_pci(dev, c, 4, dev->id[c][target_id].prdaddr); + atp_writeb_pci(dev, c, 2, 0x06); + atp_writeb_pci(dev, c, 2, 0x00); + atp_writeb_io(dev, c, 0x10, 0x41); if (dev->dev_id == ATP885_DEVID) { k = dev->id[c][target_id].last_len; - outb((unsigned char) (((unsigned char *) (&k))[2]), dev->ioport[c] + 0x12); - outb((unsigned char) (((unsigned char *) (&k))[1]), dev->ioport[c] + 0x13); - outb((unsigned char) (((unsigned char *) (&k))[0]), dev->ioport[c] + 0x14); + atp_writeb_io(dev, c, 0x12, ((unsigned char *) (&k))[2]); + atp_writeb_io(dev, c, 0x13, ((unsigned char *) (&k))[1]); + atp_writeb_io(dev, c, 0x14, ((unsigned char *) (&k))[0]); dev->id[c][target_id].dirct = 0x00; } else { dev->id[c][target_id].dirct = 0x00; } - outb(0x08, dev->ioport[c] + 0x18); - outb(0x09, dev->pciport[c]); + atp_writeb_io(dev, c, 0x18, 0x08); + atp_writeb_pci(dev, c, 0, 0x09); dev->in_int[c] = 0; return IRQ_HANDLED; } if (i == 0x08) { - outl(dev->id[c][target_id].prdaddr, dev->pciport[c] + 4); - outb(0x06, dev->pciport[c] + 2); - outb(0x00, dev->pciport[c] + 2); - outb(0x41, dev->ioport[c] + 0x10); + atp_writel_pci(dev, c, 4, dev->id[c][target_id].prdaddr); + atp_writeb_pci(dev, c, 2, 0x06); + atp_writeb_pci(dev, c, 2, 0x00); + atp_writeb_io(dev, c, 0x10, 0x41); if (dev->dev_id == ATP885_DEVID) { k = dev->id[c][target_id].last_len; - outb((unsigned char) (((unsigned char *) (&k))[2]), dev->ioport[c] + 0x12); - outb((unsigned char) (((unsigned char *) (&k))[1]), dev->ioport[c] + 0x13); - outb((unsigned char) (((unsigned char *) (&k))[0]), dev->ioport[c] + 0x14); + atp_writeb_io(dev, c, 0x12, ((unsigned char *) (&k))[2]); + atp_writeb_io(dev, c, 0x13, ((unsigned char *) (&k))[1]); + atp_writeb_io(dev, c, 0x14, ((unsigned char *) (&k))[0]); } - outb((unsigned char) (inb(dev->ioport[c] + 0x15) | 0x20), dev->ioport[c] + 0x15); + atp_writeb_io(dev, c, 0x15, atp_readb_io(dev, c, 0x15) | 0x20); dev->id[c][target_id].dirct = 0x20; - outb(0x08, dev->ioport[c] + 0x18); - outb(0x01, dev->pciport[c]); + atp_writeb_io(dev, c, 0x18, 0x08); + atp_writeb_pci(dev, c, 0, 0x01); dev->in_int[c] = 0; return IRQ_HANDLED; } - if (i == 0x0a) { - outb(0x30, dev->ioport[c] + 0x10); - } else { - outb(0x46, dev->ioport[c] + 0x10); - } + if (i == 0x0a) + atp_writeb_io(dev, c, 0x10, 0x30); + else + atp_writeb_io(dev, c, 0x10, 0x46); dev->id[c][target_id].dirct = 0x00; - outb(0x00, dev->ioport[c] + 0x12); - outb(0x00, dev->ioport[c] + 0x13); - outb(0x00, dev->ioport[c] + 0x14); - outb(0x08, dev->ioport[c] + 0x18); + atp_writeb_io(dev, c, 0x12, 0x00); + atp_writeb_io(dev, c, 0x13, 0x00); + atp_writeb_io(dev, c, 0x14, 0x00); + atp_writeb_io(dev, c, 0x18, 0x08); } dev->in_int[c] = 0; @@ -590,9 +629,9 @@ static int atp870u_queuecommand_lck(struct scsi_cmnd *req_p, } dev->quereq[c][dev->quend[c]] = req_p; #ifdef ED_DBGP - printk("dev->ioport[c] = %x inb(dev->ioport[c] + 0x1c) = %x dev->in_int[%d] = %d dev->in_snd[%d] = %d\n",dev->ioport[c],inb(dev->ioport[c] + 0x1c),c,dev->in_int[c],c,dev->in_snd[c]); + printk("dev->ioport[c] = %x atp_readb_io(dev, c, 0x1c) = %x dev->in_int[%d] = %d dev->in_snd[%d] = %d\n",dev->ioport[c],atp_readb_io(dev, c, 0x1c),c,dev->in_int[c],c,dev->in_snd[c]); #endif - if ((inb(dev->ioport[c] + 0x1c) == 0) && (dev->in_int[c] == 0) && (dev->in_snd[c] == 0)) { + if ((atp_readb_io(dev, c, 0x1c) == 0) && (dev->in_int[c] == 0) && (dev->in_snd[c] == 0)) { #ifdef ED_DBGP printk("Call sent_s870(atp870u_queuecommand)\n"); #endif @@ -666,7 +705,7 @@ static void send_s870(struct atp_unit *dev,unsigned char c) dev->id[c][scmd_id(workreq)].curr_req = workreq; dev->last_cmd[c] = scmd_id(workreq); } - if ((inb(dev->ioport[c] + 0x1f) & 0xb0) != 0 || inb(dev->ioport[c] + 0x1c) != 0) { + if ((atp_readb_io(dev, c, 0x1f) & 0xb0) != 0 || atp_readb_io(dev, c, 0x1c) != 0) { #ifdef ED_DBGP printk("Abort to Send\n"); #endif @@ -685,8 +724,8 @@ static void send_s870(struct atp_unit *dev,unsigned char c) l = scsi_bufflen(workreq); if (dev->dev_id == ATP885_DEVID) { - j = inb(dev->baseport + 0x29) & 0xfe; - outb(j, dev->baseport + 0x29); + j = atp_readb_base(dev, 0x29) & 0xfe; + atp_writeb_base(dev, 0x29, j); dev->r1f[c][scmd_id(workreq)] = 0; } @@ -709,9 +748,9 @@ static void send_s870(struct atp_unit *dev,unsigned char c) if ((w & dev->wide_id[c]) != 0) { j |= 0x01; } - outb(j, dev->ioport[c] + 0x1b); - while ((inb(dev->ioport[c] + 0x1b) & 0x01) != j) { - outb(j,dev->ioport[c] + 0x1b); + atp_writeb_io(dev, c, 0x1b, j); + while ((atp_readb_io(dev, c, 0x1b) & 0x01) != j) { + atp_writeb_pci(dev, c, 0x1b, j); #ifdef ED_DBGP printk("send_s870 while loop 1\n"); #endif @@ -720,21 +759,19 @@ static void send_s870(struct atp_unit *dev,unsigned char c) * Write the command */ - outb(workreq->cmd_len, dev->ioport[c] + 0x00); - outb(0x2c, dev->ioport[c] + 0x01); - if (dev->dev_id == ATP885_DEVID) { - outb(0x7f, dev->ioport[c] + 0x02); - } else { - outb(0xcf, dev->ioport[c] + 0x02); - } - for (i = 0; i < workreq->cmd_len; i++) { - outb(workreq->cmnd[i], dev->ioport[c] + 0x03 + i); - } - outb(workreq->device->lun, dev->ioport[c] + 0x0f); + atp_writeb_io(dev, c, 0x00, workreq->cmd_len); + atp_writeb_io(dev, c, 0x01, 0x2c); + if (dev->dev_id == ATP885_DEVID) + atp_writeb_io(dev, c, 0x02, 0x7f); + else + atp_writeb_io(dev, c, 0x02, 0xcf); + for (i = 0; i < workreq->cmd_len; i++) + atp_writeb_io(dev, c, 0x03 + i, workreq->cmnd[i]); + atp_writeb_io(dev, c, 0x0f, workreq->device->lun); /* * Write the target */ - outb(dev->id[c][target_id].devsp, dev->ioport[c] + 0x11); + atp_writeb_io(dev, c, 0x11, dev->id[c][target_id].devsp); #ifdef ED_DBGP printk("dev->id[%d][%d].devsp = %2x\n",c,target_id,dev->id[c][target_id].devsp); #endif @@ -743,9 +780,9 @@ static void send_s870(struct atp_unit *dev,unsigned char c) /* * Write transfer size */ - outb((unsigned char) (((unsigned char *) (&l))[2]), dev->ioport[c] + 0x12); - outb((unsigned char) (((unsigned char *) (&l))[1]), dev->ioport[c] + 0x13); - outb((unsigned char) (((unsigned char *) (&l))[0]), dev->ioport[c] + 0x14); + atp_writeb_io(dev, c, 0x12, ((unsigned char *) (&l))[2]); + atp_writeb_io(dev, c, 0x13, ((unsigned char *) (&l))[1]); + atp_writeb_io(dev, c, 0x14, ((unsigned char *) (&l))[0]); j = target_id; dev->id[c][j].last_len = l; dev->id[c][j].tran_len = 0; @@ -761,23 +798,21 @@ static void send_s870(struct atp_unit *dev,unsigned char c) /* * Check transfer direction */ - if (workreq->sc_data_direction == DMA_TO_DEVICE) { - outb((unsigned char) (j | 0x20), dev->ioport[c] + 0x15); - } else { - outb(j, dev->ioport[c] + 0x15); - } - outb((unsigned char) (inb(dev->ioport[c] + 0x16) | 0x80), dev->ioport[c] + 0x16); - outb(0x80, dev->ioport[c] + 0x16); + if (workreq->sc_data_direction == DMA_TO_DEVICE) + atp_writeb_io(dev, c, 0x15, j | 0x20); + else + atp_writeb_io(dev, c, 0x15, j); + atp_writeb_io(dev, c, 0x16, atp_readb_io(dev, c, 0x16) | 0x80); + atp_writeb_io(dev, c, 0x16, 0x80); dev->id[c][target_id].dirct = 0; if (l == 0) { - if (inb(dev->ioport[c] + 0x1c) == 0) { + if (atp_readb_io(dev, c, 0x1c) == 0) { #ifdef ED_DBGP printk("change SCSI_CMD_REG 0x08\n"); #endif - outb(0x08, dev->ioport[c] + 0x18); - } else { + atp_writeb_io(dev, c, 0x18, 0x08); + } else dev->last_cmd[c] |= 0x40; - } dev->in_snd[c] = 0; return; } @@ -821,36 +856,34 @@ static void send_s870(struct atp_unit *dev,unsigned char c) printk("send_s870: prdaddr_2 0x%8x target_id %d\n", dev->id[c][target_id].prdaddr,target_id); #endif dev->id[c][target_id].prdaddr = dev->id[c][target_id].prd_bus; - outl(dev->id[c][target_id].prdaddr, dev->pciport[c] + 4); - outb(0x06, dev->pciport[c] + 2); - outb(0x00, dev->pciport[c] + 2); + atp_writel_pci(dev, c, 4, dev->id[c][target_id].prdaddr); + atp_writeb_pci(dev, c, 2, 0x06); + atp_writeb_pci(dev, c, 2, 0x00); if (dev->dev_id == ATP885_DEVID) { - j = inb(dev->pciport[c] + 1) & 0xf3; + j = atp_readb_pci(dev, c, 1) & 0xf3; if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { j |= 0x0c; } - outb(j, dev->pciport[c] + 1); + atp_writeb_pci(dev, c, 1, j); } else if ((dev->dev_id == ATP880_DEVID1) || (dev->dev_id == ATP880_DEVID2)) { - if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { - outb((unsigned char) ((inb(dev->ioport[c] - 0x05) & 0x3f) | 0xc0), dev->ioport[c] - 0x05); - } else { - outb((unsigned char) (inb(dev->ioport[c] - 0x05) & 0x3f), dev->ioport[c] - 0x05); - } + if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) + atp_writeb_base(dev, 0x3b, (atp_readb_base(dev, 0x3b) & 0x3f) | 0xc0); + else + atp_writeb_base(dev, 0x3b, atp_readb_base(dev, 0x3b) & 0x3f); } else { - if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { - outb((inb(dev->ioport[c] + 0x3a) & 0xf3) | 0x08, dev->ioport[c] + 0x3a); - } else { - outb(inb(dev->ioport[c] + 0x3a) & 0xf3, dev->ioport[c] + 0x3a); - } + if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) + atp_writeb_io(dev, c, 0x3a, (atp_readb_io(dev, c, 0x3a) & 0xf3) | 0x08); + else + atp_writeb_io(dev, c, 0x3a, atp_readb_io(dev, c, 0x3a) & 0xf3); } if(workreq->sc_data_direction == DMA_TO_DEVICE) { dev->id[c][target_id].dirct = 0x20; - if (inb(dev->ioport[c] + 0x1c) == 0) { - outb(0x08, dev->ioport[c] + 0x18); - outb(0x01, dev->pciport[c]); + if (atp_readb_io(dev, c, 0x1c) == 0) { + atp_writeb_io(dev, c, 0x18, 0x08); + atp_writeb_pci(dev, c, 0, 0x01); #ifdef ED_DBGP printk( "start DMA(to target)\n"); #endif @@ -860,9 +893,9 @@ static void send_s870(struct atp_unit *dev,unsigned char c) dev->in_snd[c] = 0; return; } - if (inb(dev->ioport[c] + 0x1c) == 0) { - outb(0x08, dev->ioport[c] + 0x18); - outb(0x09, dev->pciport[c]); + if (atp_readb_io(dev, c, 0x1c) == 0) { + atp_writeb_io(dev, c, 0x18, 0x08); + atp_writeb_pci(dev, c, 0, 0x09); #ifdef ED_DBGP printk( "start DMA(to host)\n"); #endif @@ -879,28 +912,28 @@ static unsigned char fun_scam(struct atp_unit *dev, unsigned short int *val) unsigned short int i, k; unsigned char j; - outw(*val, dev->ioport[0] + 0x1c); + atp_writew_io(dev, 0, 0x1c, *val); for (i = 0; i < 10; i++) { /* stable >= bus settle delay(400 ns) */ - k = inw(dev->ioport[0] + 0x1c); + k = atp_readw_io(dev, 0, 0x1c); j = (unsigned char) (k >> 8); if ((k & 0x8000) != 0) /* DB7 all release? */ i = 0; } *val |= 0x4000; /* assert DB6 */ - outw(*val, dev->ioport[0] + 0x1c); + atp_writew_io(dev, 0, 0x1c, *val); *val &= 0xdfff; /* assert DB5 */ - outw(*val, dev->ioport[0] + 0x1c); + atp_writew_io(dev, 0, 0x1c, *val); for (i = 0; i < 10; i++) { /* stable >= bus settle delay(400 ns) */ - if ((inw(dev->ioport[0] + 0x1c) & 0x2000) != 0) /* DB5 all release? */ + if ((atp_readw_io(dev, 0, 0x1c) & 0x2000) != 0) /* DB5 all release? */ i = 0; } *val |= 0x8000; /* no DB4-0, assert DB7 */ *val &= 0xe0ff; - outw(*val, dev->ioport[0] + 0x1c); + atp_writew_io(dev, 0, 0x1c, *val); *val &= 0xbfff; /* release DB6 */ - outw(*val, dev->ioport[0] + 0x1c); + atp_writew_io(dev, 0, 0x1c, *val); for (i = 0; i < 10; i++) { /* stable >= bus settle delay(400 ns) */ - if ((inw(dev->ioport[0] + 0x1c) & 0x4000) != 0) /* DB6 all release? */ + if ((atp_readw_io(dev, 0, 0x1c) & 0x4000) != 0) /* DB6 all release? */ i = 0; } @@ -926,9 +959,9 @@ static void tscam(struct Scsi_Host *host) } */ - outb(0x08, dev->ioport[0] + 1); - outb(0x7f, dev->ioport[0] + 2); - outb(0x20, dev->ioport[0] + 0x11); + atp_writeb_io(dev, 0, 1, 0x08); + atp_writeb_io(dev, 0, 2, 0x7f); + atp_writeb_io(dev, 0, 0x11, 0x20); if ((dev->scam_on & 0x40) == 0) { return; @@ -941,13 +974,13 @@ static void tscam(struct Scsi_Host *host) j = 8; } assignid_map = m; - outb(0x02, dev->ioport[0] + 0x02); /* 2*2=4ms,3EH 2/32*3E=3.9ms */ - outb(0, dev->ioport[0] + 0x03); - outb(0, dev->ioport[0] + 0x04); - outb(0, dev->ioport[0] + 0x05); - outb(0, dev->ioport[0] + 0x06); - outb(0, dev->ioport[0] + 0x07); - outb(0, dev->ioport[0] + 0x08); + atp_writeb_io(dev, 0, 0x02, 0x02); /* 2*2=4ms,3EH 2/32*3E=3.9ms */ + atp_writeb_io(dev, 0, 0x03, 0); + atp_writeb_io(dev, 0, 0x04, 0); + atp_writeb_io(dev, 0, 0x05, 0); + atp_writeb_io(dev, 0, 0x06, 0); + atp_writeb_io(dev, 0, 0x07, 0); + atp_writeb_io(dev, 0, 0x08, 0); for (i = 0; i < j; i++) { m = 1; @@ -955,70 +988,69 @@ static void tscam(struct Scsi_Host *host) if ((m & assignid_map) != 0) { continue; } - outb(0, dev->ioport[0] + 0x0f); - outb(0, dev->ioport[0] + 0x12); - outb(0, dev->ioport[0] + 0x13); - outb(0, dev->ioport[0] + 0x14); + atp_writeb_io(dev, 0, 0x0f, 0); + atp_writeb_io(dev, 0, 0x12, 0); + atp_writeb_io(dev, 0, 0x13, 0); + atp_writeb_io(dev, 0, 0x14, 0); if (i > 7) { k = (i & 0x07) | 0x40; } else { k = i; } - outb(k, dev->ioport[0] + 0x15); - if (dev->chip_ver == 4) { - outb(0x01, dev->ioport[0] + 0x1b); - } else { - outb(0x00, dev->ioport[0] + 0x1b); - } + atp_writeb_io(dev, 0, 0x15, k); + if (dev->chip_ver == 4) + atp_writeb_io(dev, 0, 0x1b, 0x01); + else + atp_writeb_io(dev, 0, 0x1b, 0x00); do { - outb(0x09, dev->ioport[0] + 0x18); + atp_writeb_io(dev, 0, 0x18, 0x09); - while ((inb(dev->ioport[0] + 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - k = inb(dev->ioport[0] + 0x17); + k = atp_readb_io(dev, 0, 0x17); if ((k == 0x85) || (k == 0x42)) break; if (k != 0x16) - outb(0x41, dev->ioport[0] + 0x10); + atp_writeb_io(dev, 0, 0x10, 0x41); } while (k != 0x16); if ((k == 0x85) || (k == 0x42)) continue; assignid_map |= m; } - outb(0x7f, dev->ioport[0] + 0x02); - outb(0x02, dev->ioport[0] + 0x1b); + atp_writeb_io(dev, 0, 0x02, 0x7f); + atp_writeb_io(dev, 0, 0x1b, 0x02); outb(0, 0x80); val = 0x0080; /* bsy */ - outw(val, dev->ioport[0] + 0x1c); + atp_writew_io(dev, 0, 0x1c, val); val |= 0x0040; /* sel */ - outw(val, dev->ioport[0] + 0x1c); + atp_writew_io(dev, 0, 0x1c, val); val |= 0x0004; /* msg */ - outw(val, dev->ioport[0] + 0x1c); + atp_writew_io(dev, 0, 0x1c, val); inb(0x80); /* 2 deskew delay(45ns*2=90ns) */ val &= 0x007f; /* no bsy */ - outw(val, dev->ioport[0] + 0x1c); + atp_writew_io(dev, 0, 0x1c, val); mdelay(128); val &= 0x00fb; /* after 1ms no msg */ - outw(val, dev->ioport[0] + 0x1c); - while ((inb(dev->ioport[0] + 0x1c) & 0x04) != 0) + atp_writew_io(dev, 0, 0x1c, val); + while ((atp_readb_io(dev, 0, 0x1c) & 0x04) != 0) ; outb(1, 0x80); udelay(100); for (n = 0; n < 0x30000; n++) - if ((inb(dev->ioport[0] + 0x1c) & 0x80) != 0) /* bsy ? */ + if ((atp_readb_io(dev, 0, 0x1c) & 0x80) != 0) /* bsy ? */ break; if (n < 0x30000) for (n = 0; n < 0x30000; n++) - if ((inb(dev->ioport[0] + 0x1c) & 0x81) == 0x0081) { + if ((atp_readb_io(dev, 0, 0x1c) & 0x81) == 0x0081) { inb(0x80); val |= 0x8003; /* io,cd,db7 */ - outw(val, dev->ioport[0] + 0x1c); + atp_writew_io(dev, 0, 0x1c, val); inb(0x80); val &= 0x00bf; /* no sel */ - outw(val, dev->ioport[0] + 0x1c); + atp_writew_io(dev, 0, 0x1c, val); outb(2, 0x80); break; } @@ -1033,14 +1065,14 @@ static void tscam(struct Scsi_Host *host) */ mdelay(2); udelay(48); - if ((inb(dev->ioport[0] + 0x1c) & 0x80) == 0x00) { /* bsy ? */ - outw(0, dev->ioport[0] + 0x1c); - outb(0, dev->ioport[0] + 0x1b); - outb(0, dev->ioport[0] + 0x15); - outb(0x09, dev->ioport[0] + 0x18); - while ((inb(dev->ioport[0] + 0x1f) & 0x80) == 0) + if ((atp_readb_io(dev, 0, 0x1c) & 0x80) == 0x00) { /* bsy ? */ + atp_writew_io(dev, 0, 0x1c, 0); + atp_writeb_io(dev, 0, 0x1b, 0); + atp_writeb_io(dev, 0, 0x15, 0); + atp_writeb_io(dev, 0, 0x18, 0x09); + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0) cpu_relax(); - inb(dev->ioport[0] + 0x17); + atp_readb_io(dev, 0, 0x17); return; } val &= 0x00ff; /* synchronization */ @@ -1055,7 +1087,7 @@ static void tscam(struct Scsi_Host *host) j = 0; while (1) { - if ((inw(dev->ioport[0] + 0x1c) & 0x2000) == 0) + if ((atp_readw_io(dev, 0, 0x1c) & 0x2000) == 0) continue; outb(5, 0x80); val &= 0x00ff; /* get ID_STRING */ @@ -2232,6 +2264,7 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } base_io = pci_resource_start(pdev, 0); base_io &= 0xfffffff8; + atpdev->baseport = base_io; if ((ent->device == ATP880_DEVID1)||(ent->device == ATP880_DEVID2)) { atpdev->chip_ver = pdev->revision; @@ -2356,7 +2389,6 @@ flash_ok_880: atpdev->pdev = pdev; atpdev->dev_id = ent->device; - atpdev->baseport = base_io; atpdev->ioport[0] = base_io + 0x80; atpdev->ioport[1] = base_io + 0xc0; atpdev->pciport[0] = base_io + 0x40; @@ -2651,12 +2683,12 @@ static int atp870u_abort(struct scsi_cmnd * SCpnt) printk("working=%x last_cmd=%x ", dev->working[c], dev->last_cmd[c]); printk(" quhdu=%x quendu=%x ", dev->quhd[c], dev->quend[c]); for (j = 0; j < 0x18; j++) { - printk(" r%2x=%2x", j, inb(dev->ioport[c] + j)); + printk(" r%2x=%2x", j, atp_readb_io(dev, c, j)); } - printk(" r1c=%2x", inb(dev->ioport[c] + 0x1c)); - printk(" r1f=%2x in_snd=%2x ", inb(dev->ioport[c] + 0x1f), dev->in_snd[c]); - printk(" d00=%2x", inb(dev->pciport[c])); - printk(" d02=%2x", inb(dev->pciport[c] + 0x02)); + printk(" r1c=%2x", atp_readb_io(dev, c, 0x1c)); + printk(" r1f=%2x in_snd=%2x ", atp_readb_io(dev, c, 0x1f), dev->in_snd[c]); + printk(" d00=%2x", atp_readb_pci(dev, c, 0x00)); + printk(" d02=%2x", atp_readb_pci(dev, c, 0x02)); for(j=0;j<16;j++) { if (dev->id[c][j].curr_req != NULL) { workrequ = dev->id[c][j].curr_req; -- cgit v0.10.2 From 152c3ac5e18057dbec396db83c76fccfa44aa258 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:55 +0100 Subject: atp870u: Convert is870() to use wrappers Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 07b50ac..305eda8 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1162,7 +1162,7 @@ static void tscam(struct Scsi_Host *host) } } -static void is870(struct atp_unit *dev, unsigned int wkport) +static void is870(struct atp_unit *dev) { unsigned char i, j, k, rmb, n; unsigned short int m; @@ -1174,7 +1174,7 @@ static void is870(struct atp_unit *dev, unsigned int wkport) static unsigned char synw[6] = { 0x80, 1, 3, 1, 0x0c, 0x07 }; static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 }; - outb((unsigned char) (inb(wkport + 0x3a) | 0x10), wkport + 0x3a); + atp_writeb_io(dev, 0, 0x3a, atp_readb_io(dev, 0, 0x3a) | 0x10); for (i = 0; i < 16; i++) { if ((dev->chip_ver != 4) && (i > 7)) { @@ -1190,104 +1190,104 @@ static void is870(struct atp_unit *dev, unsigned int wkport) continue; } if (dev->chip_ver == 4) { - outb(0x01, wkport + 0x1b); + atp_writeb_io(dev, 0, 0x1b, 0x01); } else { - outb(0x00, wkport + 0x1b); - } - outb(0x08, wkport + 1); - outb(0x7f, wkport + 2); - outb(satn[0], wkport + 3); - outb(satn[1], wkport + 4); - outb(satn[2], wkport + 5); - outb(satn[3], wkport + 6); - outb(satn[4], wkport + 7); - outb(satn[5], wkport + 8); - outb(0, wkport + 0x0f); - outb(dev->id[0][i].devsp, wkport + 0x11); - outb(0, wkport + 0x12); - outb(satn[6], wkport + 0x13); - outb(satn[7], wkport + 0x14); + atp_writeb_io(dev, 0, 0x1b, 0x00); + } + atp_writeb_io(dev, 0, 1, 0x08); + atp_writeb_io(dev, 0, 2, 0x7f); + atp_writeb_io(dev, 0, 3, satn[0]); + atp_writeb_io(dev, 0, 4, satn[1]); + atp_writeb_io(dev, 0, 5, satn[2]); + atp_writeb_io(dev, 0, 6, satn[3]); + atp_writeb_io(dev, 0, 7, satn[4]); + atp_writeb_io(dev, 0, 8, satn[5]); + atp_writeb_io(dev, 0, 0x0f, 0); + atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); + atp_writeb_io(dev, 0, 0x12, 0); + atp_writeb_io(dev, 0, 0x13, satn[6]); + atp_writeb_io(dev, 0, 0x14, satn[7]); j = i; if ((j & 0x08) != 0) { j = (j & 0x07) | 0x40; } - outb(j, wkport + 0x15); - outb(satn[8], wkport + 0x18); + atp_writeb_io(dev, 0, 0x15, j); + atp_writeb_io(dev, 0, 0x18, satn[8]); - while ((inb(wkport + 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (inb(wkport + 0x17) != 0x11 && inb(wkport + 0x17) != 0x8e) + if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) continue; - while (inb(wkport + 0x17) != 0x8e) + while (atp_readb_io(dev, 0, 0x17) != 0x8e) cpu_relax(); dev->active_id[0] |= m; - outb(0x30, wkport + 0x10); - outb(0x00, wkport + 0x04); + atp_writeb_io(dev, 0, 0x10, 0x30); + atp_writeb_io(dev, 0, 0x04, 0x00); phase_cmd: - outb(0x08, wkport + 0x18); - while ((inb(wkport + 0x1f) & 0x80) == 0x00) + atp_writeb_io(dev, 0, 0x18, 0x08); + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x17); + j = atp_readb_io(dev, 0, 0x17); if (j != 0x16) { - outb(0x41, wkport + 0x10); + atp_writeb_io(dev, 0, 0x10, 0x41); goto phase_cmd; } sel_ok: - outb(inqd[0], wkport + 3); - outb(inqd[1], wkport + 4); - outb(inqd[2], wkport + 5); - outb(inqd[3], wkport + 6); - outb(inqd[4], wkport + 7); - outb(inqd[5], wkport + 8); - outb(0, wkport + 0x0f); - outb(dev->id[0][i].devsp, wkport + 0x11); - outb(0, wkport + 0x12); - outb(inqd[6], wkport + 0x13); - outb(inqd[7], wkport + 0x14); - outb(inqd[8], wkport + 0x18); + atp_writeb_io(dev, 0, 3, inqd[0]); + atp_writeb_io(dev, 0, 4, inqd[1]); + atp_writeb_io(dev, 0, 5, inqd[2]); + atp_writeb_io(dev, 0, 6, inqd[3]); + atp_writeb_io(dev, 0, 7, inqd[4]); + atp_writeb_io(dev, 0, 8, inqd[5]); + atp_writeb_io(dev, 0, 0x0f, 0); + atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); + atp_writeb_io(dev, 0, 0x12, 0); + atp_writeb_io(dev, 0, 0x13, inqd[6]); + atp_writeb_io(dev, 0, 0x14, inqd[7]); + atp_writeb_io(dev, 0, 0x18, inqd[8]); - while ((inb(wkport + 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (inb(wkport + 0x17) != 0x11 && inb(wkport + 0x17) != 0x8e) + if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) continue; - while (inb(wkport + 0x17) != 0x8e) + while (atp_readb_io(dev, 0, 0x17) != 0x8e) cpu_relax(); if (dev->chip_ver == 4) - outb(0x00, wkport + 0x1b); + atp_writeb_io(dev, 0, 0x1b, 0x00); - outb(0x08, wkport + 0x18); + atp_writeb_io(dev, 0, 0x18, 0x08); j = 0; rd_inq_data: - k = inb(wkport + 0x1f); + k = atp_readb_io(dev, 0, 0x1f); if ((k & 0x01) != 0) { - mbuf[j++] = inb(wkport + 0x19); + mbuf[j++] = atp_readb_io(dev, 0, 0x19); goto rd_inq_data; } if ((k & 0x80) == 0) { goto rd_inq_data; } - j = inb(wkport + 0x17); + j = atp_readb_io(dev, 0, 0x17); if (j == 0x16) { goto inq_ok; } - outb(0x46, wkport + 0x10); - outb(0, wkport + 0x12); - outb(0, wkport + 0x13); - outb(0, wkport + 0x14); - outb(0x08, wkport + 0x18); + atp_writeb_io(dev, 0, 0x10, 0x46); + atp_writeb_io(dev, 0, 0x12, 0); + atp_writeb_io(dev, 0, 0x13, 0); + atp_writeb_io(dev, 0, 0x14, 0); + atp_writeb_io(dev, 0, 0x18, 0x08); - while ((inb(wkport + 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (inb(wkport + 0x17) != 0x16) { + if (atp_readb_io(dev, 0, 0x17) != 0x16) { goto sel_ok; } inq_ok: @@ -1305,43 +1305,43 @@ inq_ok: if ((dev->global_map[0] & 0x20) == 0) { goto not_wide; } - outb(0x01, wkport + 0x1b); - outb(satn[0], wkport + 3); - outb(satn[1], wkport + 4); - outb(satn[2], wkport + 5); - outb(satn[3], wkport + 6); - outb(satn[4], wkport + 7); - outb(satn[5], wkport + 8); - outb(0, wkport + 0x0f); - outb(dev->id[0][i].devsp, wkport + 0x11); - outb(0, wkport + 0x12); - outb(satn[6], wkport + 0x13); - outb(satn[7], wkport + 0x14); - outb(satn[8], wkport + 0x18); + atp_writeb_io(dev, 0, 0x1b, 0x01); + atp_writeb_io(dev, 0, 3, satn[0]); + atp_writeb_io(dev, 0, 4, satn[1]); + atp_writeb_io(dev, 0, 5, satn[2]); + atp_writeb_io(dev, 0, 6, satn[3]); + atp_writeb_io(dev, 0, 7, satn[4]); + atp_writeb_io(dev, 0, 8, satn[5]); + atp_writeb_io(dev, 0, 0x0f, 0); + atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); + atp_writeb_io(dev, 0, 0x12, 0); + atp_writeb_io(dev, 0, 0x13, satn[6]); + atp_writeb_io(dev, 0, 0x14, satn[7]); + atp_writeb_io(dev, 0, 0x18, satn[8]); - while ((inb(wkport + 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (inb(wkport + 0x17) != 0x11 && inb(wkport + 0x17) != 0x8e) + if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) continue; - while (inb(wkport + 0x17) != 0x8e) + while (atp_readb_io(dev, 0, 0x17) != 0x8e) cpu_relax(); try_wide: j = 0; - outb(0x05, wkport + 0x14); - outb(0x20, wkport + 0x18); + atp_writeb_io(dev, 0, 0x14, 0x05); + atp_writeb_io(dev, 0, 0x18, 0x20); - while ((inb(wkport + 0x1f) & 0x80) == 0) { - if ((inb(wkport + 0x1f) & 0x01) != 0) - outb(wide[j++], wkport + 0x19); + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) + atp_writeb_io(dev, 0, 0x19, wide[j++]); } - while ((inb(wkport + 0x17) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x17) & 0x0f; + j = atp_readb_io(dev, 0, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -1353,12 +1353,12 @@ try_wide: } continue; widep_out: - outb(0x20, wkport + 0x18); - while ((inb(wkport + 0x1f) & 0x80) == 0) { - if ((inb(wkport + 0x1f) & 0x01) != 0) - outb(0, wkport + 0x19); + atp_writeb_io(dev, 0, 0x18, 0x20); + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) + atp_writeb_io(dev, 0, 0x19, 0); } - j = inb(wkport + 0x17) & 0x0f; + j = atp_readb_io(dev, 0, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -1370,19 +1370,19 @@ widep_out: } continue; widep_in: - outb(0xff, wkport + 0x14); - outb(0x20, wkport + 0x18); + atp_writeb_io(dev, 0, 0x14, 0xff); + atp_writeb_io(dev, 0, 0x18, 0x20); k = 0; widep_in1: - j = inb(wkport + 0x1f); + j = atp_readb_io(dev, 0, 0x1f); if ((j & 0x01) != 0) { - mbuf[k++] = inb(wkport + 0x19); + mbuf[k++] = atp_readb_io(dev, 0, 0x19); goto widep_in1; } if ((j & 0x80) == 0x00) { goto widep_in1; } - j = inb(wkport + 0x17) & 0x0f; + j = atp_readb_io(dev, 0, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -1394,14 +1394,14 @@ widep_in1: } continue; widep_cmd: - outb(0x30, wkport + 0x10); - outb(0x00, wkport + 0x14); - outb(0x08, wkport + 0x18); - - while ((inb(wkport + 0x1f) & 0x80) == 0x00) + atp_writeb_io(dev, 0, 0x10, 0x30); + atp_writeb_io(dev, 0, 0x14, 0x00); + atp_writeb_io(dev, 0, 0x18, 0x08); + + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x17); + j = atp_readb_io(dev, 0, 0x17); if (j != 0x16) { if (j == 0x4e) { goto widep_out; @@ -1433,52 +1433,52 @@ set_sync: if ((m & dev->wide_id[0]) != 0) { j |= 0x01; } - outb(j, wkport + 0x1b); - outb(satn[0], wkport + 3); - outb(satn[1], wkport + 4); - outb(satn[2], wkport + 5); - outb(satn[3], wkport + 6); - outb(satn[4], wkport + 7); - outb(satn[5], wkport + 8); - outb(0, wkport + 0x0f); - outb(dev->id[0][i].devsp, wkport + 0x11); - outb(0, wkport + 0x12); - outb(satn[6], wkport + 0x13); - outb(satn[7], wkport + 0x14); - outb(satn[8], wkport + 0x18); + atp_writeb_io(dev, 0, 0x1b, j); + atp_writeb_io(dev, 0, 3, satn[0]); + atp_writeb_io(dev, 0, 4, satn[1]); + atp_writeb_io(dev, 0, 5, satn[2]); + atp_writeb_io(dev, 0, 6, satn[3]); + atp_writeb_io(dev, 0, 7, satn[4]); + atp_writeb_io(dev, 0, 8, satn[5]); + atp_writeb_io(dev, 0, 0x0f, 0); + atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); + atp_writeb_io(dev, 0, 0x12, 0); + atp_writeb_io(dev, 0, 0x13, satn[6]); + atp_writeb_io(dev, 0, 0x14, satn[7]); + atp_writeb_io(dev, 0, 0x18, satn[8]); - while ((inb(wkport + 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (inb(wkport + 0x17) != 0x11 && inb(wkport + 0x17) != 0x8e) + if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) continue; - while (inb(wkport + 0x17) != 0x8e) + while (atp_readb_io(dev, 0, 0x17) != 0x8e) cpu_relax(); try_sync: j = 0; - outb(0x06, wkport + 0x14); - outb(0x20, wkport + 0x18); + atp_writeb_io(dev, 0, 0x14, 0x06); + atp_writeb_io(dev, 0, 0x18, 0x20); - while ((inb(wkport + 0x1f) & 0x80) == 0) { - if ((inb(wkport + 0x1f) & 0x01) != 0) { + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) { if ((m & dev->wide_id[0]) != 0) { - outb(synw[j++], wkport + 0x19); + atp_writeb_io(dev, 0, 0x19, synw[j++]); } else { if ((m & dev->ultra_map[0]) != 0) { - outb(synu[j++], wkport + 0x19); + atp_writeb_io(dev, 0, 0x19, synu[j++]); } else { - outb(synn[j++], wkport + 0x19); + atp_writeb_io(dev, 0, 0x19, synn[j++]); } } } } - while ((inb(wkport + 0x17) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x17) & 0x0f; + j = atp_readb_io(dev, 0, 0x17) & 0x0f; if (j == 0x0f) { goto phase_ins; } @@ -1490,12 +1490,12 @@ try_sync: } continue; phase_outs: - outb(0x20, wkport + 0x18); - while ((inb(wkport + 0x1f) & 0x80) == 0x00) { - if ((inb(wkport + 0x1f) & 0x01) != 0x00) - outb(0x00, wkport + 0x19); + atp_writeb_io(dev, 0, 0x18, 0x20); + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) { + if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0x00) + atp_writeb_io(dev, 0, 0x19, 0x00); } - j = inb(wkport + 0x17); + j = atp_readb_io(dev, 0, 0x17); if (j == 0x85) { goto tar_dcons; } @@ -1511,23 +1511,23 @@ phase_outs: } continue; phase_ins: - outb(0xff, wkport + 0x14); - outb(0x20, wkport + 0x18); + atp_writeb_io(dev, 0, 0x14, 0xff); + atp_writeb_io(dev, 0, 0x18, 0x20); k = 0; phase_ins1: - j = inb(wkport + 0x1f); + j = atp_readb_io(dev, 0, 0x1f); if ((j & 0x01) != 0x00) { - mbuf[k++] = inb(wkport + 0x19); + mbuf[k++] = atp_readb_io(dev, 0, 0x19); goto phase_ins1; } if ((j & 0x80) == 0x00) { goto phase_ins1; } - while ((inb(wkport + 0x17) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x17); + j = atp_readb_io(dev, 0, 0x17); if (j == 0x85) { goto tar_dcons; } @@ -1543,15 +1543,15 @@ phase_ins1: } continue; phase_cmds: - outb(0x30, wkport + 0x10); + atp_writeb_io(dev, 0, 0x10, 0x30); tar_dcons: - outb(0x00, wkport + 0x14); - outb(0x08, wkport + 0x18); + atp_writeb_io(dev, 0, 0x14, 0x00); + atp_writeb_io(dev, 0, 0x18, 0x08); - while ((inb(wkport + 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x17); + j = atp_readb_io(dev, 0, 0x17); if (j != 0x16) { continue; } @@ -1591,7 +1591,7 @@ tar_dcons: set_syn_ok: dev->id[0][i].devsp = (dev->id[0][i].devsp & 0x0f) | j; } - outb((unsigned char) (inb(wkport + 0x3a) & 0xef), wkport + 0x3a); + atp_writeb_io(dev, 0, 0x3a, atp_readb_io(dev, 0, 0x3a) & 0xef); } static void is880(struct atp_unit *dev, unsigned int wkport) @@ -2605,7 +2605,7 @@ flash_ok_885: outb(0x20, base_io + 0x11); tscam(shpnt); - is870(p, base_io); + is870(p); outb((inb(base_io + 0x3a) & 0xef), base_io + 0x3a); outb((inb(base_io + 0x3b) | 0x20), base_io + 0x3b); if (atpdev->chip_ver == 4) -- cgit v0.10.2 From 485025606b5bbd1024c9b2781fb8909afbd1a64d Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:56 +0100 Subject: atp870u: Convert is880() to use wrappers Subtract 0x40 to use _io access wrappers. Now it's obvious that is870() and is880() are very similar. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 305eda8..1b9276f 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1594,7 +1594,7 @@ set_syn_ok: atp_writeb_io(dev, 0, 0x3a, atp_readb_io(dev, 0, 0x3a) & 0xef); } -static void is880(struct atp_unit *dev, unsigned int wkport) +static void is880(struct atp_unit *dev) { unsigned char i, j, k, rmb, n, lvdmode; unsigned short int m; @@ -1608,7 +1608,7 @@ static void is880(struct atp_unit *dev, unsigned int wkport) static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 }; static unsigned char u3[9] = { 0x80, 1, 6, 4, 0x09, 00, 0x0e, 0x01, 0x02 }; - lvdmode = inb(wkport + 0x3f) & 0x40; + lvdmode = atp_readb_base(dev, 0x3f) & 0x40; for (i = 0; i < 16; i++) { m = 1; @@ -1620,100 +1620,100 @@ static void is880(struct atp_unit *dev, unsigned int wkport) printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_id[0]); continue; } - outb(0x01, wkport + 0x5b); - outb(0x08, wkport + 0x41); - outb(0x7f, wkport + 0x42); - outb(satn[0], wkport + 0x43); - outb(satn[1], wkport + 0x44); - outb(satn[2], wkport + 0x45); - outb(satn[3], wkport + 0x46); - outb(satn[4], wkport + 0x47); - outb(satn[5], wkport + 0x48); - outb(0, wkport + 0x4f); - outb(dev->id[0][i].devsp, wkport + 0x51); - outb(0, wkport + 0x52); - outb(satn[6], wkport + 0x53); - outb(satn[7], wkport + 0x54); + atp_writeb_io(dev, 0, 0x1b, 0x01); + atp_writeb_io(dev, 0, 1, 0x08); + atp_writeb_io(dev, 0, 2, 0x7f); + atp_writeb_io(dev, 0, 3, satn[0]); + atp_writeb_io(dev, 0, 4, satn[1]); + atp_writeb_io(dev, 0, 5, satn[2]); + atp_writeb_io(dev, 0, 6, satn[3]); + atp_writeb_io(dev, 0, 7, satn[4]); + atp_writeb_io(dev, 0, 8, satn[5]); + atp_writeb_io(dev, 0, 0x0f, 0); + atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); + atp_writeb_io(dev, 0, 0x12, 0); + atp_writeb_io(dev, 0, 0x13, satn[6]); + atp_writeb_io(dev, 0, 0x14, satn[7]); j = i; if ((j & 0x08) != 0) { j = (j & 0x07) | 0x40; } - outb(j, wkport + 0x55); - outb(satn[8], wkport + 0x58); + atp_writeb_io(dev, 0, 0x15, j); + atp_writeb_io(dev, 0, 0x18, satn[8]); - while ((inb(wkport + 0x5f) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (inb(wkport + 0x57) != 0x11 && inb(wkport + 0x57) != 0x8e) + if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) continue; - while (inb(wkport + 0x57) != 0x8e) + while (atp_readb_io(dev, 0, 0x17) != 0x8e) cpu_relax(); dev->active_id[0] |= m; - outb(0x30, wkport + 0x50); - outb(0x00, wkport + 0x54); + atp_writeb_io(dev, 0, 0x10, 0x30); + atp_writeb_io(dev, 0, 0x14, 0x00); phase_cmd: - outb(0x08, wkport + 0x58); + atp_writeb_io(dev, 0, 0x18, 0x08); - while ((inb(wkport + 0x5f) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x57); + j = atp_readb_io(dev, 0, 0x17); if (j != 0x16) { - outb(0x41, wkport + 0x50); + atp_writeb_io(dev, 0, 0x10, 0x41); goto phase_cmd; } sel_ok: - outb(inqd[0], wkport + 0x43); - outb(inqd[1], wkport + 0x44); - outb(inqd[2], wkport + 0x45); - outb(inqd[3], wkport + 0x46); - outb(inqd[4], wkport + 0x47); - outb(inqd[5], wkport + 0x48); - outb(0, wkport + 0x4f); - outb(dev->id[0][i].devsp, wkport + 0x51); - outb(0, wkport + 0x52); - outb(inqd[6], wkport + 0x53); - outb(inqd[7], wkport + 0x54); - outb(inqd[8], wkport + 0x58); + atp_writeb_io(dev, 0, 3, inqd[0]); + atp_writeb_io(dev, 0, 4, inqd[1]); + atp_writeb_io(dev, 0, 5, inqd[2]); + atp_writeb_io(dev, 0, 6, inqd[3]); + atp_writeb_io(dev, 0, 7, inqd[4]); + atp_writeb_io(dev, 0, 8, inqd[5]); + atp_writeb_io(dev, 0, 0x0f, 0); + atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); + atp_writeb_io(dev, 0, 0x12, 0); + atp_writeb_io(dev, 0, 0x13, inqd[6]); + atp_writeb_io(dev, 0, 0x14, inqd[7]); + atp_writeb_io(dev, 0, 0x18, inqd[8]); - while ((inb(wkport + 0x5f) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (inb(wkport + 0x57) != 0x11 && inb(wkport + 0x57) != 0x8e) + if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) continue; - while (inb(wkport + 0x57) != 0x8e) + while (atp_readb_io(dev, 0, 0x17) != 0x8e) cpu_relax(); - outb(0x00, wkport + 0x5b); - outb(0x08, wkport + 0x58); + atp_writeb_io(dev, 0, 0x1b, 0x00); + atp_writeb_io(dev, 0, 0x18, 0x08); j = 0; rd_inq_data: - k = inb(wkport + 0x5f); + k = atp_readb_io(dev, 0, 0x1f); if ((k & 0x01) != 0) { - mbuf[j++] = inb(wkport + 0x59); + mbuf[j++] = atp_readb_io(dev, 0, 0x19); goto rd_inq_data; } if ((k & 0x80) == 0) { goto rd_inq_data; } - j = inb(wkport + 0x57); + j = atp_readb_io(dev, 0, 0x17); if (j == 0x16) { goto inq_ok; } - outb(0x46, wkport + 0x50); - outb(0, wkport + 0x52); - outb(0, wkport + 0x53); - outb(0, wkport + 0x54); - outb(0x08, wkport + 0x58); - while ((inb(wkport + 0x5f) & 0x80) == 0x00) + atp_writeb_io(dev, 0, 0x10, 0x46); + atp_writeb_io(dev, 0, 0x12, 0); + atp_writeb_io(dev, 0, 0x13, 0); + atp_writeb_io(dev, 0, 0x14, 0); + atp_writeb_io(dev, 0, 0x18, 0x08); + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (inb(wkport + 0x57) != 0x16) + if (atp_readb_io(dev, 0, 0x17) != 0x16) goto sel_ok; inq_ok: @@ -1736,43 +1736,43 @@ inq_ok: goto chg_wide; } - outb(0x01, wkport + 0x5b); - outb(satn[0], wkport + 0x43); - outb(satn[1], wkport + 0x44); - outb(satn[2], wkport + 0x45); - outb(satn[3], wkport + 0x46); - outb(satn[4], wkport + 0x47); - outb(satn[5], wkport + 0x48); - outb(0, wkport + 0x4f); - outb(dev->id[0][i].devsp, wkport + 0x51); - outb(0, wkport + 0x52); - outb(satn[6], wkport + 0x53); - outb(satn[7], wkport + 0x54); - outb(satn[8], wkport + 0x58); - - while ((inb(wkport + 0x5f) & 0x80) == 0x00) + atp_writeb_io(dev, 0, 0x1b, 0x01); + atp_writeb_io(dev, 0, 3, satn[0]); + atp_writeb_io(dev, 0, 4, satn[1]); + atp_writeb_io(dev, 0, 5, satn[2]); + atp_writeb_io(dev, 0, 6, satn[3]); + atp_writeb_io(dev, 0, 7, satn[4]); + atp_writeb_io(dev, 0, 8, satn[5]); + atp_writeb_io(dev, 0, 0x0f, 0); + atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); + atp_writeb_io(dev, 0, 0x12, 0); + atp_writeb_io(dev, 0, 0x13, satn[6]); + atp_writeb_io(dev, 0, 0x14, satn[7]); + atp_writeb_io(dev, 0, 0x18, satn[8]); + + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (inb(wkport + 0x57) != 0x11 && inb(wkport + 0x57) != 0x8e) + if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) continue; - while (inb(wkport + 0x57) != 0x8e) + while (atp_readb_io(dev, 0, 0x17) != 0x8e) cpu_relax(); try_u3: j = 0; - outb(0x09, wkport + 0x54); - outb(0x20, wkport + 0x58); + atp_writeb_io(dev, 0, 0x14, 0x09); + atp_writeb_io(dev, 0, 0x18, 0x20); - while ((inb(wkport + 0x5f) & 0x80) == 0) { - if ((inb(wkport + 0x5f) & 0x01) != 0) - outb(u3[j++], wkport + 0x59); + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) + atp_writeb_io(dev, 0, 0x19, u3[j++]); } - while ((inb(wkport + 0x57) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x57) & 0x0f; + j = atp_readb_io(dev, 0, 0x17) & 0x0f; if (j == 0x0f) { goto u3p_in; } @@ -1784,12 +1784,12 @@ try_u3: } continue; u3p_out: - outb(0x20, wkport + 0x58); - while ((inb(wkport + 0x5f) & 0x80) == 0) { - if ((inb(wkport + 0x5f) & 0x01) != 0) - outb(0, wkport + 0x59); + atp_writeb_io(dev, 0, 0x18, 0x20); + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) + atp_writeb_io(dev, 0, 0x19, 0); } - j = inb(wkport + 0x57) & 0x0f; + j = atp_readb_io(dev, 0, 0x17) & 0x0f; if (j == 0x0f) { goto u3p_in; } @@ -1801,19 +1801,19 @@ u3p_out: } continue; u3p_in: - outb(0x09, wkport + 0x54); - outb(0x20, wkport + 0x58); + atp_writeb_io(dev, 0, 0x14, 0x09); + atp_writeb_io(dev, 0, 0x18, 0x20); k = 0; u3p_in1: - j = inb(wkport + 0x5f); + j = atp_readb_io(dev, 0, 0x1f); if ((j & 0x01) != 0) { - mbuf[k++] = inb(wkport + 0x59); + mbuf[k++] = atp_readb_io(dev, 0, 0x19); goto u3p_in1; } if ((j & 0x80) == 0x00) { goto u3p_in1; } - j = inb(wkport + 0x57) & 0x0f; + j = atp_readb_io(dev, 0, 0x17) & 0x0f; if (j == 0x0f) { goto u3p_in; } @@ -1825,14 +1825,14 @@ u3p_in1: } continue; u3p_cmd: - outb(0x30, wkport + 0x50); - outb(0x00, wkport + 0x54); - outb(0x08, wkport + 0x58); + atp_writeb_io(dev, 0, 0x10, 0x30); + atp_writeb_io(dev, 0, 0x14, 0x00); + atp_writeb_io(dev, 0, 0x18, 0x08); - while ((inb(wkport + 0x5f) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x57); + j = atp_readb_io(dev, 0, 0x17); if (j != 0x16) { if (j == 0x4e) { goto u3p_out; @@ -1856,42 +1856,42 @@ u3p_cmd: continue; } chg_wide: - outb(0x01, wkport + 0x5b); - outb(satn[0], wkport + 0x43); - outb(satn[1], wkport + 0x44); - outb(satn[2], wkport + 0x45); - outb(satn[3], wkport + 0x46); - outb(satn[4], wkport + 0x47); - outb(satn[5], wkport + 0x48); - outb(0, wkport + 0x4f); - outb(dev->id[0][i].devsp, wkport + 0x51); - outb(0, wkport + 0x52); - outb(satn[6], wkport + 0x53); - outb(satn[7], wkport + 0x54); - outb(satn[8], wkport + 0x58); - - while ((inb(wkport + 0x5f) & 0x80) == 0x00) + atp_writeb_io(dev, 0, 0x1b, 0x01); + atp_writeb_io(dev, 0, 3, satn[0]); + atp_writeb_io(dev, 0, 4, satn[1]); + atp_writeb_io(dev, 0, 5, satn[2]); + atp_writeb_io(dev, 0, 6, satn[3]); + atp_writeb_io(dev, 0, 7, satn[4]); + atp_writeb_io(dev, 0, 8, satn[5]); + atp_writeb_io(dev, 0, 0x0f, 0); + atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); + atp_writeb_io(dev, 0, 0x12, 0); + atp_writeb_io(dev, 0, 0x13, satn[6]); + atp_writeb_io(dev, 0, 0x14, satn[7]); + atp_writeb_io(dev, 0, 0x18, satn[8]); + + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (inb(wkport + 0x57) != 0x11 && inb(wkport + 0x57) != 0x8e) + if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) continue; - while (inb(wkport + 0x57) != 0x8e) + while (atp_readb_io(dev, 0, 0x17) != 0x8e) cpu_relax(); try_wide: j = 0; - outb(0x05, wkport + 0x54); - outb(0x20, wkport + 0x58); + atp_writeb_io(dev, 0, 0x14, 0x05); + atp_writeb_io(dev, 0, 0x18, 0x20); - while ((inb(wkport + 0x5f) & 0x80) == 0) { - if ((inb(wkport + 0x5f) & 0x01) != 0) - outb(wide[j++], wkport + 0x59); + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) + atp_writeb_io(dev, 0, 0x19, wide[j++]); } - while ((inb(wkport + 0x57) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x57) & 0x0f; + j = atp_readb_io(dev, 0, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -1903,12 +1903,12 @@ try_wide: } continue; widep_out: - outb(0x20, wkport + 0x58); - while ((inb(wkport + 0x5f) & 0x80) == 0) { - if ((inb(wkport + 0x5f) & 0x01) != 0) - outb(0, wkport + 0x59); + atp_writeb_io(dev, 0, 0x18, 0x20); + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) + atp_writeb_io(dev, 0, 0x19, 0); } - j = inb(wkport + 0x57) & 0x0f; + j = atp_readb_io(dev, 0, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -1920,19 +1920,19 @@ widep_out: } continue; widep_in: - outb(0xff, wkport + 0x54); - outb(0x20, wkport + 0x58); + atp_writeb_io(dev, 0, 0x14, 0xff); + atp_writeb_io(dev, 0, 0x18, 0x20); k = 0; widep_in1: - j = inb(wkport + 0x5f); + j = atp_readb_io(dev, 0, 0x1f); if ((j & 0x01) != 0) { - mbuf[k++] = inb(wkport + 0x59); + mbuf[k++] = atp_readb_io(dev, 0, 0x19); goto widep_in1; } if ((j & 0x80) == 0x00) { goto widep_in1; } - j = inb(wkport + 0x57) & 0x0f; + j = atp_readb_io(dev, 0, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -1944,14 +1944,14 @@ widep_in1: } continue; widep_cmd: - outb(0x30, wkport + 0x50); - outb(0x00, wkport + 0x54); - outb(0x08, wkport + 0x58); + atp_writeb_io(dev, 0, 0x10, 0x30); + atp_writeb_io(dev, 0, 0x14, 0x00); + atp_writeb_io(dev, 0, 0x18, 0x08); - while ((inb(wkport + 0x5f) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x57); + j = atp_readb_io(dev, 0, 0x17); if (j != 0x16) { if (j == 0x4e) { goto widep_out; @@ -1996,56 +1996,56 @@ set_sync: if ((m & dev->wide_id[0]) != 0) { j |= 0x01; } - outb(j, wkport + 0x5b); - outb(satn[0], wkport + 0x43); - outb(satn[1], wkport + 0x44); - outb(satn[2], wkport + 0x45); - outb(satn[3], wkport + 0x46); - outb(satn[4], wkport + 0x47); - outb(satn[5], wkport + 0x48); - outb(0, wkport + 0x4f); - outb(dev->id[0][i].devsp, wkport + 0x51); - outb(0, wkport + 0x52); - outb(satn[6], wkport + 0x53); - outb(satn[7], wkport + 0x54); - outb(satn[8], wkport + 0x58); - - while ((inb(wkport + 0x5f) & 0x80) == 0x00) + atp_writeb_io(dev, 0, 0x1b, j); + atp_writeb_io(dev, 0, 3, satn[0]); + atp_writeb_io(dev, 0, 4, satn[1]); + atp_writeb_io(dev, 0, 5, satn[2]); + atp_writeb_io(dev, 0, 6, satn[3]); + atp_writeb_io(dev, 0, 7, satn[4]); + atp_writeb_io(dev, 0, 8, satn[5]); + atp_writeb_io(dev, 0, 0x0f, 0); + atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); + atp_writeb_io(dev, 0, 0x12, 0); + atp_writeb_io(dev, 0, 0x13, satn[6]); + atp_writeb_io(dev, 0, 0x14, satn[7]); + atp_writeb_io(dev, 0, 0x18, satn[8]); + + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - if ((inb(wkport + 0x57) != 0x11) && (inb(wkport + 0x57) != 0x8e)) { + if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) { continue; } - while (inb(wkport + 0x57) != 0x8e) + while (atp_readb_io(dev, 0, 0x17) != 0x8e) cpu_relax(); try_sync: j = 0; - outb(0x06, wkport + 0x54); - outb(0x20, wkport + 0x58); + atp_writeb_io(dev, 0, 0x14, 0x06); + atp_writeb_io(dev, 0, 0x18, 0x20); - while ((inb(wkport + 0x5f) & 0x80) == 0) { - if ((inb(wkport + 0x5f) & 0x01) != 0) { + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) { if ((m & dev->wide_id[0]) != 0) { if ((m & dev->ultra_map[0]) != 0) { - outb(synuw[j++], wkport + 0x59); + atp_writeb_io(dev, 0, 0x19, synuw[j++]); } else { - outb(synw[j++], wkport + 0x59); + atp_writeb_io(dev, 0, 0x19, synw[j++]); } } else { if ((m & dev->ultra_map[0]) != 0) { - outb(synu[j++], wkport + 0x59); + atp_writeb_io(dev, 0, 0x19, synu[j++]); } else { - outb(synn[j++], wkport + 0x59); + atp_writeb_io(dev, 0, 0x19, synn[j++]); } } } } - while ((inb(wkport + 0x57) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x57) & 0x0f; + j = atp_readb_io(dev, 0, 0x17) & 0x0f; if (j == 0x0f) { goto phase_ins; } @@ -2057,12 +2057,12 @@ try_sync: } continue; phase_outs: - outb(0x20, wkport + 0x58); - while ((inb(wkport + 0x5f) & 0x80) == 0x00) { - if ((inb(wkport + 0x5f) & 0x01) != 0x00) - outb(0x00, wkport + 0x59); + atp_writeb_io(dev, 0, 0x18, 0x20); + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) { + if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0x00) + atp_writeb_io(dev, 0, 0x19, 0x00); } - j = inb(wkport + 0x57); + j = atp_readb_io(dev, 0, 0x17); if (j == 0x85) { goto tar_dcons; } @@ -2078,23 +2078,23 @@ phase_outs: } continue; phase_ins: - outb(0x06, wkport + 0x54); - outb(0x20, wkport + 0x58); + atp_writeb_io(dev, 0, 0x14, 0x06); + atp_writeb_io(dev, 0, 0x18, 0x20); k = 0; phase_ins1: - j = inb(wkport + 0x5f); + j = atp_readb_io(dev, 0, 0x1f); if ((j & 0x01) != 0x00) { - mbuf[k++] = inb(wkport + 0x59); + mbuf[k++] = atp_readb_io(dev, 0, 0x19); goto phase_ins1; } if ((j & 0x80) == 0x00) { goto phase_ins1; } - while ((inb(wkport + 0x57) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x57); + j = atp_readb_io(dev, 0, 0x17); if (j == 0x85) { goto tar_dcons; } @@ -2110,15 +2110,15 @@ phase_ins1: } continue; phase_cmds: - outb(0x30, wkport + 0x50); + atp_writeb_io(dev, 0, 0x10, 0x30); tar_dcons: - outb(0x00, wkport + 0x54); - outb(0x08, wkport + 0x58); + atp_writeb_io(dev, 0, 0x14, 0x00); + atp_writeb_io(dev, 0, 0x18, 0x08); - while ((inb(wkport + 0x5f) & 0x80) == 0x00) + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x57); + j = atp_readb_io(dev, 0, 0x17); if (j != 0x16) { continue; } @@ -2375,7 +2375,7 @@ flash_ok_880: outb(0x20, base_io + 0x51); tscam(shpnt); - is880(p, base_io); + is880(p); outb(0xb0, base_io + 0x38); shpnt->max_id = 16; shpnt->this_id = host_id; -- cgit v0.10.2 From 5d2a5a4f86616587a37e0c50dbef359d3078d9f5 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:57 +0100 Subject: atp870u: Convert is885() to use wrappers Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 1b9276f..ad7af54 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -41,7 +41,7 @@ static struct scsi_host_template atp870u_template; static void send_s870(struct atp_unit *dev,unsigned char c); -static void is885(struct atp_unit *dev, unsigned int wkport,unsigned char c); +static void is885(struct atp_unit *dev, unsigned char c); static void tscam_885(void); static inline void atp_writeb_base(struct atp_unit *atp, u8 reg, u8 val) @@ -2521,9 +2521,9 @@ flash_ok_885: tscam_885(); printk(KERN_INFO " Scanning Channel A SCSI Device ...\n"); - is885(p, base_io + 0x80, 0); + is885(p, 0); printk(KERN_INFO " Scanning Channel B SCSI Device ...\n"); - is885(p, base_io + 0xc0, 1); + is885(p, 1); k = inb(base_io + 0x28) & 0xcf; k |= 0xc0; @@ -2825,7 +2825,7 @@ static void tscam_885(void) -static void is885(struct atp_unit *dev, unsigned int wkport,unsigned char c) +static void is885(struct atp_unit *dev, unsigned char c) { unsigned char i, j, k, rmb, n, lvdmode; unsigned short int m; @@ -2839,7 +2839,7 @@ static void is885(struct atp_unit *dev, unsigned int wkport,unsigned char c) static unsigned char wide[6] = {0x80, 1, 2, 3, 1, 0}; static unsigned char u3[9] = { 0x80,1,6,4,0x09,00,0x0e,0x01,0x02 }; - lvdmode=inb(wkport + 0x1b) >> 7; + lvdmode=atp_readb_io(dev, c, 0x1b) >> 7; for (i = 0; i < 16; i++) { m = 1; @@ -2851,93 +2851,93 @@ static void is885(struct atp_unit *dev, unsigned int wkport,unsigned char c) printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_id[c]); continue; } - outb(0x01, wkport + 0x1b); - outb(0x08, wkport + 0x01); - outb(0x7f, wkport + 0x02); - outb(satn[0], wkport + 0x03); - outb(satn[1], wkport + 0x04); - outb(satn[2], wkport + 0x05); - outb(satn[3], wkport + 0x06); - outb(satn[4], wkport + 0x07); - outb(satn[5], wkport + 0x08); - outb(0, wkport + 0x0f); - outb(dev->id[c][i].devsp, wkport + 0x11); + atp_writeb_io(dev, c, 0x1b, 0x01); + atp_writeb_io(dev, c, 1, 0x08); + atp_writeb_io(dev, c, 2, 0x7f); + atp_writeb_io(dev, c, 3, satn[0]); + atp_writeb_io(dev, c, 4, satn[1]); + atp_writeb_io(dev, c, 5, satn[2]); + atp_writeb_io(dev, c, 6, satn[3]); + atp_writeb_io(dev, c, 7, satn[4]); + atp_writeb_io(dev, c, 8, satn[5]); + atp_writeb_io(dev, c, 0x0f, 0); + atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); - outb(0, wkport + 0x12); - outb(satn[6], wkport + 0x13); - outb(satn[7], wkport + 0x14); + atp_writeb_io(dev, c, 0x12, 0); + atp_writeb_io(dev, c, 0x13, satn[6]); + atp_writeb_io(dev, c, 0x14, satn[7]); j = i; if ((j & 0x08) != 0) { j = (j & 0x07) | 0x40; } - outb(j, wkport + 0x15); - outb(satn[8], wkport + 0x18); + atp_writeb_io(dev, c, 0x15, j); + atp_writeb_io(dev, c, 0x18, satn[8]); - while ((inb(wkport + 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if ((inb(wkport + 0x17) != 0x11) && (inb(wkport + 0x17) != 0x8e)) { + if ((atp_readb_io(dev, c, 0x17) != 0x11) && (atp_readb_io(dev, c, 0x17) != 0x8e)) { continue; } - while (inb(wkport + 0x17) != 0x8e) + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); dev->active_id[c] |= m; - outb(0x30, wkport + 0x10); - outb(0x00, wkport + 0x14); + atp_writeb_io(dev, c, 0x10, 0x30); + atp_writeb_io(dev, c, 0x14, 0x00); phase_cmd: - outb(0x08, wkport + 0x18); - while ((inb(wkport + 0x1f) & 0x80) == 0x00) + atp_writeb_io(dev, c, 0x18, 0x08); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x17); + j = atp_readb_io(dev, c, 0x17); if (j != 0x16) { - outb(0x41, wkport + 0x10); + atp_writeb_io(dev, c, 0x10, 0x41); goto phase_cmd; } sel_ok: - outb(inqd[0], wkport + 0x03); - outb(inqd[1], wkport + 0x04); - outb(inqd[2], wkport + 0x05); - outb(inqd[3], wkport + 0x06); - outb(inqd[4], wkport + 0x07); - outb(inqd[5], wkport + 0x08); - outb(0, wkport + 0x0f); - outb(dev->id[c][i].devsp, wkport + 0x11); - outb(0, wkport + 0x12); - outb(inqd[6], wkport + 0x13); - outb(inqd[7], wkport + 0x14); - outb(inqd[8], wkport + 0x18); - while ((inb(wkport + 0x1f) & 0x80) == 0x00) + atp_writeb_io(dev, c, 3, inqd[0]); + atp_writeb_io(dev, c, 4, inqd[1]); + atp_writeb_io(dev, c, 5, inqd[2]); + atp_writeb_io(dev, c, 6, inqd[3]); + atp_writeb_io(dev, c, 7, inqd[4]); + atp_writeb_io(dev, c, 8, inqd[5]); + atp_writeb_io(dev, c, 0x0f, 0); + atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); + atp_writeb_io(dev, c, 0x12, 0); + atp_writeb_io(dev, c, 0x13, inqd[6]); + atp_writeb_io(dev, c, 0x14, inqd[7]); + atp_writeb_io(dev, c, 0x18, inqd[8]); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if ((inb(wkport + 0x17) != 0x11) && (inb(wkport + 0x17) != 0x8e)) { + if ((atp_readb_io(dev, c, 0x17) != 0x11) && (atp_readb_io(dev, c, 0x17) != 0x8e)) { continue; } - while (inb(wkport + 0x17) != 0x8e) + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); - outb(0x00, wkport + 0x1b); - outb(0x08, wkport + 0x18); + atp_writeb_io(dev, c, 0x1b, 0x00); + atp_writeb_io(dev, c, 0x18, 0x08); j = 0; rd_inq_data: - k = inb(wkport + 0x1f); + k = atp_readb_io(dev, c, 0x1f); if ((k & 0x01) != 0) { - mbuf[j++] = inb(wkport + 0x19); + mbuf[j++] = atp_readb_io(dev, c, 0x19); goto rd_inq_data; } if ((k & 0x80) == 0) { goto rd_inq_data; } - j = inb(wkport + 0x17); + j = atp_readb_io(dev, c, 0x17); if (j == 0x16) { goto inq_ok; } - outb(0x46, wkport + 0x10); - outb(0, wkport + 0x12); - outb(0, wkport + 0x13); - outb(0, wkport + 0x14); - outb(0x08, wkport + 0x18); - while ((inb(wkport + 0x1f) & 0x80) == 0x00) + atp_writeb_io(dev, c, 0x10, 0x46); + atp_writeb_io(dev, c, 0x12, 0); + atp_writeb_io(dev, c, 0x13, 0); + atp_writeb_io(dev, c, 0x14, 0); + atp_writeb_io(dev, c, 0x18, 0x08); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (inb(wkport + 0x17) != 0x16) { + if (atp_readb_io(dev, c, 0x17) != 0x16) { goto sel_ok; } inq_ok: @@ -2959,40 +2959,40 @@ inq_ok: goto chg_wide; } - outb(0x01, wkport + 0x1b); - outb(satn[0], wkport + 0x03); - outb(satn[1], wkport + 0x04); - outb(satn[2], wkport + 0x05); - outb(satn[3], wkport + 0x06); - outb(satn[4], wkport + 0x07); - outb(satn[5], wkport + 0x08); - outb(0, wkport + 0x0f); - outb(dev->id[c][i].devsp, wkport + 0x11); - outb(0, wkport + 0x12); - outb(satn[6], wkport + 0x13); - outb(satn[7], wkport + 0x14); - outb(satn[8], wkport + 0x18); - - while ((inb(wkport + 0x1f) & 0x80) == 0x00) + atp_writeb_io(dev, c, 0x1b, 0x01); + atp_writeb_io(dev, c, 3, satn[0]); + atp_writeb_io(dev, c, 4, satn[1]); + atp_writeb_io(dev, c, 5, satn[2]); + atp_writeb_io(dev, c, 6, satn[3]); + atp_writeb_io(dev, c, 7, satn[4]); + atp_writeb_io(dev, c, 8, satn[5]); + atp_writeb_io(dev, c, 0x0f, 0); + atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); + atp_writeb_io(dev, c, 0x12, 0); + atp_writeb_io(dev, c, 0x13, satn[6]); + atp_writeb_io(dev, c, 0x14, satn[7]); + atp_writeb_io(dev, c, 0x18, satn[8]); + + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if ((inb(wkport + 0x17) != 0x11) && (inb(wkport + 0x17) != 0x8e)) { + if ((atp_readb_io(dev, c, 0x17) != 0x11) && (atp_readb_io(dev, c, 0x17) != 0x8e)) { continue; } - while (inb(wkport + 0x17) != 0x8e) + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); try_u3: j = 0; - outb(0x09, wkport + 0x14); - outb(0x20, wkport + 0x18); + atp_writeb_io(dev, c, 0x14, 0x09); + atp_writeb_io(dev, c, 0x18, 0x20); - while ((inb(wkport + 0x1f) & 0x80) == 0) { - if ((inb(wkport + 0x1f) & 0x01) != 0) - outb(u3[j++], wkport + 0x19); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) + atp_writeb_io(dev, c, 0x19, u3[j++]); cpu_relax(); } - while ((inb(wkport + 0x17) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto u3p_in; } @@ -3004,13 +3004,13 @@ try_u3: } continue; u3p_out: - outb(0x20, wkport + 0x18); - while ((inb(wkport + 0x1f) & 0x80) == 0) { - if ((inb(wkport + 0x1f) & 0x01) != 0) - outb(0, wkport + 0x19); + atp_writeb_io(dev, c, 0x18, 0x20); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) + atp_writeb_io(dev, c, 0x19, 0); cpu_relax(); } - j = inb(wkport + 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto u3p_in; } @@ -3022,19 +3022,19 @@ u3p_out: } continue; u3p_in: - outb(0x09, wkport + 0x14); - outb(0x20, wkport + 0x18); + atp_writeb_io(dev, c, 0x14, 0x09); + atp_writeb_io(dev, c, 0x18, 0x20); k = 0; u3p_in1: - j = inb(wkport + 0x1f); + j = atp_readb_io(dev, c, 0x1f); if ((j & 0x01) != 0) { - mbuf[k++] = inb(wkport + 0x19); + mbuf[k++] = atp_readb_io(dev, c, 0x19); goto u3p_in1; } if ((j & 0x80) == 0x00) { goto u3p_in1; } - j = inb(wkport + 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto u3p_in; } @@ -3046,11 +3046,11 @@ u3p_in1: } continue; u3p_cmd: - outb(0x30, wkport + 0x10); - outb(0x00, wkport + 0x14); - outb(0x08, wkport + 0x18); - while ((inb(wkport + 0x1f) & 0x80) == 0x00); - j = inb(wkport + 0x17); + atp_writeb_io(dev, c, 0x10, 0x30); + atp_writeb_io(dev, c, 0x14, 0x00); + atp_writeb_io(dev, c, 0x18, 0x08); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00); + j = atp_readb_io(dev, c, 0x17); if (j != 0x16) { if (j == 0x4e) { goto u3p_out; @@ -3077,40 +3077,40 @@ u3p_cmd: continue; } chg_wide: - outb(0x01, wkport + 0x1b); - outb(satn[0], wkport + 0x03); - outb(satn[1], wkport + 0x04); - outb(satn[2], wkport + 0x05); - outb(satn[3], wkport + 0x06); - outb(satn[4], wkport + 0x07); - outb(satn[5], wkport + 0x08); - outb(0, wkport + 0x0f); - outb(dev->id[c][i].devsp, wkport + 0x11); - outb(0, wkport + 0x12); - outb(satn[6], wkport + 0x13); - outb(satn[7], wkport + 0x14); - outb(satn[8], wkport + 0x18); - - while ((inb(wkport + 0x1f) & 0x80) == 0x00) + atp_writeb_io(dev, c, 0x1b, 0x01); + atp_writeb_io(dev, c, 3, satn[0]); + atp_writeb_io(dev, c, 4, satn[1]); + atp_writeb_io(dev, c, 5, satn[2]); + atp_writeb_io(dev, c, 6, satn[3]); + atp_writeb_io(dev, c, 7, satn[4]); + atp_writeb_io(dev, c, 8, satn[5]); + atp_writeb_io(dev, c, 0x0f, 0); + atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); + atp_writeb_io(dev, c, 0x12, 0); + atp_writeb_io(dev, c, 0x13, satn[6]); + atp_writeb_io(dev, c, 0x14, satn[7]); + atp_writeb_io(dev, c, 0x18, satn[8]); + + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if ((inb(wkport + 0x17) != 0x11) && (inb(wkport + 0x17) != 0x8e)) { + if ((atp_readb_io(dev, c, 0x17) != 0x11) && (atp_readb_io(dev, c, 0x17) != 0x8e)) { continue; } - while (inb(wkport + 0x17) != 0x8e) + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); try_wide: j = 0; - outb(0x05, wkport + 0x14); - outb(0x20, wkport + 0x18); + atp_writeb_io(dev, c, 0x14, 0x05); + atp_writeb_io(dev, c, 0x18, 0x20); - while ((inb(wkport + 0x1f) & 0x80) == 0) { - if ((inb(wkport + 0x1f) & 0x01) != 0) - outb(wide[j++], wkport + 0x19); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) + atp_writeb_io(dev, c, 0x19, wide[j++]); cpu_relax(); } - while ((inb(wkport + 0x17) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -3122,13 +3122,13 @@ try_wide: } continue; widep_out: - outb(0x20, wkport + 0x18); - while ((inb(wkport + 0x1f) & 0x80) == 0) { - if ((inb(wkport + 0x1f) & 0x01) != 0) - outb(0, wkport + 0x19); + atp_writeb_io(dev, c, 0x18, 0x20); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) + atp_writeb_io(dev, c, 0x19, 0); cpu_relax(); } - j = inb(wkport + 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -3140,19 +3140,19 @@ widep_out: } continue; widep_in: - outb(0xff, wkport + 0x14); - outb(0x20, wkport + 0x18); + atp_writeb_io(dev, c, 0x14, 0xff); + atp_writeb_io(dev, c, 0x18, 0x20); k = 0; widep_in1: - j = inb(wkport + 0x1f); + j = atp_readb_io(dev, c, 0x1f); if ((j & 0x01) != 0) { - mbuf[k++] = inb(wkport + 0x19); + mbuf[k++] = atp_readb_io(dev, c, 0x19); goto widep_in1; } if ((j & 0x80) == 0x00) { goto widep_in1; } - j = inb(wkport + 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -3164,12 +3164,12 @@ widep_in1: } continue; widep_cmd: - outb(0x30, wkport + 0x10); - outb(0x00, wkport + 0x14); - outb(0x08, wkport + 0x18); - while ((inb(wkport + 0x1f) & 0x80) == 0x00) + atp_writeb_io(dev, c, 0x10, 0x30); + atp_writeb_io(dev, c, 0x14, 0x00); + atp_writeb_io(dev, c, 0x18, 0x08); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x17); + j = atp_readb_io(dev, c, 0x17); if (j != 0x16) { if (j == 0x4e) { goto widep_out; @@ -3215,52 +3215,52 @@ set_sync: if ((m & dev->wide_id[c]) != 0) { j |= 0x01; } - outb(j, wkport + 0x1b); - outb(satn[0], wkport + 0x03); - outb(satn[1], wkport + 0x04); - outb(satn[2], wkport + 0x05); - outb(satn[3], wkport + 0x06); - outb(satn[4], wkport + 0x07); - outb(satn[5], wkport + 0x08); - outb(0, wkport + 0x0f); - outb(dev->id[c][i].devsp, wkport + 0x11); - outb(0, wkport + 0x12); - outb(satn[6], wkport + 0x13); - outb(satn[7], wkport + 0x14); - outb(satn[8], wkport + 0x18); - - while ((inb(wkport + 0x1f) & 0x80) == 0x00) + atp_writeb_io(dev, c, 0x1b, j); + atp_writeb_io(dev, c, 3, satn[0]); + atp_writeb_io(dev, c, 4, satn[1]); + atp_writeb_io(dev, c, 5, satn[2]); + atp_writeb_io(dev, c, 6, satn[3]); + atp_writeb_io(dev, c, 7, satn[4]); + atp_writeb_io(dev, c, 8, satn[5]); + atp_writeb_io(dev, c, 0x0f, 0); + atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); + atp_writeb_io(dev, c, 0x12, 0); + atp_writeb_io(dev, c, 0x13, satn[6]); + atp_writeb_io(dev, c, 0x14, satn[7]); + atp_writeb_io(dev, c, 0x18, satn[8]); + + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if ((inb(wkport + 0x17) != 0x11) && (inb(wkport + 0x17) != 0x8e)) { + if ((atp_readb_io(dev, c, 0x17) != 0x11) && (atp_readb_io(dev, c, 0x17) != 0x8e)) { continue; } - while (inb(wkport + 0x17) != 0x8e) + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); try_sync: j = 0; - outb(0x06, wkport + 0x14); - outb(0x20, wkport + 0x18); + atp_writeb_io(dev, c, 0x14, 0x06); + atp_writeb_io(dev, c, 0x18, 0x20); - while ((inb(wkport + 0x1f) & 0x80) == 0) { - if ((inb(wkport + 0x1f) & 0x01) != 0) { + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) { if ((m & dev->wide_id[c]) != 0) { if ((m & dev->ultra_map[c]) != 0) { - outb(synuw[j++], wkport + 0x19); + atp_writeb_io(dev, c, 0x19, synuw[j++]); } else { - outb(synw[j++], wkport + 0x19); + atp_writeb_io(dev, c, 0x19, synw[j++]); } } else { if ((m & dev->ultra_map[c]) != 0) { - outb(synu[j++], wkport + 0x19); + atp_writeb_io(dev, c, 0x19, synu[j++]); } else { - outb(synn[j++], wkport + 0x19); + atp_writeb_io(dev, c, 0x19, synn[j++]); } } } } - while ((inb(wkport + 0x17) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto phase_ins; } @@ -3272,13 +3272,13 @@ try_sync: } continue; phase_outs: - outb(0x20, wkport + 0x18); - while ((inb(wkport + 0x1f) & 0x80) == 0x00) { - if ((inb(wkport + 0x1f) & 0x01) != 0x00) - outb(0x00, wkport + 0x19); + atp_writeb_io(dev, c, 0x18, 0x20); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) { + if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0x00) + atp_writeb_io(dev, c, 0x19, 0x00); cpu_relax(); } - j = inb(wkport + 0x17); + j = atp_readb_io(dev, c, 0x17); if (j == 0x85) { goto tar_dcons; } @@ -3294,20 +3294,20 @@ phase_outs: } continue; phase_ins: - outb(0x06, wkport + 0x14); - outb(0x20, wkport + 0x18); + atp_writeb_io(dev, c, 0x14, 0x06); + atp_writeb_io(dev, c, 0x18, 0x20); k = 0; phase_ins1: - j = inb(wkport + 0x1f); + j = atp_readb_io(dev, c, 0x1f); if ((j & 0x01) != 0x00) { - mbuf[k++] = inb(wkport + 0x19); + mbuf[k++] = atp_readb_io(dev, c, 0x19); goto phase_ins1; } if ((j & 0x80) == 0x00) { goto phase_ins1; } - while ((inb(wkport + 0x17) & 0x80) == 0x00); - j = inb(wkport + 0x17); + while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00); + j = atp_readb_io(dev, c, 0x17); if (j == 0x85) { goto tar_dcons; } @@ -3323,13 +3323,13 @@ phase_ins1: } continue; phase_cmds: - outb(0x30, wkport + 0x10); + atp_writeb_io(dev, c, 0x10, 0x30); tar_dcons: - outb(0x00, wkport + 0x14); - outb(0x08, wkport + 0x18); - while ((inb(wkport + 0x1f) & 0x80) == 0x00) + atp_writeb_io(dev, c, 0x14, 0x00); + atp_writeb_io(dev, c, 0x18, 0x08); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - j = inb(wkport + 0x17); + j = atp_readb_io(dev, c, 0x17); if (j != 0x16) { continue; } @@ -3376,7 +3376,7 @@ tar_dcons: printk("dev->id[%2d][%2d].devsp = %2x\n",c,i,dev->id[c][i].devsp); #endif } - outb(0x80, wkport + 0x16); + atp_writeb_io(dev, c, 0x16, 0x80); } module_init(atp870u_init); -- cgit v0.10.2 From 80b52a7f8d2d432e21ba1bd47212bc1aa93b3647 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:58 +0100 Subject: atp870u: Unify code format in is870(), is880() and is885() Unify code formatting in is870(), is880() and is885() functions to simplify comparing them. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index ad7af54..595c5c5 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1173,7 +1173,7 @@ static void is870(struct atp_unit *dev) static unsigned char synu[6] = { 0x80, 1, 3, 1, 0x0c, 0x0e }; static unsigned char synw[6] = { 0x80, 1, 3, 1, 0x0c, 0x07 }; static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 }; - + atp_writeb_io(dev, 0, 0x3a, atp_readb_io(dev, 0, 0x3a) | 0x10); for (i = 0; i < 16; i++) { @@ -1230,8 +1230,10 @@ static void is870(struct atp_unit *dev) phase_cmd: atp_writeb_io(dev, 0, 0x18, 0x08); + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); + j = atp_readb_io(dev, 0, 0x17); if (j != 0x16) { atp_writeb_io(dev, 0, 0x10, 0x41); @@ -1253,13 +1255,13 @@ sel_ok: while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - + if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) continue; while (atp_readb_io(dev, 0, 0x17) != 0x8e) cpu_relax(); - + if (dev->chip_ver == 4) atp_writeb_io(dev, 0, 0x1b, 0x00); @@ -1286,10 +1288,10 @@ rd_inq_data: while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - - if (atp_readb_io(dev, 0, 0x17) != 0x16) { + + if (atp_readb_io(dev, 0, 0x17) != 0x16) goto sel_ok; - } + inq_ok: mbuf[36] = 0; printk(KERN_INFO " ID: %2d %s\n", i, &mbuf[8]); @@ -1321,13 +1323,13 @@ inq_ok: while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - + if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) continue; while (atp_readb_io(dev, 0, 0x17) != 0x8e) cpu_relax(); - + try_wide: j = 0; atp_writeb_io(dev, 0, 0x14, 0x05); @@ -1337,10 +1339,10 @@ try_wide: if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) atp_writeb_io(dev, 0, 0x19, wide[j++]); } - + while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) cpu_relax(); - + j = atp_readb_io(dev, 0, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; @@ -1449,13 +1451,13 @@ set_sync: while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - + if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) continue; while (atp_readb_io(dev, 0, 0x17) != 0x8e) cpu_relax(); - + try_sync: j = 0; atp_writeb_io(dev, 0, 0x14, 0x06); @@ -1474,10 +1476,10 @@ try_sync: } } } - + while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) cpu_relax(); - + j = atp_readb_io(dev, 0, 0x17) & 0x0f; if (j == 0x0f) { goto phase_ins; @@ -1526,7 +1528,7 @@ phase_ins1: while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) cpu_relax(); - + j = atp_readb_io(dev, 0, 0x17); if (j == 0x85) { goto tar_dcons; @@ -1547,10 +1549,10 @@ phase_cmds: tar_dcons: atp_writeb_io(dev, 0, 0x14, 0x00); atp_writeb_io(dev, 0, 0x18, 0x08); - + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - + j = atp_readb_io(dev, 0, 0x17); if (j != 0x16) { continue; @@ -1649,7 +1651,7 @@ static void is880(struct atp_unit *dev) while (atp_readb_io(dev, 0, 0x17) != 0x8e) cpu_relax(); - + dev->active_id[0] |= m; atp_writeb_io(dev, 0, 0x10, 0x30); @@ -1657,7 +1659,7 @@ static void is880(struct atp_unit *dev) phase_cmd: atp_writeb_io(dev, 0, 0x18, 0x08); - + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); @@ -1679,16 +1681,16 @@ sel_ok: atp_writeb_io(dev, 0, 0x13, inqd[6]); atp_writeb_io(dev, 0, 0x14, inqd[7]); atp_writeb_io(dev, 0, 0x18, inqd[8]); - + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - + if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) continue; while (atp_readb_io(dev, 0, 0x17) != 0x8e) cpu_relax(); - + atp_writeb_io(dev, 0, 0x1b, 0x00); atp_writeb_io(dev, 0, 0x18, 0x08); j = 0; @@ -1710,9 +1712,10 @@ rd_inq_data: atp_writeb_io(dev, 0, 0x13, 0); atp_writeb_io(dev, 0, 0x14, 0); atp_writeb_io(dev, 0, 0x18, 0x08); + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - + if (atp_readb_io(dev, 0, 0x17) != 0x16) goto sel_ok; @@ -1771,7 +1774,7 @@ try_u3: while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) cpu_relax(); - + j = atp_readb_io(dev, 0, 0x17) & 0x0f; if (j == 0x0f) { goto u3p_in; @@ -1828,10 +1831,10 @@ u3p_cmd: atp_writeb_io(dev, 0, 0x10, 0x30); atp_writeb_io(dev, 0, 0x14, 0x00); atp_writeb_io(dev, 0, 0x18, 0x08); - + while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - + j = atp_readb_io(dev, 0, 0x17); if (j != 0x16) { if (j == 0x4e) { @@ -1872,13 +1875,13 @@ chg_wide: while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - + if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) continue; while (atp_readb_io(dev, 0, 0x17) != 0x8e) cpu_relax(); - + try_wide: j = 0; atp_writeb_io(dev, 0, 0x14, 0x05); @@ -1888,9 +1891,10 @@ try_wide: if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) atp_writeb_io(dev, 0, 0x19, wide[j++]); } + while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) cpu_relax(); - + j = atp_readb_io(dev, 0, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; @@ -2013,9 +2017,9 @@ set_sync: while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) { + if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) continue; - } + while (atp_readb_io(dev, 0, 0x17) != 0x8e) cpu_relax(); @@ -2830,16 +2834,16 @@ static void is885(struct atp_unit *dev, unsigned char c) unsigned char i, j, k, rmb, n, lvdmode; unsigned short int m; static unsigned char mbuf[512]; - static unsigned char satn[9] = {0, 0, 0, 0, 0, 0, 0, 6, 6}; - static unsigned char inqd[9] = {0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6}; - static unsigned char synn[6] = {0x80, 1, 3, 1, 0x19, 0x0e}; - unsigned char synu[6] = {0x80, 1, 3, 1, 0x0a, 0x0e}; - static unsigned char synw[6] = {0x80, 1, 3, 1, 0x19, 0x0e}; - unsigned char synuw[6] = {0x80, 1, 3, 1, 0x0a, 0x0e}; - static unsigned char wide[6] = {0x80, 1, 2, 3, 1, 0}; - static unsigned char u3[9] = { 0x80,1,6,4,0x09,00,0x0e,0x01,0x02 }; + static unsigned char satn[9] = { 0, 0, 0, 0, 0, 0, 0, 6, 6 }; + static unsigned char inqd[9] = { 0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6 }; + static unsigned char synn[6] = { 0x80, 1, 3, 1, 0x19, 0x0e }; + unsigned char synu[6] = { 0x80, 1, 3, 1, 0x0a, 0x0e }; + static unsigned char synw[6] = { 0x80, 1, 3, 1, 0x19, 0x0e }; + unsigned char synuw[6] = { 0x80, 1, 3, 1, 0x0a, 0x0e }; + static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 }; + static unsigned char u3[9] = { 0x80, 1, 6, 4, 0x09, 00, 0x0e, 0x01, 0x02 }; - lvdmode=atp_readb_io(dev, c, 0x1b) >> 7; + lvdmode = atp_readb_io(dev, c, 0x1b) >> 7; for (i = 0; i < 16; i++) { m = 1; @@ -2862,7 +2866,6 @@ static void is885(struct atp_unit *dev, unsigned char c) atp_writeb_io(dev, c, 8, satn[5]); atp_writeb_io(dev, c, 0x0f, 0); atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); - atp_writeb_io(dev, c, 0x12, 0); atp_writeb_io(dev, c, 0x13, satn[6]); atp_writeb_io(dev, c, 0x14, satn[7]); @@ -2875,11 +2878,13 @@ static void is885(struct atp_unit *dev, unsigned char c) while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if ((atp_readb_io(dev, c, 0x17) != 0x11) && (atp_readb_io(dev, c, 0x17) != 0x8e)) { + + if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) continue; - } + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); + dev->active_id[c] |= m; atp_writeb_io(dev, c, 0x10, 0x30); @@ -2887,8 +2892,10 @@ static void is885(struct atp_unit *dev, unsigned char c) phase_cmd: atp_writeb_io(dev, c, 0x18, 0x08); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); + j = atp_readb_io(dev, c, 0x17); if (j != 0x16) { atp_writeb_io(dev, c, 0x10, 0x41); @@ -2907,13 +2914,16 @@ sel_ok: atp_writeb_io(dev, c, 0x13, inqd[6]); atp_writeb_io(dev, c, 0x14, inqd[7]); atp_writeb_io(dev, c, 0x18, inqd[8]); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if ((atp_readb_io(dev, c, 0x17) != 0x11) && (atp_readb_io(dev, c, 0x17) != 0x8e)) { + + if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) continue; - } + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); + atp_writeb_io(dev, c, 0x1b, 0x00); atp_writeb_io(dev, c, 0x18, 0x08); j = 0; @@ -2935,14 +2945,16 @@ rd_inq_data: atp_writeb_io(dev, c, 0x13, 0); atp_writeb_io(dev, c, 0x14, 0); atp_writeb_io(dev, c, 0x18, 0x08); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (atp_readb_io(dev, c, 0x17) != 0x16) { + + if (atp_readb_io(dev, c, 0x17) != 0x16) goto sel_ok; - } + inq_ok: mbuf[36] = 0; - printk( KERN_INFO" ID: %2d %s\n", i, &mbuf[8]); + printk(KERN_INFO " ID: %2d %s\n", i, &mbuf[8]); dev->id[c][i].devtype = mbuf[0]; rmb = mbuf[1]; n = mbuf[7]; @@ -2953,10 +2965,11 @@ inq_ok: goto not_wide; } if (lvdmode == 0) { - goto chg_wide; + goto chg_wide; } - if (dev->sp[c][i] != 0x04) { // force u2 - goto chg_wide; + if (dev->sp[c][i] != 0x04) // force u2 + { + goto chg_wide; } atp_writeb_io(dev, c, 0x1b, 0x01); @@ -2975,11 +2988,13 @@ inq_ok: while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if ((atp_readb_io(dev, c, 0x17) != 0x11) && (atp_readb_io(dev, c, 0x17) != 0x8e)) { + + if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) continue; - } + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); + try_u3: j = 0; atp_writeb_io(dev, c, 0x14, 0x09); @@ -2990,8 +3005,10 @@ try_u3: atp_writeb_io(dev, c, 0x19, u3[j++]); cpu_relax(); } + while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) cpu_relax(); + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto u3p_in; @@ -3049,7 +3066,9 @@ u3p_cmd: atp_writeb_io(dev, c, 0x10, 0x30); atp_writeb_io(dev, c, 0x14, 0x00); atp_writeb_io(dev, c, 0x18, 0x08); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00); + j = atp_readb_io(dev, c, 0x17); if (j != 0x16) { if (j == 0x4e) { @@ -3093,11 +3112,13 @@ chg_wide: while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if ((atp_readb_io(dev, c, 0x17) != 0x11) && (atp_readb_io(dev, c, 0x17) != 0x8e)) { + + if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) continue; - } + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); + try_wide: j = 0; atp_writeb_io(dev, c, 0x14, 0x05); @@ -3108,8 +3129,10 @@ try_wide: atp_writeb_io(dev, c, 0x19, wide[j++]); cpu_relax(); } + while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) cpu_relax(); + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; @@ -3167,8 +3190,10 @@ widep_cmd: atp_writeb_io(dev, c, 0x10, 0x30); atp_writeb_io(dev, c, 0x14, 0x00); atp_writeb_io(dev, c, 0x18, 0x08); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); + j = atp_readb_io(dev, c, 0x17); if (j != 0x16) { if (j == 0x4e) { @@ -3192,24 +3217,23 @@ widep_cmd: m = m << i; dev->wide_id[c] |= m; not_wide: - if ((dev->id[c][i].devtype == 0x00) || (dev->id[c][i].devtype == 0x07) || - ((dev->id[c][i].devtype == 0x05) && ((n & 0x10) != 0))) { + if ((dev->id[c][i].devtype == 0x00) || (dev->id[c][i].devtype == 0x07) || ((dev->id[c][i].devtype == 0x05) && ((n & 0x10) != 0))) { m = 1; m = m << i; if ((dev->async[c] & m) != 0) { - goto set_sync; + goto set_sync; } } continue; set_sync: if (dev->sp[c][i] == 0x02) { - synu[4]=0x0c; - synuw[4]=0x0c; + synu[4] = 0x0c; + synuw[4] = 0x0c; } else { - if (dev->sp[c][i] >= 0x03) { - synu[4]=0x0a; - synuw[4]=0x0a; - } + if (dev->sp[c][i] >= 0x03) { + synu[4] = 0x0a; + synuw[4] = 0x0a; + } } j = 0; if ((m & dev->wide_id[c]) != 0) { @@ -3231,11 +3255,13 @@ set_sync: while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if ((atp_readb_io(dev, c, 0x17) != 0x11) && (atp_readb_io(dev, c, 0x17) != 0x8e)) { + + if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) continue; - } + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); + try_sync: j = 0; atp_writeb_io(dev, c, 0x14, 0x06); @@ -3258,8 +3284,10 @@ try_sync: } } } + while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) cpu_relax(); + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto phase_ins; @@ -3306,7 +3334,9 @@ phase_ins1: if ((j & 0x80) == 0x00) { goto phase_ins1; } + while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00); + j = atp_readb_io(dev, c, 0x17); if (j == 0x85) { goto tar_dcons; @@ -3327,8 +3357,10 @@ phase_cmds: tar_dcons: atp_writeb_io(dev, c, 0x14, 0x00); atp_writeb_io(dev, c, 0x18, 0x08); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); + j = atp_readb_io(dev, c, 0x17); if (j != 0x16) { continue; @@ -3349,7 +3381,7 @@ tar_dcons: mbuf[4] = 0x0e; } dev->id[c][i].devsp = mbuf[4]; - if (mbuf[3] < 0x0c){ + if (mbuf[3] < 0x0c) { j = 0xb0; goto set_syn_ok; } @@ -3370,9 +3402,9 @@ tar_dcons: goto set_syn_ok; } j = 0x60; - set_syn_ok: +set_syn_ok: dev->id[c][i].devsp = (dev->id[c][i].devsp & 0x0f) | j; -#ifdef ED_DBGP +#ifdef ED_DBGP printk("dev->id[%2d][%2d].devsp = %2x\n",c,i,dev->id[c][i].devsp); #endif } -- cgit v0.10.2 From bdf8b62dc3fb2ef5df22d36d1d2ec1d38e081290 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:23:59 +0100 Subject: atp870u: Add channel parameter to is870() and is880() Add channel parameter to is870() and is880() functions to simplify comparing them with is885(). Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 595c5c5..ec61902 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1162,7 +1162,7 @@ static void tscam(struct Scsi_Host *host) } } -static void is870(struct atp_unit *dev) +static void is870(struct atp_unit *dev, unsigned char c) { unsigned char i, j, k, rmb, n; unsigned short int m; @@ -1174,7 +1174,7 @@ static void is870(struct atp_unit *dev) static unsigned char synw[6] = { 0x80, 1, 3, 1, 0x0c, 0x07 }; static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 }; - atp_writeb_io(dev, 0, 0x3a, atp_readb_io(dev, 0, 0x3a) | 0x10); + atp_writeb_io(dev, c, 0x3a, atp_readb_io(dev, c, 0x3a) | 0x10); for (i = 0; i < 16; i++) { if ((dev->chip_ver != 4) && (i > 7)) { @@ -1182,120 +1182,120 @@ static void is870(struct atp_unit *dev) } m = 1; m = m << i; - if ((m & dev->active_id[0]) != 0) { + if ((m & dev->active_id[c]) != 0) { continue; } - if (i == dev->host_id[0]) { - printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_id[0]); + if (i == dev->host_id[c]) { + printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_id[c]); continue; } if (dev->chip_ver == 4) { - atp_writeb_io(dev, 0, 0x1b, 0x01); + atp_writeb_io(dev, c, 0x1b, 0x01); } else { - atp_writeb_io(dev, 0, 0x1b, 0x00); + atp_writeb_io(dev, c, 0x1b, 0x00); } - atp_writeb_io(dev, 0, 1, 0x08); - atp_writeb_io(dev, 0, 2, 0x7f); - atp_writeb_io(dev, 0, 3, satn[0]); - atp_writeb_io(dev, 0, 4, satn[1]); - atp_writeb_io(dev, 0, 5, satn[2]); - atp_writeb_io(dev, 0, 6, satn[3]); - atp_writeb_io(dev, 0, 7, satn[4]); - atp_writeb_io(dev, 0, 8, satn[5]); - atp_writeb_io(dev, 0, 0x0f, 0); - atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); - atp_writeb_io(dev, 0, 0x12, 0); - atp_writeb_io(dev, 0, 0x13, satn[6]); - atp_writeb_io(dev, 0, 0x14, satn[7]); + atp_writeb_io(dev, c, 1, 0x08); + atp_writeb_io(dev, c, 2, 0x7f); + atp_writeb_io(dev, c, 3, satn[0]); + atp_writeb_io(dev, c, 4, satn[1]); + atp_writeb_io(dev, c, 5, satn[2]); + atp_writeb_io(dev, c, 6, satn[3]); + atp_writeb_io(dev, c, 7, satn[4]); + atp_writeb_io(dev, c, 8, satn[5]); + atp_writeb_io(dev, c, 0x0f, 0); + atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); + atp_writeb_io(dev, c, 0x12, 0); + atp_writeb_io(dev, c, 0x13, satn[6]); + atp_writeb_io(dev, c, 0x14, satn[7]); j = i; if ((j & 0x08) != 0) { j = (j & 0x07) | 0x40; } - atp_writeb_io(dev, 0, 0x15, j); - atp_writeb_io(dev, 0, 0x18, satn[8]); + atp_writeb_io(dev, c, 0x15, j); + atp_writeb_io(dev, c, 0x18, satn[8]); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) + if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) continue; - while (atp_readb_io(dev, 0, 0x17) != 0x8e) + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); - dev->active_id[0] |= m; + dev->active_id[c] |= m; - atp_writeb_io(dev, 0, 0x10, 0x30); - atp_writeb_io(dev, 0, 0x04, 0x00); + atp_writeb_io(dev, c, 0x10, 0x30); + atp_writeb_io(dev, c, 0x04, 0x00); phase_cmd: - atp_writeb_io(dev, 0, 0x18, 0x08); + atp_writeb_io(dev, c, 0x18, 0x08); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - j = atp_readb_io(dev, 0, 0x17); + j = atp_readb_io(dev, c, 0x17); if (j != 0x16) { - atp_writeb_io(dev, 0, 0x10, 0x41); + atp_writeb_io(dev, c, 0x10, 0x41); goto phase_cmd; } sel_ok: - atp_writeb_io(dev, 0, 3, inqd[0]); - atp_writeb_io(dev, 0, 4, inqd[1]); - atp_writeb_io(dev, 0, 5, inqd[2]); - atp_writeb_io(dev, 0, 6, inqd[3]); - atp_writeb_io(dev, 0, 7, inqd[4]); - atp_writeb_io(dev, 0, 8, inqd[5]); - atp_writeb_io(dev, 0, 0x0f, 0); - atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); - atp_writeb_io(dev, 0, 0x12, 0); - atp_writeb_io(dev, 0, 0x13, inqd[6]); - atp_writeb_io(dev, 0, 0x14, inqd[7]); - atp_writeb_io(dev, 0, 0x18, inqd[8]); + atp_writeb_io(dev, c, 3, inqd[0]); + atp_writeb_io(dev, c, 4, inqd[1]); + atp_writeb_io(dev, c, 5, inqd[2]); + atp_writeb_io(dev, c, 6, inqd[3]); + atp_writeb_io(dev, c, 7, inqd[4]); + atp_writeb_io(dev, c, 8, inqd[5]); + atp_writeb_io(dev, c, 0x0f, 0); + atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); + atp_writeb_io(dev, c, 0x12, 0); + atp_writeb_io(dev, c, 0x13, inqd[6]); + atp_writeb_io(dev, c, 0x14, inqd[7]); + atp_writeb_io(dev, c, 0x18, inqd[8]); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) + if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) continue; - while (atp_readb_io(dev, 0, 0x17) != 0x8e) + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); if (dev->chip_ver == 4) - atp_writeb_io(dev, 0, 0x1b, 0x00); + atp_writeb_io(dev, c, 0x1b, 0x00); - atp_writeb_io(dev, 0, 0x18, 0x08); + atp_writeb_io(dev, c, 0x18, 0x08); j = 0; rd_inq_data: - k = atp_readb_io(dev, 0, 0x1f); + k = atp_readb_io(dev, c, 0x1f); if ((k & 0x01) != 0) { - mbuf[j++] = atp_readb_io(dev, 0, 0x19); + mbuf[j++] = atp_readb_io(dev, c, 0x19); goto rd_inq_data; } if ((k & 0x80) == 0) { goto rd_inq_data; } - j = atp_readb_io(dev, 0, 0x17); + j = atp_readb_io(dev, c, 0x17); if (j == 0x16) { goto inq_ok; } - atp_writeb_io(dev, 0, 0x10, 0x46); - atp_writeb_io(dev, 0, 0x12, 0); - atp_writeb_io(dev, 0, 0x13, 0); - atp_writeb_io(dev, 0, 0x14, 0); - atp_writeb_io(dev, 0, 0x18, 0x08); + atp_writeb_io(dev, c, 0x10, 0x46); + atp_writeb_io(dev, c, 0x12, 0); + atp_writeb_io(dev, c, 0x13, 0); + atp_writeb_io(dev, c, 0x14, 0); + atp_writeb_io(dev, c, 0x18, 0x08); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (atp_readb_io(dev, 0, 0x17) != 0x16) + if (atp_readb_io(dev, c, 0x17) != 0x16) goto sel_ok; inq_ok: mbuf[36] = 0; printk(KERN_INFO " ID: %2d %s\n", i, &mbuf[8]); - dev->id[0][i].devtype = mbuf[0]; + dev->id[c][i].devtype = mbuf[0]; rmb = mbuf[1]; n = mbuf[7]; if (dev->chip_ver != 4) { @@ -1304,46 +1304,46 @@ inq_ok: if ((mbuf[7] & 0x60) == 0) { goto not_wide; } - if ((dev->global_map[0] & 0x20) == 0) { + if ((dev->global_map[c] & 0x20) == 0) { goto not_wide; } - atp_writeb_io(dev, 0, 0x1b, 0x01); - atp_writeb_io(dev, 0, 3, satn[0]); - atp_writeb_io(dev, 0, 4, satn[1]); - atp_writeb_io(dev, 0, 5, satn[2]); - atp_writeb_io(dev, 0, 6, satn[3]); - atp_writeb_io(dev, 0, 7, satn[4]); - atp_writeb_io(dev, 0, 8, satn[5]); - atp_writeb_io(dev, 0, 0x0f, 0); - atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); - atp_writeb_io(dev, 0, 0x12, 0); - atp_writeb_io(dev, 0, 0x13, satn[6]); - atp_writeb_io(dev, 0, 0x14, satn[7]); - atp_writeb_io(dev, 0, 0x18, satn[8]); + atp_writeb_io(dev, c, 0x1b, 0x01); + atp_writeb_io(dev, c, 3, satn[0]); + atp_writeb_io(dev, c, 4, satn[1]); + atp_writeb_io(dev, c, 5, satn[2]); + atp_writeb_io(dev, c, 6, satn[3]); + atp_writeb_io(dev, c, 7, satn[4]); + atp_writeb_io(dev, c, 8, satn[5]); + atp_writeb_io(dev, c, 0x0f, 0); + atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); + atp_writeb_io(dev, c, 0x12, 0); + atp_writeb_io(dev, c, 0x13, satn[6]); + atp_writeb_io(dev, c, 0x14, satn[7]); + atp_writeb_io(dev, c, 0x18, satn[8]); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) + if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) continue; - while (atp_readb_io(dev, 0, 0x17) != 0x8e) + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); try_wide: j = 0; - atp_writeb_io(dev, 0, 0x14, 0x05); - atp_writeb_io(dev, 0, 0x18, 0x20); + atp_writeb_io(dev, c, 0x14, 0x05); + atp_writeb_io(dev, c, 0x18, 0x20); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0) { - if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) - atp_writeb_io(dev, 0, 0x19, wide[j++]); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) + atp_writeb_io(dev, c, 0x19, wide[j++]); } - while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) cpu_relax(); - j = atp_readb_io(dev, 0, 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -1355,12 +1355,12 @@ try_wide: } continue; widep_out: - atp_writeb_io(dev, 0, 0x18, 0x20); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0) { - if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) - atp_writeb_io(dev, 0, 0x19, 0); + atp_writeb_io(dev, c, 0x18, 0x20); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) + atp_writeb_io(dev, c, 0x19, 0); } - j = atp_readb_io(dev, 0, 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -1372,19 +1372,19 @@ widep_out: } continue; widep_in: - atp_writeb_io(dev, 0, 0x14, 0xff); - atp_writeb_io(dev, 0, 0x18, 0x20); + atp_writeb_io(dev, c, 0x14, 0xff); + atp_writeb_io(dev, c, 0x18, 0x20); k = 0; widep_in1: - j = atp_readb_io(dev, 0, 0x1f); + j = atp_readb_io(dev, c, 0x1f); if ((j & 0x01) != 0) { - mbuf[k++] = atp_readb_io(dev, 0, 0x19); + mbuf[k++] = atp_readb_io(dev, c, 0x19); goto widep_in1; } if ((j & 0x80) == 0x00) { goto widep_in1; } - j = atp_readb_io(dev, 0, 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -1396,14 +1396,14 @@ widep_in1: } continue; widep_cmd: - atp_writeb_io(dev, 0, 0x10, 0x30); - atp_writeb_io(dev, 0, 0x14, 0x00); - atp_writeb_io(dev, 0, 0x18, 0x08); + atp_writeb_io(dev, c, 0x10, 0x30); + atp_writeb_io(dev, c, 0x14, 0x00); + atp_writeb_io(dev, c, 0x18, 0x08); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - j = atp_readb_io(dev, 0, 0x17); + j = atp_readb_io(dev, c, 0x17); if (j != 0x16) { if (j == 0x4e) { goto widep_out; @@ -1424,63 +1424,63 @@ widep_cmd: } m = 1; m = m << i; - dev->wide_id[0] |= m; + dev->wide_id[c] |= m; not_wide: - if ((dev->id[0][i].devtype == 0x00) || (dev->id[0][i].devtype == 0x07) || ((dev->id[0][i].devtype == 0x05) && ((n & 0x10) != 0))) { + if ((dev->id[c][i].devtype == 0x00) || (dev->id[c][i].devtype == 0x07) || ((dev->id[c][i].devtype == 0x05) && ((n & 0x10) != 0))) { goto set_sync; } continue; set_sync: j = 0; - if ((m & dev->wide_id[0]) != 0) { + if ((m & dev->wide_id[c]) != 0) { j |= 0x01; } - atp_writeb_io(dev, 0, 0x1b, j); - atp_writeb_io(dev, 0, 3, satn[0]); - atp_writeb_io(dev, 0, 4, satn[1]); - atp_writeb_io(dev, 0, 5, satn[2]); - atp_writeb_io(dev, 0, 6, satn[3]); - atp_writeb_io(dev, 0, 7, satn[4]); - atp_writeb_io(dev, 0, 8, satn[5]); - atp_writeb_io(dev, 0, 0x0f, 0); - atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); - atp_writeb_io(dev, 0, 0x12, 0); - atp_writeb_io(dev, 0, 0x13, satn[6]); - atp_writeb_io(dev, 0, 0x14, satn[7]); - atp_writeb_io(dev, 0, 0x18, satn[8]); + atp_writeb_io(dev, c, 0x1b, j); + atp_writeb_io(dev, c, 3, satn[0]); + atp_writeb_io(dev, c, 4, satn[1]); + atp_writeb_io(dev, c, 5, satn[2]); + atp_writeb_io(dev, c, 6, satn[3]); + atp_writeb_io(dev, c, 7, satn[4]); + atp_writeb_io(dev, c, 8, satn[5]); + atp_writeb_io(dev, c, 0x0f, 0); + atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); + atp_writeb_io(dev, c, 0x12, 0); + atp_writeb_io(dev, c, 0x13, satn[6]); + atp_writeb_io(dev, c, 0x14, satn[7]); + atp_writeb_io(dev, c, 0x18, satn[8]); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) + if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) continue; - while (atp_readb_io(dev, 0, 0x17) != 0x8e) + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); try_sync: j = 0; - atp_writeb_io(dev, 0, 0x14, 0x06); - atp_writeb_io(dev, 0, 0x18, 0x20); + atp_writeb_io(dev, c, 0x14, 0x06); + atp_writeb_io(dev, c, 0x18, 0x20); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0) { - if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) { - if ((m & dev->wide_id[0]) != 0) { - atp_writeb_io(dev, 0, 0x19, synw[j++]); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) { + if ((m & dev->wide_id[c]) != 0) { + atp_writeb_io(dev, c, 0x19, synw[j++]); } else { - if ((m & dev->ultra_map[0]) != 0) { - atp_writeb_io(dev, 0, 0x19, synu[j++]); + if ((m & dev->ultra_map[c]) != 0) { + atp_writeb_io(dev, c, 0x19, synu[j++]); } else { - atp_writeb_io(dev, 0, 0x19, synn[j++]); + atp_writeb_io(dev, c, 0x19, synn[j++]); } } } } - while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) cpu_relax(); - j = atp_readb_io(dev, 0, 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto phase_ins; } @@ -1492,12 +1492,12 @@ try_sync: } continue; phase_outs: - atp_writeb_io(dev, 0, 0x18, 0x20); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) { - if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0x00) - atp_writeb_io(dev, 0, 0x19, 0x00); + atp_writeb_io(dev, c, 0x18, 0x20); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) { + if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0x00) + atp_writeb_io(dev, c, 0x19, 0x00); } - j = atp_readb_io(dev, 0, 0x17); + j = atp_readb_io(dev, c, 0x17); if (j == 0x85) { goto tar_dcons; } @@ -1513,23 +1513,23 @@ phase_outs: } continue; phase_ins: - atp_writeb_io(dev, 0, 0x14, 0xff); - atp_writeb_io(dev, 0, 0x18, 0x20); + atp_writeb_io(dev, c, 0x14, 0xff); + atp_writeb_io(dev, c, 0x18, 0x20); k = 0; phase_ins1: - j = atp_readb_io(dev, 0, 0x1f); + j = atp_readb_io(dev, c, 0x1f); if ((j & 0x01) != 0x00) { - mbuf[k++] = atp_readb_io(dev, 0, 0x19); + mbuf[k++] = atp_readb_io(dev, c, 0x19); goto phase_ins1; } if ((j & 0x80) == 0x00) { goto phase_ins1; } - while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) cpu_relax(); - j = atp_readb_io(dev, 0, 0x17); + j = atp_readb_io(dev, c, 0x17); if (j == 0x85) { goto tar_dcons; } @@ -1545,15 +1545,15 @@ phase_ins1: } continue; phase_cmds: - atp_writeb_io(dev, 0, 0x10, 0x30); + atp_writeb_io(dev, c, 0x10, 0x30); tar_dcons: - atp_writeb_io(dev, 0, 0x14, 0x00); - atp_writeb_io(dev, 0, 0x18, 0x08); + atp_writeb_io(dev, c, 0x14, 0x00); + atp_writeb_io(dev, c, 0x18, 0x08); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - j = atp_readb_io(dev, 0, 0x17); + j = atp_readb_io(dev, c, 0x17); if (j != 0x16) { continue; } @@ -1572,7 +1572,7 @@ tar_dcons: if (mbuf[4] > 0x0c) { mbuf[4] = 0x0c; } - dev->id[0][i].devsp = mbuf[4]; + dev->id[c][i].devsp = mbuf[4]; if ((mbuf[3] < 0x0d) && (rmb == 0)) { j = 0xa0; goto set_syn_ok; @@ -1591,12 +1591,12 @@ tar_dcons: } j = 0x60; set_syn_ok: - dev->id[0][i].devsp = (dev->id[0][i].devsp & 0x0f) | j; + dev->id[c][i].devsp = (dev->id[c][i].devsp & 0x0f) | j; } - atp_writeb_io(dev, 0, 0x3a, atp_readb_io(dev, 0, 0x3a) & 0xef); + atp_writeb_io(dev, c, 0x3a, atp_readb_io(dev, c, 0x3a) & 0xef); } -static void is880(struct atp_unit *dev) +static void is880(struct atp_unit *dev, unsigned char c) { unsigned char i, j, k, rmb, n, lvdmode; unsigned short int m; @@ -1615,167 +1615,167 @@ static void is880(struct atp_unit *dev) for (i = 0; i < 16; i++) { m = 1; m = m << i; - if ((m & dev->active_id[0]) != 0) { + if ((m & dev->active_id[c]) != 0) { continue; } - if (i == dev->host_id[0]) { - printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_id[0]); + if (i == dev->host_id[c]) { + printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_id[c]); continue; } - atp_writeb_io(dev, 0, 0x1b, 0x01); - atp_writeb_io(dev, 0, 1, 0x08); - atp_writeb_io(dev, 0, 2, 0x7f); - atp_writeb_io(dev, 0, 3, satn[0]); - atp_writeb_io(dev, 0, 4, satn[1]); - atp_writeb_io(dev, 0, 5, satn[2]); - atp_writeb_io(dev, 0, 6, satn[3]); - atp_writeb_io(dev, 0, 7, satn[4]); - atp_writeb_io(dev, 0, 8, satn[5]); - atp_writeb_io(dev, 0, 0x0f, 0); - atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); - atp_writeb_io(dev, 0, 0x12, 0); - atp_writeb_io(dev, 0, 0x13, satn[6]); - atp_writeb_io(dev, 0, 0x14, satn[7]); + atp_writeb_io(dev, c, 0x1b, 0x01); + atp_writeb_io(dev, c, 1, 0x08); + atp_writeb_io(dev, c, 2, 0x7f); + atp_writeb_io(dev, c, 3, satn[0]); + atp_writeb_io(dev, c, 4, satn[1]); + atp_writeb_io(dev, c, 5, satn[2]); + atp_writeb_io(dev, c, 6, satn[3]); + atp_writeb_io(dev, c, 7, satn[4]); + atp_writeb_io(dev, c, 8, satn[5]); + atp_writeb_io(dev, c, 0x0f, 0); + atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); + atp_writeb_io(dev, c, 0x12, 0); + atp_writeb_io(dev, c, 0x13, satn[6]); + atp_writeb_io(dev, c, 0x14, satn[7]); j = i; if ((j & 0x08) != 0) { j = (j & 0x07) | 0x40; } - atp_writeb_io(dev, 0, 0x15, j); - atp_writeb_io(dev, 0, 0x18, satn[8]); + atp_writeb_io(dev, c, 0x15, j); + atp_writeb_io(dev, c, 0x18, satn[8]); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) + if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) continue; - while (atp_readb_io(dev, 0, 0x17) != 0x8e) + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); - dev->active_id[0] |= m; + dev->active_id[c] |= m; - atp_writeb_io(dev, 0, 0x10, 0x30); - atp_writeb_io(dev, 0, 0x14, 0x00); + atp_writeb_io(dev, c, 0x10, 0x30); + atp_writeb_io(dev, c, 0x14, 0x00); phase_cmd: - atp_writeb_io(dev, 0, 0x18, 0x08); + atp_writeb_io(dev, c, 0x18, 0x08); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - j = atp_readb_io(dev, 0, 0x17); + j = atp_readb_io(dev, c, 0x17); if (j != 0x16) { - atp_writeb_io(dev, 0, 0x10, 0x41); + atp_writeb_io(dev, c, 0x10, 0x41); goto phase_cmd; } sel_ok: - atp_writeb_io(dev, 0, 3, inqd[0]); - atp_writeb_io(dev, 0, 4, inqd[1]); - atp_writeb_io(dev, 0, 5, inqd[2]); - atp_writeb_io(dev, 0, 6, inqd[3]); - atp_writeb_io(dev, 0, 7, inqd[4]); - atp_writeb_io(dev, 0, 8, inqd[5]); - atp_writeb_io(dev, 0, 0x0f, 0); - atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); - atp_writeb_io(dev, 0, 0x12, 0); - atp_writeb_io(dev, 0, 0x13, inqd[6]); - atp_writeb_io(dev, 0, 0x14, inqd[7]); - atp_writeb_io(dev, 0, 0x18, inqd[8]); + atp_writeb_io(dev, c, 3, inqd[0]); + atp_writeb_io(dev, c, 4, inqd[1]); + atp_writeb_io(dev, c, 5, inqd[2]); + atp_writeb_io(dev, c, 6, inqd[3]); + atp_writeb_io(dev, c, 7, inqd[4]); + atp_writeb_io(dev, c, 8, inqd[5]); + atp_writeb_io(dev, c, 0x0f, 0); + atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); + atp_writeb_io(dev, c, 0x12, 0); + atp_writeb_io(dev, c, 0x13, inqd[6]); + atp_writeb_io(dev, c, 0x14, inqd[7]); + atp_writeb_io(dev, c, 0x18, inqd[8]); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) + if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) continue; - while (atp_readb_io(dev, 0, 0x17) != 0x8e) + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); - atp_writeb_io(dev, 0, 0x1b, 0x00); - atp_writeb_io(dev, 0, 0x18, 0x08); + atp_writeb_io(dev, c, 0x1b, 0x00); + atp_writeb_io(dev, c, 0x18, 0x08); j = 0; rd_inq_data: - k = atp_readb_io(dev, 0, 0x1f); + k = atp_readb_io(dev, c, 0x1f); if ((k & 0x01) != 0) { - mbuf[j++] = atp_readb_io(dev, 0, 0x19); + mbuf[j++] = atp_readb_io(dev, c, 0x19); goto rd_inq_data; } if ((k & 0x80) == 0) { goto rd_inq_data; } - j = atp_readb_io(dev, 0, 0x17); + j = atp_readb_io(dev, c, 0x17); if (j == 0x16) { goto inq_ok; } - atp_writeb_io(dev, 0, 0x10, 0x46); - atp_writeb_io(dev, 0, 0x12, 0); - atp_writeb_io(dev, 0, 0x13, 0); - atp_writeb_io(dev, 0, 0x14, 0); - atp_writeb_io(dev, 0, 0x18, 0x08); + atp_writeb_io(dev, c, 0x10, 0x46); + atp_writeb_io(dev, c, 0x12, 0); + atp_writeb_io(dev, c, 0x13, 0); + atp_writeb_io(dev, c, 0x14, 0); + atp_writeb_io(dev, c, 0x18, 0x08); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (atp_readb_io(dev, 0, 0x17) != 0x16) + if (atp_readb_io(dev, c, 0x17) != 0x16) goto sel_ok; inq_ok: mbuf[36] = 0; printk(KERN_INFO " ID: %2d %s\n", i, &mbuf[8]); - dev->id[0][i].devtype = mbuf[0]; + dev->id[c][i].devtype = mbuf[0]; rmb = mbuf[1]; n = mbuf[7]; if ((mbuf[7] & 0x60) == 0) { goto not_wide; } - if ((i < 8) && ((dev->global_map[0] & 0x20) == 0)) { + if ((i < 8) && ((dev->global_map[c] & 0x20) == 0)) { goto not_wide; } if (lvdmode == 0) { goto chg_wide; } - if (dev->sp[0][i] != 0x04) // force u2 + if (dev->sp[c][i] != 0x04) // force u2 { goto chg_wide; } - atp_writeb_io(dev, 0, 0x1b, 0x01); - atp_writeb_io(dev, 0, 3, satn[0]); - atp_writeb_io(dev, 0, 4, satn[1]); - atp_writeb_io(dev, 0, 5, satn[2]); - atp_writeb_io(dev, 0, 6, satn[3]); - atp_writeb_io(dev, 0, 7, satn[4]); - atp_writeb_io(dev, 0, 8, satn[5]); - atp_writeb_io(dev, 0, 0x0f, 0); - atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); - atp_writeb_io(dev, 0, 0x12, 0); - atp_writeb_io(dev, 0, 0x13, satn[6]); - atp_writeb_io(dev, 0, 0x14, satn[7]); - atp_writeb_io(dev, 0, 0x18, satn[8]); + atp_writeb_io(dev, c, 0x1b, 0x01); + atp_writeb_io(dev, c, 3, satn[0]); + atp_writeb_io(dev, c, 4, satn[1]); + atp_writeb_io(dev, c, 5, satn[2]); + atp_writeb_io(dev, c, 6, satn[3]); + atp_writeb_io(dev, c, 7, satn[4]); + atp_writeb_io(dev, c, 8, satn[5]); + atp_writeb_io(dev, c, 0x0f, 0); + atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); + atp_writeb_io(dev, c, 0x12, 0); + atp_writeb_io(dev, c, 0x13, satn[6]); + atp_writeb_io(dev, c, 0x14, satn[7]); + atp_writeb_io(dev, c, 0x18, satn[8]); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) + if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) continue; - while (atp_readb_io(dev, 0, 0x17) != 0x8e) + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); try_u3: j = 0; - atp_writeb_io(dev, 0, 0x14, 0x09); - atp_writeb_io(dev, 0, 0x18, 0x20); + atp_writeb_io(dev, c, 0x14, 0x09); + atp_writeb_io(dev, c, 0x18, 0x20); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0) { - if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) - atp_writeb_io(dev, 0, 0x19, u3[j++]); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) + atp_writeb_io(dev, c, 0x19, u3[j++]); } - while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) cpu_relax(); - j = atp_readb_io(dev, 0, 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto u3p_in; } @@ -1787,12 +1787,12 @@ try_u3: } continue; u3p_out: - atp_writeb_io(dev, 0, 0x18, 0x20); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0) { - if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) - atp_writeb_io(dev, 0, 0x19, 0); + atp_writeb_io(dev, c, 0x18, 0x20); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) + atp_writeb_io(dev, c, 0x19, 0); } - j = atp_readb_io(dev, 0, 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto u3p_in; } @@ -1804,19 +1804,19 @@ u3p_out: } continue; u3p_in: - atp_writeb_io(dev, 0, 0x14, 0x09); - atp_writeb_io(dev, 0, 0x18, 0x20); + atp_writeb_io(dev, c, 0x14, 0x09); + atp_writeb_io(dev, c, 0x18, 0x20); k = 0; u3p_in1: - j = atp_readb_io(dev, 0, 0x1f); + j = atp_readb_io(dev, c, 0x1f); if ((j & 0x01) != 0) { - mbuf[k++] = atp_readb_io(dev, 0, 0x19); + mbuf[k++] = atp_readb_io(dev, c, 0x19); goto u3p_in1; } if ((j & 0x80) == 0x00) { goto u3p_in1; } - j = atp_readb_io(dev, 0, 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto u3p_in; } @@ -1828,14 +1828,14 @@ u3p_in1: } continue; u3p_cmd: - atp_writeb_io(dev, 0, 0x10, 0x30); - atp_writeb_io(dev, 0, 0x14, 0x00); - atp_writeb_io(dev, 0, 0x18, 0x08); + atp_writeb_io(dev, c, 0x10, 0x30); + atp_writeb_io(dev, c, 0x14, 0x00); + atp_writeb_io(dev, c, 0x18, 0x08); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - j = atp_readb_io(dev, 0, 0x17); + j = atp_readb_io(dev, c, 0x17); if (j != 0x16) { if (j == 0x4e) { goto u3p_out; @@ -1854,48 +1854,48 @@ u3p_cmd: if (mbuf[3] == 0x09) { m = 1; m = m << i; - dev->wide_id[0] |= m; - dev->id[0][i].devsp = 0xce; + dev->wide_id[c] |= m; + dev->id[c][i].devsp = 0xce; continue; } chg_wide: - atp_writeb_io(dev, 0, 0x1b, 0x01); - atp_writeb_io(dev, 0, 3, satn[0]); - atp_writeb_io(dev, 0, 4, satn[1]); - atp_writeb_io(dev, 0, 5, satn[2]); - atp_writeb_io(dev, 0, 6, satn[3]); - atp_writeb_io(dev, 0, 7, satn[4]); - atp_writeb_io(dev, 0, 8, satn[5]); - atp_writeb_io(dev, 0, 0x0f, 0); - atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); - atp_writeb_io(dev, 0, 0x12, 0); - atp_writeb_io(dev, 0, 0x13, satn[6]); - atp_writeb_io(dev, 0, 0x14, satn[7]); - atp_writeb_io(dev, 0, 0x18, satn[8]); + atp_writeb_io(dev, c, 0x1b, 0x01); + atp_writeb_io(dev, c, 3, satn[0]); + atp_writeb_io(dev, c, 4, satn[1]); + atp_writeb_io(dev, c, 5, satn[2]); + atp_writeb_io(dev, c, 6, satn[3]); + atp_writeb_io(dev, c, 7, satn[4]); + atp_writeb_io(dev, c, 8, satn[5]); + atp_writeb_io(dev, c, 0x0f, 0); + atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); + atp_writeb_io(dev, c, 0x12, 0); + atp_writeb_io(dev, c, 0x13, satn[6]); + atp_writeb_io(dev, c, 0x14, satn[7]); + atp_writeb_io(dev, c, 0x18, satn[8]); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) + if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) continue; - while (atp_readb_io(dev, 0, 0x17) != 0x8e) + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); try_wide: j = 0; - atp_writeb_io(dev, 0, 0x14, 0x05); - atp_writeb_io(dev, 0, 0x18, 0x20); + atp_writeb_io(dev, c, 0x14, 0x05); + atp_writeb_io(dev, c, 0x18, 0x20); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0) { - if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) - atp_writeb_io(dev, 0, 0x19, wide[j++]); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) + atp_writeb_io(dev, c, 0x19, wide[j++]); } - while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) cpu_relax(); - j = atp_readb_io(dev, 0, 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -1907,12 +1907,12 @@ try_wide: } continue; widep_out: - atp_writeb_io(dev, 0, 0x18, 0x20); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0) { - if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) - atp_writeb_io(dev, 0, 0x19, 0); + atp_writeb_io(dev, c, 0x18, 0x20); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) + atp_writeb_io(dev, c, 0x19, 0); } - j = atp_readb_io(dev, 0, 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -1924,19 +1924,19 @@ widep_out: } continue; widep_in: - atp_writeb_io(dev, 0, 0x14, 0xff); - atp_writeb_io(dev, 0, 0x18, 0x20); + atp_writeb_io(dev, c, 0x14, 0xff); + atp_writeb_io(dev, c, 0x18, 0x20); k = 0; widep_in1: - j = atp_readb_io(dev, 0, 0x1f); + j = atp_readb_io(dev, c, 0x1f); if ((j & 0x01) != 0) { - mbuf[k++] = atp_readb_io(dev, 0, 0x19); + mbuf[k++] = atp_readb_io(dev, c, 0x19); goto widep_in1; } if ((j & 0x80) == 0x00) { goto widep_in1; } - j = atp_readb_io(dev, 0, 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto widep_in; } @@ -1948,14 +1948,14 @@ widep_in1: } continue; widep_cmd: - atp_writeb_io(dev, 0, 0x10, 0x30); - atp_writeb_io(dev, 0, 0x14, 0x00); - atp_writeb_io(dev, 0, 0x18, 0x08); + atp_writeb_io(dev, c, 0x10, 0x30); + atp_writeb_io(dev, c, 0x14, 0x00); + atp_writeb_io(dev, c, 0x18, 0x08); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - j = atp_readb_io(dev, 0, 0x17); + j = atp_readb_io(dev, c, 0x17); if (j != 0x16) { if (j == 0x4e) { goto widep_out; @@ -1976,80 +1976,80 @@ widep_cmd: } m = 1; m = m << i; - dev->wide_id[0] |= m; + dev->wide_id[c] |= m; not_wide: - if ((dev->id[0][i].devtype == 0x00) || (dev->id[0][i].devtype == 0x07) || ((dev->id[0][i].devtype == 0x05) && ((n & 0x10) != 0))) { + if ((dev->id[c][i].devtype == 0x00) || (dev->id[c][i].devtype == 0x07) || ((dev->id[c][i].devtype == 0x05) && ((n & 0x10) != 0))) { m = 1; m = m << i; - if ((dev->async[0] & m) != 0) { + if ((dev->async[c] & m) != 0) { goto set_sync; } } continue; set_sync: - if (dev->sp[0][i] == 0x02) { + if (dev->sp[c][i] == 0x02) { synu[4] = 0x0c; synuw[4] = 0x0c; } else { - if (dev->sp[0][i] >= 0x03) { + if (dev->sp[c][i] >= 0x03) { synu[4] = 0x0a; synuw[4] = 0x0a; } } j = 0; - if ((m & dev->wide_id[0]) != 0) { + if ((m & dev->wide_id[c]) != 0) { j |= 0x01; } - atp_writeb_io(dev, 0, 0x1b, j); - atp_writeb_io(dev, 0, 3, satn[0]); - atp_writeb_io(dev, 0, 4, satn[1]); - atp_writeb_io(dev, 0, 5, satn[2]); - atp_writeb_io(dev, 0, 6, satn[3]); - atp_writeb_io(dev, 0, 7, satn[4]); - atp_writeb_io(dev, 0, 8, satn[5]); - atp_writeb_io(dev, 0, 0x0f, 0); - atp_writeb_io(dev, 0, 0x11, dev->id[0][i].devsp); - atp_writeb_io(dev, 0, 0x12, 0); - atp_writeb_io(dev, 0, 0x13, satn[6]); - atp_writeb_io(dev, 0, 0x14, satn[7]); - atp_writeb_io(dev, 0, 0x18, satn[8]); + atp_writeb_io(dev, c, 0x1b, j); + atp_writeb_io(dev, c, 3, satn[0]); + atp_writeb_io(dev, c, 4, satn[1]); + atp_writeb_io(dev, c, 5, satn[2]); + atp_writeb_io(dev, c, 6, satn[3]); + atp_writeb_io(dev, c, 7, satn[4]); + atp_writeb_io(dev, c, 8, satn[5]); + atp_writeb_io(dev, c, 0x0f, 0); + atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); + atp_writeb_io(dev, c, 0x12, 0); + atp_writeb_io(dev, c, 0x13, satn[6]); + atp_writeb_io(dev, c, 0x14, satn[7]); + atp_writeb_io(dev, c, 0x18, satn[8]); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - if (atp_readb_io(dev, 0, 0x17) != 0x11 && atp_readb_io(dev, 0, 0x17) != 0x8e) + if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) continue; - while (atp_readb_io(dev, 0, 0x17) != 0x8e) + while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); try_sync: j = 0; - atp_writeb_io(dev, 0, 0x14, 0x06); - atp_writeb_io(dev, 0, 0x18, 0x20); - - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0) { - if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0) { - if ((m & dev->wide_id[0]) != 0) { - if ((m & dev->ultra_map[0]) != 0) { - atp_writeb_io(dev, 0, 0x19, synuw[j++]); + atp_writeb_io(dev, c, 0x14, 0x06); + atp_writeb_io(dev, c, 0x18, 0x20); + + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { + if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) { + if ((m & dev->wide_id[c]) != 0) { + if ((m & dev->ultra_map[c]) != 0) { + atp_writeb_io(dev, c, 0x19, synuw[j++]); } else { - atp_writeb_io(dev, 0, 0x19, synw[j++]); + atp_writeb_io(dev, c, 0x19, synw[j++]); } } else { - if ((m & dev->ultra_map[0]) != 0) { - atp_writeb_io(dev, 0, 0x19, synu[j++]); + if ((m & dev->ultra_map[c]) != 0) { + atp_writeb_io(dev, c, 0x19, synu[j++]); } else { - atp_writeb_io(dev, 0, 0x19, synn[j++]); + atp_writeb_io(dev, c, 0x19, synn[j++]); } } } } - while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) cpu_relax(); - j = atp_readb_io(dev, 0, 0x17) & 0x0f; + j = atp_readb_io(dev, c, 0x17) & 0x0f; if (j == 0x0f) { goto phase_ins; } @@ -2061,12 +2061,12 @@ try_sync: } continue; phase_outs: - atp_writeb_io(dev, 0, 0x18, 0x20); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) { - if ((atp_readb_io(dev, 0, 0x1f) & 0x01) != 0x00) - atp_writeb_io(dev, 0, 0x19, 0x00); + atp_writeb_io(dev, c, 0x18, 0x20); + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) { + if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0x00) + atp_writeb_io(dev, c, 0x19, 0x00); } - j = atp_readb_io(dev, 0, 0x17); + j = atp_readb_io(dev, c, 0x17); if (j == 0x85) { goto tar_dcons; } @@ -2082,23 +2082,23 @@ phase_outs: } continue; phase_ins: - atp_writeb_io(dev, 0, 0x14, 0x06); - atp_writeb_io(dev, 0, 0x18, 0x20); + atp_writeb_io(dev, c, 0x14, 0x06); + atp_writeb_io(dev, c, 0x18, 0x20); k = 0; phase_ins1: - j = atp_readb_io(dev, 0, 0x1f); + j = atp_readb_io(dev, c, 0x1f); if ((j & 0x01) != 0x00) { - mbuf[k++] = atp_readb_io(dev, 0, 0x19); + mbuf[k++] = atp_readb_io(dev, c, 0x19); goto phase_ins1; } if ((j & 0x80) == 0x00) { goto phase_ins1; } - while ((atp_readb_io(dev, 0, 0x17) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) cpu_relax(); - j = atp_readb_io(dev, 0, 0x17); + j = atp_readb_io(dev, c, 0x17); if (j == 0x85) { goto tar_dcons; } @@ -2114,15 +2114,15 @@ phase_ins1: } continue; phase_cmds: - atp_writeb_io(dev, 0, 0x10, 0x30); + atp_writeb_io(dev, c, 0x10, 0x30); tar_dcons: - atp_writeb_io(dev, 0, 0x14, 0x00); - atp_writeb_io(dev, 0, 0x18, 0x08); + atp_writeb_io(dev, c, 0x14, 0x00); + atp_writeb_io(dev, c, 0x18, 0x08); - while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00) + while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) cpu_relax(); - j = atp_readb_io(dev, 0, 0x17); + j = atp_readb_io(dev, c, 0x17); if (j != 0x16) { continue; } @@ -2141,7 +2141,7 @@ tar_dcons: if (mbuf[4] > 0x0e) { mbuf[4] = 0x0e; } - dev->id[0][i].devsp = mbuf[4]; + dev->id[c][i].devsp = mbuf[4]; if (mbuf[3] < 0x0c) { j = 0xb0; goto set_syn_ok; @@ -2164,7 +2164,7 @@ tar_dcons: } j = 0x60; set_syn_ok: - dev->id[0][i].devsp = (dev->id[0][i].devsp & 0x0f) | j; + dev->id[c][i].devsp = (dev->id[c][i].devsp & 0x0f) | j; } } @@ -2379,7 +2379,7 @@ flash_ok_880: outb(0x20, base_io + 0x51); tscam(shpnt); - is880(p); + is880(p, 0); outb(0xb0, base_io + 0x38); shpnt->max_id = 16; shpnt->this_id = host_id; @@ -2609,7 +2609,7 @@ flash_ok_885: outb(0x20, base_io + 0x11); tscam(shpnt); - is870(p); + is870(p, 0); outb((inb(base_io + 0x3a) & 0xef), base_io + 0x3a); outb((inb(base_io + 0x3b) | 0x20), base_io + 0x3b); if (atpdev->chip_ver == 4) -- cgit v0.10.2 From fa50b30842d8cea02903d55caf64fe22c0c4c8e2 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:00 +0100 Subject: atp870u: Move chip-specific lines out of is880() and is885() Move few chip-specifis lines out of is880() and is885() so they become almost identical. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index ec61902..1c4b1f9 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -41,7 +41,7 @@ static struct scsi_host_template atp870u_template; static void send_s870(struct atp_unit *dev,unsigned char c); -static void is885(struct atp_unit *dev, unsigned char c); +static void is885(struct atp_unit *dev, unsigned char c, unsigned char lvdmode); static void tscam_885(void); static inline void atp_writeb_base(struct atp_unit *atp, u8 reg, u8 val) @@ -1596,9 +1596,9 @@ set_syn_ok: atp_writeb_io(dev, c, 0x3a, atp_readb_io(dev, c, 0x3a) & 0xef); } -static void is880(struct atp_unit *dev, unsigned char c) +static void is880(struct atp_unit *dev, unsigned char c, unsigned char lvdmode) { - unsigned char i, j, k, rmb, n, lvdmode; + unsigned char i, j, k, rmb, n; unsigned short int m; static unsigned char mbuf[512]; static unsigned char satn[9] = { 0, 0, 0, 0, 0, 0, 0, 6, 6 }; @@ -1610,8 +1610,6 @@ static void is880(struct atp_unit *dev, unsigned char c) static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 }; static unsigned char u3[9] = { 0x80, 1, 6, 4, 0x09, 00, 0x0e, 0x01, 0x02 }; - lvdmode = atp_readb_base(dev, 0x3f) & 0x40; - for (i = 0; i < 16; i++) { m = 1; m = m << i; @@ -2379,7 +2377,7 @@ flash_ok_880: outb(0x20, base_io + 0x51); tscam(shpnt); - is880(p, 0); + is880(p, 0, atp_readb_base(p, 0x3f) & 0x40); outb(0xb0, base_io + 0x38); shpnt->max_id = 16; shpnt->this_id = host_id; @@ -2525,10 +2523,11 @@ flash_ok_885: tscam_885(); printk(KERN_INFO " Scanning Channel A SCSI Device ...\n"); - is885(p, 0); + is885(p, 0, atp_readb_io(p, 0, 0x1b) >> 7); + atp_writeb_io(p, 0, 0x16, 0x80); printk(KERN_INFO " Scanning Channel B SCSI Device ...\n"); - is885(p, 1); - + is885(p, 1, atp_readb_io(p, 1, 0x1b) >> 7); + atp_writeb_io(p, 1, 0x16, 0x80); k = inb(base_io + 0x28) & 0xcf; k |= 0xc0; outb(k, base_io + 0x28); @@ -2829,9 +2828,9 @@ static void tscam_885(void) -static void is885(struct atp_unit *dev, unsigned char c) +static void is885(struct atp_unit *dev, unsigned char c, unsigned char lvdmode) { - unsigned char i, j, k, rmb, n, lvdmode; + unsigned char i, j, k, rmb, n; unsigned short int m; static unsigned char mbuf[512]; static unsigned char satn[9] = { 0, 0, 0, 0, 0, 0, 0, 6, 6 }; @@ -2843,8 +2842,6 @@ static void is885(struct atp_unit *dev, unsigned char c) static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 }; static unsigned char u3[9] = { 0x80, 1, 6, 4, 0x09, 00, 0x0e, 0x01, 0x02 }; - lvdmode = atp_readb_io(dev, c, 0x1b) >> 7; - for (i = 0; i < 16; i++) { m = 1; m = m << i; @@ -3408,7 +3405,6 @@ set_syn_ok: printk("dev->id[%2d][%2d].devsp = %2x\n",c,i,dev->id[c][i].devsp); #endif } - atp_writeb_io(dev, c, 0x16, 0x80); } module_init(atp870u_init); -- cgit v0.10.2 From e7d6d140328cb8c92ad749ab8a614c9299269975 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:01 +0100 Subject: atp870u: Remove is880() Now that is880() and is885() are almost identical (except for some cpu_relax() calls and debug printks), remove is880() and use is885() instead. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 1c4b1f9..d10026a 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1596,576 +1596,6 @@ set_syn_ok: atp_writeb_io(dev, c, 0x3a, atp_readb_io(dev, c, 0x3a) & 0xef); } -static void is880(struct atp_unit *dev, unsigned char c, unsigned char lvdmode) -{ - unsigned char i, j, k, rmb, n; - unsigned short int m; - static unsigned char mbuf[512]; - static unsigned char satn[9] = { 0, 0, 0, 0, 0, 0, 0, 6, 6 }; - static unsigned char inqd[9] = { 0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6 }; - static unsigned char synn[6] = { 0x80, 1, 3, 1, 0x19, 0x0e }; - unsigned char synu[6] = { 0x80, 1, 3, 1, 0x0a, 0x0e }; - static unsigned char synw[6] = { 0x80, 1, 3, 1, 0x19, 0x0e }; - unsigned char synuw[6] = { 0x80, 1, 3, 1, 0x0a, 0x0e }; - static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 }; - static unsigned char u3[9] = { 0x80, 1, 6, 4, 0x09, 00, 0x0e, 0x01, 0x02 }; - - for (i = 0; i < 16; i++) { - m = 1; - m = m << i; - if ((m & dev->active_id[c]) != 0) { - continue; - } - if (i == dev->host_id[c]) { - printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_id[c]); - continue; - } - atp_writeb_io(dev, c, 0x1b, 0x01); - atp_writeb_io(dev, c, 1, 0x08); - atp_writeb_io(dev, c, 2, 0x7f); - atp_writeb_io(dev, c, 3, satn[0]); - atp_writeb_io(dev, c, 4, satn[1]); - atp_writeb_io(dev, c, 5, satn[2]); - atp_writeb_io(dev, c, 6, satn[3]); - atp_writeb_io(dev, c, 7, satn[4]); - atp_writeb_io(dev, c, 8, satn[5]); - atp_writeb_io(dev, c, 0x0f, 0); - atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); - atp_writeb_io(dev, c, 0x12, 0); - atp_writeb_io(dev, c, 0x13, satn[6]); - atp_writeb_io(dev, c, 0x14, satn[7]); - j = i; - if ((j & 0x08) != 0) { - j = (j & 0x07) | 0x40; - } - atp_writeb_io(dev, c, 0x15, j); - atp_writeb_io(dev, c, 0x18, satn[8]); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) - continue; - - while (atp_readb_io(dev, c, 0x17) != 0x8e) - cpu_relax(); - - dev->active_id[c] |= m; - - atp_writeb_io(dev, c, 0x10, 0x30); - atp_writeb_io(dev, c, 0x14, 0x00); - -phase_cmd: - atp_writeb_io(dev, c, 0x18, 0x08); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - j = atp_readb_io(dev, c, 0x17); - if (j != 0x16) { - atp_writeb_io(dev, c, 0x10, 0x41); - goto phase_cmd; - } -sel_ok: - atp_writeb_io(dev, c, 3, inqd[0]); - atp_writeb_io(dev, c, 4, inqd[1]); - atp_writeb_io(dev, c, 5, inqd[2]); - atp_writeb_io(dev, c, 6, inqd[3]); - atp_writeb_io(dev, c, 7, inqd[4]); - atp_writeb_io(dev, c, 8, inqd[5]); - atp_writeb_io(dev, c, 0x0f, 0); - atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); - atp_writeb_io(dev, c, 0x12, 0); - atp_writeb_io(dev, c, 0x13, inqd[6]); - atp_writeb_io(dev, c, 0x14, inqd[7]); - atp_writeb_io(dev, c, 0x18, inqd[8]); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) - continue; - - while (atp_readb_io(dev, c, 0x17) != 0x8e) - cpu_relax(); - - atp_writeb_io(dev, c, 0x1b, 0x00); - atp_writeb_io(dev, c, 0x18, 0x08); - j = 0; -rd_inq_data: - k = atp_readb_io(dev, c, 0x1f); - if ((k & 0x01) != 0) { - mbuf[j++] = atp_readb_io(dev, c, 0x19); - goto rd_inq_data; - } - if ((k & 0x80) == 0) { - goto rd_inq_data; - } - j = atp_readb_io(dev, c, 0x17); - if (j == 0x16) { - goto inq_ok; - } - atp_writeb_io(dev, c, 0x10, 0x46); - atp_writeb_io(dev, c, 0x12, 0); - atp_writeb_io(dev, c, 0x13, 0); - atp_writeb_io(dev, c, 0x14, 0); - atp_writeb_io(dev, c, 0x18, 0x08); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - if (atp_readb_io(dev, c, 0x17) != 0x16) - goto sel_ok; - -inq_ok: - mbuf[36] = 0; - printk(KERN_INFO " ID: %2d %s\n", i, &mbuf[8]); - dev->id[c][i].devtype = mbuf[0]; - rmb = mbuf[1]; - n = mbuf[7]; - if ((mbuf[7] & 0x60) == 0) { - goto not_wide; - } - if ((i < 8) && ((dev->global_map[c] & 0x20) == 0)) { - goto not_wide; - } - if (lvdmode == 0) { - goto chg_wide; - } - if (dev->sp[c][i] != 0x04) // force u2 - { - goto chg_wide; - } - - atp_writeb_io(dev, c, 0x1b, 0x01); - atp_writeb_io(dev, c, 3, satn[0]); - atp_writeb_io(dev, c, 4, satn[1]); - atp_writeb_io(dev, c, 5, satn[2]); - atp_writeb_io(dev, c, 6, satn[3]); - atp_writeb_io(dev, c, 7, satn[4]); - atp_writeb_io(dev, c, 8, satn[5]); - atp_writeb_io(dev, c, 0x0f, 0); - atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); - atp_writeb_io(dev, c, 0x12, 0); - atp_writeb_io(dev, c, 0x13, satn[6]); - atp_writeb_io(dev, c, 0x14, satn[7]); - atp_writeb_io(dev, c, 0x18, satn[8]); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) - continue; - - while (atp_readb_io(dev, c, 0x17) != 0x8e) - cpu_relax(); - -try_u3: - j = 0; - atp_writeb_io(dev, c, 0x14, 0x09); - atp_writeb_io(dev, c, 0x18, 0x20); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { - if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) - atp_writeb_io(dev, c, 0x19, u3[j++]); - } - - while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) - cpu_relax(); - - j = atp_readb_io(dev, c, 0x17) & 0x0f; - if (j == 0x0f) { - goto u3p_in; - } - if (j == 0x0a) { - goto u3p_cmd; - } - if (j == 0x0e) { - goto try_u3; - } - continue; -u3p_out: - atp_writeb_io(dev, c, 0x18, 0x20); - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { - if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) - atp_writeb_io(dev, c, 0x19, 0); - } - j = atp_readb_io(dev, c, 0x17) & 0x0f; - if (j == 0x0f) { - goto u3p_in; - } - if (j == 0x0a) { - goto u3p_cmd; - } - if (j == 0x0e) { - goto u3p_out; - } - continue; -u3p_in: - atp_writeb_io(dev, c, 0x14, 0x09); - atp_writeb_io(dev, c, 0x18, 0x20); - k = 0; -u3p_in1: - j = atp_readb_io(dev, c, 0x1f); - if ((j & 0x01) != 0) { - mbuf[k++] = atp_readb_io(dev, c, 0x19); - goto u3p_in1; - } - if ((j & 0x80) == 0x00) { - goto u3p_in1; - } - j = atp_readb_io(dev, c, 0x17) & 0x0f; - if (j == 0x0f) { - goto u3p_in; - } - if (j == 0x0a) { - goto u3p_cmd; - } - if (j == 0x0e) { - goto u3p_out; - } - continue; -u3p_cmd: - atp_writeb_io(dev, c, 0x10, 0x30); - atp_writeb_io(dev, c, 0x14, 0x00); - atp_writeb_io(dev, c, 0x18, 0x08); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - j = atp_readb_io(dev, c, 0x17); - if (j != 0x16) { - if (j == 0x4e) { - goto u3p_out; - } - continue; - } - if (mbuf[0] != 0x01) { - goto chg_wide; - } - if (mbuf[1] != 0x06) { - goto chg_wide; - } - if (mbuf[2] != 0x04) { - goto chg_wide; - } - if (mbuf[3] == 0x09) { - m = 1; - m = m << i; - dev->wide_id[c] |= m; - dev->id[c][i].devsp = 0xce; - continue; - } -chg_wide: - atp_writeb_io(dev, c, 0x1b, 0x01); - atp_writeb_io(dev, c, 3, satn[0]); - atp_writeb_io(dev, c, 4, satn[1]); - atp_writeb_io(dev, c, 5, satn[2]); - atp_writeb_io(dev, c, 6, satn[3]); - atp_writeb_io(dev, c, 7, satn[4]); - atp_writeb_io(dev, c, 8, satn[5]); - atp_writeb_io(dev, c, 0x0f, 0); - atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); - atp_writeb_io(dev, c, 0x12, 0); - atp_writeb_io(dev, c, 0x13, satn[6]); - atp_writeb_io(dev, c, 0x14, satn[7]); - atp_writeb_io(dev, c, 0x18, satn[8]); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) - continue; - - while (atp_readb_io(dev, c, 0x17) != 0x8e) - cpu_relax(); - -try_wide: - j = 0; - atp_writeb_io(dev, c, 0x14, 0x05); - atp_writeb_io(dev, c, 0x18, 0x20); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { - if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) - atp_writeb_io(dev, c, 0x19, wide[j++]); - } - - while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) - cpu_relax(); - - j = atp_readb_io(dev, c, 0x17) & 0x0f; - if (j == 0x0f) { - goto widep_in; - } - if (j == 0x0a) { - goto widep_cmd; - } - if (j == 0x0e) { - goto try_wide; - } - continue; -widep_out: - atp_writeb_io(dev, c, 0x18, 0x20); - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { - if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) - atp_writeb_io(dev, c, 0x19, 0); - } - j = atp_readb_io(dev, c, 0x17) & 0x0f; - if (j == 0x0f) { - goto widep_in; - } - if (j == 0x0a) { - goto widep_cmd; - } - if (j == 0x0e) { - goto widep_out; - } - continue; -widep_in: - atp_writeb_io(dev, c, 0x14, 0xff); - atp_writeb_io(dev, c, 0x18, 0x20); - k = 0; -widep_in1: - j = atp_readb_io(dev, c, 0x1f); - if ((j & 0x01) != 0) { - mbuf[k++] = atp_readb_io(dev, c, 0x19); - goto widep_in1; - } - if ((j & 0x80) == 0x00) { - goto widep_in1; - } - j = atp_readb_io(dev, c, 0x17) & 0x0f; - if (j == 0x0f) { - goto widep_in; - } - if (j == 0x0a) { - goto widep_cmd; - } - if (j == 0x0e) { - goto widep_out; - } - continue; -widep_cmd: - atp_writeb_io(dev, c, 0x10, 0x30); - atp_writeb_io(dev, c, 0x14, 0x00); - atp_writeb_io(dev, c, 0x18, 0x08); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - j = atp_readb_io(dev, c, 0x17); - if (j != 0x16) { - if (j == 0x4e) { - goto widep_out; - } - continue; - } - if (mbuf[0] != 0x01) { - goto not_wide; - } - if (mbuf[1] != 0x02) { - goto not_wide; - } - if (mbuf[2] != 0x03) { - goto not_wide; - } - if (mbuf[3] != 0x01) { - goto not_wide; - } - m = 1; - m = m << i; - dev->wide_id[c] |= m; -not_wide: - if ((dev->id[c][i].devtype == 0x00) || (dev->id[c][i].devtype == 0x07) || ((dev->id[c][i].devtype == 0x05) && ((n & 0x10) != 0))) { - m = 1; - m = m << i; - if ((dev->async[c] & m) != 0) { - goto set_sync; - } - } - continue; -set_sync: - if (dev->sp[c][i] == 0x02) { - synu[4] = 0x0c; - synuw[4] = 0x0c; - } else { - if (dev->sp[c][i] >= 0x03) { - synu[4] = 0x0a; - synuw[4] = 0x0a; - } - } - j = 0; - if ((m & dev->wide_id[c]) != 0) { - j |= 0x01; - } - atp_writeb_io(dev, c, 0x1b, j); - atp_writeb_io(dev, c, 3, satn[0]); - atp_writeb_io(dev, c, 4, satn[1]); - atp_writeb_io(dev, c, 5, satn[2]); - atp_writeb_io(dev, c, 6, satn[3]); - atp_writeb_io(dev, c, 7, satn[4]); - atp_writeb_io(dev, c, 8, satn[5]); - atp_writeb_io(dev, c, 0x0f, 0); - atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); - atp_writeb_io(dev, c, 0x12, 0); - atp_writeb_io(dev, c, 0x13, satn[6]); - atp_writeb_io(dev, c, 0x14, satn[7]); - atp_writeb_io(dev, c, 0x18, satn[8]); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) - continue; - - while (atp_readb_io(dev, c, 0x17) != 0x8e) - cpu_relax(); - -try_sync: - j = 0; - atp_writeb_io(dev, c, 0x14, 0x06); - atp_writeb_io(dev, c, 0x18, 0x20); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { - if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) { - if ((m & dev->wide_id[c]) != 0) { - if ((m & dev->ultra_map[c]) != 0) { - atp_writeb_io(dev, c, 0x19, synuw[j++]); - } else { - atp_writeb_io(dev, c, 0x19, synw[j++]); - } - } else { - if ((m & dev->ultra_map[c]) != 0) { - atp_writeb_io(dev, c, 0x19, synu[j++]); - } else { - atp_writeb_io(dev, c, 0x19, synn[j++]); - } - } - } - } - - while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) - cpu_relax(); - - j = atp_readb_io(dev, c, 0x17) & 0x0f; - if (j == 0x0f) { - goto phase_ins; - } - if (j == 0x0a) { - goto phase_cmds; - } - if (j == 0x0e) { - goto try_sync; - } - continue; -phase_outs: - atp_writeb_io(dev, c, 0x18, 0x20); - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) { - if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0x00) - atp_writeb_io(dev, c, 0x19, 0x00); - } - j = atp_readb_io(dev, c, 0x17); - if (j == 0x85) { - goto tar_dcons; - } - j &= 0x0f; - if (j == 0x0f) { - goto phase_ins; - } - if (j == 0x0a) { - goto phase_cmds; - } - if (j == 0x0e) { - goto phase_outs; - } - continue; -phase_ins: - atp_writeb_io(dev, c, 0x14, 0x06); - atp_writeb_io(dev, c, 0x18, 0x20); - k = 0; -phase_ins1: - j = atp_readb_io(dev, c, 0x1f); - if ((j & 0x01) != 0x00) { - mbuf[k++] = atp_readb_io(dev, c, 0x19); - goto phase_ins1; - } - if ((j & 0x80) == 0x00) { - goto phase_ins1; - } - - while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) - cpu_relax(); - - j = atp_readb_io(dev, c, 0x17); - if (j == 0x85) { - goto tar_dcons; - } - j &= 0x0f; - if (j == 0x0f) { - goto phase_ins; - } - if (j == 0x0a) { - goto phase_cmds; - } - if (j == 0x0e) { - goto phase_outs; - } - continue; -phase_cmds: - atp_writeb_io(dev, c, 0x10, 0x30); -tar_dcons: - atp_writeb_io(dev, c, 0x14, 0x00); - atp_writeb_io(dev, c, 0x18, 0x08); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - j = atp_readb_io(dev, c, 0x17); - if (j != 0x16) { - continue; - } - if (mbuf[0] != 0x01) { - continue; - } - if (mbuf[1] != 0x03) { - continue; - } - if (mbuf[4] == 0x00) { - continue; - } - if (mbuf[3] > 0x64) { - continue; - } - if (mbuf[4] > 0x0e) { - mbuf[4] = 0x0e; - } - dev->id[c][i].devsp = mbuf[4]; - if (mbuf[3] < 0x0c) { - j = 0xb0; - goto set_syn_ok; - } - if ((mbuf[3] < 0x0d) && (rmb == 0)) { - j = 0xa0; - goto set_syn_ok; - } - if (mbuf[3] < 0x1a) { - j = 0x20; - goto set_syn_ok; - } - if (mbuf[3] < 0x33) { - j = 0x40; - goto set_syn_ok; - } - if (mbuf[3] < 0x4c) { - j = 0x50; - goto set_syn_ok; - } - j = 0x60; -set_syn_ok: - dev->id[c][i].devsp = (dev->id[c][i].devsp & 0x0f) | j; - } -} - static void atp870u_free_tables(struct Scsi_Host *host) { struct atp_unit *atp_dev = (struct atp_unit *)&host->hostdata; @@ -2377,7 +1807,7 @@ flash_ok_880: outb(0x20, base_io + 0x51); tscam(shpnt); - is880(p, 0, atp_readb_base(p, 0x3f) & 0x40); + is885(p, 0, atp_readb_base(p, 0x3f) & 0x40); outb(0xb0, base_io + 0x38); shpnt->max_id = 16; shpnt->this_id = host_id; -- cgit v0.10.2 From 197fb8d85707d07eab68ac17d20e95c7104f1d5e Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:02 +0100 Subject: atp870u: Add wide_chip parameter to is870() and is885() Don't check chip_ver in is870() but add wide_chip parameter for that. Then add the non-wide support to is885(). Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index d10026a..0548d07 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -41,7 +41,7 @@ static struct scsi_host_template atp870u_template; static void send_s870(struct atp_unit *dev,unsigned char c); -static void is885(struct atp_unit *dev, unsigned char c, unsigned char lvdmode); +static void is885(struct atp_unit *dev, unsigned char c, bool wide_chip, unsigned char lvdmode); static void tscam_885(void); static inline void atp_writeb_base(struct atp_unit *atp, u8 reg, u8 val) @@ -1162,7 +1162,7 @@ static void tscam(struct Scsi_Host *host) } } -static void is870(struct atp_unit *dev, unsigned char c) +static void is870(struct atp_unit *dev, unsigned char c, bool wide_chip) { unsigned char i, j, k, rmb, n; unsigned short int m; @@ -1177,9 +1177,8 @@ static void is870(struct atp_unit *dev, unsigned char c) atp_writeb_io(dev, c, 0x3a, atp_readb_io(dev, c, 0x3a) | 0x10); for (i = 0; i < 16; i++) { - if ((dev->chip_ver != 4) && (i > 7)) { + if (!wide_chip && (i > 7)) break; - } m = 1; m = m << i; if ((m & dev->active_id[c]) != 0) { @@ -1189,11 +1188,7 @@ static void is870(struct atp_unit *dev, unsigned char c) printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_id[c]); continue; } - if (dev->chip_ver == 4) { - atp_writeb_io(dev, c, 0x1b, 0x01); - } else { - atp_writeb_io(dev, c, 0x1b, 0x00); - } + atp_writeb_io(dev, c, 0x1b, wide_chip ? 0x01 : 0x00); atp_writeb_io(dev, c, 1, 0x08); atp_writeb_io(dev, c, 2, 0x7f); atp_writeb_io(dev, c, 3, satn[0]); @@ -1262,7 +1257,7 @@ sel_ok: while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); - if (dev->chip_ver == 4) + if (wide_chip) atp_writeb_io(dev, c, 0x1b, 0x00); atp_writeb_io(dev, c, 0x18, 0x08); @@ -1298,9 +1293,8 @@ inq_ok: dev->id[c][i].devtype = mbuf[0]; rmb = mbuf[1]; n = mbuf[7]; - if (dev->chip_ver != 4) { + if (!wide_chip) goto not_wide; - } if ((mbuf[7] & 0x60) == 0) { goto not_wide; } @@ -1807,7 +1801,7 @@ flash_ok_880: outb(0x20, base_io + 0x51); tscam(shpnt); - is885(p, 0, atp_readb_base(p, 0x3f) & 0x40); + is885(p, 0, true, atp_readb_base(p, 0x3f) & 0x40); outb(0xb0, base_io + 0x38); shpnt->max_id = 16; shpnt->this_id = host_id; @@ -1953,10 +1947,10 @@ flash_ok_885: tscam_885(); printk(KERN_INFO " Scanning Channel A SCSI Device ...\n"); - is885(p, 0, atp_readb_io(p, 0, 0x1b) >> 7); + is885(p, 0, true, atp_readb_io(p, 0, 0x1b) >> 7); atp_writeb_io(p, 0, 0x16, 0x80); printk(KERN_INFO " Scanning Channel B SCSI Device ...\n"); - is885(p, 1, atp_readb_io(p, 1, 0x1b) >> 7); + is885(p, 1, true, atp_readb_io(p, 1, 0x1b) >> 7); atp_writeb_io(p, 1, 0x16, 0x80); k = inb(base_io + 0x28) & 0xcf; k |= 0xc0; @@ -2038,7 +2032,7 @@ flash_ok_885: outb(0x20, base_io + 0x11); tscam(shpnt); - is870(p, 0); + is870(p, 0, p->chip_ver == 4); outb((inb(base_io + 0x3a) & 0xef), base_io + 0x3a); outb((inb(base_io + 0x3b) | 0x20), base_io + 0x3b); if (atpdev->chip_ver == 4) @@ -2258,7 +2252,7 @@ static void tscam_885(void) -static void is885(struct atp_unit *dev, unsigned char c, unsigned char lvdmode) +static void is885(struct atp_unit *dev, unsigned char c, bool wide_chip, unsigned char lvdmode) { unsigned char i, j, k, rmb, n; unsigned short int m; @@ -2273,6 +2267,8 @@ static void is885(struct atp_unit *dev, unsigned char c, unsigned char lvdmode) static unsigned char u3[9] = { 0x80, 1, 6, 4, 0x09, 00, 0x0e, 0x01, 0x02 }; for (i = 0; i < 16; i++) { + if (!wide_chip && (i > 7)) + break; m = 1; m = m << i; if ((m & dev->active_id[c]) != 0) { @@ -2282,7 +2278,7 @@ static void is885(struct atp_unit *dev, unsigned char c, unsigned char lvdmode) printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_id[c]); continue; } - atp_writeb_io(dev, c, 0x1b, 0x01); + atp_writeb_io(dev, c, 0x1b, wide_chip ? 0x01 : 0x00); atp_writeb_io(dev, c, 1, 0x08); atp_writeb_io(dev, c, 2, 0x7f); atp_writeb_io(dev, c, 3, satn[0]); @@ -2351,7 +2347,9 @@ sel_ok: while (atp_readb_io(dev, c, 0x17) != 0x8e) cpu_relax(); - atp_writeb_io(dev, c, 0x1b, 0x00); + if (wide_chip) + atp_writeb_io(dev, c, 0x1b, 0x00); + atp_writeb_io(dev, c, 0x18, 0x08); j = 0; rd_inq_data: @@ -2385,11 +2383,17 @@ inq_ok: dev->id[c][i].devtype = mbuf[0]; rmb = mbuf[1]; n = mbuf[7]; + if (!wide_chip) + goto not_wide; if ((mbuf[7] & 0x60) == 0) { goto not_wide; } - if ((i < 8) && ((dev->global_map[c] & 0x20) == 0)) { - goto not_wide; + if (dev->dev_id == ATP885_DEVID || dev->dev_id == ATP880_DEVID1 || dev->dev_id == ATP880_DEVID2) { + if ((i < 8) && ((dev->global_map[c] & 0x20) == 0)) + goto not_wide; + } else { /* result of is870() merge - is this a bug? */ + if ((dev->global_map[c] & 0x20) == 0) + goto not_wide; } if (lvdmode == 0) { goto chg_wide; -- cgit v0.10.2 From 460da918d46b075dcc9fdcf77281f8ebde169bd4 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:03 +0100 Subject: atp870u: Add remaining 870 support to is885() Add remaining 870 support to is885(): - different synw, no synuw - synu[4] = 0x0c - atp_writeb_io(dev, c, 0x04, 0x00); instead of atp_writeb_io(dev, c, 0x14, 0x00); (isn't that a bug?) - atp_writeb_io(dev, c, 0x14, 0xff); instead of atp_writeb_io(dev, c, 0x14, 0x06); - different mbuf[3] and mbuf[4] checks Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 0548d07..d76d386 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -2262,6 +2262,7 @@ static void is885(struct atp_unit *dev, unsigned char c, bool wide_chip, unsigne static unsigned char synn[6] = { 0x80, 1, 3, 1, 0x19, 0x0e }; unsigned char synu[6] = { 0x80, 1, 3, 1, 0x0a, 0x0e }; static unsigned char synw[6] = { 0x80, 1, 3, 1, 0x19, 0x0e }; + static unsigned char synw_870[6] = { 0x80, 1, 3, 1, 0x0c, 0x07 }; unsigned char synuw[6] = { 0x80, 1, 3, 1, 0x0a, 0x0e }; static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 }; static unsigned char u3[9] = { 0x80, 1, 6, 4, 0x09, 00, 0x0e, 0x01, 0x02 }; @@ -2311,7 +2312,10 @@ static void is885(struct atp_unit *dev, unsigned char c, bool wide_chip, unsigne dev->active_id[c] |= m; atp_writeb_io(dev, c, 0x10, 0x30); - atp_writeb_io(dev, c, 0x14, 0x00); + if (dev->dev_id == ATP885_DEVID || dev->dev_id == ATP880_DEVID1 || dev->dev_id == ATP880_DEVID2) + atp_writeb_io(dev, c, 0x14, 0x00); + else /* result of is870() merge - is this a bug? */ + atp_writeb_io(dev, c, 0x04, 0x00); phase_cmd: atp_writeb_io(dev, c, 0x18, 0x08); @@ -2657,7 +2661,7 @@ not_wide: } continue; set_sync: - if (dev->sp[c][i] == 0x02) { + if ((dev->dev_id != ATP885_DEVID && dev->dev_id != ATP880_DEVID1 && dev->dev_id != ATP880_DEVID2) || (dev->sp[c][i] == 0x02)) { synu[4] = 0x0c; synuw[4] = 0x0c; } else { @@ -2701,11 +2705,14 @@ try_sync: while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) { if ((m & dev->wide_id[c]) != 0) { - if ((m & dev->ultra_map[c]) != 0) { - atp_writeb_io(dev, c, 0x19, synuw[j++]); - } else { - atp_writeb_io(dev, c, 0x19, synw[j++]); - } + if (dev->dev_id == ATP885_DEVID || dev->dev_id == ATP880_DEVID1 || dev->dev_id == ATP880_DEVID2) { + if ((m & dev->ultra_map[c]) != 0) { + atp_writeb_io(dev, c, 0x19, synuw[j++]); + } else { + atp_writeb_io(dev, c, 0x19, synw[j++]); + } + } else + atp_writeb_io(dev, c, 0x19, synw_870[j++]); } else { if ((m & dev->ultra_map[c]) != 0) { atp_writeb_io(dev, c, 0x19, synu[j++]); @@ -2753,7 +2760,10 @@ phase_outs: } continue; phase_ins: - atp_writeb_io(dev, c, 0x14, 0x06); + if (dev->dev_id == ATP885_DEVID || dev->dev_id == ATP880_DEVID1 || dev->dev_id == ATP880_DEVID2) + atp_writeb_io(dev, c, 0x14, 0x06); + else + atp_writeb_io(dev, c, 0x14, 0xff); atp_writeb_io(dev, c, 0x18, 0x20); k = 0; phase_ins1: @@ -2808,14 +2818,21 @@ tar_dcons: if (mbuf[3] > 0x64) { continue; } - if (mbuf[4] > 0x0e) { - mbuf[4] = 0x0e; + if (dev->dev_id == ATP885_DEVID || dev->dev_id == ATP880_DEVID1 || dev->dev_id == ATP880_DEVID2) { + if (mbuf[4] > 0x0e) { + mbuf[4] = 0x0e; + } + } else { + if (mbuf[4] > 0x0c) { + mbuf[4] = 0x0c; + } } dev->id[c][i].devsp = mbuf[4]; - if (mbuf[3] < 0x0c) { - j = 0xb0; - goto set_syn_ok; - } + if (dev->dev_id == ATP885_DEVID || dev->dev_id == ATP880_DEVID1 || dev->dev_id == ATP880_DEVID2) + if (mbuf[3] < 0x0c) { + j = 0xb0; + goto set_syn_ok; + } if ((mbuf[3] < 0x0d) && (rmb == 0)) { j = 0xa0; goto set_syn_ok; -- cgit v0.10.2 From 95c1def50dd6b1de4ceb0d6950e37e74c301d9d2 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:04 +0100 Subject: atp870u: Move 870-specific code out of is870() Move few remaining 870-specific code lines out of is870() Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index d76d386..6427f87 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1174,8 +1174,6 @@ static void is870(struct atp_unit *dev, unsigned char c, bool wide_chip) static unsigned char synw[6] = { 0x80, 1, 3, 1, 0x0c, 0x07 }; static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 }; - atp_writeb_io(dev, c, 0x3a, atp_readb_io(dev, c, 0x3a) | 0x10); - for (i = 0; i < 16; i++) { if (!wide_chip && (i > 7)) break; @@ -1587,7 +1585,6 @@ tar_dcons: set_syn_ok: dev->id[c][i].devsp = (dev->id[c][i].devsp & 0x0f) | j; } - atp_writeb_io(dev, c, 0x3a, atp_readb_io(dev, c, 0x3a) & 0xef); } static void atp870u_free_tables(struct Scsi_Host *host) @@ -2032,7 +2029,9 @@ flash_ok_885: outb(0x20, base_io + 0x11); tscam(shpnt); + atp_writeb_io(p, 0, 0x3a, atp_readb_io(p, 0, 0x3a) | 0x10); is870(p, 0, p->chip_ver == 4); + atp_writeb_io(p, 0, 0x3a, atp_readb_io(p, 0, 0x3a) & 0xef); outb((inb(base_io + 0x3a) & 0xef), base_io + 0x3a); outb((inb(base_io + 0x3b) | 0x20), base_io + 0x3b); if (atpdev->chip_ver == 4) -- cgit v0.10.2 From 851eb6618e6a27004e33c0422fdcf05b5b45c025 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:05 +0100 Subject: atp870u: Remove is870() Now that is885() supports everything from is870() and the rest of the code is almost identical, remove is870() and use is885() instead. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 6427f87..918875b 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1162,431 +1162,6 @@ static void tscam(struct Scsi_Host *host) } } -static void is870(struct atp_unit *dev, unsigned char c, bool wide_chip) -{ - unsigned char i, j, k, rmb, n; - unsigned short int m; - static unsigned char mbuf[512]; - static unsigned char satn[9] = { 0, 0, 0, 0, 0, 0, 0, 6, 6 }; - static unsigned char inqd[9] = { 0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6 }; - static unsigned char synn[6] = { 0x80, 1, 3, 1, 0x19, 0x0e }; - static unsigned char synu[6] = { 0x80, 1, 3, 1, 0x0c, 0x0e }; - static unsigned char synw[6] = { 0x80, 1, 3, 1, 0x0c, 0x07 }; - static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 }; - - for (i = 0; i < 16; i++) { - if (!wide_chip && (i > 7)) - break; - m = 1; - m = m << i; - if ((m & dev->active_id[c]) != 0) { - continue; - } - if (i == dev->host_id[c]) { - printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_id[c]); - continue; - } - atp_writeb_io(dev, c, 0x1b, wide_chip ? 0x01 : 0x00); - atp_writeb_io(dev, c, 1, 0x08); - atp_writeb_io(dev, c, 2, 0x7f); - atp_writeb_io(dev, c, 3, satn[0]); - atp_writeb_io(dev, c, 4, satn[1]); - atp_writeb_io(dev, c, 5, satn[2]); - atp_writeb_io(dev, c, 6, satn[3]); - atp_writeb_io(dev, c, 7, satn[4]); - atp_writeb_io(dev, c, 8, satn[5]); - atp_writeb_io(dev, c, 0x0f, 0); - atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); - atp_writeb_io(dev, c, 0x12, 0); - atp_writeb_io(dev, c, 0x13, satn[6]); - atp_writeb_io(dev, c, 0x14, satn[7]); - j = i; - if ((j & 0x08) != 0) { - j = (j & 0x07) | 0x40; - } - atp_writeb_io(dev, c, 0x15, j); - atp_writeb_io(dev, c, 0x18, satn[8]); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) - continue; - - while (atp_readb_io(dev, c, 0x17) != 0x8e) - cpu_relax(); - - dev->active_id[c] |= m; - - atp_writeb_io(dev, c, 0x10, 0x30); - atp_writeb_io(dev, c, 0x04, 0x00); - -phase_cmd: - atp_writeb_io(dev, c, 0x18, 0x08); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - j = atp_readb_io(dev, c, 0x17); - if (j != 0x16) { - atp_writeb_io(dev, c, 0x10, 0x41); - goto phase_cmd; - } -sel_ok: - atp_writeb_io(dev, c, 3, inqd[0]); - atp_writeb_io(dev, c, 4, inqd[1]); - atp_writeb_io(dev, c, 5, inqd[2]); - atp_writeb_io(dev, c, 6, inqd[3]); - atp_writeb_io(dev, c, 7, inqd[4]); - atp_writeb_io(dev, c, 8, inqd[5]); - atp_writeb_io(dev, c, 0x0f, 0); - atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); - atp_writeb_io(dev, c, 0x12, 0); - atp_writeb_io(dev, c, 0x13, inqd[6]); - atp_writeb_io(dev, c, 0x14, inqd[7]); - atp_writeb_io(dev, c, 0x18, inqd[8]); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) - continue; - - while (atp_readb_io(dev, c, 0x17) != 0x8e) - cpu_relax(); - - if (wide_chip) - atp_writeb_io(dev, c, 0x1b, 0x00); - - atp_writeb_io(dev, c, 0x18, 0x08); - j = 0; -rd_inq_data: - k = atp_readb_io(dev, c, 0x1f); - if ((k & 0x01) != 0) { - mbuf[j++] = atp_readb_io(dev, c, 0x19); - goto rd_inq_data; - } - if ((k & 0x80) == 0) { - goto rd_inq_data; - } - j = atp_readb_io(dev, c, 0x17); - if (j == 0x16) { - goto inq_ok; - } - atp_writeb_io(dev, c, 0x10, 0x46); - atp_writeb_io(dev, c, 0x12, 0); - atp_writeb_io(dev, c, 0x13, 0); - atp_writeb_io(dev, c, 0x14, 0); - atp_writeb_io(dev, c, 0x18, 0x08); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - if (atp_readb_io(dev, c, 0x17) != 0x16) - goto sel_ok; - -inq_ok: - mbuf[36] = 0; - printk(KERN_INFO " ID: %2d %s\n", i, &mbuf[8]); - dev->id[c][i].devtype = mbuf[0]; - rmb = mbuf[1]; - n = mbuf[7]; - if (!wide_chip) - goto not_wide; - if ((mbuf[7] & 0x60) == 0) { - goto not_wide; - } - if ((dev->global_map[c] & 0x20) == 0) { - goto not_wide; - } - atp_writeb_io(dev, c, 0x1b, 0x01); - atp_writeb_io(dev, c, 3, satn[0]); - atp_writeb_io(dev, c, 4, satn[1]); - atp_writeb_io(dev, c, 5, satn[2]); - atp_writeb_io(dev, c, 6, satn[3]); - atp_writeb_io(dev, c, 7, satn[4]); - atp_writeb_io(dev, c, 8, satn[5]); - atp_writeb_io(dev, c, 0x0f, 0); - atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); - atp_writeb_io(dev, c, 0x12, 0); - atp_writeb_io(dev, c, 0x13, satn[6]); - atp_writeb_io(dev, c, 0x14, satn[7]); - atp_writeb_io(dev, c, 0x18, satn[8]); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) - continue; - - while (atp_readb_io(dev, c, 0x17) != 0x8e) - cpu_relax(); - -try_wide: - j = 0; - atp_writeb_io(dev, c, 0x14, 0x05); - atp_writeb_io(dev, c, 0x18, 0x20); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { - if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) - atp_writeb_io(dev, c, 0x19, wide[j++]); - } - - while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) - cpu_relax(); - - j = atp_readb_io(dev, c, 0x17) & 0x0f; - if (j == 0x0f) { - goto widep_in; - } - if (j == 0x0a) { - goto widep_cmd; - } - if (j == 0x0e) { - goto try_wide; - } - continue; -widep_out: - atp_writeb_io(dev, c, 0x18, 0x20); - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { - if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) - atp_writeb_io(dev, c, 0x19, 0); - } - j = atp_readb_io(dev, c, 0x17) & 0x0f; - if (j == 0x0f) { - goto widep_in; - } - if (j == 0x0a) { - goto widep_cmd; - } - if (j == 0x0e) { - goto widep_out; - } - continue; -widep_in: - atp_writeb_io(dev, c, 0x14, 0xff); - atp_writeb_io(dev, c, 0x18, 0x20); - k = 0; -widep_in1: - j = atp_readb_io(dev, c, 0x1f); - if ((j & 0x01) != 0) { - mbuf[k++] = atp_readb_io(dev, c, 0x19); - goto widep_in1; - } - if ((j & 0x80) == 0x00) { - goto widep_in1; - } - j = atp_readb_io(dev, c, 0x17) & 0x0f; - if (j == 0x0f) { - goto widep_in; - } - if (j == 0x0a) { - goto widep_cmd; - } - if (j == 0x0e) { - goto widep_out; - } - continue; -widep_cmd: - atp_writeb_io(dev, c, 0x10, 0x30); - atp_writeb_io(dev, c, 0x14, 0x00); - atp_writeb_io(dev, c, 0x18, 0x08); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - j = atp_readb_io(dev, c, 0x17); - if (j != 0x16) { - if (j == 0x4e) { - goto widep_out; - } - continue; - } - if (mbuf[0] != 0x01) { - goto not_wide; - } - if (mbuf[1] != 0x02) { - goto not_wide; - } - if (mbuf[2] != 0x03) { - goto not_wide; - } - if (mbuf[3] != 0x01) { - goto not_wide; - } - m = 1; - m = m << i; - dev->wide_id[c] |= m; -not_wide: - if ((dev->id[c][i].devtype == 0x00) || (dev->id[c][i].devtype == 0x07) || ((dev->id[c][i].devtype == 0x05) && ((n & 0x10) != 0))) { - goto set_sync; - } - continue; -set_sync: - j = 0; - if ((m & dev->wide_id[c]) != 0) { - j |= 0x01; - } - atp_writeb_io(dev, c, 0x1b, j); - atp_writeb_io(dev, c, 3, satn[0]); - atp_writeb_io(dev, c, 4, satn[1]); - atp_writeb_io(dev, c, 5, satn[2]); - atp_writeb_io(dev, c, 6, satn[3]); - atp_writeb_io(dev, c, 7, satn[4]); - atp_writeb_io(dev, c, 8, satn[5]); - atp_writeb_io(dev, c, 0x0f, 0); - atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp); - atp_writeb_io(dev, c, 0x12, 0); - atp_writeb_io(dev, c, 0x13, satn[6]); - atp_writeb_io(dev, c, 0x14, satn[7]); - atp_writeb_io(dev, c, 0x18, satn[8]); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e) - continue; - - while (atp_readb_io(dev, c, 0x17) != 0x8e) - cpu_relax(); - -try_sync: - j = 0; - atp_writeb_io(dev, c, 0x14, 0x06); - atp_writeb_io(dev, c, 0x18, 0x20); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { - if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) { - if ((m & dev->wide_id[c]) != 0) { - atp_writeb_io(dev, c, 0x19, synw[j++]); - } else { - if ((m & dev->ultra_map[c]) != 0) { - atp_writeb_io(dev, c, 0x19, synu[j++]); - } else { - atp_writeb_io(dev, c, 0x19, synn[j++]); - } - } - } - } - - while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) - cpu_relax(); - - j = atp_readb_io(dev, c, 0x17) & 0x0f; - if (j == 0x0f) { - goto phase_ins; - } - if (j == 0x0a) { - goto phase_cmds; - } - if (j == 0x0e) { - goto try_sync; - } - continue; -phase_outs: - atp_writeb_io(dev, c, 0x18, 0x20); - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) { - if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0x00) - atp_writeb_io(dev, c, 0x19, 0x00); - } - j = atp_readb_io(dev, c, 0x17); - if (j == 0x85) { - goto tar_dcons; - } - j &= 0x0f; - if (j == 0x0f) { - goto phase_ins; - } - if (j == 0x0a) { - goto phase_cmds; - } - if (j == 0x0e) { - goto phase_outs; - } - continue; -phase_ins: - atp_writeb_io(dev, c, 0x14, 0xff); - atp_writeb_io(dev, c, 0x18, 0x20); - k = 0; -phase_ins1: - j = atp_readb_io(dev, c, 0x1f); - if ((j & 0x01) != 0x00) { - mbuf[k++] = atp_readb_io(dev, c, 0x19); - goto phase_ins1; - } - if ((j & 0x80) == 0x00) { - goto phase_ins1; - } - - while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00) - cpu_relax(); - - j = atp_readb_io(dev, c, 0x17); - if (j == 0x85) { - goto tar_dcons; - } - j &= 0x0f; - if (j == 0x0f) { - goto phase_ins; - } - if (j == 0x0a) { - goto phase_cmds; - } - if (j == 0x0e) { - goto phase_outs; - } - continue; -phase_cmds: - atp_writeb_io(dev, c, 0x10, 0x30); -tar_dcons: - atp_writeb_io(dev, c, 0x14, 0x00); - atp_writeb_io(dev, c, 0x18, 0x08); - - while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) - cpu_relax(); - - j = atp_readb_io(dev, c, 0x17); - if (j != 0x16) { - continue; - } - if (mbuf[0] != 0x01) { - continue; - } - if (mbuf[1] != 0x03) { - continue; - } - if (mbuf[4] == 0x00) { - continue; - } - if (mbuf[3] > 0x64) { - continue; - } - if (mbuf[4] > 0x0c) { - mbuf[4] = 0x0c; - } - dev->id[c][i].devsp = mbuf[4]; - if ((mbuf[3] < 0x0d) && (rmb == 0)) { - j = 0xa0; - goto set_syn_ok; - } - if (mbuf[3] < 0x1a) { - j = 0x20; - goto set_syn_ok; - } - if (mbuf[3] < 0x33) { - j = 0x40; - goto set_syn_ok; - } - if (mbuf[3] < 0x4c) { - j = 0x50; - goto set_syn_ok; - } - j = 0x60; -set_syn_ok: - dev->id[c][i].devsp = (dev->id[c][i].devsp & 0x0f) | j; - } -} - static void atp870u_free_tables(struct Scsi_Host *host) { struct atp_unit *atp_dev = (struct atp_unit *)&host->hostdata; @@ -2030,7 +1605,7 @@ flash_ok_885: tscam(shpnt); atp_writeb_io(p, 0, 0x3a, atp_readb_io(p, 0, 0x3a) | 0x10); - is870(p, 0, p->chip_ver == 4); + is885(p, 0, p->chip_ver == 4, 0); atp_writeb_io(p, 0, 0x3a, atp_readb_io(p, 0, 0x3a) & 0xef); outb((inb(base_io + 0x3a) & 0xef), base_io + 0x3a); outb((inb(base_io + 0x3b) | 0x20), base_io + 0x3b); -- cgit v0.10.2 From 4192a40f49f0ab3028019deaba5cdc3b9db789dd Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:06 +0100 Subject: atp870u: Rename is885() to atp_is() Now that all the is* functions except is885() are gone, rename is885() to atp_is() to avoid confusion. Don't know what "is" means, though... Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 918875b..0b7d3bd 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -41,7 +41,7 @@ static struct scsi_host_template atp870u_template; static void send_s870(struct atp_unit *dev,unsigned char c); -static void is885(struct atp_unit *dev, unsigned char c, bool wide_chip, unsigned char lvdmode); +static void atp_is(struct atp_unit *dev, unsigned char c, bool wide_chip, unsigned char lvdmode); static void tscam_885(void); static inline void atp_writeb_base(struct atp_unit *atp, u8 reg, u8 val) @@ -1373,7 +1373,7 @@ flash_ok_880: outb(0x20, base_io + 0x51); tscam(shpnt); - is885(p, 0, true, atp_readb_base(p, 0x3f) & 0x40); + atp_is(p, 0, true, atp_readb_base(p, 0x3f) & 0x40); outb(0xb0, base_io + 0x38); shpnt->max_id = 16; shpnt->this_id = host_id; @@ -1519,10 +1519,10 @@ flash_ok_885: tscam_885(); printk(KERN_INFO " Scanning Channel A SCSI Device ...\n"); - is885(p, 0, true, atp_readb_io(p, 0, 0x1b) >> 7); + atp_is(p, 0, true, atp_readb_io(p, 0, 0x1b) >> 7); atp_writeb_io(p, 0, 0x16, 0x80); printk(KERN_INFO " Scanning Channel B SCSI Device ...\n"); - is885(p, 1, true, atp_readb_io(p, 1, 0x1b) >> 7); + atp_is(p, 1, true, atp_readb_io(p, 1, 0x1b) >> 7); atp_writeb_io(p, 1, 0x16, 0x80); k = inb(base_io + 0x28) & 0xcf; k |= 0xc0; @@ -1605,7 +1605,7 @@ flash_ok_885: tscam(shpnt); atp_writeb_io(p, 0, 0x3a, atp_readb_io(p, 0, 0x3a) | 0x10); - is885(p, 0, p->chip_ver == 4, 0); + atp_is(p, 0, p->chip_ver == 4, 0); atp_writeb_io(p, 0, 0x3a, atp_readb_io(p, 0, 0x3a) & 0xef); outb((inb(base_io + 0x3a) & 0xef), base_io + 0x3a); outb((inb(base_io + 0x3b) | 0x20), base_io + 0x3b); @@ -1826,7 +1826,7 @@ static void tscam_885(void) -static void is885(struct atp_unit *dev, unsigned char c, bool wide_chip, unsigned char lvdmode) +static void atp_is(struct atp_unit *dev, unsigned char c, bool wide_chip, unsigned char lvdmode) { unsigned char i, j, k, rmb, n; unsigned short int m; -- cgit v0.10.2 From d804bb255ce85b1fd7dfe447da5415952ba341c5 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:07 +0100 Subject: atp870u: Convert remaining in[bwl] and out[bwl] to wrappers Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 0b7d3bd..bccf872 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -49,6 +49,11 @@ static inline void atp_writeb_base(struct atp_unit *atp, u8 reg, u8 val) outb(val, atp->baseport + reg); } +static inline void atp_writew_base(struct atp_unit *atp, u8 reg, u16 val) +{ + outw(val, atp->baseport + reg); +} + static inline void atp_writeb_io(struct atp_unit *atp, u8 channel, u8 reg, u8 val) { outb(val, atp->ioport[channel] + reg); @@ -74,6 +79,16 @@ static inline u8 atp_readb_base(struct atp_unit *atp, u8 reg) return inb(atp->baseport + reg); } +static inline u16 atp_readw_base(struct atp_unit *atp, u8 reg) +{ + return inw(atp->baseport + reg); +} + +static inline u32 atp_readl_base(struct atp_unit *atp, u8 reg) +{ + return inl(atp->baseport + reg); +} + static inline u8 atp_readb_io(struct atp_unit *atp, u8 channel, u8 reg) { return inb(atp->ioport[channel] + reg); @@ -1268,19 +1283,20 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) atpdev->chip_ver = pdev->revision; pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);//JCC082803 - host_id = inb(base_io + 0x39); + atpdev->ioport[0] = base_io + 0x40; + atpdev->pciport[0] = base_io + 0x28; + + host_id = atp_readb_base(atpdev, 0x39); host_id >>= 0x04; printk(KERN_INFO " ACARD AEC-67160 PCI Ultra3 LVD Host Adapter: %d" " IO:%x, IRQ:%d.\n", count, base_io, pdev->irq); - atpdev->ioport[0] = base_io + 0x40; - atpdev->pciport[0] = base_io + 0x28; atpdev->dev_id = ent->device; atpdev->host_id[0] = host_id; - atpdev->scam_on = inb(base_io + 0x22); - atpdev->global_map[0] = inb(base_io + 0x35); - atpdev->ultra_map[0] = inw(base_io + 0x3c); + atpdev->scam_on = atp_readb_base(atpdev, 0x22); + atpdev->global_map[0] = atp_readb_base(atpdev, 0x35); + atpdev->ultra_map[0] = atp_readw_base(atpdev, 0x3c); n = 0x3f09; next_fblk_880: @@ -1288,37 +1304,37 @@ next_fblk_880: goto flash_ok_880; m = 0; - outw(n, base_io + 0x34); + atp_writew_base(atpdev, 0x34, n); n += 0x0002; - if (inb(base_io + 0x30) == 0xff) + if (atp_readb_base(atpdev, 0x30) == 0xff) goto flash_ok_880; - atpdev->sp[0][m++] = inb(base_io + 0x30); - atpdev->sp[0][m++] = inb(base_io + 0x31); - atpdev->sp[0][m++] = inb(base_io + 0x32); - atpdev->sp[0][m++] = inb(base_io + 0x33); - outw(n, base_io + 0x34); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x30); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x31); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x32); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x33); + atp_writew_base(atpdev, 0x34, n); n += 0x0002; - atpdev->sp[0][m++] = inb(base_io + 0x30); - atpdev->sp[0][m++] = inb(base_io + 0x31); - atpdev->sp[0][m++] = inb(base_io + 0x32); - atpdev->sp[0][m++] = inb(base_io + 0x33); - outw(n, base_io + 0x34); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x30); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x31); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x32); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x33); + atp_writew_base(atpdev, 0x34, n); n += 0x0002; - atpdev->sp[0][m++] = inb(base_io + 0x30); - atpdev->sp[0][m++] = inb(base_io + 0x31); - atpdev->sp[0][m++] = inb(base_io + 0x32); - atpdev->sp[0][m++] = inb(base_io + 0x33); - outw(n, base_io + 0x34); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x30); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x31); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x32); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x33); + atp_writew_base(atpdev, 0x34, n); n += 0x0002; - atpdev->sp[0][m++] = inb(base_io + 0x30); - atpdev->sp[0][m++] = inb(base_io + 0x31); - atpdev->sp[0][m++] = inb(base_io + 0x32); - atpdev->sp[0][m++] = inb(base_io + 0x33); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x30); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x31); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x32); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x33); n += 0x0018; goto next_fblk_880; flash_ok_880: - outw(0, base_io + 0x34); + atp_writew_base(atpdev, 0x34, 0); atpdev->ultra_map[0] = 0; atpdev->async[0] = 0; for (k = 0; k < 16; k++) { @@ -1332,7 +1348,7 @@ flash_ok_880: } } atpdev->async[0] = ~(atpdev->async[0]); - outb(atpdev->global_map[0], base_io + 0x35); + atp_writeb_base(atpdev, 0x35, atpdev->global_map[0]); shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); if (!shpnt) @@ -1355,26 +1371,26 @@ flash_ok_880: } spin_lock_irqsave(shpnt->host_lock, flags); - k = inb(base_io + 0x38) & 0x80; - outb(k, base_io + 0x38); - outb(0x20, base_io + 0x3b); + k = atp_readb_base(p, 0x38) & 0x80; + atp_writeb_base(p, 0x38, k); + atp_writeb_base(p, 0x3b, 0x20); mdelay(32); - outb(0, base_io + 0x3b); + atp_writeb_base(p, 0x3b, 0); mdelay(32); - inb(base_io + 0x5b); - inb(base_io + 0x57); - outb((host_id | 0x08), base_io + 0x40); - outb(0, base_io + 0x58); - while ((inb(base_io + 0x5f) & 0x80) == 0) + atp_readb_io(p, 0, 0x1b); + atp_readb_io(p, 0, 0x17); + atp_writeb_io(p, 0, 0, host_id | 0x08); + atp_writeb_io(p, 0, 0x18, 0); + while ((atp_readb_io(p, 0, 0x1f) & 0x80) == 0) mdelay(1); - inb(base_io + 0x57); - outb(8, base_io + 0x41); - outb(0x7f, base_io + 0x42); - outb(0x20, base_io + 0x51); + atp_readb_io(p, 0, 0x17); + atp_writeb_io(p, 0, 1, 8); + atp_writeb_io(p, 0, 2, 0x7f); + atp_writeb_io(p, 0, 0x11, 0x20); tscam(shpnt); atp_is(p, 0, true, atp_readb_base(p, 0x3f) & 0x40); - outb(0xb0, base_io + 0x38); + atp_writeb_base(p, 0x38, 0xb0); shpnt->max_id = 16; shpnt->this_id = host_id; shpnt->unique_id = base_io; @@ -1415,27 +1431,27 @@ flash_ok_880: spin_lock_irqsave(shpnt->host_lock, flags); - c=inb(base_io + 0x29); - outb((c | 0x04),base_io + 0x29); + c = atp_readb_base(p, 0x29); + atp_writeb_base(p, 0x29, c | 0x04); n=0x1f80; next_fblk_885: if (n >= 0x2000) { goto flash_ok_885; } - outw(n,base_io + 0x3c); - if (inl(base_io + 0x38) == 0xffffffff) { + atp_writew_base(p, 0x3c, n); + if (atp_readl_base(p, 0x38) == 0xffffffff) { goto flash_ok_885; } for (m=0; m < 2; m++) { p->global_map[m]= 0; for (k=0; k < 4; k++) { - outw(n++,base_io + 0x3c); - ((unsigned long *)&setupdata[m][0])[k]=inl(base_io + 0x38); + atp_writew_base(p, 0x3c, n++); + ((unsigned long *)&setupdata[m][0])[k] = atp_readl_base(p, 0x38); } for (k=0; k < 4; k++) { - outw(n++,base_io + 0x3c); - ((unsigned long *)&p->sp[m][0])[k]=inl(base_io + 0x38); + atp_writew_base(p, 0x3c, n++); + ((unsigned long *)&p->sp[m][0])[k] = atp_readl_base(p, 0x38); } n += 8; } @@ -1444,8 +1460,8 @@ flash_ok_885: #ifdef ED_DBGP printk( "Flash Read OK\n"); #endif - c=inb(base_io + 0x29); - outb((c & 0xfb),base_io + 0x29); + c = atp_readb_base(p, 0x29); + atp_writeb_base(p, 0x29, c & 0xfb); for (c=0;c < 2;c++) { p->ultra_map[c]=0; p->async[c] = 0; @@ -1474,48 +1490,48 @@ flash_ok_885: } } - k = inb(base_io + 0x28) & 0x8f; + k = atp_readb_base(p, 0x28) & 0x8f; k |= 0x10; - outb(k, base_io + 0x28); - outb(0x80, base_io + 0x41); - outb(0x80, base_io + 0x51); + atp_writeb_base(p, 0x28, k); + atp_writeb_pci(p, 0, 1, 0x80); + atp_writeb_pci(p, 1, 1, 0x80); mdelay(100); - outb(0, base_io + 0x41); - outb(0, base_io + 0x51); + atp_writeb_pci(p, 0, 1, 0); + atp_writeb_pci(p, 1, 1, 0); mdelay(1000); - inb(base_io + 0x9b); - inb(base_io + 0x97); - inb(base_io + 0xdb); - inb(base_io + 0xd7); + atp_readb_io(p, 0, 0x1b); + atp_readb_io(p, 0, 0x17); + atp_readb_io(p, 1, 0x1b); + atp_readb_io(p, 1, 0x17); k=p->host_id[0]; if (k > 7) k = (k & 0x07) | 0x40; k |= 0x08; - outb(k, base_io + 0x80); - outb(0, base_io + 0x98); + atp_writeb_io(p, 0, 0, k); + atp_writeb_io(p, 0, 0x18, 0); - while ((inb(base_io + 0x9f) & 0x80) == 0) + while ((atp_readb_io(p, 0, 0x1f) & 0x80) == 0) cpu_relax(); - inb(base_io + 0x97); - outb(8, base_io + 0x81); - outb(0x7f, base_io + 0x82); - outb(0x20, base_io + 0x91); + atp_readb_io(p, 0, 0x17); + atp_writeb_io(p, 0, 1, 8); + atp_writeb_io(p, 0, 2, 0x7f); + atp_writeb_io(p, 0, 0x11, 0x20); k=p->host_id[1]; if (k > 7) k = (k & 0x07) | 0x40; k |= 0x08; - outb(k, base_io + 0xc0); - outb(0, base_io + 0xd8); + atp_writeb_io(p, 1, 0, k); + atp_writeb_io(p, 1, 0x18, 0); - while ((inb(base_io + 0xdf) & 0x80) == 0) + while ((atp_readb_io(p, 1, 0x1f) & 0x80) == 0) cpu_relax(); - inb(base_io + 0xd7); - outb(8, base_io + 0xc1); - outb(0x7f, base_io + 0xc2); - outb(0x20, base_io + 0xd1); + atp_readb_io(p, 1, 0x17); + atp_writeb_io(p, 1, 1, 8); + atp_writeb_io(p, 1, 2, 0x7f); + atp_writeb_io(p, 1, 0x11, 0x20); tscam_885(); printk(KERN_INFO " Scanning Channel A SCSI Device ...\n"); @@ -1524,13 +1540,13 @@ flash_ok_885: printk(KERN_INFO " Scanning Channel B SCSI Device ...\n"); atp_is(p, 1, true, atp_readb_io(p, 1, 0x1b) >> 7); atp_writeb_io(p, 1, 0x16, 0x80); - k = inb(base_io + 0x28) & 0xcf; + k = atp_readb_base(p, 0x28) & 0xcf; k |= 0xc0; - outb(k, base_io + 0x28); - k = inb(base_io + 0x1f) | 0x80; - outb(k, base_io + 0x1f); - k = inb(base_io + 0x29) | 0x01; - outb(k, base_io + 0x29); + atp_writeb_base(p, 0x28, k); + k = atp_readb_base(p, 0x1f) | 0x80; + atp_writeb_base(p, 0x1f, k); + k = atp_readb_base(p, 0x29) | 0x01; + atp_writeb_base(p, 0x29, k); #ifdef ED_DBGP //printk("atp885: atp_host[0] 0x%p\n", atp_host[0]); #endif @@ -1554,9 +1570,9 @@ flash_ok_885: atpdev->dev_id = ent->device; host_id &= 0x07; atpdev->host_id[0] = host_id; - atpdev->scam_on = inb(base_io + 0x22); - atpdev->global_map[0] = inb(base_io + 0x2d); - atpdev->ultra_map[0] = inw(base_io + 0x2e); + atpdev->scam_on = atp_readb_pci(atpdev, 0, 2); + atpdev->global_map[0] = atp_readb_base(atpdev, 0x2d); + atpdev->ultra_map[0] = atp_readw_base(atpdev, 0x2e); if (atpdev->ultra_map[0] == 0) { atpdev->scam_on = 0x00; @@ -1583,32 +1599,30 @@ flash_ok_885: } spin_lock_irqsave(shpnt->host_lock, flags); - if (atpdev->chip_ver > 0x07) { /* check if atp876 chip then enable terminator */ - outb(0x00, base_io + 0x3e); - } + if (atpdev->chip_ver > 0x07) /* check if atp876 chip then enable terminator */ + atp_writeb_base(p, 0x3e, 0x00); - k = (inb(base_io + 0x3a) & 0xf3) | 0x10; - outb(k, base_io + 0x3a); - outb((k & 0xdf), base_io + 0x3a); + k = (atp_readb_base(p, 0x3a) & 0xf3) | 0x10; + atp_writeb_base(p, 0x3a, k); + atp_writeb_base(p, 0x3a, k & 0xdf); mdelay(32); - outb(k, base_io + 0x3a); + atp_writeb_base(p, 0x3a, k); mdelay(32); - outb((host_id | 0x08), base_io + 0); - outb(0, base_io + 0x18); - while ((inb(base_io + 0x1f) & 0x80) == 0) + atp_writeb_io(p, 0, 0, host_id | 0x08); + atp_writeb_io(p, 0, 0x18, 0); + while ((atp_readb_io(p, 0, 0x1f) & 0x80) == 0) mdelay(1); - inb(base_io + 0x17); - outb(8, base_io + 1); - outb(0x7f, base_io + 2); - outb(0x20, base_io + 0x11); + atp_readb_io(p, 0, 0x17); + atp_writeb_io(p, 0, 1, 8); + atp_writeb_io(p, 0, 2, 0x7f); + atp_writeb_io(p, 0, 0x11, 0x20); tscam(shpnt); - atp_writeb_io(p, 0, 0x3a, atp_readb_io(p, 0, 0x3a) | 0x10); + atp_writeb_base(p, 0x3a, atp_readb_base(p, 0x3a) | 0x10); atp_is(p, 0, p->chip_ver == 4, 0); - atp_writeb_io(p, 0, 0x3a, atp_readb_io(p, 0, 0x3a) & 0xef); - outb((inb(base_io + 0x3a) & 0xef), base_io + 0x3a); - outb((inb(base_io + 0x3b) | 0x20), base_io + 0x3b); + atp_writeb_base(p, 0x3a, atp_readb_base(p, 0x3a) & 0xef); + atp_writeb_base(p, 0x3b, atp_readb_base(p, 0x3b) | 0x20); if (atpdev->chip_ver == 4) shpnt->max_id = 16; else -- cgit v0.10.2 From 2bbbac4571de7983f142ed22add59e5217674169 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:08 +0100 Subject: atp870u: Replace port 0x80 delay by udelay tscam() is using port 0x80 access for delays but that's x86-only. Use udelay(2) instead. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index bccf872..c4a59cc 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1036,7 +1036,7 @@ static void tscam(struct Scsi_Host *host) atp_writeb_io(dev, 0, 0x02, 0x7f); atp_writeb_io(dev, 0, 0x1b, 0x02); - outb(0, 0x80); + udelay(2); val = 0x0080; /* bsy */ atp_writew_io(dev, 0, 0x1c, val); @@ -1044,7 +1044,7 @@ static void tscam(struct Scsi_Host *host) atp_writew_io(dev, 0, 0x1c, val); val |= 0x0004; /* msg */ atp_writew_io(dev, 0, 0x1c, val); - inb(0x80); /* 2 deskew delay(45ns*2=90ns) */ + udelay(2); /* 2 deskew delay(45ns*2=90ns) */ val &= 0x007f; /* no bsy */ atp_writew_io(dev, 0, 0x1c, val); mdelay(128); @@ -1052,7 +1052,7 @@ static void tscam(struct Scsi_Host *host) atp_writew_io(dev, 0, 0x1c, val); while ((atp_readb_io(dev, 0, 0x1c) & 0x04) != 0) ; - outb(1, 0x80); + udelay(2); udelay(100); for (n = 0; n < 0x30000; n++) if ((atp_readb_io(dev, 0, 0x1c) & 0x80) != 0) /* bsy ? */ @@ -1060,13 +1060,13 @@ static void tscam(struct Scsi_Host *host) if (n < 0x30000) for (n = 0; n < 0x30000; n++) if ((atp_readb_io(dev, 0, 0x1c) & 0x81) == 0x0081) { - inb(0x80); + udelay(2); val |= 0x8003; /* io,cd,db7 */ atp_writew_io(dev, 0, 0x1c, val); - inb(0x80); + udelay(2); val &= 0x00bf; /* no sel */ atp_writew_io(dev, 0, 0x1c, val); - outb(2, 0x80); + udelay(2); break; } while (1) { @@ -1093,18 +1093,18 @@ static void tscam(struct Scsi_Host *host) val &= 0x00ff; /* synchronization */ val |= 0x3f00; fun_scam(dev, &val); - outb(3, 0x80); + udelay(2); val &= 0x00ff; /* isolation */ val |= 0x2000; fun_scam(dev, &val); - outb(4, 0x80); + udelay(2); i = 8; j = 0; while (1) { if ((atp_readw_io(dev, 0, 0x1c) & 0x2000) == 0) continue; - outb(5, 0x80); + udelay(2); val &= 0x00ff; /* get ID_STRING */ val |= 0x2000; k = fun_scam(dev, &val); -- cgit v0.10.2 From c751d9f1fce4187bf1c0848d7d3a5bf7644d7f9c Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:09 +0100 Subject: atp870u: Fix incorrect writeb_io access to register 0x3a The ioport region is 0x20 bytes long so accessing 0x3a register using writeb_io is incorrect. Use writeb_base instead. There's no change in behavior as 870 chips have ioport = baseport. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index c4a59cc..04b29d3 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -364,9 +364,9 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) atp_writeb_base(dev, 0x3b, atp_readb_base(dev, 0x3b) & 0x3f); } else { if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) - atp_writeb_io(dev, c, 0x3a, (atp_readb_io(dev, c, 0x3a) & 0xf3) | 0x08); + atp_writeb_base(dev, 0x3a, (atp_readb_base(dev, 0x3a) & 0xf3) | 0x08); else - atp_writeb_io(dev, c, 0x3a, atp_readb_io(dev, c, 0x3a) & 0xf3); + atp_writeb_base(dev, 0x3a, atp_readb_base(dev, 0x3a) & 0xf3); } j = 0; id = 1; @@ -889,9 +889,9 @@ static void send_s870(struct atp_unit *dev,unsigned char c) atp_writeb_base(dev, 0x3b, atp_readb_base(dev, 0x3b) & 0x3f); } else { if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) - atp_writeb_io(dev, c, 0x3a, (atp_readb_io(dev, c, 0x3a) & 0xf3) | 0x08); + atp_writeb_base(dev, 0x3a, (atp_readb_base(dev, 0x3a) & 0xf3) | 0x08); else - atp_writeb_io(dev, c, 0x3a, atp_readb_io(dev, c, 0x3a) & 0xf3); + atp_writeb_base(dev, 0x3a, atp_readb_base(dev, 0x3a) & 0xf3); } if(workreq->sc_data_direction == DMA_TO_DEVICE) { -- cgit v0.10.2 From 6a1961bc9c8916fc40423cc71e44fd8c59fef360 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:10 +0100 Subject: atp870u: Introduce atp_set_host_id The code for setting host adapter ID is the same for all chips. Move it to a common function. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 04b29d3..9621403 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1229,6 +1229,18 @@ static int atp870u_init_tables(struct Scsi_Host *host) return 0; } +static void atp_set_host_id(struct atp_unit *atp, u8 c, u8 host_id) +{ + atp_writeb_io(atp, c, 0, host_id | 0x08); + atp_writeb_io(atp, c, 0x18, 0); + while ((atp_readb_io(atp, c, 0x1f) & 0x80) == 0) + mdelay(1); + atp_readb_io(atp, c, 0x17); + atp_writeb_io(atp, c, 1, 8); + atp_writeb_io(atp, c, 2, 0x7f); + atp_writeb_io(atp, c, 0x11, 0x20); +} + /* return non-zero on detection */ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -1379,14 +1391,8 @@ flash_ok_880: mdelay(32); atp_readb_io(p, 0, 0x1b); atp_readb_io(p, 0, 0x17); - atp_writeb_io(p, 0, 0, host_id | 0x08); - atp_writeb_io(p, 0, 0x18, 0); - while ((atp_readb_io(p, 0, 0x1f) & 0x80) == 0) - mdelay(1); - atp_readb_io(p, 0, 0x17); - atp_writeb_io(p, 0, 1, 8); - atp_writeb_io(p, 0, 2, 0x7f); - atp_writeb_io(p, 0, 0x11, 0x20); + + atp_set_host_id(p, 0, host_id); tscam(shpnt); atp_is(p, 0, true, atp_readb_base(p, 0x3f) & 0x40); @@ -1503,35 +1509,16 @@ flash_ok_885: atp_readb_io(p, 0, 0x17); atp_readb_io(p, 1, 0x1b); atp_readb_io(p, 1, 0x17); + k=p->host_id[0]; if (k > 7) k = (k & 0x07) | 0x40; - k |= 0x08; - atp_writeb_io(p, 0, 0, k); - atp_writeb_io(p, 0, 0x18, 0); - - while ((atp_readb_io(p, 0, 0x1f) & 0x80) == 0) - cpu_relax(); - - atp_readb_io(p, 0, 0x17); - atp_writeb_io(p, 0, 1, 8); - atp_writeb_io(p, 0, 2, 0x7f); - atp_writeb_io(p, 0, 0x11, 0x20); + atp_set_host_id(p, 0, k); k=p->host_id[1]; if (k > 7) k = (k & 0x07) | 0x40; - k |= 0x08; - atp_writeb_io(p, 1, 0, k); - atp_writeb_io(p, 1, 0x18, 0); - - while ((atp_readb_io(p, 1, 0x1f) & 0x80) == 0) - cpu_relax(); - - atp_readb_io(p, 1, 0x17); - atp_writeb_io(p, 1, 1, 8); - atp_writeb_io(p, 1, 2, 0x7f); - atp_writeb_io(p, 1, 0x11, 0x20); + atp_set_host_id(p, 1, k); tscam_885(); printk(KERN_INFO " Scanning Channel A SCSI Device ...\n"); @@ -1608,15 +1595,7 @@ flash_ok_885: mdelay(32); atp_writeb_base(p, 0x3a, k); mdelay(32); - atp_writeb_io(p, 0, 0, host_id | 0x08); - atp_writeb_io(p, 0, 0x18, 0); - while ((atp_readb_io(p, 0, 0x1f) & 0x80) == 0) - mdelay(1); - - atp_readb_io(p, 0, 0x17); - atp_writeb_io(p, 0, 1, 8); - atp_writeb_io(p, 0, 2, 0x7f); - atp_writeb_io(p, 0, 0x11, 0x20); + atp_set_host_id(p, 0, host_id); tscam(shpnt); atp_writeb_base(p, 0x3a, atp_readb_base(p, 0x3a) | 0x10); -- cgit v0.10.2 From 34a2c35d29a160b326bc63dfbff64ae38fe0a994 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:11 +0100 Subject: atp870u: Reduce log spam on module load/unload Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 9621403..b662e39 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1260,9 +1260,7 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (pci_enable_device(pdev)) goto err_eio; - if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { - printk(KERN_INFO "atp870u: use 32bit DMA mask.\n"); - } else { + if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { printk(KERN_ERR "atp870u: DMA mask required but not available.\n"); goto err_eio; } @@ -1742,12 +1740,9 @@ static void atp870u_remove (struct pci_dev *pdev) scsi_remove_host(pshost); - printk(KERN_INFO "free_irq : %d\n",pshost->irq); free_irq(pshost->irq, pshost); release_region(pshost->io_port, pshost->n_io_port); - printk(KERN_INFO "atp870u_free_tables : %p\n",pshost); atp870u_free_tables(pshost); - printk(KERN_INFO "scsi_host_put : %p\n",pshost); scsi_host_put(pshost); } MODULE_LICENSE("GPL"); -- cgit v0.10.2 From c4ad92bce06bf73946ea4bd5771b987685221e8a Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:12 +0100 Subject: atp870u: Remove empty tscam_885() tscam_885() is empty (except a delay) so remove it. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index b662e39..2570919 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -42,7 +42,6 @@ static struct scsi_host_template atp870u_template; static void send_s870(struct atp_unit *dev,unsigned char c); static void atp_is(struct atp_unit *dev, unsigned char c, bool wide_chip, unsigned char lvdmode); -static void tscam_885(void); static inline void atp_writeb_base(struct atp_unit *atp, u8 reg, u8 val) { @@ -1518,7 +1517,7 @@ flash_ok_885: k = (k & 0x07) | 0x40; atp_set_host_id(p, 1, k); - tscam_885(); + mdelay(600); /* this delay used to be called tscam_885() */ printk(KERN_INFO " Scanning Channel A SCSI Device ...\n"); atp_is(p, 0, true, atp_readb_io(p, 0, 0x1b) >> 7); atp_writeb_io(p, 0, 0x16, 0x80); @@ -1802,18 +1801,6 @@ static void __exit atp870u_exit(void) pci_unregister_driver(&atp870u_driver); } -static void tscam_885(void) -{ - unsigned char i; - - for (i = 0; i < 0x2; i++) { - mdelay(300); - } - return; -} - - - static void atp_is(struct atp_unit *dev, unsigned char c, bool wide_chip, unsigned char lvdmode) { unsigned char i, j, k, rmb, n; -- cgit v0.10.2 From 1ccd7d68fc3004e3ed111753e62385176fa28f40 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:13 +0100 Subject: atp870u: Use module_pci_driver Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 2570919..7f53a50 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1785,21 +1785,7 @@ static struct pci_driver atp870u_driver = { .remove = atp870u_remove, }; -static int __init atp870u_init(void) -{ -#ifdef ED_DBGP - printk("atp870u_init: Entry\n"); -#endif - return pci_register_driver(&atp870u_driver); -} - -static void __exit atp870u_exit(void) -{ -#ifdef ED_DBGP - printk("atp870u_exit: Entry\n"); -#endif - pci_unregister_driver(&atp870u_driver); -} +module_pci_driver(atp870u_driver); static void atp_is(struct atp_unit *dev, unsigned char c, bool wide_chip, unsigned char lvdmode) { @@ -2406,7 +2392,3 @@ set_syn_ok: #endif } } - -module_init(atp870u_init); -module_exit(atp870u_exit); - -- cgit v0.10.2 From 30ebc7efcf5cf653ec2f5567d9fce2b4e1247ab7 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:14 +0100 Subject: atp870u: Use n_io_port in request_region and release_region Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 7f53a50..a06a0a4 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1610,16 +1610,8 @@ flash_ok_885: shpnt->irq = pdev->irq; } spin_unlock_irqrestore(shpnt->host_lock, flags); - if(ent->device==ATP885_DEVID) { - if(!request_region(base_io, 0xff, "atp870u")) /* Register the IO ports that we use */ - goto request_io_fail; - } else if((ent->device==ATP880_DEVID1)||(ent->device==ATP880_DEVID2)) { - if(!request_region(base_io, 0x60, "atp870u")) /* Register the IO ports that we use */ - goto request_io_fail; - } else { - if(!request_region(base_io, 0x40, "atp870u")) /* Register the IO ports that we use */ - goto request_io_fail; - } + if (!request_region(base_io, shpnt->n_io_port, "atp870u")) + goto request_io_fail; count++; if (scsi_add_host(shpnt, &pdev->dev)) goto scsi_add_fail; @@ -1631,13 +1623,7 @@ flash_ok_885: scsi_add_fail: printk("atp870u_prob:scsi_add_fail\n"); - if(ent->device==ATP885_DEVID) { - release_region(base_io, 0xff); - } else if((ent->device==ATP880_DEVID1)||(ent->device==ATP880_DEVID2)) { - release_region(base_io, 0x60); - } else { - release_region(base_io, 0x40); - } + release_region(base_io, shpnt->n_io_port); request_io_fail: printk("atp870u_prob:request_io_fail\n"); free_irq(pdev->irq, shpnt); -- cgit v0.10.2 From c48442d1277a9b9e20ad38c29ca68485b921d4e9 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:15 +0100 Subject: atp870u: Remove useless and broken card counting Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index a06a0a4..0b349bc 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1250,7 +1250,6 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct Scsi_Host *shpnt = NULL; struct atp_unit *atpdev, *p; unsigned char setupdata[2][16]; - int count = 0; atpdev = kzalloc(sizeof(*atpdev), GFP_KERNEL); if (!atpdev) @@ -1298,8 +1297,8 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) host_id = atp_readb_base(atpdev, 0x39); host_id >>= 0x04; - printk(KERN_INFO " ACARD AEC-67160 PCI Ultra3 LVD Host Adapter: %d" - " IO:%x, IRQ:%d.\n", count, base_io, pdev->irq); + printk(KERN_INFO " ACARD AEC-67160 PCI Ultra3 LVD Host Adapter:" + " IO:%x, IRQ:%d.\n", base_io, pdev->irq); atpdev->dev_id = ent->device; atpdev->host_id[0] = host_id; @@ -1546,8 +1545,8 @@ flash_ok_885: } else { error = pci_read_config_byte(pdev, 0x49, &host_id); - printk(KERN_INFO " ACARD AEC-671X PCI Ultra/W SCSI-2/3 Host Adapter: %d " - "IO:%x, IRQ:%d.\n", count, base_io, pdev->irq); + printk(KERN_INFO " ACARD AEC-671X PCI Ultra/W SCSI-2/3 Host Adapter: " + "IO:%x, IRQ:%d.\n", base_io, pdev->irq); atpdev->ioport[0] = base_io; atpdev->pciport[0] = base_io + 0x20; @@ -1612,7 +1611,6 @@ flash_ok_885: spin_unlock_irqrestore(shpnt->host_lock, flags); if (!request_region(base_io, shpnt->n_io_port, "atp870u")) goto request_io_fail; - count++; if (scsi_add_host(shpnt, &pdev->dev)) goto scsi_add_fail; scsi_scan_host(shpnt); -- cgit v0.10.2 From e1e9a70642309020571a07b2918eca84cec6287a Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:16 +0100 Subject: atp870u: Remove unused irq from struct atp_unit Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.h b/drivers/scsi/atp870u.h index 5cf6256..c3c6c13 100644 --- a/drivers/scsi/atp870u.h +++ b/drivers/scsi/atp870u.h @@ -26,7 +26,6 @@ struct atp_unit unsigned long baseport; unsigned long ioport[2]; unsigned long pciport[2]; - unsigned long irq; unsigned char last_cmd[2]; unsigned char in_snd[2]; unsigned char in_int[2]; -- cgit v0.10.2 From bdd5ac4065dbc2bb1478ae0c9205a651487c7432 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:17 +0100 Subject: atp870u: Improve _probe() Move scsi_host_alloc() to the top of _probe() to remove code duplication, *p and unneeded atpdev (de)allocation and copying. While at it, fix the error paths to return real error codes and also add missing pci_disble_device() call. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 0b349bc..d0119f1 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1248,29 +1248,41 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) unsigned int base_io, error,n; unsigned char host_id; struct Scsi_Host *shpnt = NULL; - struct atp_unit *atpdev, *p; + struct atp_unit *atpdev; unsigned char setupdata[2][16]; + int err; - atpdev = kzalloc(sizeof(*atpdev), GFP_KERNEL); - if (!atpdev) - return -ENOMEM; - - if (pci_enable_device(pdev)) - goto err_eio; + err = pci_enable_device(pdev); + if (err) + goto fail; if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { printk(KERN_ERR "atp870u: DMA mask required but not available.\n"); - goto err_eio; + err = -EIO; + goto disable_device; } + err = -ENOMEM; + shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); + if (!shpnt) + goto disable_device; + + atpdev = shost_priv(shpnt); + + atpdev->host = shpnt; + atpdev->pdev = pdev; + pci_set_drvdata(pdev, atpdev); + /* * It's probably easier to weed out some revisions like * this than via the PCI device table */ if (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610) { atpdev->chip_ver = pdev->revision; - if (atpdev->chip_ver < 2) - goto err_eio; + if (atpdev->chip_ver < 2) { + err = -ENODEV; + goto unregister; + } } switch (ent->device) { @@ -1358,41 +1370,33 @@ flash_ok_880: atpdev->async[0] = ~(atpdev->async[0]); atp_writeb_base(atpdev, 0x35, atpdev->global_map[0]); - shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); - if (!shpnt) - goto err_nomem; - - p = (struct atp_unit *)&shpnt->hostdata; - - atpdev->host = shpnt; - atpdev->pdev = pdev; - pci_set_drvdata(pdev, p); - memcpy(p, atpdev, sizeof(*atpdev)); if (atp870u_init_tables(shpnt) < 0) { printk(KERN_ERR "Unable to allocate tables for Acard controller\n"); + err = -ENOMEM; goto unregister; } - if (request_irq(pdev->irq, atp870u_intr_handle, IRQF_SHARED, "atp880i", shpnt)) { + err = request_irq(pdev->irq, atp870u_intr_handle, IRQF_SHARED, "atp880i", shpnt); + if (err) { printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", pdev->irq); goto free_tables; } spin_lock_irqsave(shpnt->host_lock, flags); - k = atp_readb_base(p, 0x38) & 0x80; - atp_writeb_base(p, 0x38, k); - atp_writeb_base(p, 0x3b, 0x20); + k = atp_readb_base(atpdev, 0x38) & 0x80; + atp_writeb_base(atpdev, 0x38, k); + atp_writeb_base(atpdev, 0x3b, 0x20); mdelay(32); - atp_writeb_base(p, 0x3b, 0); + atp_writeb_base(atpdev, 0x3b, 0); mdelay(32); - atp_readb_io(p, 0, 0x1b); - atp_readb_io(p, 0, 0x17); + atp_readb_io(atpdev, 0, 0x1b); + atp_readb_io(atpdev, 0, 0x17); - atp_set_host_id(p, 0, host_id); + atp_set_host_id(atpdev, 0, host_id); tscam(shpnt); - atp_is(p, 0, true, atp_readb_base(p, 0x3f) & 0x40); - atp_writeb_base(p, 0x38, 0xb0); + atp_is(atpdev, 0, true, atp_readb_base(atpdev, 0x3f) & 0x40); + atp_writeb_base(atpdev, 0x38, 0xb0); shpnt->max_id = 16; shpnt->this_id = host_id; shpnt->unique_id = base_io; @@ -1410,50 +1414,43 @@ flash_ok_880: atpdev->pciport[0] = base_io + 0x40; atpdev->pciport[1] = base_io + 0x50; - shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); - if (!shpnt) - goto err_nomem; - - p = (struct atp_unit *)&shpnt->hostdata; - - atpdev->host = shpnt; - atpdev->pdev = pdev; - pci_set_drvdata(pdev, p); - memcpy(p, atpdev, sizeof(struct atp_unit)); - if (atp870u_init_tables(shpnt) < 0) + if (atp870u_init_tables(shpnt) < 0) { + err = -ENOMEM; goto unregister; + } #ifdef ED_DBGP - printk("request_irq() shpnt %p hostdata %p\n", shpnt, p); + printk("request_irq() shpnt %p hostdata %p\n", shpnt, atpdev); #endif - if (request_irq(pdev->irq, atp870u_intr_handle, IRQF_SHARED, "atp870u", shpnt)) { + err = request_irq(pdev->irq, atp870u_intr_handle, IRQF_SHARED, "atp870u", shpnt); + if (err) { printk(KERN_ERR "Unable to allocate IRQ for Acard controller.\n"); goto free_tables; } spin_lock_irqsave(shpnt->host_lock, flags); - c = atp_readb_base(p, 0x29); - atp_writeb_base(p, 0x29, c | 0x04); + c = atp_readb_base(atpdev, 0x29); + atp_writeb_base(atpdev, 0x29, c | 0x04); n=0x1f80; next_fblk_885: if (n >= 0x2000) { goto flash_ok_885; } - atp_writew_base(p, 0x3c, n); - if (atp_readl_base(p, 0x38) == 0xffffffff) { + atp_writew_base(atpdev, 0x3c, n); + if (atp_readl_base(atpdev, 0x38) == 0xffffffff) { goto flash_ok_885; } for (m=0; m < 2; m++) { - p->global_map[m]= 0; + atpdev->global_map[m]= 0; for (k=0; k < 4; k++) { - atp_writew_base(p, 0x3c, n++); - ((unsigned long *)&setupdata[m][0])[k] = atp_readl_base(p, 0x38); + atp_writew_base(atpdev, 0x3c, n++); + ((unsigned long *)&setupdata[m][0])[k] = atp_readl_base(atpdev, 0x38); } for (k=0; k < 4; k++) { - atp_writew_base(p, 0x3c, n++); - ((unsigned long *)&p->sp[m][0])[k] = atp_readl_base(p, 0x38); + atp_writew_base(atpdev, 0x3c, n++); + ((unsigned long *)&atpdev->sp[m][0])[k] = atp_readl_base(atpdev, 0x38); } n += 8; } @@ -1462,81 +1459,81 @@ flash_ok_885: #ifdef ED_DBGP printk( "Flash Read OK\n"); #endif - c = atp_readb_base(p, 0x29); - atp_writeb_base(p, 0x29, c & 0xfb); + c = atp_readb_base(atpdev, 0x29); + atp_writeb_base(atpdev, 0x29, c & 0xfb); for (c=0;c < 2;c++) { - p->ultra_map[c]=0; - p->async[c] = 0; + atpdev->ultra_map[c]=0; + atpdev->async[c] = 0; for (k=0; k < 16; k++) { n=1; n = n << k; - if (p->sp[c][k] > 1) { - p->ultra_map[c] |= n; + if (atpdev->sp[c][k] > 1) { + atpdev->ultra_map[c] |= n; } else { - if (p->sp[c][k] == 0) { - p->async[c] |= n; + if (atpdev->sp[c][k] == 0) { + atpdev->async[c] |= n; } } } - p->async[c] = ~(p->async[c]); + atpdev->async[c] = ~(atpdev->async[c]); - if (p->global_map[c] == 0) { + if (atpdev->global_map[c] == 0) { k=setupdata[c][1]; if ((k & 0x40) != 0) - p->global_map[c] |= 0x20; + atpdev->global_map[c] |= 0x20; k &= 0x07; - p->global_map[c] |= k; + atpdev->global_map[c] |= k; if ((setupdata[c][2] & 0x04) != 0) - p->global_map[c] |= 0x08; - p->host_id[c] = setupdata[c][0] & 0x07; + atpdev->global_map[c] |= 0x08; + atpdev->host_id[c] = setupdata[c][0] & 0x07; } } - k = atp_readb_base(p, 0x28) & 0x8f; + k = atp_readb_base(atpdev, 0x28) & 0x8f; k |= 0x10; - atp_writeb_base(p, 0x28, k); - atp_writeb_pci(p, 0, 1, 0x80); - atp_writeb_pci(p, 1, 1, 0x80); + atp_writeb_base(atpdev, 0x28, k); + atp_writeb_pci(atpdev, 0, 1, 0x80); + atp_writeb_pci(atpdev, 1, 1, 0x80); mdelay(100); - atp_writeb_pci(p, 0, 1, 0); - atp_writeb_pci(p, 1, 1, 0); + atp_writeb_pci(atpdev, 0, 1, 0); + atp_writeb_pci(atpdev, 1, 1, 0); mdelay(1000); - atp_readb_io(p, 0, 0x1b); - atp_readb_io(p, 0, 0x17); - atp_readb_io(p, 1, 0x1b); - atp_readb_io(p, 1, 0x17); + atp_readb_io(atpdev, 0, 0x1b); + atp_readb_io(atpdev, 0, 0x17); + atp_readb_io(atpdev, 1, 0x1b); + atp_readb_io(atpdev, 1, 0x17); - k=p->host_id[0]; + k=atpdev->host_id[0]; if (k > 7) k = (k & 0x07) | 0x40; - atp_set_host_id(p, 0, k); + atp_set_host_id(atpdev, 0, k); - k=p->host_id[1]; + k=atpdev->host_id[1]; if (k > 7) k = (k & 0x07) | 0x40; - atp_set_host_id(p, 1, k); + atp_set_host_id(atpdev, 1, k); mdelay(600); /* this delay used to be called tscam_885() */ printk(KERN_INFO " Scanning Channel A SCSI Device ...\n"); - atp_is(p, 0, true, atp_readb_io(p, 0, 0x1b) >> 7); - atp_writeb_io(p, 0, 0x16, 0x80); + atp_is(atpdev, 0, true, atp_readb_io(atpdev, 0, 0x1b) >> 7); + atp_writeb_io(atpdev, 0, 0x16, 0x80); printk(KERN_INFO " Scanning Channel B SCSI Device ...\n"); - atp_is(p, 1, true, atp_readb_io(p, 1, 0x1b) >> 7); - atp_writeb_io(p, 1, 0x16, 0x80); - k = atp_readb_base(p, 0x28) & 0xcf; + atp_is(atpdev, 1, true, atp_readb_io(atpdev, 1, 0x1b) >> 7); + atp_writeb_io(atpdev, 1, 0x16, 0x80); + k = atp_readb_base(atpdev, 0x28) & 0xcf; k |= 0xc0; - atp_writeb_base(p, 0x28, k); - k = atp_readb_base(p, 0x1f) | 0x80; - atp_writeb_base(p, 0x1f, k); - k = atp_readb_base(p, 0x29) | 0x01; - atp_writeb_base(p, 0x29, k); + atp_writeb_base(atpdev, 0x28, k); + k = atp_readb_base(atpdev, 0x1f) | 0x80; + atp_writeb_base(atpdev, 0x1f, k); + k = atp_readb_base(atpdev, 0x29) | 0x01; + atp_writeb_base(atpdev, 0x29, k); #ifdef ED_DBGP //printk("atp885: atp_host[0] 0x%p\n", atp_host[0]); #endif shpnt->max_id = 16; - shpnt->max_lun = (p->global_map[0] & 0x07) + 1; + shpnt->max_lun = (atpdev->global_map[0] & 0x07) + 1; shpnt->max_channel = 1; - shpnt->this_id = p->host_id[0]; + shpnt->this_id = atpdev->host_id[0]; shpnt->unique_id = base_io; shpnt->io_port = base_io; shpnt->n_io_port = 0xff; /* Number of bytes of I/O space used */ @@ -1563,41 +1560,35 @@ flash_ok_885: atpdev->ultra_map[0] = 0xffff; } - shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); - if (!shpnt) - goto err_nomem; - p = (struct atp_unit *)&shpnt->hostdata; - - atpdev->host = shpnt; - atpdev->pdev = pdev; - pci_set_drvdata(pdev, p); - memcpy(p, atpdev, sizeof(*atpdev)); - if (atp870u_init_tables(shpnt) < 0) + if (atp870u_init_tables(shpnt) < 0) { + err = -ENOMEM; goto unregister; + } - if (request_irq(pdev->irq, atp870u_intr_handle, IRQF_SHARED, "atp870i", shpnt)) { + err = request_irq(pdev->irq, atp870u_intr_handle, IRQF_SHARED, "atp870i", shpnt); + if (err) { printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", pdev->irq); goto free_tables; } spin_lock_irqsave(shpnt->host_lock, flags); if (atpdev->chip_ver > 0x07) /* check if atp876 chip then enable terminator */ - atp_writeb_base(p, 0x3e, 0x00); + atp_writeb_base(atpdev, 0x3e, 0x00); - k = (atp_readb_base(p, 0x3a) & 0xf3) | 0x10; - atp_writeb_base(p, 0x3a, k); - atp_writeb_base(p, 0x3a, k & 0xdf); + k = (atp_readb_base(atpdev, 0x3a) & 0xf3) | 0x10; + atp_writeb_base(atpdev, 0x3a, k); + atp_writeb_base(atpdev, 0x3a, k & 0xdf); mdelay(32); - atp_writeb_base(p, 0x3a, k); + atp_writeb_base(atpdev, 0x3a, k); mdelay(32); - atp_set_host_id(p, 0, host_id); + atp_set_host_id(atpdev, 0, host_id); tscam(shpnt); - atp_writeb_base(p, 0x3a, atp_readb_base(p, 0x3a) | 0x10); - atp_is(p, 0, p->chip_ver == 4, 0); - atp_writeb_base(p, 0x3a, atp_readb_base(p, 0x3a) & 0xef); - atp_writeb_base(p, 0x3b, atp_readb_base(p, 0x3b) | 0x20); + atp_writeb_base(atpdev, 0x3a, atp_readb_base(atpdev, 0x3a) | 0x10); + atp_is(atpdev, 0, atpdev->chip_ver == 4, 0); + atp_writeb_base(atpdev, 0x3a, atp_readb_base(atpdev, 0x3a) & 0xef); + atp_writeb_base(atpdev, 0x3b, atp_readb_base(atpdev, 0x3b) | 0x20); if (atpdev->chip_ver == 4) shpnt->max_id = 16; else @@ -1609,9 +1600,12 @@ flash_ok_885: shpnt->irq = pdev->irq; } spin_unlock_irqrestore(shpnt->host_lock, flags); - if (!request_region(base_io, shpnt->n_io_port, "atp870u")) + if (!request_region(base_io, shpnt->n_io_port, "atp870u")) { + err = -EBUSY; goto request_io_fail; - if (scsi_add_host(shpnt, &pdev->dev)) + } + err = scsi_add_host(shpnt, &pdev->dev); + if (err) goto scsi_add_fail; scsi_scan_host(shpnt); #ifdef ED_DBGP @@ -1629,15 +1623,11 @@ free_tables: printk("atp870u_prob:free_table\n"); atp870u_free_tables(shpnt); unregister: - printk("atp870u_prob:unregister\n"); scsi_host_put(shpnt); - return -1; -err_eio: - kfree(atpdev); - return -EIO; -err_nomem: - kfree(atpdev); - return -ENOMEM; +disable_device: + pci_disable_device(pdev); +fail: + return err; } /* The abort command does not leave the device in a clean state where -- cgit v0.10.2 From b1e850630b746e347f80cb3f70bdaa791c10b4f6 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:18 +0100 Subject: atp870u: Improve unsupported chip detection Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index d0119f1..128613e 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1252,6 +1252,11 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) unsigned char setupdata[2][16]; int err; + if (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610 && pdev->revision < 2) { + dev_err(&pdev->dev, "ATP850S chips (AEC6710L/F cards) are not supported.\n"); + return -ENODEV; + } + err = pci_enable_device(pdev); if (err) goto fail; @@ -1273,19 +1278,10 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) atpdev->pdev = pdev; pci_set_drvdata(pdev, atpdev); - /* - * It's probably easier to weed out some revisions like - * this than via the PCI device table - */ - if (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610) { - atpdev->chip_ver = pdev->revision; - if (atpdev->chip_ver < 2) { - err = -ENODEV; - goto unregister; - } - } - switch (ent->device) { + case PCI_DEVICE_ID_ARTOP_AEC7610: + atpdev->chip_ver = pdev->revision; + break; case PCI_DEVICE_ID_ARTOP_AEC7612UW: case PCI_DEVICE_ID_ARTOP_AEC7612SUW: case ATP880_DEVID1: -- cgit v0.10.2 From dd5a5f7951e253b81ac480a63dfd8b826a9ef61e Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:19 +0100 Subject: atp870u: Remove chip_ver from struct atp_unit chip_ver is used for wide chip detection only. Remove it and use a local variable instead (for 870; 880 and 885 are always wide). Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 128613e..f92eb00 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -954,7 +954,7 @@ static unsigned char fun_scam(struct atp_unit *dev, unsigned short int *val) return j; } -static void tscam(struct Scsi_Host *host) +static void tscam(struct Scsi_Host *host, bool wide_chip) { unsigned char i, j, k; @@ -983,7 +983,7 @@ static void tscam(struct Scsi_Host *host) m = 1; m <<= dev->host_id[0]; j = 16; - if (dev->chip_ver < 4) { + if (!wide_chip) { m |= 0xff00; j = 8; } @@ -1012,7 +1012,7 @@ static void tscam(struct Scsi_Host *host) k = i; } atp_writeb_io(dev, 0, 0x15, k); - if (dev->chip_ver == 4) + if (wide_chip) atp_writeb_io(dev, 0, 0x1b, 0x01); else atp_writeb_io(dev, 0, 0x1b, 0x00); @@ -1278,25 +1278,11 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) atpdev->pdev = pdev; pci_set_drvdata(pdev, atpdev); - switch (ent->device) { - case PCI_DEVICE_ID_ARTOP_AEC7610: - atpdev->chip_ver = pdev->revision; - break; - case PCI_DEVICE_ID_ARTOP_AEC7612UW: - case PCI_DEVICE_ID_ARTOP_AEC7612SUW: - case ATP880_DEVID1: - case ATP880_DEVID2: - case ATP885_DEVID: - atpdev->chip_ver = 0x04; - default: - break; - } base_io = pci_resource_start(pdev, 0); base_io &= 0xfffffff8; atpdev->baseport = base_io; if ((ent->device == ATP880_DEVID1)||(ent->device == ATP880_DEVID2)) { - atpdev->chip_ver = pdev->revision; pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);//JCC082803 atpdev->ioport[0] = base_io + 0x40; @@ -1390,7 +1376,7 @@ flash_ok_880: atp_set_host_id(atpdev, 0, host_id); - tscam(shpnt); + tscam(shpnt, true); atp_is(atpdev, 0, true, atp_readb_base(atpdev, 0x3f) & 0x40); atp_writeb_base(atpdev, 0x38, 0xb0); shpnt->max_id = 16; @@ -1536,6 +1522,11 @@ flash_ok_885: shpnt->irq = pdev->irq; } else { + bool wide_chip = + (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610 && + pdev->revision == 4) || + (ent->device == PCI_DEVICE_ID_ARTOP_AEC7612UW) || + (ent->device == PCI_DEVICE_ID_ARTOP_AEC7612SUW); error = pci_read_config_byte(pdev, 0x49, &host_id); printk(KERN_INFO " ACARD AEC-671X PCI Ultra/W SCSI-2/3 Host Adapter: " @@ -1569,7 +1560,7 @@ flash_ok_885: } spin_lock_irqsave(shpnt->host_lock, flags); - if (atpdev->chip_ver > 0x07) /* check if atp876 chip then enable terminator */ + if (pdev->revision > 0x07) /* check if atp876 chip then enable terminator */ atp_writeb_base(atpdev, 0x3e, 0x00); k = (atp_readb_base(atpdev, 0x3a) & 0xf3) | 0x10; @@ -1580,15 +1571,13 @@ flash_ok_885: mdelay(32); atp_set_host_id(atpdev, 0, host_id); - tscam(shpnt); + + tscam(shpnt, wide_chip); atp_writeb_base(atpdev, 0x3a, atp_readb_base(atpdev, 0x3a) | 0x10); - atp_is(atpdev, 0, atpdev->chip_ver == 4, 0); + atp_is(atpdev, 0, wide_chip, 0); atp_writeb_base(atpdev, 0x3a, atp_readb_base(atpdev, 0x3a) & 0xef); atp_writeb_base(atpdev, 0x3b, atp_readb_base(atpdev, 0x3b) | 0x20); - if (atpdev->chip_ver == 4) - shpnt->max_id = 16; - else - shpnt->max_id = 8; + shpnt->max_id = wide_chip ? 16 : 8; shpnt->this_id = host_id; shpnt->unique_id = base_io; shpnt->io_port = base_io; diff --git a/drivers/scsi/atp870u.h b/drivers/scsi/atp870u.h index c3c6c13..8c47c53 100644 --- a/drivers/scsi/atp870u.h +++ b/drivers/scsi/atp870u.h @@ -32,7 +32,6 @@ struct atp_unit unsigned char quhd[2]; unsigned char quend[2]; unsigned char global_map[2]; - unsigned char chip_ver; unsigned char scam_on; unsigned char host_id[2]; unsigned int working[2]; -- cgit v0.10.2 From 6c9b9c554b2a369d2b46558975ef2eaa3a84c1c3 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:20 +0100 Subject: atp870u: Simplify _probe() Move shpnt common code to the top, remove base_io, use pci_resource_len. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index f92eb00..8af51a9 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1245,7 +1245,7 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { unsigned char k, m, c; unsigned long flags; - unsigned int base_io, error,n; + unsigned int error,n; unsigned char host_id; struct Scsi_Host *shpnt = NULL; struct atp_unit *atpdev; @@ -1278,21 +1278,24 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) atpdev->pdev = pdev; pci_set_drvdata(pdev, atpdev); - base_io = pci_resource_start(pdev, 0); - base_io &= 0xfffffff8; - atpdev->baseport = base_io; + shpnt->io_port = pci_resource_start(pdev, 0); + shpnt->io_port &= 0xfffffff8; + shpnt->n_io_port = pci_resource_len(pdev, 0); + atpdev->baseport = shpnt->io_port; + shpnt->unique_id = shpnt->io_port; + shpnt->irq = pdev->irq; if ((ent->device == ATP880_DEVID1)||(ent->device == ATP880_DEVID2)) { pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);//JCC082803 - atpdev->ioport[0] = base_io + 0x40; - atpdev->pciport[0] = base_io + 0x28; + atpdev->ioport[0] = shpnt->io_port + 0x40; + atpdev->pciport[0] = shpnt->io_port + 0x28; host_id = atp_readb_base(atpdev, 0x39); host_id >>= 0x04; printk(KERN_INFO " ACARD AEC-67160 PCI Ultra3 LVD Host Adapter:" - " IO:%x, IRQ:%d.\n", base_io, pdev->irq); + " IO:%lx, IRQ:%d.\n", shpnt->io_port, shpnt->irq); atpdev->dev_id = ent->device; atpdev->host_id[0] = host_id; @@ -1358,9 +1361,9 @@ flash_ok_880: goto unregister; } - err = request_irq(pdev->irq, atp870u_intr_handle, IRQF_SHARED, "atp880i", shpnt); + err = request_irq(shpnt->irq, atp870u_intr_handle, IRQF_SHARED, "atp880i", shpnt); if (err) { - printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", pdev->irq); + printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", shpnt->irq); goto free_tables; } @@ -1381,20 +1384,16 @@ flash_ok_880: atp_writeb_base(atpdev, 0x38, 0xb0); shpnt->max_id = 16; shpnt->this_id = host_id; - shpnt->unique_id = base_io; - shpnt->io_port = base_io; - shpnt->n_io_port = 0x60; /* Number of bytes of I/O space used */ - shpnt->irq = pdev->irq; } else if (ent->device == ATP885_DEVID) { - printk(KERN_INFO " ACARD AEC-67162 PCI Ultra3 LVD Host Adapter: IO:%x, IRQ:%d.\n" - , base_io, pdev->irq); + printk(KERN_INFO " ACARD AEC-67162 PCI Ultra3 LVD Host Adapter: IO:%lx, IRQ:%d.\n" + , shpnt->io_port, shpnt->irq); atpdev->pdev = pdev; atpdev->dev_id = ent->device; - atpdev->ioport[0] = base_io + 0x80; - atpdev->ioport[1] = base_io + 0xc0; - atpdev->pciport[0] = base_io + 0x40; - atpdev->pciport[1] = base_io + 0x50; + atpdev->ioport[0] = shpnt->io_port + 0x80; + atpdev->ioport[1] = shpnt->io_port + 0xc0; + atpdev->pciport[0] = shpnt->io_port + 0x40; + atpdev->pciport[1] = shpnt->io_port + 0x50; if (atp870u_init_tables(shpnt) < 0) { err = -ENOMEM; @@ -1404,7 +1403,7 @@ flash_ok_880: #ifdef ED_DBGP printk("request_irq() shpnt %p hostdata %p\n", shpnt, atpdev); #endif - err = request_irq(pdev->irq, atp870u_intr_handle, IRQF_SHARED, "atp870u", shpnt); + err = request_irq(shpnt->irq, atp870u_intr_handle, IRQF_SHARED, "atp870u", shpnt); if (err) { printk(KERN_ERR "Unable to allocate IRQ for Acard controller.\n"); goto free_tables; @@ -1516,11 +1515,6 @@ flash_ok_885: shpnt->max_lun = (atpdev->global_map[0] & 0x07) + 1; shpnt->max_channel = 1; shpnt->this_id = atpdev->host_id[0]; - shpnt->unique_id = base_io; - shpnt->io_port = base_io; - shpnt->n_io_port = 0xff; /* Number of bytes of I/O space used */ - shpnt->irq = pdev->irq; - } else { bool wide_chip = (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610 && @@ -1530,10 +1524,10 @@ flash_ok_885: error = pci_read_config_byte(pdev, 0x49, &host_id); printk(KERN_INFO " ACARD AEC-671X PCI Ultra/W SCSI-2/3 Host Adapter: " - "IO:%x, IRQ:%d.\n", base_io, pdev->irq); + "IO:%lx, IRQ:%d.\n", shpnt->io_port, shpnt->irq); - atpdev->ioport[0] = base_io; - atpdev->pciport[0] = base_io + 0x20; + atpdev->ioport[0] = shpnt->io_port; + atpdev->pciport[0] = shpnt->io_port + 0x20; atpdev->dev_id = ent->device; host_id &= 0x07; atpdev->host_id[0] = host_id; @@ -1553,9 +1547,9 @@ flash_ok_885: goto unregister; } - err = request_irq(pdev->irq, atp870u_intr_handle, IRQF_SHARED, "atp870i", shpnt); + err = request_irq(shpnt->irq, atp870u_intr_handle, IRQF_SHARED, "atp870i", shpnt); if (err) { - printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", pdev->irq); + printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", shpnt->irq); goto free_tables; } @@ -1579,13 +1573,10 @@ flash_ok_885: atp_writeb_base(atpdev, 0x3b, atp_readb_base(atpdev, 0x3b) | 0x20); shpnt->max_id = wide_chip ? 16 : 8; shpnt->this_id = host_id; - shpnt->unique_id = base_io; - shpnt->io_port = base_io; - shpnt->n_io_port = 0x40; /* Number of bytes of I/O space used */ - shpnt->irq = pdev->irq; + } spin_unlock_irqrestore(shpnt->host_lock, flags); - if (!request_region(base_io, shpnt->n_io_port, "atp870u")) { + if (!request_region(shpnt->io_port, shpnt->n_io_port, "atp870u")) { err = -EBUSY; goto request_io_fail; } @@ -1600,10 +1591,10 @@ flash_ok_885: scsi_add_fail: printk("atp870u_prob:scsi_add_fail\n"); - release_region(base_io, shpnt->n_io_port); + release_region(shpnt->io_port, shpnt->n_io_port); request_io_fail: printk("atp870u_prob:request_io_fail\n"); - free_irq(pdev->irq, shpnt); + free_irq(shpnt->irq, shpnt); free_tables: printk("atp870u_prob:free_table\n"); atp870u_free_tables(shpnt); -- cgit v0.10.2 From b922a44995a6e94560aa3eae0602bf92a4e7b084 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:21 +0100 Subject: atp870u: Introduce is880(), is885() and remove dev_id Introduce chip type inline functions to simplify code, allowing to delete dev_id from struct atp_unit. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 8af51a9..4bb0f4f 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -103,6 +103,17 @@ static inline u8 atp_readb_pci(struct atp_unit *atp, u8 channel, u8 reg) return inb(atp->pciport[channel] + reg); } +static inline bool is880(struct atp_unit *atp) +{ + return atp->pdev->device == ATP880_DEVID1 || + atp->pdev->device == ATP880_DEVID2; +} + +static inline bool is885(struct atp_unit *atp) +{ + return atp->pdev->device == ATP885_DEVID; +} + static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) { unsigned long flags; @@ -131,7 +142,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) dev->in_int[c] = 1; cmdp = atp_readb_io(dev, c, 0x10); if (dev->working[c] != 0) { - if (dev->dev_id == ATP885_DEVID) { + if (is885(dev)) { if ((atp_readb_io(dev, c, 0x16) & 0x80) == 0) atp_writeb_io(dev, c, 0x16, (atp_readb_io(dev, c, 0x16) | 0x80)); } @@ -148,7 +159,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) i = atp_readb_io(dev, c, 0x17); - if (dev->dev_id == ATP885_DEVID) + if (is885(dev)) atp_writeb_pci(dev, c, 2, 0x06); target_id = atp_readb_io(dev, c, 0x15); @@ -169,7 +180,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) } dev->last_cmd[c] |= 0x40; } - if (dev->dev_id == ATP885_DEVID) + if (is885(dev)) dev->r1f[c][target_id] |= j; #ifdef ED_DBGP printk("atp870u_intr_handle status = %x\n",i); @@ -178,7 +189,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) if ((dev->last_cmd[c] & 0xf0) != 0x40) { dev->last_cmd[c] = 0xff; } - if (dev->dev_id == ATP885_DEVID) { + if (is885(dev)) { adrcnt = 0; ((unsigned char *) &adrcnt)[2] = atp_readb_io(dev, c, 0x12); ((unsigned char *) &adrcnt)[1] = atp_readb_io(dev, c, 0x13); @@ -249,7 +260,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) return IRQ_HANDLED; } - if (dev->dev_id == ATP885_DEVID) { + if (is885(dev)) { if ((i == 0x4c) || (i == 0x4d) || (i == 0x8c) || (i == 0x8d)) { if ((i == 0x4c) || (i == 0x8c)) i=0x48; @@ -301,7 +312,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) if (dev->last_cmd[c] != 0xff) { dev->last_cmd[c] |= 0x40; } - if (dev->dev_id == ATP885_DEVID) { + if (is885(dev)) { j = atp_readb_base(dev, 0x29) & 0xfe; atp_writeb_base(dev, 0x29, j); } else @@ -316,7 +327,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) } else { target_id &= 0x07; } - if (dev->dev_id == ATP885_DEVID) + if (is885(dev)) atp_writeb_io(dev, c, 0x10, 0x45); workreq = dev->id[c][target_id].curr_req; #ifdef ED_DBGP @@ -348,15 +359,14 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) atp_writeb_io(dev, c, 0x16, 0x80); /* enable 32 bit fifo transfer */ - if (dev->dev_id == ATP885_DEVID) { + if (is885(dev)) { i = atp_readb_pci(dev, c, 1) & 0xf3; //j=workreq->cmnd[0]; if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { i |= 0x0c; } atp_writeb_pci(dev, c, 1, i); - } else if ((dev->dev_id == ATP880_DEVID1) || - (dev->dev_id == ATP880_DEVID2) ) { + } else if (is880(dev)) { if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) atp_writeb_base(dev, 0x3b, (atp_readb_base(dev, 0x3b) & 0x3f) | 0xc0); else @@ -417,7 +427,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) #ifdef ED_DBGP printk("dev->id[%d][%d].prdaddr 0x%8x\n", c, target_id, dev->id[c][target_id].prdaddr); #endif - if (dev->dev_id != ATP885_DEVID) { + if (!is885(dev)) { atp_writeb_pci(dev, c, 2, 0x06); atp_writeb_pci(dev, c, 2, 0x00); } @@ -454,14 +464,14 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) } if (i == 0x16) { workreq->result = atp_readb_io(dev, c, 0x0f); - if (((dev->r1f[c][target_id] & 0x10) != 0)&&(dev->dev_id==ATP885_DEVID)) { + if (((dev->r1f[c][target_id] & 0x10) != 0) && is885(dev)) { printk(KERN_WARNING "AEC67162 CRC ERROR !\n"); workreq->result = 0x02; } } else workreq->result = 0x02; - if (dev->dev_id == ATP885_DEVID) { + if (is885(dev)) { j = atp_readb_base(dev, 0x29) | 0x01; atp_writeb_base(dev, 0x29, j); } @@ -516,7 +526,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) atp_writeb_pci(dev, c, 2, 0x06); atp_writeb_pci(dev, c, 2, 0x00); atp_writeb_io(dev, c, 0x10, 0x41); - if (dev->dev_id == ATP885_DEVID) { + if (is885(dev)) { k = dev->id[c][target_id].last_len; atp_writeb_io(dev, c, 0x12, ((unsigned char *) (&k))[2]); atp_writeb_io(dev, c, 0x13, ((unsigned char *) (&k))[1]); @@ -535,7 +545,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) atp_writeb_pci(dev, c, 2, 0x06); atp_writeb_pci(dev, c, 2, 0x00); atp_writeb_io(dev, c, 0x10, 0x41); - if (dev->dev_id == ATP885_DEVID) { + if (is885(dev)) { k = dev->id[c][target_id].last_len; atp_writeb_io(dev, c, 0x12, ((unsigned char *) (&k))[2]); atp_writeb_io(dev, c, 0x13, ((unsigned char *) (&k))[1]); @@ -737,7 +747,7 @@ static void send_s870(struct atp_unit *dev,unsigned char c) #endif l = scsi_bufflen(workreq); - if (dev->dev_id == ATP885_DEVID) { + if (is885(dev)) { j = atp_readb_base(dev, 0x29) & 0xfe; atp_writeb_base(dev, 0x29, j); dev->r1f[c][scmd_id(workreq)] = 0; @@ -775,7 +785,7 @@ static void send_s870(struct atp_unit *dev,unsigned char c) atp_writeb_io(dev, c, 0x00, workreq->cmd_len); atp_writeb_io(dev, c, 0x01, 0x2c); - if (dev->dev_id == ATP885_DEVID) + if (is885(dev)) atp_writeb_io(dev, c, 0x02, 0x7f); else atp_writeb_io(dev, c, 0x02, 0xcf); @@ -873,15 +883,14 @@ static void send_s870(struct atp_unit *dev,unsigned char c) atp_writel_pci(dev, c, 4, dev->id[c][target_id].prdaddr); atp_writeb_pci(dev, c, 2, 0x06); atp_writeb_pci(dev, c, 2, 0x00); - if (dev->dev_id == ATP885_DEVID) { + if (is885(dev)) { j = atp_readb_pci(dev, c, 1) & 0xf3; if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { j |= 0x0c; } atp_writeb_pci(dev, c, 1, j); - } else if ((dev->dev_id == ATP880_DEVID1) || - (dev->dev_id == ATP880_DEVID2)) { + } else if (is880(dev)) { if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) atp_writeb_base(dev, 0x3b, (atp_readb_base(dev, 0x3b) & 0x3f) | 0xc0); else @@ -1285,7 +1294,7 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) shpnt->unique_id = shpnt->io_port; shpnt->irq = pdev->irq; - if ((ent->device == ATP880_DEVID1)||(ent->device == ATP880_DEVID2)) { + if (is880(atpdev)) { pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);//JCC082803 atpdev->ioport[0] = shpnt->io_port + 0x40; @@ -1296,7 +1305,6 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) printk(KERN_INFO " ACARD AEC-67160 PCI Ultra3 LVD Host Adapter:" " IO:%lx, IRQ:%d.\n", shpnt->io_port, shpnt->irq); - atpdev->dev_id = ent->device; atpdev->host_id[0] = host_id; atpdev->scam_on = atp_readb_base(atpdev, 0x22); @@ -1384,12 +1392,11 @@ flash_ok_880: atp_writeb_base(atpdev, 0x38, 0xb0); shpnt->max_id = 16; shpnt->this_id = host_id; - } else if (ent->device == ATP885_DEVID) { + } else if (is885(atpdev)) { printk(KERN_INFO " ACARD AEC-67162 PCI Ultra3 LVD Host Adapter: IO:%lx, IRQ:%d.\n" , shpnt->io_port, shpnt->irq); atpdev->pdev = pdev; - atpdev->dev_id = ent->device; atpdev->ioport[0] = shpnt->io_port + 0x80; atpdev->ioport[1] = shpnt->io_port + 0xc0; atpdev->pciport[0] = shpnt->io_port + 0x40; @@ -1528,7 +1535,6 @@ flash_ok_885: atpdev->ioport[0] = shpnt->io_port; atpdev->pciport[0] = shpnt->io_port + 0x20; - atpdev->dev_id = ent->device; host_id &= 0x07; atpdev->host_id[0] = host_id; atpdev->scam_on = atp_readb_pci(atpdev, 0, 2); @@ -1797,7 +1803,7 @@ static void atp_is(struct atp_unit *dev, unsigned char c, bool wide_chip, unsign dev->active_id[c] |= m; atp_writeb_io(dev, c, 0x10, 0x30); - if (dev->dev_id == ATP885_DEVID || dev->dev_id == ATP880_DEVID1 || dev->dev_id == ATP880_DEVID2) + if (is885(dev) || is880(dev)) atp_writeb_io(dev, c, 0x14, 0x00); else /* result of is870() merge - is this a bug? */ atp_writeb_io(dev, c, 0x04, 0x00); @@ -1877,7 +1883,7 @@ inq_ok: if ((mbuf[7] & 0x60) == 0) { goto not_wide; } - if (dev->dev_id == ATP885_DEVID || dev->dev_id == ATP880_DEVID1 || dev->dev_id == ATP880_DEVID2) { + if (is885(dev) || is880(dev)) { if ((i < 8) && ((dev->global_map[c] & 0x20) == 0)) goto not_wide; } else { /* result of is870() merge - is this a bug? */ @@ -2146,7 +2152,7 @@ not_wide: } continue; set_sync: - if ((dev->dev_id != ATP885_DEVID && dev->dev_id != ATP880_DEVID1 && dev->dev_id != ATP880_DEVID2) || (dev->sp[c][i] == 0x02)) { + if ((!is885(dev) && !is880(dev)) || (dev->sp[c][i] == 0x02)) { synu[4] = 0x0c; synuw[4] = 0x0c; } else { @@ -2190,7 +2196,7 @@ try_sync: while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) { if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) { if ((m & dev->wide_id[c]) != 0) { - if (dev->dev_id == ATP885_DEVID || dev->dev_id == ATP880_DEVID1 || dev->dev_id == ATP880_DEVID2) { + if (is885(dev) || is880(dev)) { if ((m & dev->ultra_map[c]) != 0) { atp_writeb_io(dev, c, 0x19, synuw[j++]); } else { @@ -2245,7 +2251,7 @@ phase_outs: } continue; phase_ins: - if (dev->dev_id == ATP885_DEVID || dev->dev_id == ATP880_DEVID1 || dev->dev_id == ATP880_DEVID2) + if (is885(dev) || is880(dev)) atp_writeb_io(dev, c, 0x14, 0x06); else atp_writeb_io(dev, c, 0x14, 0xff); @@ -2303,7 +2309,7 @@ tar_dcons: if (mbuf[3] > 0x64) { continue; } - if (dev->dev_id == ATP885_DEVID || dev->dev_id == ATP880_DEVID1 || dev->dev_id == ATP880_DEVID2) { + if (is885(dev) || is880(dev)) { if (mbuf[4] > 0x0e) { mbuf[4] = 0x0e; } @@ -2313,7 +2319,7 @@ tar_dcons: } } dev->id[c][i].devsp = mbuf[4]; - if (dev->dev_id == ATP885_DEVID || dev->dev_id == ATP880_DEVID1 || dev->dev_id == ATP880_DEVID2) + if (is885(dev) || is880(dev)) if (mbuf[3] < 0x0c) { j = 0xb0; goto set_syn_ok; diff --git a/drivers/scsi/atp870u.h b/drivers/scsi/atp870u.h index 8c47c53..f9d62a2 100644 --- a/drivers/scsi/atp870u.h +++ b/drivers/scsi/atp870u.h @@ -39,7 +39,6 @@ struct atp_unit unsigned short active_id[2]; unsigned short ultra_map[2]; unsigned short async[2]; - unsigned short dev_id; unsigned char sp[2][16]; unsigned char r1f[2][16]; struct scsi_cmnd *quereq[2][qcnt]; -- cgit v0.10.2 From 11ec131804e75b73f07ac04f94888efc65c5d4c4 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:22 +0100 Subject: atp870u: Use pci_request_regions Use pci_request_regions and do it before accessing the I/O ports. Also add missing pci_disable_device() call to atp870u_remove(). Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 4bb0f4f..87dd886 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1276,10 +1276,15 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto disable_device; } + err = pci_request_regions(pdev, "atp870u"); + if (err) + goto disable_device; + pci_set_master(pdev); + err = -ENOMEM; shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); if (!shpnt) - goto disable_device; + goto release_region; atpdev = shost_priv(shpnt); @@ -1582,10 +1587,6 @@ flash_ok_885: } spin_unlock_irqrestore(shpnt->host_lock, flags); - if (!request_region(shpnt->io_port, shpnt->n_io_port, "atp870u")) { - err = -EBUSY; - goto request_io_fail; - } err = scsi_add_host(shpnt, &pdev->dev); if (err) goto scsi_add_fail; @@ -1596,16 +1597,13 @@ flash_ok_885: return 0; scsi_add_fail: - printk("atp870u_prob:scsi_add_fail\n"); - release_region(shpnt->io_port, shpnt->n_io_port); -request_io_fail: - printk("atp870u_prob:request_io_fail\n"); free_irq(shpnt->irq, shpnt); free_tables: - printk("atp870u_prob:free_table\n"); atp870u_free_tables(shpnt); unregister: scsi_host_put(shpnt); +release_region: + pci_release_regions(pdev); disable_device: pci_disable_device(pdev); fail: @@ -1696,7 +1694,8 @@ static void atp870u_remove (struct pci_dev *pdev) scsi_remove_host(pshost); free_irq(pshost->irq, pshost); - release_region(pshost->io_port, pshost->n_io_port); + pci_release_regions(pdev); + pci_disable_device(pdev); atp870u_free_tables(pshost); scsi_host_put(pshost); } -- cgit v0.10.2 From 1729c0d22bddfa949551c38301af3ce52d40c3b9 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:23 +0100 Subject: atp870u: Request IRQ later, remove weird locking Allocate IRQ later during probe to avoid code duplication and also remove the need for weird locking in _probe. (It was probably there to prevent race with the IRQ handler?) Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 87dd886..4719df4 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1253,7 +1253,6 @@ static void atp_set_host_id(struct atp_unit *atp, u8 c, u8 host_id) static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { unsigned char k, m, c; - unsigned long flags; unsigned int error,n; unsigned char host_id; struct Scsi_Host *shpnt = NULL; @@ -1374,13 +1373,6 @@ flash_ok_880: goto unregister; } - err = request_irq(shpnt->irq, atp870u_intr_handle, IRQF_SHARED, "atp880i", shpnt); - if (err) { - printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", shpnt->irq); - goto free_tables; - } - - spin_lock_irqsave(shpnt->host_lock, flags); k = atp_readb_base(atpdev, 0x38) & 0x80; atp_writeb_base(atpdev, 0x38, k); atp_writeb_base(atpdev, 0x3b, 0x20); @@ -1412,17 +1404,6 @@ flash_ok_880: goto unregister; } -#ifdef ED_DBGP - printk("request_irq() shpnt %p hostdata %p\n", shpnt, atpdev); -#endif - err = request_irq(shpnt->irq, atp870u_intr_handle, IRQF_SHARED, "atp870u", shpnt); - if (err) { - printk(KERN_ERR "Unable to allocate IRQ for Acard controller.\n"); - goto free_tables; - } - - spin_lock_irqsave(shpnt->host_lock, flags); - c = atp_readb_base(atpdev, 0x29); atp_writeb_base(atpdev, 0x29, c | 0x04); @@ -1558,13 +1539,6 @@ flash_ok_885: goto unregister; } - err = request_irq(shpnt->irq, atp870u_intr_handle, IRQF_SHARED, "atp870i", shpnt); - if (err) { - printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", shpnt->irq); - goto free_tables; - } - - spin_lock_irqsave(shpnt->host_lock, flags); if (pdev->revision > 0x07) /* check if atp876 chip then enable terminator */ atp_writeb_base(atpdev, 0x3e, 0x00); @@ -1586,15 +1560,18 @@ flash_ok_885: shpnt->this_id = host_id; } - spin_unlock_irqrestore(shpnt->host_lock, flags); - err = scsi_add_host(shpnt, &pdev->dev); - if (err) - goto scsi_add_fail; - scsi_scan_host(shpnt); -#ifdef ED_DBGP - printk("atp870u_prob : exit\n"); -#endif - return 0; + err = request_irq(shpnt->irq, atp870u_intr_handle, IRQF_SHARED, "atp870u", shpnt); + if (err) { + dev_err(&pdev->dev, "Unable to allocate IRQ %d.\n", shpnt->irq); + goto free_tables; + } + + err = scsi_add_host(shpnt, &pdev->dev); + if (err) + goto scsi_add_fail; + scsi_scan_host(shpnt); + + return 0; scsi_add_fail: free_irq(shpnt->irq, shpnt); -- cgit v0.10.2 From 8177c507523e053011861cce08cb73a77d5896e3 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:24 +0100 Subject: atp870u: Remove scam_on from struct atp_unit scam_on is used only during probe, no need to keep it later. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 4719df4..dd0b520 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -963,7 +963,7 @@ static unsigned char fun_scam(struct atp_unit *dev, unsigned short int *val) return j; } -static void tscam(struct Scsi_Host *host, bool wide_chip) +static void tscam(struct Scsi_Host *host, bool wide_chip, u8 scam_on) { unsigned char i, j, k; @@ -986,7 +986,7 @@ static void tscam(struct Scsi_Host *host, bool wide_chip) atp_writeb_io(dev, 0, 2, 0x7f); atp_writeb_io(dev, 0, 0x11, 0x20); - if ((dev->scam_on & 0x40) == 0) { + if ((scam_on & 0x40) == 0) { return; } m = 1; @@ -1311,7 +1311,6 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) " IO:%lx, IRQ:%d.\n", shpnt->io_port, shpnt->irq); atpdev->host_id[0] = host_id; - atpdev->scam_on = atp_readb_base(atpdev, 0x22); atpdev->global_map[0] = atp_readb_base(atpdev, 0x35); atpdev->ultra_map[0] = atp_readw_base(atpdev, 0x3c); @@ -1384,7 +1383,7 @@ flash_ok_880: atp_set_host_id(atpdev, 0, host_id); - tscam(shpnt, true); + tscam(shpnt, true, atp_readb_base(atpdev, 0x22)); atp_is(atpdev, 0, true, atp_readb_base(atpdev, 0x3f) & 0x40); atp_writeb_base(atpdev, 0x38, 0xb0); shpnt->max_id = 16; @@ -1509,6 +1508,7 @@ flash_ok_885: shpnt->max_channel = 1; shpnt->this_id = atpdev->host_id[0]; } else { + u8 scam_on; bool wide_chip = (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610 && pdev->revision == 4) || @@ -1523,12 +1523,12 @@ flash_ok_885: atpdev->pciport[0] = shpnt->io_port + 0x20; host_id &= 0x07; atpdev->host_id[0] = host_id; - atpdev->scam_on = atp_readb_pci(atpdev, 0, 2); + scam_on = atp_readb_pci(atpdev, 0, 2); atpdev->global_map[0] = atp_readb_base(atpdev, 0x2d); atpdev->ultra_map[0] = atp_readw_base(atpdev, 0x2e); if (atpdev->ultra_map[0] == 0) { - atpdev->scam_on = 0x00; + scam_on = 0x00; atpdev->global_map[0] = 0x20; atpdev->ultra_map[0] = 0xffff; } @@ -1551,7 +1551,7 @@ flash_ok_885: atp_set_host_id(atpdev, 0, host_id); - tscam(shpnt, wide_chip); + tscam(shpnt, wide_chip, scam_on); atp_writeb_base(atpdev, 0x3a, atp_readb_base(atpdev, 0x3a) | 0x10); atp_is(atpdev, 0, wide_chip, 0); atp_writeb_base(atpdev, 0x3a, atp_readb_base(atpdev, 0x3a) & 0xef); diff --git a/drivers/scsi/atp870u.h b/drivers/scsi/atp870u.h index f9d62a2..9b839b1 100644 --- a/drivers/scsi/atp870u.h +++ b/drivers/scsi/atp870u.h @@ -32,7 +32,6 @@ struct atp_unit unsigned char quhd[2]; unsigned char quend[2]; unsigned char global_map[2]; - unsigned char scam_on; unsigned char host_id[2]; unsigned int working[2]; unsigned short wide_id[2]; -- cgit v0.10.2 From f5f53a38c2f8671f9fc249c711411ba44d76a618 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:25 +0100 Subject: atp870u: Initialize tables earlier Call _init_tables before chip-specific initialization. This avoids code duplication and fixes a bug(?) in 880 init where the values read from flash into atpdev->sp are then overwritten by calling init_tables. Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index dd0b520..3c66539 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1298,6 +1298,12 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) shpnt->unique_id = shpnt->io_port; shpnt->irq = pdev->irq; + err = atp870u_init_tables(shpnt); + if (err) { + dev_err(&pdev->dev, "Unable to allocate tables for Acard controller\n"); + goto unregister; + } + if (is880(atpdev)) { pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);//JCC082803 @@ -1366,11 +1372,6 @@ flash_ok_880: atpdev->async[0] = ~(atpdev->async[0]); atp_writeb_base(atpdev, 0x35, atpdev->global_map[0]); - if (atp870u_init_tables(shpnt) < 0) { - printk(KERN_ERR "Unable to allocate tables for Acard controller\n"); - err = -ENOMEM; - goto unregister; - } k = atp_readb_base(atpdev, 0x38) & 0x80; atp_writeb_base(atpdev, 0x38, k); @@ -1398,11 +1399,6 @@ flash_ok_880: atpdev->pciport[0] = shpnt->io_port + 0x40; atpdev->pciport[1] = shpnt->io_port + 0x50; - if (atp870u_init_tables(shpnt) < 0) { - err = -ENOMEM; - goto unregister; - } - c = atp_readb_base(atpdev, 0x29); atp_writeb_base(atpdev, 0x29, c | 0x04); @@ -1533,12 +1529,6 @@ flash_ok_885: atpdev->ultra_map[0] = 0xffff; } - - if (atp870u_init_tables(shpnt) < 0) { - err = -ENOMEM; - goto unregister; - } - if (pdev->revision > 0x07) /* check if atp876 chip then enable terminator */ atp_writeb_base(atpdev, 0x3e, 0x00); -- cgit v0.10.2 From c7e6a0298d56694d79189cd9127ac8ec1c2275ca Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:26 +0100 Subject: atp870u: Introduce atp880_init() Move 880-specific init code to a separate function atp880_init() Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 3c66539..c1fd9fb 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1249,6 +1249,91 @@ static void atp_set_host_id(struct atp_unit *atp, u8 c, u8 host_id) atp_writeb_io(atp, c, 0x11, 0x20); } +static void atp880_init(struct Scsi_Host *shpnt) +{ + struct atp_unit *atpdev = shost_priv(shpnt); + struct pci_dev *pdev = atpdev->pdev; + unsigned char k, m, host_id; + unsigned int n; + + pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80); + + atpdev->ioport[0] = shpnt->io_port + 0x40; + atpdev->pciport[0] = shpnt->io_port + 0x28; + + host_id = atp_readb_base(atpdev, 0x39) >> 4; + + dev_info(&pdev->dev, "ACARD AEC-67160 PCI Ultra3 LVD Host Adapter: IO:%lx, IRQ:%d.\n", + shpnt->io_port, shpnt->irq); + atpdev->host_id[0] = host_id; + + atpdev->global_map[0] = atp_readb_base(atpdev, 0x35); + atpdev->ultra_map[0] = atp_readw_base(atpdev, 0x3c); + + n = 0x3f09; + while (n < 0x4000) { + m = 0; + atp_writew_base(atpdev, 0x34, n); + n += 0x0002; + if (atp_readb_base(atpdev, 0x30) == 0xff) + break; + + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x30); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x31); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x32); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x33); + atp_writew_base(atpdev, 0x34, n); + n += 0x0002; + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x30); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x31); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x32); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x33); + atp_writew_base(atpdev, 0x34, n); + n += 0x0002; + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x30); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x31); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x32); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x33); + atp_writew_base(atpdev, 0x34, n); + n += 0x0002; + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x30); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x31); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x32); + atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x33); + n += 0x0018; + } + atp_writew_base(atpdev, 0x34, 0); + atpdev->ultra_map[0] = 0; + atpdev->async[0] = 0; + for (k = 0; k < 16; k++) { + n = 1 << k; + if (atpdev->sp[0][k] > 1) + atpdev->ultra_map[0] |= n; + else + if (atpdev->sp[0][k] == 0) + atpdev->async[0] |= n; + } + atpdev->async[0] = ~(atpdev->async[0]); + atp_writeb_base(atpdev, 0x35, atpdev->global_map[0]); + + k = atp_readb_base(atpdev, 0x38) & 0x80; + atp_writeb_base(atpdev, 0x38, k); + atp_writeb_base(atpdev, 0x3b, 0x20); + mdelay(32); + atp_writeb_base(atpdev, 0x3b, 0); + mdelay(32); + atp_readb_io(atpdev, 0, 0x1b); + atp_readb_io(atpdev, 0, 0x17); + + atp_set_host_id(atpdev, 0, host_id); + + tscam(shpnt, true, atp_readb_base(atpdev, 0x22)); + atp_is(atpdev, 0, true, atp_readb_base(atpdev, 0x3f) & 0x40); + atp_writeb_base(atpdev, 0x38, 0xb0); + shpnt->max_id = 16; + shpnt->this_id = host_id; +} + /* return non-zero on detection */ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -1304,92 +1389,9 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto unregister; } - if (is880(atpdev)) { - pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);//JCC082803 - - atpdev->ioport[0] = shpnt->io_port + 0x40; - atpdev->pciport[0] = shpnt->io_port + 0x28; - - host_id = atp_readb_base(atpdev, 0x39); - host_id >>= 0x04; - - printk(KERN_INFO " ACARD AEC-67160 PCI Ultra3 LVD Host Adapter:" - " IO:%lx, IRQ:%d.\n", shpnt->io_port, shpnt->irq); - atpdev->host_id[0] = host_id; - - atpdev->global_map[0] = atp_readb_base(atpdev, 0x35); - atpdev->ultra_map[0] = atp_readw_base(atpdev, 0x3c); - - n = 0x3f09; -next_fblk_880: - if (n >= 0x4000) - goto flash_ok_880; - - m = 0; - atp_writew_base(atpdev, 0x34, n); - n += 0x0002; - if (atp_readb_base(atpdev, 0x30) == 0xff) - goto flash_ok_880; - - atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x30); - atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x31); - atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x32); - atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x33); - atp_writew_base(atpdev, 0x34, n); - n += 0x0002; - atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x30); - atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x31); - atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x32); - atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x33); - atp_writew_base(atpdev, 0x34, n); - n += 0x0002; - atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x30); - atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x31); - atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x32); - atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x33); - atp_writew_base(atpdev, 0x34, n); - n += 0x0002; - atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x30); - atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x31); - atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x32); - atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x33); - n += 0x0018; - goto next_fblk_880; -flash_ok_880: - atp_writew_base(atpdev, 0x34, 0); - atpdev->ultra_map[0] = 0; - atpdev->async[0] = 0; - for (k = 0; k < 16; k++) { - n = 1; - n = n << k; - if (atpdev->sp[0][k] > 1) { - atpdev->ultra_map[0] |= n; - } else { - if (atpdev->sp[0][k] == 0) - atpdev->async[0] |= n; - } - } - atpdev->async[0] = ~(atpdev->async[0]); - atp_writeb_base(atpdev, 0x35, atpdev->global_map[0]); - - - k = atp_readb_base(atpdev, 0x38) & 0x80; - atp_writeb_base(atpdev, 0x38, k); - atp_writeb_base(atpdev, 0x3b, 0x20); - mdelay(32); - atp_writeb_base(atpdev, 0x3b, 0); - mdelay(32); - atp_readb_io(atpdev, 0, 0x1b); - atp_readb_io(atpdev, 0, 0x17); - - atp_set_host_id(atpdev, 0, host_id); - - tscam(shpnt, true, atp_readb_base(atpdev, 0x22)); - atp_is(atpdev, 0, true, atp_readb_base(atpdev, 0x3f) & 0x40); - atp_writeb_base(atpdev, 0x38, 0xb0); - shpnt->max_id = 16; - shpnt->this_id = host_id; - } else if (is885(atpdev)) { + if (is880(atpdev)) + atp880_init(shpnt); + else if (is885(atpdev)) { printk(KERN_INFO " ACARD AEC-67162 PCI Ultra3 LVD Host Adapter: IO:%lx, IRQ:%d.\n" , shpnt->io_port, shpnt->irq); -- cgit v0.10.2 From ecc6ff95d1a84f0a025112e071be40dd905a5168 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:27 +0100 Subject: atp870u: Introduce atp885_init() Move 885-specific init code to a separate function atp885_init() Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index c1fd9fb..584b90f 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1334,15 +1334,122 @@ static void atp880_init(struct Scsi_Host *shpnt) shpnt->this_id = host_id; } +static void atp885_init(struct Scsi_Host *shpnt) +{ + struct atp_unit *atpdev = shost_priv(shpnt); + struct pci_dev *pdev = atpdev->pdev; + unsigned char k, m, c; + unsigned int n; + unsigned char setupdata[2][16]; + + dev_info(&pdev->dev, "ACARD AEC-67162 PCI Ultra3 LVD Host Adapter: IO:%lx, IRQ:%d.\n", + shpnt->io_port, shpnt->irq); + + atpdev->ioport[0] = shpnt->io_port + 0x80; + atpdev->ioport[1] = shpnt->io_port + 0xc0; + atpdev->pciport[0] = shpnt->io_port + 0x40; + atpdev->pciport[1] = shpnt->io_port + 0x50; + + c = atp_readb_base(atpdev, 0x29); + atp_writeb_base(atpdev, 0x29, c | 0x04); + + n = 0x1f80; + while (n < 0x2000) { + atp_writew_base(atpdev, 0x3c, n); + if (atp_readl_base(atpdev, 0x38) == 0xffffffff) + break; + for (m = 0; m < 2; m++) { + atpdev->global_map[m] = 0; + for (k = 0; k < 4; k++) { + atp_writew_base(atpdev, 0x3c, n++); + ((unsigned long *)&setupdata[m][0])[k] = atp_readl_base(atpdev, 0x38); + } + for (k = 0; k < 4; k++) { + atp_writew_base(atpdev, 0x3c, n++); + ((unsigned long *)&atpdev->sp[m][0])[k] = atp_readl_base(atpdev, 0x38); + } + n += 8; + } + } + c = atp_readb_base(atpdev, 0x29); + atp_writeb_base(atpdev, 0x29, c & 0xfb); + for (c = 0; c < 2; c++) { + atpdev->ultra_map[c] = 0; + atpdev->async[c] = 0; + for (k = 0; k < 16; k++) { + n = 1 << k; + if (atpdev->sp[c][k] > 1) + atpdev->ultra_map[c] |= n; + else + if (atpdev->sp[c][k] == 0) + atpdev->async[c] |= n; + } + atpdev->async[c] = ~(atpdev->async[c]); + + if (atpdev->global_map[c] == 0) { + k = setupdata[c][1]; + if ((k & 0x40) != 0) + atpdev->global_map[c] |= 0x20; + k &= 0x07; + atpdev->global_map[c] |= k; + if ((setupdata[c][2] & 0x04) != 0) + atpdev->global_map[c] |= 0x08; + atpdev->host_id[c] = setupdata[c][0] & 0x07; + } + } + + k = atp_readb_base(atpdev, 0x28) & 0x8f; + k |= 0x10; + atp_writeb_base(atpdev, 0x28, k); + atp_writeb_pci(atpdev, 0, 1, 0x80); + atp_writeb_pci(atpdev, 1, 1, 0x80); + mdelay(100); + atp_writeb_pci(atpdev, 0, 1, 0); + atp_writeb_pci(atpdev, 1, 1, 0); + mdelay(1000); + atp_readb_io(atpdev, 0, 0x1b); + atp_readb_io(atpdev, 0, 0x17); + atp_readb_io(atpdev, 1, 0x1b); + atp_readb_io(atpdev, 1, 0x17); + + k = atpdev->host_id[0]; + if (k > 7) + k = (k & 0x07) | 0x40; + atp_set_host_id(atpdev, 0, k); + + k = atpdev->host_id[1]; + if (k > 7) + k = (k & 0x07) | 0x40; + atp_set_host_id(atpdev, 1, k); + + mdelay(600); /* this delay used to be called tscam_885() */ + dev_info(&pdev->dev, "Scanning Channel A SCSI Device ...\n"); + atp_is(atpdev, 0, true, atp_readb_io(atpdev, 0, 0x1b) >> 7); + atp_writeb_io(atpdev, 0, 0x16, 0x80); + dev_info(&pdev->dev, "Scanning Channel B SCSI Device ...\n"); + atp_is(atpdev, 1, true, atp_readb_io(atpdev, 1, 0x1b) >> 7); + atp_writeb_io(atpdev, 1, 0x16, 0x80); + k = atp_readb_base(atpdev, 0x28) & 0xcf; + k |= 0xc0; + atp_writeb_base(atpdev, 0x28, k); + k = atp_readb_base(atpdev, 0x1f) | 0x80; + atp_writeb_base(atpdev, 0x1f, k); + k = atp_readb_base(atpdev, 0x29) | 0x01; + atp_writeb_base(atpdev, 0x29, k); + shpnt->max_id = 16; + shpnt->max_lun = (atpdev->global_map[0] & 0x07) + 1; + shpnt->max_channel = 1; + shpnt->this_id = atpdev->host_id[0]; +} + /* return non-zero on detection */ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - unsigned char k, m, c; - unsigned int error,n; + unsigned char k; + unsigned int error; unsigned char host_id; struct Scsi_Host *shpnt = NULL; struct atp_unit *atpdev; - unsigned char setupdata[2][16]; int err; if (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610 && pdev->revision < 2) { @@ -1391,121 +1498,9 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (is880(atpdev)) atp880_init(shpnt); - else if (is885(atpdev)) { - printk(KERN_INFO " ACARD AEC-67162 PCI Ultra3 LVD Host Adapter: IO:%lx, IRQ:%d.\n" - , shpnt->io_port, shpnt->irq); - - atpdev->pdev = pdev; - atpdev->ioport[0] = shpnt->io_port + 0x80; - atpdev->ioport[1] = shpnt->io_port + 0xc0; - atpdev->pciport[0] = shpnt->io_port + 0x40; - atpdev->pciport[1] = shpnt->io_port + 0x50; - - c = atp_readb_base(atpdev, 0x29); - atp_writeb_base(atpdev, 0x29, c | 0x04); - - n=0x1f80; -next_fblk_885: - if (n >= 0x2000) { - goto flash_ok_885; - } - atp_writew_base(atpdev, 0x3c, n); - if (atp_readl_base(atpdev, 0x38) == 0xffffffff) { - goto flash_ok_885; - } - for (m=0; m < 2; m++) { - atpdev->global_map[m]= 0; - for (k=0; k < 4; k++) { - atp_writew_base(atpdev, 0x3c, n++); - ((unsigned long *)&setupdata[m][0])[k] = atp_readl_base(atpdev, 0x38); - } - for (k=0; k < 4; k++) { - atp_writew_base(atpdev, 0x3c, n++); - ((unsigned long *)&atpdev->sp[m][0])[k] = atp_readl_base(atpdev, 0x38); - } - n += 8; - } - goto next_fblk_885; -flash_ok_885: -#ifdef ED_DBGP - printk( "Flash Read OK\n"); -#endif - c = atp_readb_base(atpdev, 0x29); - atp_writeb_base(atpdev, 0x29, c & 0xfb); - for (c=0;c < 2;c++) { - atpdev->ultra_map[c]=0; - atpdev->async[c] = 0; - for (k=0; k < 16; k++) { - n=1; - n = n << k; - if (atpdev->sp[c][k] > 1) { - atpdev->ultra_map[c] |= n; - } else { - if (atpdev->sp[c][k] == 0) { - atpdev->async[c] |= n; - } - } - } - atpdev->async[c] = ~(atpdev->async[c]); - - if (atpdev->global_map[c] == 0) { - k=setupdata[c][1]; - if ((k & 0x40) != 0) - atpdev->global_map[c] |= 0x20; - k &= 0x07; - atpdev->global_map[c] |= k; - if ((setupdata[c][2] & 0x04) != 0) - atpdev->global_map[c] |= 0x08; - atpdev->host_id[c] = setupdata[c][0] & 0x07; - } - } - - k = atp_readb_base(atpdev, 0x28) & 0x8f; - k |= 0x10; - atp_writeb_base(atpdev, 0x28, k); - atp_writeb_pci(atpdev, 0, 1, 0x80); - atp_writeb_pci(atpdev, 1, 1, 0x80); - mdelay(100); - atp_writeb_pci(atpdev, 0, 1, 0); - atp_writeb_pci(atpdev, 1, 1, 0); - mdelay(1000); - atp_readb_io(atpdev, 0, 0x1b); - atp_readb_io(atpdev, 0, 0x17); - atp_readb_io(atpdev, 1, 0x1b); - atp_readb_io(atpdev, 1, 0x17); - - k=atpdev->host_id[0]; - if (k > 7) - k = (k & 0x07) | 0x40; - atp_set_host_id(atpdev, 0, k); - - k=atpdev->host_id[1]; - if (k > 7) - k = (k & 0x07) | 0x40; - atp_set_host_id(atpdev, 1, k); - - mdelay(600); /* this delay used to be called tscam_885() */ - printk(KERN_INFO " Scanning Channel A SCSI Device ...\n"); - atp_is(atpdev, 0, true, atp_readb_io(atpdev, 0, 0x1b) >> 7); - atp_writeb_io(atpdev, 0, 0x16, 0x80); - printk(KERN_INFO " Scanning Channel B SCSI Device ...\n"); - atp_is(atpdev, 1, true, atp_readb_io(atpdev, 1, 0x1b) >> 7); - atp_writeb_io(atpdev, 1, 0x16, 0x80); - k = atp_readb_base(atpdev, 0x28) & 0xcf; - k |= 0xc0; - atp_writeb_base(atpdev, 0x28, k); - k = atp_readb_base(atpdev, 0x1f) | 0x80; - atp_writeb_base(atpdev, 0x1f, k); - k = atp_readb_base(atpdev, 0x29) | 0x01; - atp_writeb_base(atpdev, 0x29, k); -#ifdef ED_DBGP - //printk("atp885: atp_host[0] 0x%p\n", atp_host[0]); -#endif - shpnt->max_id = 16; - shpnt->max_lun = (atpdev->global_map[0] & 0x07) + 1; - shpnt->max_channel = 1; - shpnt->this_id = atpdev->host_id[0]; - } else { + else if (is885(atpdev)) + atp885_init(shpnt); + else { u8 scam_on; bool wide_chip = (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610 && -- cgit v0.10.2 From 4190230edbbe8864f04610900249db3738e2f51c Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Nov 2015 19:24:28 +0100 Subject: atp870u: Introduce atp870_init() Move 870-specific init code to a separate function atp870_init() Signed-off-by: Ondrej Zary Reviewed-by: Hannes Reinicke Acked-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 584b90f..8b52a9d 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1249,6 +1249,57 @@ static void atp_set_host_id(struct atp_unit *atp, u8 c, u8 host_id) atp_writeb_io(atp, c, 0x11, 0x20); } +static void atp870_init(struct Scsi_Host *shpnt) +{ + struct atp_unit *atpdev = shost_priv(shpnt); + struct pci_dev *pdev = atpdev->pdev; + unsigned char k, host_id; + u8 scam_on; + bool wide_chip = + (pdev->device == PCI_DEVICE_ID_ARTOP_AEC7610 && + pdev->revision == 4) || + (pdev->device == PCI_DEVICE_ID_ARTOP_AEC7612UW) || + (pdev->device == PCI_DEVICE_ID_ARTOP_AEC7612SUW); + + pci_read_config_byte(pdev, 0x49, &host_id); + + dev_info(&pdev->dev, "ACARD AEC-671X PCI Ultra/W SCSI-2/3 Host Adapter: IO:%lx, IRQ:%d.\n", + shpnt->io_port, shpnt->irq); + + atpdev->ioport[0] = shpnt->io_port; + atpdev->pciport[0] = shpnt->io_port + 0x20; + host_id &= 0x07; + atpdev->host_id[0] = host_id; + scam_on = atp_readb_pci(atpdev, 0, 2); + atpdev->global_map[0] = atp_readb_base(atpdev, 0x2d); + atpdev->ultra_map[0] = atp_readw_base(atpdev, 0x2e); + + if (atpdev->ultra_map[0] == 0) { + scam_on = 0x00; + atpdev->global_map[0] = 0x20; + atpdev->ultra_map[0] = 0xffff; + } + + if (pdev->revision > 0x07) /* check if atp876 chip */ + atp_writeb_base(atpdev, 0x3e, 0x00); /* enable terminator */ + + k = (atp_readb_base(atpdev, 0x3a) & 0xf3) | 0x10; + atp_writeb_base(atpdev, 0x3a, k); + atp_writeb_base(atpdev, 0x3a, k & 0xdf); + mdelay(32); + atp_writeb_base(atpdev, 0x3a, k); + mdelay(32); + atp_set_host_id(atpdev, 0, host_id); + + tscam(shpnt, wide_chip, scam_on); + atp_writeb_base(atpdev, 0x3a, atp_readb_base(atpdev, 0x3a) | 0x10); + atp_is(atpdev, 0, wide_chip, 0); + atp_writeb_base(atpdev, 0x3a, atp_readb_base(atpdev, 0x3a) & 0xef); + atp_writeb_base(atpdev, 0x3b, atp_readb_base(atpdev, 0x3b) | 0x20); + shpnt->max_id = wide_chip ? 16 : 8; + shpnt->this_id = host_id; +} + static void atp880_init(struct Scsi_Host *shpnt) { struct atp_unit *atpdev = shost_priv(shpnt); @@ -1445,9 +1496,6 @@ static void atp885_init(struct Scsi_Host *shpnt) /* return non-zero on detection */ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - unsigned char k; - unsigned int error; - unsigned char host_id; struct Scsi_Host *shpnt = NULL; struct atp_unit *atpdev; int err; @@ -1500,53 +1548,9 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) atp880_init(shpnt); else if (is885(atpdev)) atp885_init(shpnt); - else { - u8 scam_on; - bool wide_chip = - (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610 && - pdev->revision == 4) || - (ent->device == PCI_DEVICE_ID_ARTOP_AEC7612UW) || - (ent->device == PCI_DEVICE_ID_ARTOP_AEC7612SUW); - error = pci_read_config_byte(pdev, 0x49, &host_id); - - printk(KERN_INFO " ACARD AEC-671X PCI Ultra/W SCSI-2/3 Host Adapter: " - "IO:%lx, IRQ:%d.\n", shpnt->io_port, shpnt->irq); - - atpdev->ioport[0] = shpnt->io_port; - atpdev->pciport[0] = shpnt->io_port + 0x20; - host_id &= 0x07; - atpdev->host_id[0] = host_id; - scam_on = atp_readb_pci(atpdev, 0, 2); - atpdev->global_map[0] = atp_readb_base(atpdev, 0x2d); - atpdev->ultra_map[0] = atp_readw_base(atpdev, 0x2e); - - if (atpdev->ultra_map[0] == 0) { - scam_on = 0x00; - atpdev->global_map[0] = 0x20; - atpdev->ultra_map[0] = 0xffff; - } - - if (pdev->revision > 0x07) /* check if atp876 chip then enable terminator */ - atp_writeb_base(atpdev, 0x3e, 0x00); - - k = (atp_readb_base(atpdev, 0x3a) & 0xf3) | 0x10; - atp_writeb_base(atpdev, 0x3a, k); - atp_writeb_base(atpdev, 0x3a, k & 0xdf); - mdelay(32); - atp_writeb_base(atpdev, 0x3a, k); - mdelay(32); - atp_set_host_id(atpdev, 0, host_id); - - - tscam(shpnt, wide_chip, scam_on); - atp_writeb_base(atpdev, 0x3a, atp_readb_base(atpdev, 0x3a) | 0x10); - atp_is(atpdev, 0, wide_chip, 0); - atp_writeb_base(atpdev, 0x3a, atp_readb_base(atpdev, 0x3a) & 0xef); - atp_writeb_base(atpdev, 0x3b, atp_readb_base(atpdev, 0x3b) | 0x20); - shpnt->max_id = wide_chip ? 16 : 8; - shpnt->this_id = host_id; - - } + else + atp870_init(shpnt); + err = request_irq(shpnt->irq, atp870u_intr_handle, IRQF_SHARED, "atp870u", shpnt); if (err) { dev_err(&pdev->dev, "Unable to allocate IRQ %d.\n", shpnt->irq); -- cgit v0.10.2 From c15d75bec6d0a937f7a15b81052ed99d310e9767 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:28 +0800 Subject: scsi: Centralise ssp frame information units The xfer_rdy, command, and task frame's iu structures are not available in , but only aic94xx driver folder. Add them to include/scsi/sas.h Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/aic94xx/aic94xx_sas.h b/drivers/scsi/aic94xx/aic94xx_sas.h index 912e6b7..101072c 100644 --- a/drivers/scsi/aic94xx/aic94xx_sas.h +++ b/drivers/scsi/aic94xx/aic94xx_sas.h @@ -327,46 +327,9 @@ struct scb_header { #define LUN_SIZE 8 -/* See SAS spec, task IU - */ -struct ssp_task_iu { - u8 lun[LUN_SIZE]; /* BE */ - u16 _r_a; - u8 tmf; - u8 _r_b; - __be16 tag; /* BE */ - u8 _r_c[14]; -} __attribute__ ((packed)); - -/* See SAS spec, command IU - */ -struct ssp_command_iu { - u8 lun[LUN_SIZE]; - u8 _r_a; - u8 efb_prio_attr; /* enable first burst, task prio & attr */ -#define EFB_MASK 0x80 -#define TASK_PRIO_MASK 0x78 -#define TASK_ATTR_MASK 0x07 - - u8 _r_b; - u8 add_cdb_len; /* in dwords, since bit 0,1 are reserved */ - union { - u8 cdb[16]; - struct { - __le64 long_cdb_addr; /* bus address, LE */ - __le32 long_cdb_size; /* LE */ - u8 _r_c[3]; - u8 eol_ds; /* eol:6,6, ds:5,4 */ - } long_cdb; /* sequencer extension */ - }; -} __attribute__ ((packed)); - -struct xfer_rdy_iu { - __be32 requested_offset; /* BE */ - __be32 write_data_len; /* BE */ - __be32 _r_a; -} __attribute__ ((packed)); - +#define EFB_MASK 0x80 +#define TASK_PRIO_MASK 0x78 +#define TASK_ATTR_MASK 0x07 /* ---------- SCB tasks ---------- */ /* This is both ssp_task and long_ssp_task @@ -511,7 +474,7 @@ struct abort_task { u8 proto_conn_rate; __le32 _r_a; struct ssp_frame_hdr ssp_frame; - struct ssp_task_iu ssp_task; + struct ssp_tmf_iu ssp_task; __le16 sister_scb; __le16 conn_handle; u8 flags; /* ovrd_itnl_timer:3,3, suspend_data_trans:2,2 */ @@ -549,7 +512,7 @@ struct clear_nexus { u8 _r_b[3]; u8 conn_mask; u8 _r_c[19]; - struct ssp_task_iu ssp_task; /* LUN and TAG */ + struct ssp_tmf_iu ssp_task; /* LUN and TAG */ __le16 _r_d; __le16 conn_handle; __le64 _r_e; @@ -562,7 +525,7 @@ struct initiate_ssp_tmf { u8 proto_conn_rate; __le32 _r_a; struct ssp_frame_hdr ssp_frame; - struct ssp_task_iu ssp_task; + struct ssp_tmf_iu ssp_task; __le16 sister_scb; __le16 conn_handle; u8 flags; /* itnl override and suspend data tx */ diff --git a/include/scsi/sas.h b/include/scsi/sas.h index 0d2607d..42a84ef 100644 --- a/include/scsi/sas.h +++ b/include/scsi/sas.h @@ -344,6 +344,43 @@ struct ssp_response_iu { u8 sense_data[0]; } __attribute__ ((packed)); +struct ssp_command_iu { + u8 lun[8]; + u8 _r_a; + + union { + struct { + u8 attr:3; + u8 prio:4; + u8 efb:1; + }; + u8 efb_prio_attr; + }; + + u8 _r_b; + + u8 _r_c:2; + u8 add_cdb_len:6; + + u8 cdb[16]; + u8 add_cdb[0]; +} __attribute__ ((packed)); + +struct xfer_rdy_iu { + __be32 requested_offset; + __be32 write_data_len; + __be32 _r_a; +} __attribute__ ((packed)); + +struct ssp_tmf_iu { + u8 lun[8]; + u16 _r_a; + u8 tmf; + u8 _r_b; + __be16 tag; + u8 _r_c[14]; +} __attribute__ ((packed)); + /* ---------- SMP ---------- */ struct report_general_resp { @@ -538,6 +575,43 @@ struct ssp_response_iu { u8 sense_data[0]; } __attribute__ ((packed)); +struct ssp_command_iu { + u8 lun[8]; + u8 _r_a; + + union { + struct { + u8 efb:1; + u8 prio:4; + u8 attr:3; + }; + u8 efb_prio_attr; + }; + + u8 _r_b; + + u8 add_cdb_len:6; + u8 _r_c:2; + + u8 cdb[16]; + u8 add_cdb[0]; +} __attribute__ ((packed)); + +struct xfer_rdy_iu { + __be32 requested_offset; + __be32 write_data_len; + __be32 _r_a; +} __attribute__ ((packed)); + +struct ssp_tmf_iu { + u8 lun[8]; + u16 _r_a; + u8 tmf; + u8 _r_b; + __be16 tag; + u8 _r_c[14]; +} __attribute__ ((packed)); + /* ---------- SMP ---------- */ struct report_general_resp { -- cgit v0.10.2 From 47caad1577cd7a39e2048c5e4edbce4b863dc12b Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:29 +0800 Subject: devicetree: bindings: scsi: HiSi SAS Add devicetree bindings for HiSilicon SAS driver. Signed-off-by: John Garry Signed-off-by: Zhangfei Gao Acked-by: Rob Herring Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt b/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt new file mode 100644 index 0000000..f67e761 --- /dev/null +++ b/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt @@ -0,0 +1,69 @@ +* HiSilicon SAS controller + +The HiSilicon SAS controller supports SAS/SATA. + +Main node required properties: + - compatible : value should be as follows: + (a) "hisilicon,hip05-sas-v1" for v1 hw in hip05 chipset + - sas-addr : array of 8 bytes for host SAS address + - reg : Address and length of the SAS register + - hisilicon,sas-syscon: phandle of syscon used for sas control + - ctrl-reset-reg : offset to controller reset register in ctrl reg + - ctrl-reset-sts-reg : offset to controller reset status register in ctrl reg + - ctrl-clock-ena-reg : offset to controller clock enable register in ctrl reg + - queue-count : number of delivery and completion queues in the controller + - phy-count : number of phys accessible by the controller + - interrupts : Interrupts for phys, completion queues, and fatal + sources; the interrupts are ordered in 3 groups, as follows: + - Phy interrupts + - Completion queue interrupts + - Fatal interrupts + Phy interrupts : Each phy has 3 interrupt sources: + - broadcast + - phyup + - abnormal + The phy interrupts are ordered into groups of 3 per phy + (broadcast, phyup, and abnormal) in increasing order. + Completion queue interrupts : each completion queue has 1 + interrupt source. + The interrupts are ordered in increasing order. + Fatal interrupts : the fatal interrupts are ordered as follows: + - ECC + - AXI bus + +Example: + sas0: sas@c1000000 { + compatible = "hisilicon,hip05-sas-v1"; + sas-addr = [50 01 88 20 16 00 00 0a]; + reg = <0x0 0xc1000000 0x0 0x10000>; + hisilicon,sas-syscon = <&pcie_sas>; + ctrl-reset-reg = <0xa60>; + ctrl-reset-sts-reg = <0x5a30>; + ctrl-clock-ena-reg = <0x338>; + queue-count = <32>; + phy-count = <8>; + dma-coherent; + interrupt-parent = <&mbigen_dsa>; + interrupts = <259 4>,<263 4>,<264 4>,/* phy0 */ + <269 4>,<273 4>,<274 4>,/* phy1 */ + <279 4>,<283 4>,<284 4>,/* phy2 */ + <289 4>,<293 4>,<294 4>,/* phy3 */ + <299 4>,<303 4>,<304 4>,/* phy4 */ + <309 4>,<313 4>,<314 4>,/* phy5 */ + <319 4>,<323 4>,<324 4>,/* phy6 */ + <329 4>,<333 4>,<334 4>,/* phy7 */ + <336 1>,<337 1>,<338 1>,/* cq0-2 */ + <339 1>,<340 1>,<341 1>,/* cq3-5 */ + <342 1>,<343 1>,<344 1>,/* cq6-8 */ + <345 1>,<346 1>,<347 1>,/* cq9-11 */ + <348 1>,<349 1>,<350 1>,/* cq12-14 */ + <351 1>,<352 1>,<353 1>,/* cq15-17 */ + <354 1>,<355 1>,<356 1>,/* cq18-20 */ + <357 1>,<358 1>,<359 1>,/* cq21-23 */ + <360 1>,<361 1>,<362 1>,/* cq24-26 */ + <363 1>,<364 1>,<365 1>,/* cq27-29 */ + <366 1>,<367 1>/* cq30-31 */ + <376 4>,/* fatal ecc */ + <381 4>;/* fatal axi */ + status = "disabled"; + }; -- cgit v0.10.2 From e8899fad9672ca8b414db36e16ce4d21818802dc Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:30 +0800 Subject: hisi_sas: Add initial bare main driver This patch adds the initial bare main driver for the HiSilicon SAS HBA. This only introduces the changes to build and load the main driver module. The complete driver consists of the core main module and also a module platform driver for driving the hw. The HBA is a platform device. Signed-off-by: John Garry Signed-off-by: Zhangfei Gao Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 5f692ae..37dce23 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -473,6 +473,7 @@ config SCSI_AACRAID source "drivers/scsi/aic7xxx/Kconfig.aic7xxx" source "drivers/scsi/aic7xxx/Kconfig.aic79xx" source "drivers/scsi/aic94xx/Kconfig" +source "drivers/scsi/hisi_sas/Kconfig" source "drivers/scsi/mvsas/Kconfig" config SCSI_MVUMI diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index c14bca4..862ab4e 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -157,6 +157,7 @@ obj-$(CONFIG_CHR_DEV_SCH) += ch.o obj-$(CONFIG_SCSI_ENCLOSURE) += ses.o obj-$(CONFIG_SCSI_OSD_INITIATOR) += osd/ +obj-$(CONFIG_SCSI_HISI_SAS) += hisi_sas/ # This goes last, so that "real" scsi devices probe earlier obj-$(CONFIG_SCSI_DEBUG) += scsi_debug.o diff --git a/drivers/scsi/hisi_sas/Kconfig b/drivers/scsi/hisi_sas/Kconfig new file mode 100644 index 0000000..37a0c71 --- /dev/null +++ b/drivers/scsi/hisi_sas/Kconfig @@ -0,0 +1,6 @@ +config SCSI_HISI_SAS + tristate "HiSilicon SAS" + select SCSI_SAS_LIBSAS + select BLK_DEV_INTEGRITY + help + This driver supports HiSilicon's SAS HBA diff --git a/drivers/scsi/hisi_sas/Makefile b/drivers/scsi/hisi_sas/Makefile new file mode 100644 index 0000000..d86b05e --- /dev/null +++ b/drivers/scsi/hisi_sas/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_SCSI_HISI_SAS) += hisi_sas_main.o diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h new file mode 100644 index 0000000..a5cec22 --- /dev/null +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2015 Linaro Ltd. + * Copyright (c) 2015 Hisilicon Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ + +#ifndef _HISI_SAS_H_ +#define _HISI_SAS_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRV_VERSION "v1.0" + +#endif diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c new file mode 100644 index 0000000..7201363 --- /dev/null +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2015 Linaro Ltd. + * Copyright (c) 2015 Hisilicon Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ + +#include "hisi_sas.h" +#define DRV_NAME "hisi_sas" + +static struct scsi_transport_template *hisi_sas_stt; + +static struct sas_domain_function_template hisi_sas_transport_ops = { +}; + +static __init int hisi_sas_init(void) +{ + pr_info("hisi_sas: driver version %s\n", DRV_VERSION); + + hisi_sas_stt = sas_domain_attach_transport(&hisi_sas_transport_ops); + if (!hisi_sas_stt) + return -ENOMEM; + + return 0; +} + +static __exit void hisi_sas_exit(void) +{ + sas_release_transport(hisi_sas_stt); +} + +module_init(hisi_sas_init); +module_exit(hisi_sas_exit); + +MODULE_VERSION(DRV_VERSION); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("John Garry "); +MODULE_DESCRIPTION("HISILICON SAS controller driver"); +MODULE_ALIAS("platform:" DRV_NAME); -- cgit v0.10.2 From 7eb7869f1307cc86fca9afd1425bba023c35414f Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:31 +0800 Subject: hisi_sas: Add scsi host registration Add functionality to register device as a scsi host. The SAS domain transport ops are empty at this point. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index a5cec22..6f57fd1 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -23,4 +23,38 @@ #define DRV_VERSION "v1.0" +#define HISI_SAS_MAX_PHYS 9 +#define HISI_SAS_MAX_ITCT_ENTRIES 4096 +#define HISI_SAS_MAX_DEVICES HISI_SAS_MAX_ITCT_ENTRIES +#define HISI_SAS_COMMAND_ENTRIES 8192 + +struct hisi_sas_phy { + struct asd_sas_phy sas_phy; +}; + +struct hisi_sas_port { + struct asd_sas_port sas_port; +}; + +struct hisi_sas_hw { +}; + +struct hisi_hba { + /* This must be the first element, used by SHOST_TO_SAS_HA */ + struct sas_ha_struct *p; + + struct platform_device *pdev; + u8 sas_addr[SAS_ADDR_SIZE]; + + int n_phy; + + /* SCSI/SAS glue */ + struct sas_ha_struct sha; + struct Scsi_Host *shost; + struct hisi_sas_phy phy[HISI_SAS_MAX_PHYS]; + struct hisi_sas_port port[HISI_SAS_MAX_PHYS]; + const struct hisi_sas_hw *hw; /* Low level hw interface */ +}; + +#define HISI_SAS_SGE_PAGE_CNT SCSI_MAX_SG_SEGMENTS #endif diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 7201363..4fd000e 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -14,9 +14,125 @@ static struct scsi_transport_template *hisi_sas_stt; +static struct scsi_host_template hisi_sas_sht = { + .module = THIS_MODULE, + .name = DRV_NAME, + .queuecommand = sas_queuecommand, + .target_alloc = sas_target_alloc, + .slave_configure = sas_slave_configure, + .change_queue_depth = sas_change_queue_depth, + .bios_param = sas_bios_param, + .can_queue = 1, + .this_id = -1, + .sg_tablesize = SG_ALL, + .max_sectors = SCSI_DEFAULT_MAX_SECTORS, + .use_clustering = ENABLE_CLUSTERING, + .eh_device_reset_handler = sas_eh_device_reset_handler, + .eh_bus_reset_handler = sas_eh_bus_reset_handler, + .target_destroy = sas_target_destroy, + .ioctl = sas_ioctl, +}; + static struct sas_domain_function_template hisi_sas_transport_ops = { }; +static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev, + const struct hisi_sas_hw *hw) +{ + struct Scsi_Host *shost; + struct hisi_hba *hisi_hba; + struct device *dev = &pdev->dev; + + shost = scsi_host_alloc(&hisi_sas_sht, sizeof(*hisi_hba)); + if (!shost) + goto err_out; + hisi_hba = shost_priv(shost); + + hisi_hba->hw = hw; + hisi_hba->pdev = pdev; + hisi_hba->shost = shost; + SHOST_TO_SAS_HA(shost) = &hisi_hba->sha; + + return shost; +err_out: + dev_err(dev, "shost alloc failed\n"); + return NULL; +} + +int hisi_sas_probe(struct platform_device *pdev, + const struct hisi_sas_hw *hw) +{ + struct Scsi_Host *shost; + struct hisi_hba *hisi_hba; + struct device *dev = &pdev->dev; + struct asd_sas_phy **arr_phy; + struct asd_sas_port **arr_port; + struct sas_ha_struct *sha; + int rc, phy_nr, port_nr, i; + + shost = hisi_sas_shost_alloc(pdev, hw); + if (!shost) { + rc = -ENOMEM; + goto err_out_ha; + } + + sha = SHOST_TO_SAS_HA(shost); + hisi_hba = shost_priv(shost); + platform_set_drvdata(pdev, sha); + hisi_hba->n_phy = HISI_SAS_MAX_PHYS; + phy_nr = port_nr = hisi_hba->n_phy; + + arr_phy = devm_kcalloc(dev, phy_nr, sizeof(void *), GFP_KERNEL); + arr_port = devm_kcalloc(dev, port_nr, sizeof(void *), GFP_KERNEL); + if (!arr_phy || !arr_port) + return -ENOMEM; + + sha->sas_phy = arr_phy; + sha->sas_port = arr_port; + sha->core.shost = shost; + sha->lldd_ha = hisi_hba; + + shost->transportt = hisi_sas_stt; + shost->max_id = HISI_SAS_MAX_DEVICES; + shost->max_lun = ~0; + shost->max_channel = 1; + shost->max_cmd_len = 16; + shost->sg_tablesize = min_t(u16, SG_ALL, HISI_SAS_SGE_PAGE_CNT); + shost->can_queue = HISI_SAS_COMMAND_ENTRIES; + shost->cmd_per_lun = HISI_SAS_COMMAND_ENTRIES; + + sha->sas_ha_name = DRV_NAME; + sha->dev = &hisi_hba->pdev->dev; + sha->lldd_module = THIS_MODULE; + sha->sas_addr = &hisi_hba->sas_addr[0]; + sha->num_phys = hisi_hba->n_phy; + sha->core.shost = hisi_hba->shost; + + for (i = 0; i < hisi_hba->n_phy; i++) { + sha->sas_phy[i] = &hisi_hba->phy[i].sas_phy; + sha->sas_port[i] = &hisi_hba->port[i].sas_port; + } + + rc = scsi_add_host(shost, &pdev->dev); + if (rc) + goto err_out_ha; + + rc = sas_register_ha(sha); + if (rc) + goto err_out_register_ha; + + scsi_scan_host(shost); + + return 0; + +err_out_register_ha: + scsi_remove_host(shost); +err_out_ha: + kfree(shost); + return rc; +} +EXPORT_SYMBOL_GPL(hisi_sas_probe); + static __init int hisi_sas_init(void) { pr_info("hisi_sas: driver version %s\n", DRV_VERSION); -- cgit v0.10.2 From e26b2f405a6a65c0ce0ea168aef7d4607ec7ad80 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:32 +0800 Subject: hisi_sas: Scan device tree Scan the device tree for all properties. Also do this: - do ioremap for SAS registers - allocate memory for interrupt names Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 6f57fd1..87f4b61 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -28,6 +28,8 @@ #define HISI_SAS_MAX_DEVICES HISI_SAS_MAX_ITCT_ENTRIES #define HISI_SAS_COMMAND_ENTRIES 8192 +#define HISI_SAS_NAME_LEN 32 + struct hisi_sas_phy { struct asd_sas_phy sas_phy; }; @@ -44,6 +46,11 @@ struct hisi_hba { struct sas_ha_struct *p; struct platform_device *pdev; + void __iomem *regs; + struct regmap *ctrl; + u32 ctrl_reset_reg; + u32 ctrl_reset_sts_reg; + u32 ctrl_clock_ena_reg; u8 sas_addr[SAS_ADDR_SIZE]; int n_phy; @@ -53,6 +60,9 @@ struct hisi_hba { struct Scsi_Host *shost; struct hisi_sas_phy phy[HISI_SAS_MAX_PHYS]; struct hisi_sas_port port[HISI_SAS_MAX_PHYS]; + + int queue_count; + char *int_names; const struct hisi_sas_hw *hw; /* Low level hw interface */ }; diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 4fd000e..4fc5a6c 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -39,9 +39,13 @@ static struct sas_domain_function_template hisi_sas_transport_ops = { static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev, const struct hisi_sas_hw *hw) { + struct resource *res; struct Scsi_Host *shost; struct hisi_hba *hisi_hba; struct device *dev = &pdev->dev; + struct device_node *np = pdev->dev.of_node; + struct property *sas_addr_prop; + int num; shost = scsi_host_alloc(&hisi_sas_sht, sizeof(*hisi_hba)); if (!shost) @@ -53,6 +57,46 @@ static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev, hisi_hba->shost = shost; SHOST_TO_SAS_HA(shost) = &hisi_hba->sha; + sas_addr_prop = of_find_property(np, "sas-addr", NULL); + if (!sas_addr_prop || (sas_addr_prop->length != SAS_ADDR_SIZE)) + goto err_out; + memcpy(hisi_hba->sas_addr, sas_addr_prop->value, SAS_ADDR_SIZE); + + if (of_property_read_u32(np, "ctrl-reset-reg", + &hisi_hba->ctrl_reset_reg)) + goto err_out; + + if (of_property_read_u32(np, "ctrl-reset-sts-reg", + &hisi_hba->ctrl_reset_sts_reg)) + goto err_out; + + if (of_property_read_u32(np, "ctrl-clock-ena-reg", + &hisi_hba->ctrl_clock_ena_reg)) + goto err_out; + + if (of_property_read_u32(np, "phy-count", &hisi_hba->n_phy)) + goto err_out; + + if (of_property_read_u32(np, "queue-count", &hisi_hba->queue_count)) + goto err_out; + + num = of_irq_count(np); + hisi_hba->int_names = devm_kcalloc(dev, num, + HISI_SAS_NAME_LEN, + GFP_KERNEL); + if (!hisi_hba->int_names) + goto err_out; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + hisi_hba->regs = devm_ioremap_resource(dev, res); + if (IS_ERR(hisi_hba->regs)) + goto err_out; + + hisi_hba->ctrl = syscon_regmap_lookup_by_phandle( + np, "hisilicon,sas-syscon"); + if (IS_ERR(hisi_hba->ctrl)) + goto err_out; + return shost; err_out: dev_err(dev, "shost alloc failed\n"); @@ -79,7 +123,6 @@ int hisi_sas_probe(struct platform_device *pdev, sha = SHOST_TO_SAS_HA(shost); hisi_hba = shost_priv(shost); platform_set_drvdata(pdev, sha); - hisi_hba->n_phy = HISI_SAS_MAX_PHYS; phy_nr = port_nr = hisi_hba->n_phy; arr_phy = devm_kcalloc(dev, phy_nr, sizeof(void *), GFP_KERNEL); -- cgit v0.10.2 From c799d6bd8fe4a82333fd11f8699f621e10af2f4b Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:33 +0800 Subject: hisi_sas: Add HW DMA structures Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 87f4b61..19d40b7 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -66,5 +66,136 @@ struct hisi_hba { const struct hisi_sas_hw *hw; /* Low level hw interface */ }; +/* Generic HW DMA host memory structures */ +/* Delivery queue header */ +struct hisi_sas_cmd_hdr { + /* dw0 */ + __le32 dw0; + + /* dw1 */ + __le32 dw1; + + /* dw2 */ + __le32 dw2; + + /* dw3 */ + __le32 transfer_tags; + + /* dw4 */ + __le32 data_transfer_len; + + /* dw5 */ + __le32 first_burst_num; + + /* dw6 */ + __le32 sg_len; + + /* dw7 */ + __le32 dw7; + + /* dw8-9 */ + __le64 cmd_table_addr; + + /* dw10-11 */ + __le64 sts_buffer_addr; + + /* dw12-13 */ + __le64 prd_table_addr; + + /* dw14-15 */ + __le64 dif_prd_table_addr; +}; + +struct hisi_sas_itct { + __le64 qw0; + __le64 sas_addr; + __le64 qw2; + __le64 qw3; + __le64 qw4; + __le64 qw_sata_ncq0_3; + __le64 qw_sata_ncq7_4; + __le64 qw_sata_ncq11_8; + __le64 qw_sata_ncq15_12; + __le64 qw_sata_ncq19_16; + __le64 qw_sata_ncq23_20; + __le64 qw_sata_ncq27_24; + __le64 qw_sata_ncq31_28; + __le64 qw_non_ncq_iptt; + __le64 qw_rsvd0; + __le64 qw_rsvd1; +}; + +struct hisi_sas_iost { + __le64 qw0; + __le64 qw1; + __le64 qw2; + __le64 qw3; +}; + +struct hisi_sas_err_record { + /* dw0 */ + __le32 dma_err_type; + + /* dw1 */ + __le32 trans_tx_fail_type; + + /* dw2 */ + __le32 trans_rx_fail_type; + + /* dw3 */ + u32 rsvd; +}; + +struct hisi_sas_initial_fis { + struct hisi_sas_err_record err_record; + struct dev_to_host_fis fis; + u32 rsvd[3]; +}; + +struct hisi_sas_breakpoint { + u8 data[128]; /*io128 byte*/ +}; + +struct hisi_sas_sge { + __le64 addr; + __le32 page_ctrl_0; + __le32 page_ctrl_1; + __le32 data_len; + __le32 data_off; +}; + +struct hisi_sas_command_table_smp { + u8 bytes[44]; +}; + +struct hisi_sas_command_table_stp { + struct host_to_dev_fis command_fis; + u8 dummy[12]; + u8 atapi_cdb[ATAPI_CDB_LEN]; +}; + #define HISI_SAS_SGE_PAGE_CNT SCSI_MAX_SG_SEGMENTS +struct hisi_sas_sge_page { + struct hisi_sas_sge sge[HISI_SAS_SGE_PAGE_CNT]; +}; + +struct hisi_sas_command_table_ssp { + struct ssp_frame_hdr hdr; + union { + struct { + struct ssp_command_iu task; + u32 prot[6]; + }; + struct ssp_tmf_iu ssp_task; + struct xfer_rdy_iu xfer_rdy; + struct ssp_response_iu ssp_res; + } u; +}; + +union hisi_sas_command_table { + struct hisi_sas_command_table_ssp ssp; + struct hisi_sas_command_table_smp smp; + struct hisi_sas_command_table_stp stp; +}; + #endif -- cgit v0.10.2 From 6be6de18891d5533451b2c00424f6a557dc901ec Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:34 +0800 Subject: hisi_sas: Allocate memories and create pools Allocate DMA and non-DMA memories for the controller. Also create DMA pools. These include: - Delivery queues - Completion queues - Command status buffer - Command table - ITCT (For device context) - Host slot info - IO status - Breakpoint - host slot indexing - SG data - FIS - interrupts names Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 19d40b7..6d1b7d8 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -24,10 +24,17 @@ #define DRV_VERSION "v1.0" #define HISI_SAS_MAX_PHYS 9 +#define HISI_SAS_MAX_QUEUES 32 +#define HISI_SAS_QUEUE_SLOTS 512 #define HISI_SAS_MAX_ITCT_ENTRIES 4096 #define HISI_SAS_MAX_DEVICES HISI_SAS_MAX_ITCT_ENTRIES #define HISI_SAS_COMMAND_ENTRIES 8192 +#define HISI_SAS_STATUS_BUF_SZ \ + (sizeof(struct hisi_sas_err_record) + 1024) +#define HISI_SAS_COMMAND_TABLE_SZ \ + (((sizeof(union hisi_sas_command_table)+3)/4)*4) + #define HISI_SAS_NAME_LEN 32 struct hisi_sas_phy { @@ -38,7 +45,11 @@ struct hisi_sas_port { struct asd_sas_port sas_port; }; +struct hisi_sas_slot { +}; + struct hisi_sas_hw { + int complete_hdr_size; }; struct hisi_hba { @@ -63,6 +74,25 @@ struct hisi_hba { int queue_count; char *int_names; + + struct dma_pool *sge_page_pool; + struct dma_pool *command_table_pool; + struct dma_pool *status_buffer_pool; + struct hisi_sas_cmd_hdr *cmd_hdr[HISI_SAS_MAX_QUEUES]; + dma_addr_t cmd_hdr_dma[HISI_SAS_MAX_QUEUES]; + void *complete_hdr[HISI_SAS_MAX_QUEUES]; + dma_addr_t complete_hdr_dma[HISI_SAS_MAX_QUEUES]; + struct hisi_sas_initial_fis *initial_fis; + dma_addr_t initial_fis_dma; + struct hisi_sas_itct *itct; + dma_addr_t itct_dma; + struct hisi_sas_iost *iost; + dma_addr_t iost_dma; + struct hisi_sas_breakpoint *breakpoint; + dma_addr_t breakpoint_dma; + struct hisi_sas_breakpoint *sata_breakpoint; + dma_addr_t sata_breakpoint_dma; + struct hisi_sas_slot *slot_info; const struct hisi_sas_hw *hw; /* Low level hw interface */ }; diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 4fc5a6c..97f5368 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -36,6 +36,97 @@ static struct scsi_host_template hisi_sas_sht = { static struct sas_domain_function_template hisi_sas_transport_ops = { }; +static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost) +{ + int i, s; + struct platform_device *pdev = hisi_hba->pdev; + struct device *dev = &pdev->dev; + + for (i = 0; i < hisi_hba->queue_count; i++) { + /* Delivery queue */ + s = sizeof(struct hisi_sas_cmd_hdr) * HISI_SAS_QUEUE_SLOTS; + hisi_hba->cmd_hdr[i] = dma_alloc_coherent(dev, s, + &hisi_hba->cmd_hdr_dma[i], GFP_KERNEL); + if (!hisi_hba->cmd_hdr[i]) + goto err_out; + memset(hisi_hba->cmd_hdr[i], 0, s); + + /* Completion queue */ + s = hisi_hba->hw->complete_hdr_size * HISI_SAS_QUEUE_SLOTS; + hisi_hba->complete_hdr[i] = dma_alloc_coherent(dev, s, + &hisi_hba->complete_hdr_dma[i], GFP_KERNEL); + if (!hisi_hba->complete_hdr[i]) + goto err_out; + memset(hisi_hba->complete_hdr[i], 0, s); + } + + s = HISI_SAS_STATUS_BUF_SZ; + hisi_hba->status_buffer_pool = dma_pool_create("status_buffer", + dev, s, 16, 0); + if (!hisi_hba->status_buffer_pool) + goto err_out; + + s = HISI_SAS_COMMAND_TABLE_SZ; + hisi_hba->command_table_pool = dma_pool_create("command_table", + dev, s, 16, 0); + if (!hisi_hba->command_table_pool) + goto err_out; + + s = HISI_SAS_MAX_ITCT_ENTRIES * sizeof(struct hisi_sas_itct); + hisi_hba->itct = dma_alloc_coherent(dev, s, &hisi_hba->itct_dma, + GFP_KERNEL); + if (!hisi_hba->itct) + goto err_out; + + memset(hisi_hba->itct, 0, s); + + hisi_hba->slot_info = devm_kcalloc(dev, HISI_SAS_COMMAND_ENTRIES, + sizeof(struct hisi_sas_slot), + GFP_KERNEL); + if (!hisi_hba->slot_info) + goto err_out; + + s = HISI_SAS_COMMAND_ENTRIES * sizeof(struct hisi_sas_iost); + hisi_hba->iost = dma_alloc_coherent(dev, s, &hisi_hba->iost_dma, + GFP_KERNEL); + if (!hisi_hba->iost) + goto err_out; + + memset(hisi_hba->iost, 0, s); + + s = HISI_SAS_COMMAND_ENTRIES * sizeof(struct hisi_sas_breakpoint); + hisi_hba->breakpoint = dma_alloc_coherent(dev, s, + &hisi_hba->breakpoint_dma, GFP_KERNEL); + if (!hisi_hba->breakpoint) + goto err_out; + + memset(hisi_hba->breakpoint, 0, s); + + hisi_hba->sge_page_pool = dma_pool_create("status_sge", dev, + sizeof(struct hisi_sas_sge_page), 16, 0); + if (!hisi_hba->sge_page_pool) + goto err_out; + + s = sizeof(struct hisi_sas_initial_fis) * HISI_SAS_MAX_PHYS; + hisi_hba->initial_fis = dma_alloc_coherent(dev, s, + &hisi_hba->initial_fis_dma, GFP_KERNEL); + if (!hisi_hba->initial_fis) + goto err_out; + memset(hisi_hba->initial_fis, 0, s); + + s = HISI_SAS_COMMAND_ENTRIES * sizeof(struct hisi_sas_breakpoint) * 2; + hisi_hba->sata_breakpoint = dma_alloc_coherent(dev, s, + &hisi_hba->sata_breakpoint_dma, GFP_KERNEL); + if (!hisi_hba->sata_breakpoint) + goto err_out; + memset(hisi_hba->sata_breakpoint, 0, s); + + return 0; +err_out: + return -ENOMEM; +} + + static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev, const struct hisi_sas_hw *hw) { @@ -97,6 +188,9 @@ static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev, if (IS_ERR(hisi_hba->ctrl)) goto err_out; + if (hisi_sas_alloc(hisi_hba, shost)) + goto err_out; + return shost; err_out: dev_err(dev, "shost alloc failed\n"); -- cgit v0.10.2 From 89d533223de0fe30e3b30900d1fc9c98020c2215 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:35 +0800 Subject: hisi_sas: Add hisi_sas_remove This patch also includes relevant memory/pool freeing and sas/scsi host removal. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 97f5368..b96a2ab 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -126,6 +126,59 @@ err_out: return -ENOMEM; } +static void hisi_sas_free(struct hisi_hba *hisi_hba) +{ + struct device *dev = &hisi_hba->pdev->dev; + int i, s; + + for (i = 0; i < hisi_hba->queue_count; i++) { + s = sizeof(struct hisi_sas_cmd_hdr) * HISI_SAS_QUEUE_SLOTS; + if (hisi_hba->cmd_hdr[i]) + dma_free_coherent(dev, s, + hisi_hba->cmd_hdr[i], + hisi_hba->cmd_hdr_dma[i]); + + s = hisi_hba->hw->complete_hdr_size * HISI_SAS_QUEUE_SLOTS; + if (hisi_hba->complete_hdr[i]) + dma_free_coherent(dev, s, + hisi_hba->complete_hdr[i], + hisi_hba->complete_hdr_dma[i]); + } + + dma_pool_destroy(hisi_hba->status_buffer_pool); + dma_pool_destroy(hisi_hba->command_table_pool); + dma_pool_destroy(hisi_hba->sge_page_pool); + + s = HISI_SAS_MAX_ITCT_ENTRIES * sizeof(struct hisi_sas_itct); + if (hisi_hba->itct) + dma_free_coherent(dev, s, + hisi_hba->itct, hisi_hba->itct_dma); + + s = HISI_SAS_COMMAND_ENTRIES * sizeof(struct hisi_sas_iost); + if (hisi_hba->iost) + dma_free_coherent(dev, s, + hisi_hba->iost, hisi_hba->iost_dma); + + s = HISI_SAS_COMMAND_ENTRIES * sizeof(struct hisi_sas_breakpoint); + if (hisi_hba->breakpoint) + dma_free_coherent(dev, s, + hisi_hba->breakpoint, + hisi_hba->breakpoint_dma); + + + s = sizeof(struct hisi_sas_initial_fis) * HISI_SAS_MAX_PHYS; + if (hisi_hba->initial_fis) + dma_free_coherent(dev, s, + hisi_hba->initial_fis, + hisi_hba->initial_fis_dma); + + s = HISI_SAS_COMMAND_ENTRIES * sizeof(struct hisi_sas_breakpoint) * 2; + if (hisi_hba->sata_breakpoint) + dma_free_coherent(dev, s, + hisi_hba->sata_breakpoint, + hisi_hba->sata_breakpoint_dma); + +} static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev, const struct hisi_sas_hw *hw) @@ -188,8 +241,10 @@ static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev, if (IS_ERR(hisi_hba->ctrl)) goto err_out; - if (hisi_sas_alloc(hisi_hba, shost)) + if (hisi_sas_alloc(hisi_hba, shost)) { + hisi_sas_free(hisi_hba); goto err_out; + } return shost; err_out: @@ -270,6 +325,20 @@ err_out_ha: } EXPORT_SYMBOL_GPL(hisi_sas_probe); +int hisi_sas_remove(struct platform_device *pdev) +{ + struct sas_ha_struct *sha = platform_get_drvdata(pdev); + struct hisi_hba *hisi_hba = sha->lldd_ha; + + scsi_remove_host(sha->core.shost); + sas_unregister_ha(sha); + sas_remove_host(sha->core.shost); + + hisi_sas_free(hisi_hba); + return 0; +} +EXPORT_SYMBOL_GPL(hisi_sas_remove); + static __init int hisi_sas_init(void) { pr_info("hisi_sas: driver version %s\n", DRV_VERSION); -- cgit v0.10.2 From 257efd1f69dd1789b1db0f12425e31d6c05118db Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:36 +0800 Subject: hisi_sas: Add slot init code Add functionality to init slot indexing. Slot indexing is for the host to track which slots (or tags) are free and which are used. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 6d1b7d8..2cd6771 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -66,6 +66,10 @@ struct hisi_hba { int n_phy; + + int slot_index_count; + unsigned long *slot_index_tags; + /* SCSI/SAS glue */ struct sas_ha_struct sha; struct Scsi_Host *shost; diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index b96a2ab..d7e5b66 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -12,6 +12,21 @@ #include "hisi_sas.h" #define DRV_NAME "hisi_sas" +static void hisi_sas_slot_index_clear(struct hisi_hba *hisi_hba, int slot_idx) +{ + void *bitmap = hisi_hba->slot_index_tags; + + clear_bit(slot_idx, bitmap); +} + +static void hisi_sas_slot_index_init(struct hisi_hba *hisi_hba) +{ + int i; + + for (i = 0; i < hisi_hba->slot_index_count; ++i) + hisi_sas_slot_index_clear(hisi_hba, i); +} + static struct scsi_transport_template *hisi_sas_stt; static struct scsi_host_template hisi_sas_sht = { @@ -102,6 +117,12 @@ static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost) memset(hisi_hba->breakpoint, 0, s); + hisi_hba->slot_index_count = HISI_SAS_COMMAND_ENTRIES; + s = hisi_hba->slot_index_count / sizeof(unsigned long); + hisi_hba->slot_index_tags = devm_kzalloc(dev, s, GFP_KERNEL); + if (!hisi_hba->slot_index_tags) + goto err_out; + hisi_hba->sge_page_pool = dma_pool_create("status_sge", dev, sizeof(struct hisi_sas_sge_page), 16, 0); if (!hisi_hba->sge_page_pool) @@ -121,6 +142,8 @@ static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost) goto err_out; memset(hisi_hba->sata_breakpoint, 0, s); + hisi_sas_slot_index_init(hisi_hba); + return 0; err_out: return -ENOMEM; -- cgit v0.10.2 From 9101a0792d2ad49a0bf293d346f391c198d72843 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:37 +0800 Subject: hisi_sas: Add cq structure initialization Each completion queue has a structure. This is mainly for passing to irq handler so we know which queue the irq occured on. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 2cd6771..315fe46 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -45,6 +45,11 @@ struct hisi_sas_port { struct asd_sas_port sas_port; }; +struct hisi_sas_cq { + struct hisi_hba *hisi_hba; + int id; +}; + struct hisi_sas_slot { }; @@ -73,6 +78,8 @@ struct hisi_hba { /* SCSI/SAS glue */ struct sas_ha_struct sha; struct Scsi_Host *shost; + + struct hisi_sas_cq cq[HISI_SAS_MAX_QUEUES]; struct hisi_sas_phy phy[HISI_SAS_MAX_PHYS]; struct hisi_sas_port port[HISI_SAS_MAX_PHYS]; diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index d7e5b66..d10bf24 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -58,6 +58,12 @@ static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost) struct device *dev = &pdev->dev; for (i = 0; i < hisi_hba->queue_count; i++) { + struct hisi_sas_cq *cq = &hisi_hba->cq[i]; + + /* Completion queue structure */ + cq->id = i; + cq->hisi_hba = hisi_hba; + /* Delivery queue */ s = sizeof(struct hisi_sas_cmd_hdr) * HISI_SAS_QUEUE_SLOTS; hisi_hba->cmd_hdr[i] = dma_alloc_coherent(dev, s, -- cgit v0.10.2 From 5d74242e37feb5d06aecb3118d642ff621d08b75 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:38 +0800 Subject: hisi_sas: Add phy SAS ADDR initialization The SAS address for the HBA comes from the device tree. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 315fe46..c50384f 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -39,6 +39,7 @@ struct hisi_sas_phy { struct asd_sas_phy sas_phy; + u64 dev_sas_addr; }; struct hisi_sas_port { diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index d10bf24..8cd1b55 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -281,6 +281,16 @@ err_out: return NULL; } +static void hisi_sas_init_add(struct hisi_hba *hisi_hba) +{ + int i; + + for (i = 0; i < hisi_hba->n_phy; i++) + memcpy(&hisi_hba->phy[i].dev_sas_addr, + hisi_hba->sas_addr, + SAS_ADDR_SIZE); +} + int hisi_sas_probe(struct platform_device *pdev, const struct hisi_sas_hw *hw) { @@ -334,6 +344,8 @@ int hisi_sas_probe(struct platform_device *pdev, sha->sas_port[i] = &hisi_hba->port[i].sas_port; } + hisi_sas_init_add(hisi_hba); + rc = scsi_add_host(shost, &pdev->dev); if (rc) goto err_out_ha; -- cgit v0.10.2 From 50cb916f4361e9202866d388eaddbe1d3f0ee0f7 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:39 +0800 Subject: hisi_sas: Set dev DMA mask Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 8cd1b55..d7d9516 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -311,6 +311,14 @@ int hisi_sas_probe(struct platform_device *pdev, sha = SHOST_TO_SAS_HA(shost); hisi_hba = shost_priv(shost); platform_set_drvdata(pdev, sha); + + if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)) && + dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32))) { + dev_err(dev, "No usable DMA addressing method\n"); + rc = -EIO; + goto err_out_ha; + } + phy_nr = port_nr = hisi_hba->n_phy; arr_phy = devm_kcalloc(dev, phy_nr, sizeof(void *), GFP_KERNEL); -- cgit v0.10.2 From 7e9080e1c68dba3324ba307395b8dcb80bec308c Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:40 +0800 Subject: hisi_sas: Add hisi_hba workqueue Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index c50384f..62bc6f3 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -72,6 +72,7 @@ struct hisi_hba { int n_phy; + struct workqueue_struct *wq; int slot_index_count; unsigned long *slot_index_tags; diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index d7d9516..7f32c6b 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -150,6 +150,12 @@ static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost) hisi_sas_slot_index_init(hisi_hba); + hisi_hba->wq = create_singlethread_workqueue(dev_name(dev)); + if (!hisi_hba->wq) { + dev_err(dev, "sas_alloc: failed to create workqueue\n"); + goto err_out; + } + return 0; err_out: return -ENOMEM; @@ -207,6 +213,8 @@ static void hisi_sas_free(struct hisi_hba *hisi_hba) hisi_hba->sata_breakpoint, hisi_hba->sata_breakpoint_dma); + if (hisi_hba->wq) + destroy_workqueue(hisi_hba->wq); } static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev, -- cgit v0.10.2 From af740dbe659f1eee07a18801f89d9b2e2f9b5329 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:41 +0800 Subject: hisi_sas: Add hisi sas device type Include initialisation. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 62bc6f3..5ac5a82 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -37,6 +37,11 @@ #define HISI_SAS_NAME_LEN 32 + +enum dev_status { + HISI_SAS_DEV_NORMAL, + HISI_SAS_DEV_EH, +}; struct hisi_sas_phy { struct asd_sas_phy sas_phy; u64 dev_sas_addr; @@ -51,6 +56,12 @@ struct hisi_sas_cq { int id; }; +struct hisi_sas_device { + enum sas_device_type dev_type; + u64 device_id; + u8 dev_status; +}; + struct hisi_sas_slot { }; @@ -89,6 +100,7 @@ struct hisi_hba { char *int_names; struct dma_pool *sge_page_pool; + struct hisi_sas_device devices[HISI_SAS_MAX_DEVICES]; struct dma_pool *command_table_pool; struct dma_pool *status_buffer_pool; struct hisi_sas_cmd_hdr *cmd_hdr[HISI_SAS_MAX_QUEUES]; diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 7f32c6b..21111d4 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -57,6 +57,12 @@ static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost) struct platform_device *pdev = hisi_hba->pdev; struct device *dev = &pdev->dev; + for (i = 0; i < HISI_SAS_MAX_DEVICES; i++) { + hisi_hba->devices[i].dev_type = SAS_PHY_UNUSED; + hisi_hba->devices[i].device_id = i; + hisi_hba->devices[i].dev_status = HISI_SAS_DEV_NORMAL; + } + for (i = 0; i < hisi_hba->queue_count; i++) { struct hisi_sas_cq *cq = &hisi_hba->cq[i]; -- cgit v0.10.2 From 976867e6ed0384b9c0598d692e3858d7c1ec349f Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:42 +0800 Subject: hisi_sas: Add phy and port init Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 5ac5a82..3a2400e 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -43,12 +43,27 @@ enum dev_status { HISI_SAS_DEV_EH, }; struct hisi_sas_phy { + struct hisi_hba *hisi_hba; + struct hisi_sas_port *port; struct asd_sas_phy sas_phy; + struct sas_identify identify; + struct timer_list timer; + u64 port_id; /* from hw */ u64 dev_sas_addr; + u64 phy_type; + u64 frame_rcvd_size; + u8 frame_rcvd[32]; + u8 phy_attached; + u8 reserved[3]; + enum sas_linkrate minimum_linkrate; + enum sas_linkrate maximum_linkrate; }; struct hisi_sas_port { struct asd_sas_port sas_port; + u8 port_attached; + u8 id; /* from hw */ + struct list_head list; }; struct hisi_sas_cq { diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 21111d4..bc41ce4 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -27,6 +27,30 @@ static void hisi_sas_slot_index_init(struct hisi_hba *hisi_hba) hisi_sas_slot_index_clear(hisi_hba, i); } + +static void hisi_sas_phy_init(struct hisi_hba *hisi_hba, int phy_no) +{ + struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; + struct asd_sas_phy *sas_phy = &phy->sas_phy; + + phy->hisi_hba = hisi_hba; + phy->port = NULL; + init_timer(&phy->timer); + sas_phy->enabled = (phy_no < hisi_hba->n_phy) ? 1 : 0; + sas_phy->class = SAS; + sas_phy->iproto = SAS_PROTOCOL_ALL; + sas_phy->tproto = 0; + sas_phy->type = PHY_TYPE_PHYSICAL; + sas_phy->role = PHY_ROLE_INITIATOR; + sas_phy->oob_mode = OOB_NOT_CONNECTED; + sas_phy->linkrate = SAS_LINK_RATE_UNKNOWN; + sas_phy->id = phy_no; + sas_phy->sas_addr = &hisi_hba->sas_addr[0]; + sas_phy->frame_rcvd = &phy->frame_rcvd[0]; + sas_phy->ha = (struct sas_ha_struct *)hisi_hba->shost->hostdata; + sas_phy->lldd_phy = phy; +} + static struct scsi_transport_template *hisi_sas_stt; static struct scsi_host_template hisi_sas_sht = { @@ -57,6 +81,13 @@ static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost) struct platform_device *pdev = hisi_hba->pdev; struct device *dev = &pdev->dev; + for (i = 0; i < hisi_hba->n_phy; i++) { + hisi_sas_phy_init(hisi_hba, i); + hisi_hba->port[i].port_attached = 0; + hisi_hba->port[i].id = -1; + INIT_LIST_HEAD(&hisi_hba->port[i].list); + } + for (i = 0; i < HISI_SAS_MAX_DEVICES; i++) { hisi_hba->devices[i].dev_type = SAS_PHY_UNUSED; hisi_hba->devices[i].device_id = i; -- cgit v0.10.2 From fa42d80dc3c5196b0359fab9a212cc4ede257502 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:43 +0800 Subject: hisi_sas: Add timer and spinlock init Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 3a2400e..3749c46 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -97,7 +97,9 @@ struct hisi_hba { u8 sas_addr[SAS_ADDR_SIZE]; int n_phy; + spinlock_t lock; + struct timer_list timer; struct workqueue_struct *wq; int slot_index_count; diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index bc41ce4..06b863c 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -81,6 +81,7 @@ static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost) struct platform_device *pdev = hisi_hba->pdev; struct device *dev = &pdev->dev; + spin_lock_init(&hisi_hba->lock); for (i = 0; i < hisi_hba->n_phy; i++) { hisi_sas_phy_init(hisi_hba, i); hisi_hba->port[i].port_attached = 0; @@ -275,6 +276,8 @@ static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev, hisi_hba->shost = shost; SHOST_TO_SAS_HA(shost) = &hisi_hba->sha; + init_timer(&hisi_hba->timer); + sas_addr_prop = of_find_property(np, "sas-addr", NULL); if (!sas_addr_prop || (sas_addr_prop->length != SAS_ADDR_SIZE)) goto err_out; -- cgit v0.10.2 From 9fb10b54861f481de4c484a67a60d981e54fe9a1 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:44 +0800 Subject: hisi_sas: Add v1 hw module init Add module init code for v1 hw. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/hisi_sas/Makefile b/drivers/scsi/hisi_sas/Makefile index d86b05e..3e70eae 100644 --- a/drivers/scsi/hisi_sas/Makefile +++ b/drivers/scsi/hisi_sas/Makefile @@ -1 +1,2 @@ obj-$(CONFIG_SCSI_HISI_SAS) += hisi_sas_main.o +obj-$(CONFIG_SCSI_HISI_SAS) += hisi_sas_v1_hw.o diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 3749c46..72533ca 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -269,5 +269,8 @@ union hisi_sas_command_table { struct hisi_sas_command_table_smp smp; struct hisi_sas_command_table_stp stp; }; +extern int hisi_sas_probe(struct platform_device *pdev, + const struct hisi_sas_hw *ops); +extern int hisi_sas_remove(struct platform_device *pdev); #endif diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c new file mode 100644 index 0000000..e9aebce --- /dev/null +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2015 Linaro Ltd. + * Copyright (c) 2015 Hisilicon Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ + +#include "hisi_sas.h" +#define DRV_NAME "hisi_sas_v1_hw" + + +struct hisi_sas_complete_v1_hdr { + __le32 data; +}; +static const struct hisi_sas_hw hisi_sas_v1_hw = { + .complete_hdr_size = sizeof(struct hisi_sas_complete_v1_hdr), +}; + +static int hisi_sas_v1_probe(struct platform_device *pdev) +{ + return hisi_sas_probe(pdev, &hisi_sas_v1_hw); +} + +static int hisi_sas_v1_remove(struct platform_device *pdev) +{ + return hisi_sas_remove(pdev); +} + +static const struct of_device_id sas_v1_of_match[] = { + { .compatible = "hisilicon,hip05-sas-v1",}, + {}, +}; +MODULE_DEVICE_TABLE(of, sas_v1_of_match); + +static struct platform_driver hisi_sas_v1_driver = { + .probe = hisi_sas_v1_probe, + .remove = hisi_sas_v1_remove, + .driver = { + .name = DRV_NAME, + .of_match_table = sas_v1_of_match, + }, +}; + +module_platform_driver(hisi_sas_v1_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("John Garry "); +MODULE_DESCRIPTION("HISILICON SAS controller v1 hw driver"); +MODULE_ALIAS("platform:" DRV_NAME); -- cgit v0.10.2 From 50af155b6cabd398bc2dca5aa32ddb879bb9331e Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:45 +0800 Subject: hisi_sas: Add v1 hardware register definitions Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index e9aebce..9fe89bb 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -12,10 +12,399 @@ #include "hisi_sas.h" #define DRV_NAME "hisi_sas_v1_hw" +/* global registers need init*/ +#define DLVRY_QUEUE_ENABLE 0x0 +#define IOST_BASE_ADDR_LO 0x8 +#define IOST_BASE_ADDR_HI 0xc +#define ITCT_BASE_ADDR_LO 0x10 +#define ITCT_BASE_ADDR_HI 0x14 +#define BROKEN_MSG_ADDR_LO 0x18 +#define BROKEN_MSG_ADDR_HI 0x1c +#define PHY_CONTEXT 0x20 +#define PHY_STATE 0x24 +#define PHY_PORT_NUM_MA 0x28 +#define PORT_STATE 0x2c +#define PHY_CONN_RATE 0x30 +#define HGC_TRANS_TASK_CNT_LIMIT 0x38 +#define AXI_AHB_CLK_CFG 0x3c +#define HGC_SAS_TXFAIL_RETRY_CTRL 0x84 +#define HGC_GET_ITV_TIME 0x90 +#define DEVICE_MSG_WORK_MODE 0x94 +#define I_T_NEXUS_LOSS_TIME 0xa0 +#define BUS_INACTIVE_LIMIT_TIME 0xa8 +#define REJECT_TO_OPEN_LIMIT_TIME 0xac +#define CFG_AGING_TIME 0xbc +#define CFG_AGING_TIME_ITCT_REL_OFF 0 +#define CFG_AGING_TIME_ITCT_REL_MSK (0x1 << CFG_AGING_TIME_ITCT_REL_OFF) +#define HGC_DFX_CFG2 0xc0 +#define FIS_LIST_BADDR_L 0xc4 +#define CFG_1US_TIMER_TRSH 0xcc +#define CFG_SAS_CONFIG 0xd4 +#define HGC_IOST_ECC_ADDR 0x140 +#define HGC_IOST_ECC_ADDR_BAD_OFF 16 +#define HGC_IOST_ECC_ADDR_BAD_MSK (0x3ff << HGC_IOST_ECC_ADDR_BAD_OFF) +#define HGC_DQ_ECC_ADDR 0x144 +#define HGC_DQ_ECC_ADDR_BAD_OFF 16 +#define HGC_DQ_ECC_ADDR_BAD_MSK (0xfff << HGC_DQ_ECC_ADDR_BAD_OFF) +#define HGC_INVLD_DQE_INFO 0x148 +#define HGC_INVLD_DQE_INFO_DQ_OFF 0 +#define HGC_INVLD_DQE_INFO_DQ_MSK (0xffff << HGC_INVLD_DQE_INFO_DQ_OFF) +#define HGC_INVLD_DQE_INFO_TYPE_OFF 16 +#define HGC_INVLD_DQE_INFO_TYPE_MSK (0x1 << HGC_INVLD_DQE_INFO_TYPE_OFF) +#define HGC_INVLD_DQE_INFO_FORCE_OFF 17 +#define HGC_INVLD_DQE_INFO_FORCE_MSK (0x1 << HGC_INVLD_DQE_INFO_FORCE_OFF) +#define HGC_INVLD_DQE_INFO_PHY_OFF 18 +#define HGC_INVLD_DQE_INFO_PHY_MSK (0x1 << HGC_INVLD_DQE_INFO_PHY_OFF) +#define HGC_INVLD_DQE_INFO_ABORT_OFF 19 +#define HGC_INVLD_DQE_INFO_ABORT_MSK (0x1 << HGC_INVLD_DQE_INFO_ABORT_OFF) +#define HGC_INVLD_DQE_INFO_IPTT_OF_OFF 20 +#define HGC_INVLD_DQE_INFO_IPTT_OF_MSK (0x1 << HGC_INVLD_DQE_INFO_IPTT_OF_OFF) +#define HGC_INVLD_DQE_INFO_SSP_ERR_OFF 21 +#define HGC_INVLD_DQE_INFO_SSP_ERR_MSK (0x1 << HGC_INVLD_DQE_INFO_SSP_ERR_OFF) +#define HGC_INVLD_DQE_INFO_OFL_OFF 22 +#define HGC_INVLD_DQE_INFO_OFL_MSK (0x1 << HGC_INVLD_DQE_INFO_OFL_OFF) +#define HGC_ITCT_ECC_ADDR 0x150 +#define HGC_ITCT_ECC_ADDR_BAD_OFF 16 +#define HGC_ITCT_ECC_ADDR_BAD_MSK (0x3ff << HGC_ITCT_ECC_ADDR_BAD_OFF) +#define HGC_AXI_FIFO_ERR_INFO 0x154 +#define INT_COAL_EN 0x1bc +#define OQ_INT_COAL_TIME 0x1c0 +#define OQ_INT_COAL_CNT 0x1c4 +#define ENT_INT_COAL_TIME 0x1c8 +#define ENT_INT_COAL_CNT 0x1cc +#define OQ_INT_SRC 0x1d0 +#define OQ_INT_SRC_MSK 0x1d4 +#define ENT_INT_SRC1 0x1d8 +#define ENT_INT_SRC2 0x1dc +#define ENT_INT_SRC2_DQ_CFG_ERR_OFF 25 +#define ENT_INT_SRC2_DQ_CFG_ERR_MSK (0x1 << ENT_INT_SRC2_DQ_CFG_ERR_OFF) +#define ENT_INT_SRC2_CQ_CFG_ERR_OFF 27 +#define ENT_INT_SRC2_CQ_CFG_ERR_MSK (0x1 << ENT_INT_SRC2_CQ_CFG_ERR_OFF) +#define ENT_INT_SRC2_AXI_WRONG_INT_OFF 28 +#define ENT_INT_SRC2_AXI_WRONG_INT_MSK (0x1 << ENT_INT_SRC2_AXI_WRONG_INT_OFF) +#define ENT_INT_SRC2_AXI_OVERLF_INT_OFF 29 +#define ENT_INT_SRC2_AXI_OVERLF_INT_MSK (0x1 << ENT_INT_SRC2_AXI_OVERLF_INT_OFF) +#define ENT_INT_SRC_MSK1 0x1e0 +#define ENT_INT_SRC_MSK2 0x1e4 +#define SAS_ECC_INTR 0x1e8 +#define SAS_ECC_INTR_DQ_ECC1B_OFF 0 +#define SAS_ECC_INTR_DQ_ECC1B_MSK (0x1 << SAS_ECC_INTR_DQ_ECC1B_OFF) +#define SAS_ECC_INTR_DQ_ECCBAD_OFF 1 +#define SAS_ECC_INTR_DQ_ECCBAD_MSK (0x1 << SAS_ECC_INTR_DQ_ECCBAD_OFF) +#define SAS_ECC_INTR_IOST_ECC1B_OFF 2 +#define SAS_ECC_INTR_IOST_ECC1B_MSK (0x1 << SAS_ECC_INTR_IOST_ECC1B_OFF) +#define SAS_ECC_INTR_IOST_ECCBAD_OFF 3 +#define SAS_ECC_INTR_IOST_ECCBAD_MSK (0x1 << SAS_ECC_INTR_IOST_ECCBAD_OFF) +#define SAS_ECC_INTR_ITCT_ECC1B_OFF 4 +#define SAS_ECC_INTR_ITCT_ECC1B_MSK (0x1 << SAS_ECC_INTR_ITCT_ECC1B_OFF) +#define SAS_ECC_INTR_ITCT_ECCBAD_OFF 5 +#define SAS_ECC_INTR_ITCT_ECCBAD_MSK (0x1 << SAS_ECC_INTR_ITCT_ECCBAD_OFF) +#define SAS_ECC_INTR_MSK 0x1ec +#define HGC_ERR_STAT_EN 0x238 +#define DLVRY_Q_0_BASE_ADDR_LO 0x260 +#define DLVRY_Q_0_BASE_ADDR_HI 0x264 +#define DLVRY_Q_0_DEPTH 0x268 +#define DLVRY_Q_0_WR_PTR 0x26c +#define DLVRY_Q_0_RD_PTR 0x270 +#define COMPL_Q_0_BASE_ADDR_LO 0x4e0 +#define COMPL_Q_0_BASE_ADDR_HI 0x4e4 +#define COMPL_Q_0_DEPTH 0x4e8 +#define COMPL_Q_0_WR_PTR 0x4ec +#define COMPL_Q_0_RD_PTR 0x4f0 +#define HGC_ECC_ERR 0x7d0 + +/* phy registers need init */ +#define PORT_BASE (0x800) + +#define PHY_CFG (PORT_BASE + 0x0) +#define PHY_CFG_ENA_OFF 0 +#define PHY_CFG_ENA_MSK (0x1 << PHY_CFG_ENA_OFF) +#define PHY_CFG_DC_OPT_OFF 2 +#define PHY_CFG_DC_OPT_MSK (0x1 << PHY_CFG_DC_OPT_OFF) +#define PROG_PHY_LINK_RATE (PORT_BASE + 0xc) +#define PROG_PHY_LINK_RATE_MAX_OFF 0 +#define PROG_PHY_LINK_RATE_MAX_MSK (0xf << PROG_PHY_LINK_RATE_MAX_OFF) +#define PROG_PHY_LINK_RATE_MIN_OFF 4 +#define PROG_PHY_LINK_RATE_MIN_MSK (0xf << PROG_PHY_LINK_RATE_MIN_OFF) +#define PROG_PHY_LINK_RATE_OOB_OFF 8 +#define PROG_PHY_LINK_RATE_OOB_MSK (0xf << PROG_PHY_LINK_RATE_OOB_OFF) +#define PHY_CTRL (PORT_BASE + 0x14) +#define PHY_CTRL_RESET_OFF 0 +#define PHY_CTRL_RESET_MSK (0x1 << PHY_CTRL_RESET_OFF) +#define PHY_RATE_NEGO (PORT_BASE + 0x30) +#define PHY_PCN (PORT_BASE + 0x44) +#define SL_TOUT_CFG (PORT_BASE + 0x8c) +#define SL_CONTROL (PORT_BASE + 0x94) +#define SL_CONTROL_NOTIFY_EN_OFF 0 +#define SL_CONTROL_NOTIFY_EN_MSK (0x1 << SL_CONTROL_NOTIFY_EN_OFF) +#define TX_ID_DWORD0 (PORT_BASE + 0x9c) +#define TX_ID_DWORD1 (PORT_BASE + 0xa0) +#define TX_ID_DWORD2 (PORT_BASE + 0xa4) +#define TX_ID_DWORD3 (PORT_BASE + 0xa8) +#define TX_ID_DWORD4 (PORT_BASE + 0xaC) +#define TX_ID_DWORD5 (PORT_BASE + 0xb0) +#define TX_ID_DWORD6 (PORT_BASE + 0xb4) +#define RX_IDAF_DWORD0 (PORT_BASE + 0xc4) +#define RX_IDAF_DWORD1 (PORT_BASE + 0xc8) +#define RX_IDAF_DWORD2 (PORT_BASE + 0xcc) +#define RX_IDAF_DWORD3 (PORT_BASE + 0xd0) +#define RX_IDAF_DWORD4 (PORT_BASE + 0xd4) +#define RX_IDAF_DWORD5 (PORT_BASE + 0xd8) +#define RX_IDAF_DWORD6 (PORT_BASE + 0xdc) +#define RXOP_CHECK_CFG_H (PORT_BASE + 0xfc) +#define DONE_RECEIVED_TIME (PORT_BASE + 0x12c) +#define CON_CFG_DRIVER (PORT_BASE + 0x130) +#define PHY_CONFIG2 (PORT_BASE + 0x1a8) +#define PHY_CONFIG2_FORCE_TXDEEMPH_OFF 3 +#define PHY_CONFIG2_FORCE_TXDEEMPH_MSK (0x1 << PHY_CONFIG2_FORCE_TXDEEMPH_OFF) +#define PHY_CONFIG2_TX_TRAIN_COMP_OFF 24 +#define PHY_CONFIG2_TX_TRAIN_COMP_MSK (0x1 << PHY_CONFIG2_TX_TRAIN_COMP_OFF) +#define CHL_INT0 (PORT_BASE + 0x1b0) +#define CHL_INT0_PHYCTRL_NOTRDY_OFF 0 +#define CHL_INT0_PHYCTRL_NOTRDY_MSK (0x1 << CHL_INT0_PHYCTRL_NOTRDY_OFF) +#define CHL_INT0_SN_FAIL_NGR_OFF 2 +#define CHL_INT0_SN_FAIL_NGR_MSK (0x1 << CHL_INT0_SN_FAIL_NGR_OFF) +#define CHL_INT0_DWS_LOST_OFF 4 +#define CHL_INT0_DWS_LOST_MSK (0x1 << CHL_INT0_DWS_LOST_OFF) +#define CHL_INT0_SL_IDAF_FAIL_OFF 10 +#define CHL_INT0_SL_IDAF_FAIL_MSK (0x1 << CHL_INT0_SL_IDAF_FAIL_OFF) +#define CHL_INT0_ID_TIMEOUT_OFF 11 +#define CHL_INT0_ID_TIMEOUT_MSK (0x1 << CHL_INT0_ID_TIMEOUT_OFF) +#define CHL_INT0_SL_OPAF_FAIL_OFF 12 +#define CHL_INT0_SL_OPAF_FAIL_MSK (0x1 << CHL_INT0_SL_OPAF_FAIL_OFF) +#define CHL_INT0_SL_PS_FAIL_OFF 21 +#define CHL_INT0_SL_PS_FAIL_MSK (0x1 << CHL_INT0_SL_PS_FAIL_OFF) +#define CHL_INT1 (PORT_BASE + 0x1b4) +#define CHL_INT2 (PORT_BASE + 0x1b8) +#define CHL_INT2_SL_RX_BC_ACK_OFF 2 +#define CHL_INT2_SL_RX_BC_ACK_MSK (0x1 << CHL_INT2_SL_RX_BC_ACK_OFF) +#define CHL_INT2_SL_PHY_ENA_OFF 6 +#define CHL_INT2_SL_PHY_ENA_MSK (0x1 << CHL_INT2_SL_PHY_ENA_OFF) +#define CHL_INT0_MSK (PORT_BASE + 0x1bc) +#define CHL_INT0_MSK_PHYCTRL_NOTRDY_OFF 0 +#define CHL_INT0_MSK_PHYCTRL_NOTRDY_MSK (0x1 << CHL_INT0_MSK_PHYCTRL_NOTRDY_OFF) +#define CHL_INT1_MSK (PORT_BASE + 0x1c0) +#define CHL_INT2_MSK (PORT_BASE + 0x1c4) +#define CHL_INT_COAL_EN (PORT_BASE + 0x1d0) +#define DMA_TX_STATUS (PORT_BASE + 0x2d0) +#define DMA_TX_STATUS_BUSY_OFF 0 +#define DMA_TX_STATUS_BUSY_MSK (0x1 << DMA_TX_STATUS_BUSY_OFF) +#define DMA_RX_STATUS (PORT_BASE + 0x2e8) +#define DMA_RX_STATUS_BUSY_OFF 0 +#define DMA_RX_STATUS_BUSY_MSK (0x1 << DMA_RX_STATUS_BUSY_OFF) + +#define AXI_CFG 0x5100 +#define RESET_VALUE 0x7ffff + +/* HW dma structures */ +/* Delivery queue header */ +/* dw0 */ +#define CMD_HDR_RESP_REPORT_OFF 5 +#define CMD_HDR_RESP_REPORT_MSK 0x20 +#define CMD_HDR_TLR_CTRL_OFF 6 +#define CMD_HDR_TLR_CTRL_MSK 0xc0 +#define CMD_HDR_PORT_OFF 17 +#define CMD_HDR_PORT_MSK 0xe0000 +#define CMD_HDR_PRIORITY_OFF 27 +#define CMD_HDR_PRIORITY_MSK 0x8000000 +#define CMD_HDR_MODE_OFF 28 +#define CMD_HDR_MODE_MSK 0x10000000 +#define CMD_HDR_CMD_OFF 29 +#define CMD_HDR_CMD_MSK 0xe0000000 +/* dw1 */ +#define CMD_HDR_VERIFY_DTL_OFF 10 +#define CMD_HDR_VERIFY_DTL_MSK 0x400 +#define CMD_HDR_SSP_FRAME_TYPE_OFF 13 +#define CMD_HDR_SSP_FRAME_TYPE_MSK 0xe000 +#define CMD_HDR_DEVICE_ID_OFF 16 +#define CMD_HDR_DEVICE_ID_MSK 0xffff0000 +/* dw2 */ +#define CMD_HDR_CFL_OFF 0 +#define CMD_HDR_CFL_MSK 0x1ff +#define CMD_HDR_MRFL_OFF 15 +#define CMD_HDR_MRFL_MSK 0xff8000 +#define CMD_HDR_FIRST_BURST_OFF 25 +#define CMD_HDR_FIRST_BURST_MSK 0x2000000 +/* dw3 */ +#define CMD_HDR_IPTT_OFF 0 +#define CMD_HDR_IPTT_MSK 0xffff +/* dw6 */ +#define CMD_HDR_DATA_SGL_LEN_OFF 16 +#define CMD_HDR_DATA_SGL_LEN_MSK 0xffff0000 + +/* Completion header */ +#define CMPLT_HDR_IPTT_OFF 0 +#define CMPLT_HDR_IPTT_MSK (0xffff << CMPLT_HDR_IPTT_OFF) +#define CMPLT_HDR_CMD_CMPLT_OFF 17 +#define CMPLT_HDR_CMD_CMPLT_MSK (0x1 << CMPLT_HDR_CMD_CMPLT_OFF) +#define CMPLT_HDR_ERR_RCRD_XFRD_OFF 18 +#define CMPLT_HDR_ERR_RCRD_XFRD_MSK (0x1 << CMPLT_HDR_ERR_RCRD_XFRD_OFF) +#define CMPLT_HDR_RSPNS_XFRD_OFF 19 +#define CMPLT_HDR_RSPNS_XFRD_MSK (0x1 << CMPLT_HDR_RSPNS_XFRD_OFF) +#define CMPLT_HDR_IO_CFG_ERR_OFF 27 +#define CMPLT_HDR_IO_CFG_ERR_MSK (0x1 << CMPLT_HDR_IO_CFG_ERR_OFF) + +/* ITCT header */ +/* qw0 */ +#define ITCT_HDR_DEV_TYPE_OFF 0 +#define ITCT_HDR_DEV_TYPE_MSK (0x3 << ITCT_HDR_DEV_TYPE_OFF) +#define ITCT_HDR_VALID_OFF 2 +#define ITCT_HDR_VALID_MSK (0x1 << ITCT_HDR_VALID_OFF) +#define ITCT_HDR_BREAK_REPLY_ENA_OFF 3 +#define ITCT_HDR_BREAK_REPLY_ENA_MSK (0x1 << ITCT_HDR_BREAK_REPLY_ENA_OFF) +#define ITCT_HDR_AWT_CONTROL_OFF 4 +#define ITCT_HDR_AWT_CONTROL_MSK (0x1 << ITCT_HDR_AWT_CONTROL_OFF) +#define ITCT_HDR_MAX_CONN_RATE_OFF 5 +#define ITCT_HDR_MAX_CONN_RATE_MSK (0xf << ITCT_HDR_MAX_CONN_RATE_OFF) +#define ITCT_HDR_VALID_LINK_NUM_OFF 9 +#define ITCT_HDR_VALID_LINK_NUM_MSK (0xf << ITCT_HDR_VALID_LINK_NUM_OFF) +#define ITCT_HDR_PORT_ID_OFF 13 +#define ITCT_HDR_PORT_ID_MSK (0x7 << ITCT_HDR_PORT_ID_OFF) +#define ITCT_HDR_SMP_TIMEOUT_OFF 16 +#define ITCT_HDR_SMP_TIMEOUT_MSK (0xffff << ITCT_HDR_SMP_TIMEOUT_OFF) +#define ITCT_HDR_MAX_BURST_BYTES_OFF 16 +#define ITCT_HDR_MAX_BURST_BYTES_MSK (0xffffffff << \ + ITCT_MAX_BURST_BYTES_OFF) +/* qw1 */ +#define ITCT_HDR_MAX_SAS_ADDR_OFF 0 +#define ITCT_HDR_MAX_SAS_ADDR_MSK (0xffffffffffffffff << \ + ITCT_HDR_MAX_SAS_ADDR_OFF) +/* qw2 */ +#define ITCT_HDR_IT_NEXUS_LOSS_TL_OFF 0 +#define ITCT_HDR_IT_NEXUS_LOSS_TL_MSK (0xffff << \ + ITCT_HDR_IT_NEXUS_LOSS_TL_OFF) +#define ITCT_HDR_BUS_INACTIVE_TL_OFF 16 +#define ITCT_HDR_BUS_INACTIVE_TL_MSK (0xffff << \ + ITCT_HDR_BUS_INACTIVE_TL_OFF) +#define ITCT_HDR_MAX_CONN_TL_OFF 32 +#define ITCT_HDR_MAX_CONN_TL_MSK (0xffff << \ + ITCT_HDR_MAX_CONN_TL_OFF) +#define ITCT_HDR_REJ_OPEN_TL_OFF 48 +#define ITCT_HDR_REJ_OPEN_TL_MSK (0xffff << \ + ITCT_REJ_OPEN_TL_OFF) + +/* Err record header */ +#define ERR_HDR_DMA_TX_ERR_TYPE_OFF 0 +#define ERR_HDR_DMA_TX_ERR_TYPE_MSK (0xffff << ERR_HDR_DMA_TX_ERR_TYPE_OFF) +#define ERR_HDR_DMA_RX_ERR_TYPE_OFF 16 +#define ERR_HDR_DMA_RX_ERR_TYPE_MSK (0xffff << ERR_HDR_DMA_RX_ERR_TYPE_OFF) struct hisi_sas_complete_v1_hdr { __le32 data; }; + +enum { + HISI_SAS_PHY_BCAST_ACK = 0, + HISI_SAS_PHY_SL_PHY_ENABLED, + HISI_SAS_PHY_INT_ABNORMAL, + HISI_SAS_PHY_INT_NR +}; + +enum { + DMA_TX_ERR_BASE = 0x0, + DMA_RX_ERR_BASE = 0x100, + TRANS_TX_FAIL_BASE = 0x200, + TRANS_RX_FAIL_BASE = 0x300, + + /* dma tx */ + DMA_TX_DIF_CRC_ERR = DMA_TX_ERR_BASE, /* 0x0 */ + DMA_TX_DIF_APP_ERR, /* 0x1 */ + DMA_TX_DIF_RPP_ERR, /* 0x2 */ + DMA_TX_AXI_BUS_ERR, /* 0x3 */ + DMA_TX_DATA_SGL_OVERFLOW_ERR, /* 0x4 */ + DMA_TX_DIF_SGL_OVERFLOW_ERR, /* 0x5 */ + DMA_TX_UNEXP_XFER_RDY_ERR, /* 0x6 */ + DMA_TX_XFER_RDY_OFFSET_ERR, /* 0x7 */ + DMA_TX_DATA_UNDERFLOW_ERR, /* 0x8 */ + DMA_TX_XFER_RDY_LENGTH_OVERFLOW_ERR, /* 0x9 */ + + /* dma rx */ + DMA_RX_BUFFER_ECC_ERR = DMA_RX_ERR_BASE, /* 0x100 */ + DMA_RX_DIF_CRC_ERR, /* 0x101 */ + DMA_RX_DIF_APP_ERR, /* 0x102 */ + DMA_RX_DIF_RPP_ERR, /* 0x103 */ + DMA_RX_RESP_BUFFER_OVERFLOW_ERR, /* 0x104 */ + DMA_RX_AXI_BUS_ERR, /* 0x105 */ + DMA_RX_DATA_SGL_OVERFLOW_ERR, /* 0x106 */ + DMA_RX_DIF_SGL_OVERFLOW_ERR, /* 0x107 */ + DMA_RX_DATA_OFFSET_ERR, /* 0x108 */ + DMA_RX_UNEXP_RX_DATA_ERR, /* 0x109 */ + DMA_RX_DATA_OVERFLOW_ERR, /* 0x10a */ + DMA_RX_DATA_UNDERFLOW_ERR, /* 0x10b */ + DMA_RX_UNEXP_RETRANS_RESP_ERR, /* 0x10c */ + + /* trans tx */ + TRANS_TX_RSVD0_ERR = TRANS_TX_FAIL_BASE, /* 0x200 */ + TRANS_TX_PHY_NOT_ENABLE_ERR, /* 0x201 */ + TRANS_TX_OPEN_REJCT_WRONG_DEST_ERR, /* 0x202 */ + TRANS_TX_OPEN_REJCT_ZONE_VIOLATION_ERR, /* 0x203 */ + TRANS_TX_OPEN_REJCT_BY_OTHER_ERR, /* 0x204 */ + TRANS_TX_RSVD1_ERR, /* 0x205 */ + TRANS_TX_OPEN_REJCT_AIP_TIMEOUT_ERR, /* 0x206 */ + TRANS_TX_OPEN_REJCT_STP_BUSY_ERR, /* 0x207 */ + TRANS_TX_OPEN_REJCT_PROTOCOL_NOT_SUPPORT_ERR, /* 0x208 */ + TRANS_TX_OPEN_REJCT_RATE_NOT_SUPPORT_ERR, /* 0x209 */ + TRANS_TX_OPEN_REJCT_BAD_DEST_ERR, /* 0x20a */ + TRANS_TX_OPEN_BREAK_RECEIVE_ERR, /* 0x20b */ + TRANS_TX_LOW_PHY_POWER_ERR, /* 0x20c */ + TRANS_TX_OPEN_REJCT_PATHWAY_BLOCKED_ERR, /* 0x20d */ + TRANS_TX_OPEN_TIMEOUT_ERR, /* 0x20e */ + TRANS_TX_OPEN_REJCT_NO_DEST_ERR, /* 0x20f */ + TRANS_TX_OPEN_RETRY_ERR, /* 0x210 */ + TRANS_TX_RSVD2_ERR, /* 0x211 */ + TRANS_TX_BREAK_TIMEOUT_ERR, /* 0x212 */ + TRANS_TX_BREAK_REQUEST_ERR, /* 0x213 */ + TRANS_TX_BREAK_RECEIVE_ERR, /* 0x214 */ + TRANS_TX_CLOSE_TIMEOUT_ERR, /* 0x215 */ + TRANS_TX_CLOSE_NORMAL_ERR, /* 0x216 */ + TRANS_TX_CLOSE_PHYRESET_ERR, /* 0x217 */ + TRANS_TX_WITH_CLOSE_DWS_TIMEOUT_ERR, /* 0x218 */ + TRANS_TX_WITH_CLOSE_COMINIT_ERR, /* 0x219 */ + TRANS_TX_NAK_RECEIVE_ERR, /* 0x21a */ + TRANS_TX_ACK_NAK_TIMEOUT_ERR, /* 0x21b */ + TRANS_TX_CREDIT_TIMEOUT_ERR, /* 0x21c */ + TRANS_TX_IPTT_CONFLICT_ERR, /* 0x21d */ + TRANS_TX_TXFRM_TYPE_ERR, /* 0x21e */ + TRANS_TX_TXSMP_LENGTH_ERR, /* 0x21f */ + + /* trans rx */ + TRANS_RX_FRAME_CRC_ERR = TRANS_RX_FAIL_BASE, /* 0x300 */ + TRANS_RX_FRAME_DONE_ERR, /* 0x301 */ + TRANS_RX_FRAME_ERRPRM_ERR, /* 0x302 */ + TRANS_RX_FRAME_NO_CREDIT_ERR, /* 0x303 */ + TRANS_RX_RSVD0_ERR, /* 0x304 */ + TRANS_RX_FRAME_OVERRUN_ERR, /* 0x305 */ + TRANS_RX_FRAME_NO_EOF_ERR, /* 0x306 */ + TRANS_RX_LINK_BUF_OVERRUN_ERR, /* 0x307 */ + TRANS_RX_BREAK_TIMEOUT_ERR, /* 0x308 */ + TRANS_RX_BREAK_REQUEST_ERR, /* 0x309 */ + TRANS_RX_BREAK_RECEIVE_ERR, /* 0x30a */ + TRANS_RX_CLOSE_TIMEOUT_ERR, /* 0x30b */ + TRANS_RX_CLOSE_NORMAL_ERR, /* 0x30c */ + TRANS_RX_CLOSE_PHYRESET_ERR, /* 0x30d */ + TRANS_RX_WITH_CLOSE_DWS_TIMEOUT_ERR, /* 0x30e */ + TRANS_RX_WITH_CLOSE_COMINIT_ERR, /* 0x30f */ + TRANS_RX_DATA_LENGTH0_ERR, /* 0x310 */ + TRANS_RX_BAD_HASH_ERR, /* 0x311 */ + TRANS_RX_XRDY_ZERO_ERR, /* 0x312 */ + TRANS_RX_SSP_FRAME_LEN_ERR, /* 0x313 */ + TRANS_RX_TRANS_RX_RSVD1_ERR, /* 0x314 */ + TRANS_RX_NO_BALANCE_ERR, /* 0x315 */ + TRANS_RX_TRANS_RX_RSVD2_ERR, /* 0x316 */ + TRANS_RX_TRANS_RX_RSVD3_ERR, /* 0x317 */ + TRANS_RX_BAD_FRAME_TYPE_ERR, /* 0x318 */ + TRANS_RX_SMP_FRAME_LEN_ERR, /* 0x319 */ + TRANS_RX_SMP_RESP_TIMEOUT_ERR, /* 0x31a */ +}; + +#define HISI_SAS_PHY_MAX_INT_NR (HISI_SAS_PHY_INT_NR * HISI_SAS_MAX_PHYS) +#define HISI_SAS_CQ_MAX_INT_NR (HISI_SAS_MAX_QUEUES) +#define HISI_SAS_FATAL_INT_NR (2) + +#define HISI_SAS_MAX_INT_NR \ + (HISI_SAS_PHY_MAX_INT_NR + HISI_SAS_CQ_MAX_INT_NR +\ + HISI_SAS_FATAL_INT_NR) + static const struct hisi_sas_hw hisi_sas_v1_hw = { .complete_hdr_size = sizeof(struct hisi_sas_complete_v1_hdr), }; -- cgit v0.10.2 From 8ff1d5718e9d42e3d0d2331492b5cb49b5c5442b Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:46 +0800 Subject: hisi_sas: Add v1 hardware initialisation code Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 72533ca..ba3bf5e 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -81,6 +81,7 @@ struct hisi_sas_slot { }; struct hisi_sas_hw { + int (*hw_init)(struct hisi_hba *hisi_hba); int complete_hdr_size; }; diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 06b863c..6c13547 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -402,6 +402,10 @@ int hisi_sas_probe(struct platform_device *pdev, hisi_sas_init_add(hisi_hba); + rc = hisi_hba->hw->hw_init(hisi_hba); + if (rc) + goto err_out_ha; + rc = scsi_add_host(shost, &pdev->dev); if (rc) goto err_out_ha; diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 9fe89bb..9bfe1aa 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -405,7 +405,344 @@ enum { (HISI_SAS_PHY_MAX_INT_NR + HISI_SAS_CQ_MAX_INT_NR +\ HISI_SAS_FATAL_INT_NR) +static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off) +{ + void __iomem *regs = hisi_hba->regs + off; + + return readl(regs); +} + +static void hisi_sas_write32(struct hisi_hba *hisi_hba, + u32 off, u32 val) +{ + void __iomem *regs = hisi_hba->regs + off; + + writel(val, regs); +} + +static void hisi_sas_phy_write32(struct hisi_hba *hisi_hba, + int phy_no, u32 off, u32 val) +{ + void __iomem *regs = hisi_hba->regs + (0x400 * phy_no) + off; + + writel(val, regs); +} + +static u32 hisi_sas_phy_read32(struct hisi_hba *hisi_hba, + int phy_no, u32 off) +{ + void __iomem *regs = hisi_hba->regs + (0x400 * phy_no) + off; + + return readl(regs); +} + +static void config_phy_opt_mode_v1_hw(struct hisi_hba *hisi_hba, int phy_no) +{ + u32 cfg = hisi_sas_phy_read32(hisi_hba, phy_no, PHY_CFG); + + cfg &= ~PHY_CFG_DC_OPT_MSK; + cfg |= 1 << PHY_CFG_DC_OPT_OFF; + hisi_sas_phy_write32(hisi_hba, phy_no, PHY_CFG, cfg); +} + +static void config_tx_tfe_autoneg_v1_hw(struct hisi_hba *hisi_hba, int phy_no) +{ + u32 cfg = hisi_sas_phy_read32(hisi_hba, phy_no, PHY_CONFIG2); + + cfg &= ~PHY_CONFIG2_FORCE_TXDEEMPH_MSK; + hisi_sas_phy_write32(hisi_hba, phy_no, PHY_CONFIG2, cfg); +} + +static void config_id_frame_v1_hw(struct hisi_hba *hisi_hba, int phy_no) +{ + struct sas_identify_frame identify_frame; + u32 *identify_buffer; + + memset(&identify_frame, 0, sizeof(identify_frame)); + identify_frame.dev_type = SAS_END_DEVICE; + identify_frame.frame_type = 0; + identify_frame._un1 = 1; + identify_frame.initiator_bits = SAS_PROTOCOL_ALL; + identify_frame.target_bits = SAS_PROTOCOL_NONE; + memcpy(&identify_frame._un4_11[0], hisi_hba->sas_addr, SAS_ADDR_SIZE); + memcpy(&identify_frame.sas_addr[0], hisi_hba->sas_addr, SAS_ADDR_SIZE); + identify_frame.phy_id = phy_no; + identify_buffer = (u32 *)(&identify_frame); + + hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD0, + __swab32(identify_buffer[0])); + hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD1, + identify_buffer[2]); + hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD2, + identify_buffer[1]); + hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD3, + identify_buffer[4]); + hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD4, + identify_buffer[3]); + hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD5, + __swab32(identify_buffer[5])); +} + +static void init_id_frame_v1_hw(struct hisi_hba *hisi_hba) +{ + int i; + + for (i = 0; i < hisi_hba->n_phy; i++) + config_id_frame_v1_hw(hisi_hba, i); +} + +static int reset_hw_v1_hw(struct hisi_hba *hisi_hba) +{ + int i; + unsigned long end_time; + u32 val; + struct device *dev = &hisi_hba->pdev->dev; + + for (i = 0; i < hisi_hba->n_phy; i++) { + u32 phy_ctrl = hisi_sas_phy_read32(hisi_hba, i, PHY_CTRL); + + phy_ctrl |= PHY_CTRL_RESET_MSK; + hisi_sas_phy_write32(hisi_hba, i, PHY_CTRL, phy_ctrl); + } + msleep(1); /* It is safe to wait for 50us */ + + /* Ensure DMA tx & rx idle */ + for (i = 0; i < hisi_hba->n_phy; i++) { + u32 dma_tx_status, dma_rx_status; + + end_time = jiffies + msecs_to_jiffies(1000); + + while (1) { + dma_tx_status = hisi_sas_phy_read32(hisi_hba, i, + DMA_TX_STATUS); + dma_rx_status = hisi_sas_phy_read32(hisi_hba, i, + DMA_RX_STATUS); + + if (!(dma_tx_status & DMA_TX_STATUS_BUSY_MSK) && + !(dma_rx_status & DMA_RX_STATUS_BUSY_MSK)) + break; + + msleep(20); + if (time_after(jiffies, end_time)) + return -EIO; + } + } + + /* Ensure axi bus idle */ + end_time = jiffies + msecs_to_jiffies(1000); + while (1) { + u32 axi_status = + hisi_sas_read32(hisi_hba, AXI_CFG); + + if (axi_status == 0) + break; + + msleep(20); + if (time_after(jiffies, end_time)) + return -EIO; + } + + /* Apply reset and disable clock */ + /* clk disable reg is offset by +4 bytes from clk enable reg */ + regmap_write(hisi_hba->ctrl, hisi_hba->ctrl_reset_reg, + RESET_VALUE); + regmap_write(hisi_hba->ctrl, hisi_hba->ctrl_clock_ena_reg + 4, + RESET_VALUE); + msleep(1); + regmap_read(hisi_hba->ctrl, hisi_hba->ctrl_reset_sts_reg, &val); + if (RESET_VALUE != (val & RESET_VALUE)) { + dev_err(dev, "Reset failed\n"); + return -EIO; + } + + /* De-reset and enable clock */ + /* deassert rst reg is offset by +4 bytes from assert reg */ + regmap_write(hisi_hba->ctrl, hisi_hba->ctrl_reset_reg + 4, + RESET_VALUE); + regmap_write(hisi_hba->ctrl, hisi_hba->ctrl_clock_ena_reg, + RESET_VALUE); + msleep(1); + regmap_read(hisi_hba->ctrl, hisi_hba->ctrl_reset_sts_reg, &val); + if (val & RESET_VALUE) { + dev_err(dev, "De-reset failed\n"); + return -EIO; + } + + return 0; +} + +static void init_reg_v1_hw(struct hisi_hba *hisi_hba) +{ + int i; + + /* Global registers init*/ + hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, + (u32)((1ULL << hisi_hba->queue_count) - 1)); + hisi_sas_write32(hisi_hba, HGC_TRANS_TASK_CNT_LIMIT, 0x11); + hisi_sas_write32(hisi_hba, DEVICE_MSG_WORK_MODE, 0x1); + hisi_sas_write32(hisi_hba, HGC_SAS_TXFAIL_RETRY_CTRL, 0x1ff); + hisi_sas_write32(hisi_hba, HGC_ERR_STAT_EN, 0x401); + hisi_sas_write32(hisi_hba, CFG_1US_TIMER_TRSH, 0x64); + hisi_sas_write32(hisi_hba, HGC_GET_ITV_TIME, 0x1); + hisi_sas_write32(hisi_hba, I_T_NEXUS_LOSS_TIME, 0x64); + hisi_sas_write32(hisi_hba, BUS_INACTIVE_LIMIT_TIME, 0x2710); + hisi_sas_write32(hisi_hba, REJECT_TO_OPEN_LIMIT_TIME, 0x1); + hisi_sas_write32(hisi_hba, CFG_AGING_TIME, 0x7a12); + hisi_sas_write32(hisi_hba, HGC_DFX_CFG2, 0x9c40); + hisi_sas_write32(hisi_hba, FIS_LIST_BADDR_L, 0x2); + hisi_sas_write32(hisi_hba, INT_COAL_EN, 0xc); + hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME, 0x186a0); + hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT, 1); + hisi_sas_write32(hisi_hba, ENT_INT_COAL_TIME, 0x1); + hisi_sas_write32(hisi_hba, ENT_INT_COAL_CNT, 0x1); + hisi_sas_write32(hisi_hba, OQ_INT_SRC, 0xffffffff); + hisi_sas_write32(hisi_hba, OQ_INT_SRC_MSK, 0); + hisi_sas_write32(hisi_hba, ENT_INT_SRC1, 0xffffffff); + hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, 0); + hisi_sas_write32(hisi_hba, ENT_INT_SRC2, 0xffffffff); + hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK2, 0); + hisi_sas_write32(hisi_hba, SAS_ECC_INTR_MSK, 0); + hisi_sas_write32(hisi_hba, AXI_AHB_CLK_CFG, 0x2); + hisi_sas_write32(hisi_hba, CFG_SAS_CONFIG, 0x22000000); + + for (i = 0; i < hisi_hba->n_phy; i++) { + hisi_sas_phy_write32(hisi_hba, i, PROG_PHY_LINK_RATE, 0x88a); + hisi_sas_phy_write32(hisi_hba, i, PHY_CONFIG2, 0x7c080); + hisi_sas_phy_write32(hisi_hba, i, PHY_RATE_NEGO, 0x415ee00); + hisi_sas_phy_write32(hisi_hba, i, PHY_PCN, 0x80a80000); + hisi_sas_phy_write32(hisi_hba, i, SL_TOUT_CFG, 0x7d7d7d7d); + hisi_sas_phy_write32(hisi_hba, i, DONE_RECEIVED_TIME, 0x0); + hisi_sas_phy_write32(hisi_hba, i, RXOP_CHECK_CFG_H, 0x1000); + hisi_sas_phy_write32(hisi_hba, i, DONE_RECEIVED_TIME, 0); + hisi_sas_phy_write32(hisi_hba, i, CON_CFG_DRIVER, 0x13f0a); + hisi_sas_phy_write32(hisi_hba, i, CHL_INT_COAL_EN, 3); + hisi_sas_phy_write32(hisi_hba, i, DONE_RECEIVED_TIME, 8); + } + + for (i = 0; i < hisi_hba->queue_count; i++) { + /* Delivery queue */ + hisi_sas_write32(hisi_hba, + DLVRY_Q_0_BASE_ADDR_HI + (i * 0x14), + upper_32_bits(hisi_hba->cmd_hdr_dma[i])); + + hisi_sas_write32(hisi_hba, + DLVRY_Q_0_BASE_ADDR_LO + (i * 0x14), + lower_32_bits(hisi_hba->cmd_hdr_dma[i])); + + hisi_sas_write32(hisi_hba, + DLVRY_Q_0_DEPTH + (i * 0x14), + HISI_SAS_QUEUE_SLOTS); + + /* Completion queue */ + hisi_sas_write32(hisi_hba, + COMPL_Q_0_BASE_ADDR_HI + (i * 0x14), + upper_32_bits(hisi_hba->complete_hdr_dma[i])); + + hisi_sas_write32(hisi_hba, + COMPL_Q_0_BASE_ADDR_LO + (i * 0x14), + lower_32_bits(hisi_hba->complete_hdr_dma[i])); + + hisi_sas_write32(hisi_hba, COMPL_Q_0_DEPTH + (i * 0x14), + HISI_SAS_QUEUE_SLOTS); + } + + /* itct */ + hisi_sas_write32(hisi_hba, ITCT_BASE_ADDR_LO, + lower_32_bits(hisi_hba->itct_dma)); + + hisi_sas_write32(hisi_hba, ITCT_BASE_ADDR_HI, + upper_32_bits(hisi_hba->itct_dma)); + + /* iost */ + hisi_sas_write32(hisi_hba, IOST_BASE_ADDR_LO, + lower_32_bits(hisi_hba->iost_dma)); + + hisi_sas_write32(hisi_hba, IOST_BASE_ADDR_HI, + upper_32_bits(hisi_hba->iost_dma)); + + /* breakpoint */ + hisi_sas_write32(hisi_hba, BROKEN_MSG_ADDR_LO, + lower_32_bits(hisi_hba->breakpoint_dma)); + + hisi_sas_write32(hisi_hba, BROKEN_MSG_ADDR_HI, + upper_32_bits(hisi_hba->breakpoint_dma)); +} + +static int hw_init_v1_hw(struct hisi_hba *hisi_hba) +{ + struct device *dev = &hisi_hba->pdev->dev; + int rc; + + rc = reset_hw_v1_hw(hisi_hba); + if (rc) { + dev_err(dev, "hisi_sas_reset_hw failed, rc=%d", rc); + return rc; + } + + msleep(100); + init_reg_v1_hw(hisi_hba); + + init_id_frame_v1_hw(hisi_hba); + + return 0; +} + +static void enable_phy_v1_hw(struct hisi_hba *hisi_hba, int phy_no) +{ + u32 cfg = hisi_sas_phy_read32(hisi_hba, phy_no, PHY_CFG); + + cfg |= PHY_CFG_ENA_MSK; + hisi_sas_phy_write32(hisi_hba, phy_no, PHY_CFG, cfg); +} + +static void start_phy_v1_hw(struct hisi_hba *hisi_hba, int phy_no) +{ + config_id_frame_v1_hw(hisi_hba, phy_no); + config_phy_opt_mode_v1_hw(hisi_hba, phy_no); + config_tx_tfe_autoneg_v1_hw(hisi_hba, phy_no); + enable_phy_v1_hw(hisi_hba, phy_no); +} + +static void start_phys_v1_hw(unsigned long data) +{ + struct hisi_hba *hisi_hba = (struct hisi_hba *)data; + int i; + + for (i = 0; i < hisi_hba->n_phy; i++) { + hisi_sas_phy_write32(hisi_hba, i, CHL_INT2_MSK, 0x12a); + start_phy_v1_hw(hisi_hba, i); + } +} + +static void phys_init_v1_hw(struct hisi_hba *hisi_hba) +{ + int i; + struct timer_list *timer = &hisi_hba->timer; + + for (i = 0; i < hisi_hba->n_phy; i++) { + hisi_sas_phy_write32(hisi_hba, i, CHL_INT2_MSK, 0x6a); + hisi_sas_phy_read32(hisi_hba, i, CHL_INT2_MSK); + } + + setup_timer(timer, start_phys_v1_hw, (unsigned long)hisi_hba); + mod_timer(timer, jiffies + HZ); +} + +static int hisi_sas_v1_init(struct hisi_hba *hisi_hba) +{ + int rc; + + rc = hw_init_v1_hw(hisi_hba); + if (rc) + return rc; + + phys_init_v1_hw(hisi_hba); + + return 0; +} + static const struct hisi_sas_hw hisi_sas_v1_hw = { + .hw_init = hisi_sas_v1_init, .complete_hdr_size = sizeof(struct hisi_sas_complete_v1_hdr), }; -- cgit v0.10.2 From 07d785923fa5353eabb451976defeedd407936ac Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:47 +0800 Subject: hisi_sas: Add v1 hardware interrupt init Add code to interrupts, so now we can get a phy up interrupt when a disk is connected. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index ba3bf5e..938fa75 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -38,6 +38,11 @@ #define HISI_SAS_NAME_LEN 32 +enum { + PORT_TYPE_SAS = (1U << 1), + PORT_TYPE_SATA = (1U << 0), +}; + enum dev_status { HISI_SAS_DEV_NORMAL, HISI_SAS_DEV_EH, diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 9bfe1aa..3ea666f 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -728,6 +728,159 @@ static void phys_init_v1_hw(struct hisi_hba *hisi_hba) mod_timer(timer, jiffies + HZ); } +/* Interrupts */ +static irqreturn_t int_phyup_v1_hw(int irq_no, void *p) +{ + struct hisi_sas_phy *phy = p; + struct hisi_hba *hisi_hba = phy->hisi_hba; + struct device *dev = &hisi_hba->pdev->dev; + struct asd_sas_phy *sas_phy = &phy->sas_phy; + int i, phy_no = sas_phy->id; + u32 irq_value, context, port_id, link_rate; + u32 *frame_rcvd = (u32 *)sas_phy->frame_rcvd; + struct sas_identify_frame *id = (struct sas_identify_frame *)frame_rcvd; + irqreturn_t res = IRQ_HANDLED; + + irq_value = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT2); + if (!(irq_value & CHL_INT2_SL_PHY_ENA_MSK)) { + dev_dbg(dev, "phyup: irq_value = %x not set enable bit\n", + irq_value); + res = IRQ_NONE; + goto end; + } + + context = hisi_sas_read32(hisi_hba, PHY_CONTEXT); + if (context & 1 << phy_no) { + dev_err(dev, "phyup: phy%d SATA attached equipment\n", + phy_no); + goto end; + } + + port_id = (hisi_sas_read32(hisi_hba, PHY_PORT_NUM_MA) >> (4 * phy_no)) + & 0xf; + if (port_id == 0xf) { + dev_err(dev, "phyup: phy%d invalid portid\n", phy_no); + res = IRQ_NONE; + goto end; + } + + for (i = 0; i < 6; i++) { + u32 idaf = hisi_sas_phy_read32(hisi_hba, phy_no, + RX_IDAF_DWORD0 + (i * 4)); + frame_rcvd[i] = __swab32(idaf); + } + + /* Get the linkrate */ + link_rate = hisi_sas_read32(hisi_hba, PHY_CONN_RATE); + link_rate = (link_rate >> (phy_no * 4)) & 0xf; + sas_phy->linkrate = link_rate; + sas_phy->oob_mode = SAS_OOB_MODE; + memcpy(sas_phy->attached_sas_addr, + &id->sas_addr, SAS_ADDR_SIZE); + dev_info(dev, "phyup: phy%d link_rate=%d\n", + phy_no, link_rate); + phy->port_id = port_id; + phy->phy_type &= ~(PORT_TYPE_SAS | PORT_TYPE_SATA); + phy->phy_type |= PORT_TYPE_SAS; + phy->phy_attached = 1; + phy->identify.device_type = id->dev_type; + phy->frame_rcvd_size = sizeof(struct sas_identify_frame); + if (phy->identify.device_type == SAS_END_DEVICE) + phy->identify.target_port_protocols = + SAS_PROTOCOL_SSP; + else if (phy->identify.device_type != SAS_PHY_UNUSED) + phy->identify.target_port_protocols = + SAS_PROTOCOL_SMP; + +end: + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2, + CHL_INT2_SL_PHY_ENA_MSK); + + if (irq_value & CHL_INT2_SL_PHY_ENA_MSK) { + u32 chl_int0 = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT0); + + chl_int0 &= ~CHL_INT0_PHYCTRL_NOTRDY_MSK; + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, chl_int0); + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0_MSK, 0x3ce3ee); + } + + return res; +} +static const char phy_int_names[HISI_SAS_PHY_INT_NR][32] = { + {"Phy Up"}, +}; +static irq_handler_t phy_interrupts[HISI_SAS_PHY_INT_NR] = { + int_phyup_v1_hw, +}; + +static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) +{ + struct device *dev = &hisi_hba->pdev->dev; + struct device_node *np = dev->of_node; + char *int_names = hisi_hba->int_names; + int i, j, irq, rc, idx; + + if (!np) + return -ENOENT; + + for (i = 0; i < hisi_hba->n_phy; i++) { + struct hisi_sas_phy *phy = &hisi_hba->phy[i]; + + idx = i * HISI_SAS_PHY_INT_NR; + for (j = 0; j < HISI_SAS_PHY_INT_NR; j++, idx++) { + irq = irq_of_parse_and_map(np, idx); + if (!irq) { + dev_err(dev, + "irq init: fail map phy interrupt %d\n", + idx); + return -ENOENT; + } + + (void)snprintf(&int_names[idx * HISI_SAS_NAME_LEN], + HISI_SAS_NAME_LEN, + "%s %s:%d", dev_name(dev), + phy_int_names[j], i); + rc = devm_request_irq(dev, irq, phy_interrupts[j], 0, + &int_names[idx * HISI_SAS_NAME_LEN], + phy); + if (rc) { + dev_err(dev, "irq init: could not request " + "phy interrupt %d, rc=%d\n", + irq, rc); + return -ENOENT; + } + } + } + return 0; +} + +static int interrupt_openall_v1_hw(struct hisi_hba *hisi_hba) +{ + int i; + u32 val; + + for (i = 0; i < hisi_hba->n_phy; i++) { + /* Clear interrupt status */ + val = hisi_sas_phy_read32(hisi_hba, i, CHL_INT0); + hisi_sas_phy_write32(hisi_hba, i, CHL_INT0, val); + val = hisi_sas_phy_read32(hisi_hba, i, CHL_INT1); + hisi_sas_phy_write32(hisi_hba, i, CHL_INT1, val); + val = hisi_sas_phy_read32(hisi_hba, i, CHL_INT2); + hisi_sas_phy_write32(hisi_hba, i, CHL_INT2, val); + + /* Unmask interrupt */ + hisi_sas_phy_write32(hisi_hba, i, CHL_INT0_MSK, 0x3ce3ee); + hisi_sas_phy_write32(hisi_hba, i, CHL_INT1_MSK, 0x17fff); + hisi_sas_phy_write32(hisi_hba, i, CHL_INT2_MSK, 0x8000012a); + + /* bypass chip bug mask abnormal intr */ + hisi_sas_phy_write32(hisi_hba, i, CHL_INT0_MSK, + 0x3fffff & ~CHL_INT0_MSK_PHYCTRL_NOTRDY_MSK); + } + + return 0; +} + static int hisi_sas_v1_init(struct hisi_hba *hisi_hba) { int rc; @@ -736,6 +889,14 @@ static int hisi_sas_v1_init(struct hisi_hba *hisi_hba) if (rc) return rc; + rc = interrupt_init_v1_hw(hisi_hba); + if (rc) + return rc; + + rc = interrupt_openall_v1_hw(hisi_hba); + if (rc) + return rc; + phys_init_v1_hw(hisi_hba); return 0; -- cgit v0.10.2 From 66139921973db60c2fc93a4d467c3c574d9657a0 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:48 +0800 Subject: hisi_sas: Add path from phyup irq to SAS framework Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 938fa75..837d139 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -53,6 +53,7 @@ struct hisi_sas_phy { struct asd_sas_phy sas_phy; struct sas_identify identify; struct timer_list timer; + struct work_struct phyup_ws; u64 port_id; /* from hw */ u64 dev_sas_addr; u64 phy_type; @@ -87,6 +88,7 @@ struct hisi_sas_slot { struct hisi_sas_hw { int (*hw_init)(struct hisi_hba *hisi_hba); + void (*sl_notify)(struct hisi_hba *hisi_hba, int phy_no); int complete_hdr_size; }; diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 6c13547..7bf6d2f 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -27,6 +27,53 @@ static void hisi_sas_slot_index_init(struct hisi_hba *hisi_hba) hisi_sas_slot_index_clear(hisi_hba, i); } +static void hisi_sas_bytes_dmaed(struct hisi_hba *hisi_hba, int phy_no) +{ + struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; + struct asd_sas_phy *sas_phy = &phy->sas_phy; + struct sas_ha_struct *sas_ha; + + if (!phy->phy_attached) + return; + + sas_ha = &hisi_hba->sha; + sas_ha->notify_phy_event(sas_phy, PHYE_OOB_DONE); + + if (sas_phy->phy) { + struct sas_phy *sphy = sas_phy->phy; + + sphy->negotiated_linkrate = sas_phy->linkrate; + sphy->minimum_linkrate = phy->minimum_linkrate; + sphy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS; + sphy->maximum_linkrate = phy->maximum_linkrate; + } + + if (phy->phy_type & PORT_TYPE_SAS) { + struct sas_identify_frame *id; + + id = (struct sas_identify_frame *)phy->frame_rcvd; + id->dev_type = phy->identify.device_type; + id->initiator_bits = SAS_PROTOCOL_ALL; + id->target_bits = phy->identify.target_port_protocols; + } else if (phy->phy_type & PORT_TYPE_SATA) { + /*Nothing*/ + } + + sas_phy->frame_rcvd_size = phy->frame_rcvd_size; + sas_ha->notify_port_event(sas_phy, PORTE_BYTES_DMAED); +} + +static void hisi_sas_phyup_work(struct work_struct *work) +{ + struct hisi_sas_phy *phy = + container_of(work, struct hisi_sas_phy, phyup_ws); + struct hisi_hba *hisi_hba = phy->hisi_hba; + struct asd_sas_phy *sas_phy = &phy->sas_phy; + int phy_no = sas_phy->id; + + hisi_hba->hw->sl_notify(hisi_hba, phy_no); /* This requires a sleep */ + hisi_sas_bytes_dmaed(hisi_hba, phy_no); +} static void hisi_sas_phy_init(struct hisi_hba *hisi_hba, int phy_no) { @@ -49,6 +96,8 @@ static void hisi_sas_phy_init(struct hisi_hba *hisi_hba, int phy_no) sas_phy->frame_rcvd = &phy->frame_rcvd[0]; sas_phy->ha = (struct sas_ha_struct *)hisi_hba->shost->hostdata; sas_phy->lldd_phy = phy; + + INIT_WORK(&phy->phyup_ws, hisi_sas_phyup_work); } static struct scsi_transport_template *hisi_sas_stt; diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 3ea666f..4364279 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -728,6 +728,19 @@ static void phys_init_v1_hw(struct hisi_hba *hisi_hba) mod_timer(timer, jiffies + HZ); } +static void sl_notify_v1_hw(struct hisi_hba *hisi_hba, int phy_no) +{ + u32 sl_control; + + sl_control = hisi_sas_phy_read32(hisi_hba, phy_no, SL_CONTROL); + sl_control |= SL_CONTROL_NOTIFY_EN_MSK; + hisi_sas_phy_write32(hisi_hba, phy_no, SL_CONTROL, sl_control); + msleep(1); + sl_control = hisi_sas_phy_read32(hisi_hba, phy_no, SL_CONTROL); + sl_control &= ~SL_CONTROL_NOTIFY_EN_MSK; + hisi_sas_phy_write32(hisi_hba, phy_no, SL_CONTROL, sl_control); +} + /* Interrupts */ static irqreturn_t int_phyup_v1_hw(int irq_no, void *p) { @@ -791,6 +804,7 @@ static irqreturn_t int_phyup_v1_hw(int irq_no, void *p) else if (phy->identify.device_type != SAS_PHY_UNUSED) phy->identify.target_port_protocols = SAS_PROTOCOL_SMP; + queue_work(hisi_hba->wq, &phy->phyup_ws); end: hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2, @@ -904,6 +918,7 @@ static int hisi_sas_v1_init(struct hisi_hba *hisi_hba) static const struct hisi_sas_hw hisi_sas_v1_hw = { .hw_init = hisi_sas_v1_init, + .sl_notify = sl_notify_v1_hw, .complete_hdr_size = sizeof(struct hisi_sas_complete_v1_hdr), }; -- cgit v0.10.2 From 42e7a69368a5855b36cbaff130e58e2cc9976ff3 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:49 +0800 Subject: hisi_sas: Add ssp command function Add path to send ssp command to HW. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 837d139..72657eb 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -35,6 +35,8 @@ #define HISI_SAS_COMMAND_TABLE_SZ \ (((sizeof(union hisi_sas_command_table)+3)/4)*4) +#define HISI_SAS_MAX_SSP_RESP_SZ (sizeof(struct ssp_frame_hdr) + 1024) + #define HISI_SAS_NAME_LEN 32 @@ -80,15 +82,41 @@ struct hisi_sas_cq { struct hisi_sas_device { enum sas_device_type dev_type; u64 device_id; + u64 running_req; u8 dev_status; }; struct hisi_sas_slot { + struct list_head entry; + struct sas_task *task; + struct hisi_sas_port *port; + u64 n_elem; + int dlvry_queue; + int dlvry_queue_slot; + int idx; + void *cmd_hdr; + dma_addr_t cmd_hdr_dma; + void *status_buffer; + dma_addr_t status_buffer_dma; + void *command_table; + dma_addr_t command_table_dma; + struct hisi_sas_sge_page *sge_page; + dma_addr_t sge_page_dma; +}; + +struct hisi_sas_tmf_task { + u8 tmf; + u16 tag_of_task_to_be_managed; }; struct hisi_sas_hw { int (*hw_init)(struct hisi_hba *hisi_hba); void (*sl_notify)(struct hisi_hba *hisi_hba, int phy_no); + int (*get_free_slot)(struct hisi_hba *hisi_hba, int *q, int *s); + void (*start_delivery)(struct hisi_hba *hisi_hba); + int (*prep_ssp)(struct hisi_hba *hisi_hba, + struct hisi_sas_slot *slot, int is_tmf, + struct hisi_sas_tmf_task *tmf); int complete_hdr_size; }; @@ -122,7 +150,9 @@ struct hisi_hba { struct hisi_sas_port port[HISI_SAS_MAX_PHYS]; int queue_count; + int queue; char *int_names; + struct hisi_sas_slot *slot_prep; struct dma_pool *sge_page_pool; struct hisi_sas_device devices[HISI_SAS_MAX_DEVICES]; diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 7bf6d2f..660ef6c 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -12,6 +12,15 @@ #include "hisi_sas.h" #define DRV_NAME "hisi_sas" + +#define DEV_IS_GONE(dev) \ + ((!dev) || (dev->dev_type == SAS_PHY_UNUSED)) + +static struct hisi_hba *dev_to_hisi_hba(struct domain_device *device) +{ + return device->port->ha->lldd_ha; +} + static void hisi_sas_slot_index_clear(struct hisi_hba *hisi_hba, int slot_idx) { void *bitmap = hisi_hba->slot_index_tags; @@ -19,6 +28,31 @@ static void hisi_sas_slot_index_clear(struct hisi_hba *hisi_hba, int slot_idx) clear_bit(slot_idx, bitmap); } +static void hisi_sas_slot_index_free(struct hisi_hba *hisi_hba, int slot_idx) +{ + hisi_sas_slot_index_clear(hisi_hba, slot_idx); +} + +static void hisi_sas_slot_index_set(struct hisi_hba *hisi_hba, int slot_idx) +{ + void *bitmap = hisi_hba->slot_index_tags; + + set_bit(slot_idx, bitmap); +} + +static int hisi_sas_slot_index_alloc(struct hisi_hba *hisi_hba, int *slot_idx) +{ + unsigned int index; + void *bitmap = hisi_hba->slot_index_tags; + + index = find_first_zero_bit(bitmap, hisi_hba->slot_index_count); + if (index >= hisi_hba->slot_index_count) + return -SAS_QUEUE_FULL; + hisi_sas_slot_index_set(hisi_hba, index); + *slot_idx = index; + return 0; +} + static void hisi_sas_slot_index_init(struct hisi_hba *hisi_hba) { int i; @@ -26,6 +60,199 @@ static void hisi_sas_slot_index_init(struct hisi_hba *hisi_hba) for (i = 0; i < hisi_hba->slot_index_count; ++i) hisi_sas_slot_index_clear(hisi_hba, i); } +static int hisi_sas_task_prep_ssp(struct hisi_hba *hisi_hba, + struct hisi_sas_slot *slot, int is_tmf, + struct hisi_sas_tmf_task *tmf) +{ + return hisi_hba->hw->prep_ssp(hisi_hba, slot, is_tmf, tmf); +} + +static int hisi_sas_task_prep(struct sas_task *task, struct hisi_hba *hisi_hba, + int is_tmf, struct hisi_sas_tmf_task *tmf, + int *pass) +{ + struct domain_device *device = task->dev; + struct hisi_sas_device *sas_dev = device->lldd_dev; + struct hisi_sas_port *port; + struct hisi_sas_slot *slot; + struct hisi_sas_cmd_hdr *cmd_hdr_base; + struct device *dev = &hisi_hba->pdev->dev; + int dlvry_queue_slot, dlvry_queue, n_elem = 0, rc, slot_idx; + + if (!device->port) { + struct task_status_struct *ts = &task->task_status; + + ts->resp = SAS_TASK_UNDELIVERED; + ts->stat = SAS_PHY_DOWN; + /* + * libsas will use dev->port, should + * not call task_done for sata + */ + if (device->dev_type != SAS_SATA_DEV) + task->task_done(task); + return 0; + } + + if (DEV_IS_GONE(sas_dev)) { + if (sas_dev) + dev_info(dev, "task prep: device %llu not ready\n", + sas_dev->device_id); + else + dev_info(dev, "task prep: device %016llx not ready\n", + SAS_ADDR(device->sas_addr)); + + rc = SAS_PHY_DOWN; + return rc; + } + port = device->port->lldd_port; + if (port && !port->port_attached && !tmf) { + if (sas_protocol_ata(task->task_proto)) { + struct task_status_struct *ts = &task->task_status; + + dev_info(dev, + "task prep: SATA/STP port%d not attach device\n", + device->port->id); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_PHY_DOWN; + task->task_done(task); + } else { + struct task_status_struct *ts = &task->task_status; + + dev_info(dev, + "task prep: SAS port%d does not attach device\n", + device->port->id); + ts->resp = SAS_TASK_UNDELIVERED; + ts->stat = SAS_PHY_DOWN; + task->task_done(task); + } + return 0; + } + + if (!sas_protocol_ata(task->task_proto)) { + if (task->num_scatter) { + n_elem = dma_map_sg(dev, task->scatter, + task->num_scatter, task->data_dir); + if (!n_elem) { + rc = -ENOMEM; + goto prep_out; + } + } + } else + n_elem = task->num_scatter; + + rc = hisi_sas_slot_index_alloc(hisi_hba, &slot_idx); + if (rc) + goto err_out; + rc = hisi_hba->hw->get_free_slot(hisi_hba, &dlvry_queue, + &dlvry_queue_slot); + if (rc) + goto err_out_tag; + + slot = &hisi_hba->slot_info[slot_idx]; + memset(slot, 0, sizeof(struct hisi_sas_slot)); + + slot->idx = slot_idx; + slot->n_elem = n_elem; + slot->dlvry_queue = dlvry_queue; + slot->dlvry_queue_slot = dlvry_queue_slot; + cmd_hdr_base = hisi_hba->cmd_hdr[dlvry_queue]; + slot->cmd_hdr = &cmd_hdr_base[dlvry_queue_slot]; + slot->task = task; + slot->port = port; + task->lldd_task = slot; + + slot->status_buffer = dma_pool_alloc(hisi_hba->status_buffer_pool, + GFP_ATOMIC, + &slot->status_buffer_dma); + if (!slot->status_buffer) + goto err_out_slot_buf; + memset(slot->status_buffer, 0, HISI_SAS_STATUS_BUF_SZ); + + slot->command_table = dma_pool_alloc(hisi_hba->command_table_pool, + GFP_ATOMIC, + &slot->command_table_dma); + if (!slot->command_table) + goto err_out_status_buf; + memset(slot->command_table, 0, HISI_SAS_COMMAND_TABLE_SZ); + memset(slot->cmd_hdr, 0, sizeof(struct hisi_sas_cmd_hdr)); + + switch (task->task_proto) { + case SAS_PROTOCOL_SSP: + rc = hisi_sas_task_prep_ssp(hisi_hba, slot, is_tmf, tmf); + break; + case SAS_PROTOCOL_SATA: + case SAS_PROTOCOL_STP: + case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: + default: + dev_err(dev, "task prep: unknown/unsupported proto (0x%x)\n", + task->task_proto); + rc = -EINVAL; + break; + } + + if (rc) { + dev_err(dev, "task prep: rc = 0x%x\n", rc); + if (slot->sge_page) + goto err_out_sge; + goto err_out_command_table; + } + + list_add_tail(&slot->entry, &port->list); + spin_lock(&task->task_state_lock); + task->task_state_flags |= SAS_TASK_AT_INITIATOR; + spin_unlock(&task->task_state_lock); + + hisi_hba->slot_prep = slot; + + sas_dev->running_req++; + ++(*pass); + + return rc; + +err_out_sge: + dma_pool_free(hisi_hba->sge_page_pool, slot->sge_page, + slot->sge_page_dma); +err_out_command_table: + dma_pool_free(hisi_hba->command_table_pool, slot->command_table, + slot->command_table_dma); +err_out_status_buf: + dma_pool_free(hisi_hba->status_buffer_pool, slot->status_buffer, + slot->status_buffer_dma); +err_out_slot_buf: + /* Nothing to be done */ +err_out_tag: + hisi_sas_slot_index_free(hisi_hba, slot_idx); +err_out: + dev_err(dev, "task prep: failed[%d]!\n", rc); + if (!sas_protocol_ata(task->task_proto)) + if (n_elem) + dma_unmap_sg(dev, task->scatter, n_elem, + task->data_dir); +prep_out: + return rc; +} + +static int hisi_sas_task_exec(struct sas_task *task, gfp_t gfp_flags, + int is_tmf, struct hisi_sas_tmf_task *tmf) +{ + u32 rc; + u32 pass = 0; + unsigned long flags; + struct hisi_hba *hisi_hba = dev_to_hisi_hba(task->dev); + struct device *dev = &hisi_hba->pdev->dev; + + /* protect task_prep and start_delivery sequence */ + spin_lock_irqsave(&hisi_hba->lock, flags); + rc = hisi_sas_task_prep(task, hisi_hba, is_tmf, tmf, &pass); + if (rc) + dev_err(dev, "task exec: failed[%d]!\n", rc); + + if (likely(pass)) + hisi_hba->hw->start_delivery(hisi_hba); + spin_unlock_irqrestore(&hisi_hba->lock, flags); + + return rc; +} static void hisi_sas_bytes_dmaed(struct hisi_hba *hisi_hba, int phy_no) { @@ -100,6 +327,12 @@ static void hisi_sas_phy_init(struct hisi_hba *hisi_hba, int phy_no) INIT_WORK(&phy->phyup_ws, hisi_sas_phyup_work); } + +static int hisi_sas_queue_command(struct sas_task *task, gfp_t gfp_flags) +{ + return hisi_sas_task_exec(task, gfp_flags, 0, NULL); +} + static struct scsi_transport_template *hisi_sas_stt; static struct scsi_host_template hisi_sas_sht = { @@ -122,6 +355,7 @@ static struct scsi_host_template hisi_sas_sht = { }; static struct sas_domain_function_template hisi_sas_transport_ops = { + .lldd_execute_task = hisi_sas_queue_command, }; static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost) diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 4364279..07b9750 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -412,6 +412,13 @@ static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off) return readl(regs); } +static u32 hisi_sas_read32_relaxed(struct hisi_hba *hisi_hba, u32 off) +{ + void __iomem *regs = hisi_hba->regs + off; + + return readl_relaxed(regs); +} + static void hisi_sas_write32(struct hisi_hba *hisi_hba, u32 off, u32 val) { @@ -741,6 +748,190 @@ static void sl_notify_v1_hw(struct hisi_hba *hisi_hba, int phy_no) hisi_sas_phy_write32(hisi_hba, phy_no, SL_CONTROL, sl_control); } +/** + * This function allocates across all queues to load balance. + * Slots are allocated from queues in a round-robin fashion. + * + * The callpath to this function and upto writing the write + * queue pointer should be safe from interruption. + */ +static int get_free_slot_v1_hw(struct hisi_hba *hisi_hba, int *q, int *s) +{ + struct device *dev = &hisi_hba->pdev->dev; + u32 r, w; + int queue = hisi_hba->queue; + + while (1) { + w = hisi_sas_read32_relaxed(hisi_hba, + DLVRY_Q_0_WR_PTR + (queue * 0x14)); + r = hisi_sas_read32_relaxed(hisi_hba, + DLVRY_Q_0_RD_PTR + (queue * 0x14)); + if (r == (w+1) % HISI_SAS_QUEUE_SLOTS) { + queue = (queue + 1) % hisi_hba->queue_count; + if (queue == hisi_hba->queue) { + dev_warn(dev, "could not find free slot\n"); + return -EAGAIN; + } + continue; + } + break; + } + hisi_hba->queue = (queue + 1) % hisi_hba->queue_count; + *q = queue; + *s = w; + return 0; +} + +static void start_delivery_v1_hw(struct hisi_hba *hisi_hba) +{ + int dlvry_queue = hisi_hba->slot_prep->dlvry_queue; + int dlvry_queue_slot = hisi_hba->slot_prep->dlvry_queue_slot; + + hisi_sas_write32(hisi_hba, + DLVRY_Q_0_WR_PTR + (dlvry_queue * 0x14), + ++dlvry_queue_slot % HISI_SAS_QUEUE_SLOTS); +} + +static int prep_prd_sge_v1_hw(struct hisi_hba *hisi_hba, + struct hisi_sas_slot *slot, + struct hisi_sas_cmd_hdr *hdr, + struct scatterlist *scatter, + int n_elem) +{ + struct device *dev = &hisi_hba->pdev->dev; + struct scatterlist *sg; + int i; + + if (n_elem > HISI_SAS_SGE_PAGE_CNT) { + dev_err(dev, "prd err: n_elem(%d) > HISI_SAS_SGE_PAGE_CNT", + n_elem); + return -EINVAL; + } + + slot->sge_page = dma_pool_alloc(hisi_hba->sge_page_pool, GFP_ATOMIC, + &slot->sge_page_dma); + if (!slot->sge_page) + return -ENOMEM; + + for_each_sg(scatter, sg, n_elem, i) { + struct hisi_sas_sge *entry = &slot->sge_page->sge[i]; + + entry->addr = cpu_to_le64(sg_dma_address(sg)); + entry->page_ctrl_0 = entry->page_ctrl_1 = 0; + entry->data_len = cpu_to_le32(sg_dma_len(sg)); + entry->data_off = 0; + } + + hdr->prd_table_addr = cpu_to_le64(slot->sge_page_dma); + + hdr->sg_len = cpu_to_le32(n_elem << CMD_HDR_DATA_SGL_LEN_OFF); + + return 0; +} + + +static int prep_ssp_v1_hw(struct hisi_hba *hisi_hba, + struct hisi_sas_slot *slot, int is_tmf, + struct hisi_sas_tmf_task *tmf) +{ + struct sas_task *task = slot->task; + struct hisi_sas_cmd_hdr *hdr = slot->cmd_hdr; + struct domain_device *device = task->dev; + struct hisi_sas_device *sas_dev = device->lldd_dev; + struct hisi_sas_port *port = slot->port; + struct sas_ssp_task *ssp_task = &task->ssp_task; + struct scsi_cmnd *scsi_cmnd = ssp_task->cmd; + int has_data = 0, rc, priority = is_tmf; + u8 *buf_cmd, fburst = 0; + u32 dw1, dw2; + + /* create header */ + hdr->dw0 = cpu_to_le32((1 << CMD_HDR_RESP_REPORT_OFF) | + (0x2 << CMD_HDR_TLR_CTRL_OFF) | + (port->id << CMD_HDR_PORT_OFF) | + (priority << CMD_HDR_PRIORITY_OFF) | + (1 << CMD_HDR_MODE_OFF) | /* ini mode */ + (1 << CMD_HDR_CMD_OFF)); /* ssp */ + + dw1 = 1 << CMD_HDR_VERIFY_DTL_OFF; + + if (is_tmf) { + dw1 |= 3 << CMD_HDR_SSP_FRAME_TYPE_OFF; + } else { + switch (scsi_cmnd->sc_data_direction) { + case DMA_TO_DEVICE: + dw1 |= 2 << CMD_HDR_SSP_FRAME_TYPE_OFF; + has_data = 1; + break; + case DMA_FROM_DEVICE: + dw1 |= 1 << CMD_HDR_SSP_FRAME_TYPE_OFF; + has_data = 1; + break; + default: + dw1 |= 0 << CMD_HDR_SSP_FRAME_TYPE_OFF; + } + } + + /* map itct entry */ + dw1 |= sas_dev->device_id << CMD_HDR_DEVICE_ID_OFF; + hdr->dw1 = cpu_to_le32(dw1); + + if (is_tmf) { + dw2 = ((sizeof(struct ssp_tmf_iu) + + sizeof(struct ssp_frame_hdr)+3)/4) << + CMD_HDR_CFL_OFF; + } else { + dw2 = ((sizeof(struct ssp_command_iu) + + sizeof(struct ssp_frame_hdr)+3)/4) << + CMD_HDR_CFL_OFF; + } + + dw2 |= (HISI_SAS_MAX_SSP_RESP_SZ/4) << CMD_HDR_MRFL_OFF; + + hdr->transfer_tags = cpu_to_le32(slot->idx << CMD_HDR_IPTT_OFF); + + if (has_data) { + rc = prep_prd_sge_v1_hw(hisi_hba, slot, hdr, task->scatter, + slot->n_elem); + if (rc) + return rc; + } + + hdr->data_transfer_len = cpu_to_le32(task->total_xfer_len); + hdr->cmd_table_addr = cpu_to_le64(slot->command_table_dma); + hdr->sts_buffer_addr = cpu_to_le64(slot->status_buffer_dma); + + buf_cmd = slot->command_table + sizeof(struct ssp_frame_hdr); + if (task->ssp_task.enable_first_burst) { + fburst = (1 << 7); + dw2 |= 1 << CMD_HDR_FIRST_BURST_OFF; + } + hdr->dw2 = cpu_to_le32(dw2); + + memcpy(buf_cmd, &task->ssp_task.LUN, 8); + if (!is_tmf) { + buf_cmd[9] = fburst | task->ssp_task.task_attr | + (task->ssp_task.task_prio << 3); + memcpy(buf_cmd + 12, task->ssp_task.cmd->cmnd, + task->ssp_task.cmd->cmd_len); + } else { + buf_cmd[10] = tmf->tmf; + switch (tmf->tmf) { + case TMF_ABORT_TASK: + case TMF_QUERY_TASK: + buf_cmd[12] = + (tmf->tag_of_task_to_be_managed >> 8) & 0xff; + buf_cmd[13] = + tmf->tag_of_task_to_be_managed & 0xff; + break; + default: + break; + } + } + + return 0; +} + /* Interrupts */ static irqreturn_t int_phyup_v1_hw(int irq_no, void *p) { @@ -919,6 +1110,9 @@ static int hisi_sas_v1_init(struct hisi_hba *hisi_hba) static const struct hisi_sas_hw hisi_sas_v1_hw = { .hw_init = hisi_sas_v1_init, .sl_notify = sl_notify_v1_hw, + .prep_ssp = prep_ssp_v1_hw, + .get_free_slot = get_free_slot_v1_hw, + .start_delivery = start_delivery_v1_hw, .complete_hdr_size = sizeof(struct hisi_sas_complete_v1_hdr), }; -- cgit v0.10.2 From 27a3f2292ea2508d2d1ddd85846910a69ed95a3f Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:50 +0800 Subject: hisi_sas: Add cq interrupt handler Add cq interrupt handler and also slot error handler function. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 72657eb..fe4055b 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -93,6 +93,8 @@ struct hisi_sas_slot { u64 n_elem; int dlvry_queue; int dlvry_queue_slot; + int cmplt_queue; + int cmplt_queue_slot; int idx; void *cmd_hdr; dma_addr_t cmd_hdr_dma; @@ -117,6 +119,10 @@ struct hisi_sas_hw { int (*prep_ssp)(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot, int is_tmf, struct hisi_sas_tmf_task *tmf); + int (*slot_complete)(struct hisi_hba *hisi_hba, + struct hisi_sas_slot *slot, int abort); + void (*free_device)(struct hisi_hba *hisi_hba, + struct hisi_sas_device *dev); int complete_hdr_size; }; @@ -311,4 +317,7 @@ extern int hisi_sas_probe(struct platform_device *pdev, const struct hisi_sas_hw *ops); extern int hisi_sas_remove(struct platform_device *pdev); +extern void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, + struct sas_task *task, + struct hisi_sas_slot *slot); #endif diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 660ef6c..ddbd2b71 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -60,6 +60,41 @@ static void hisi_sas_slot_index_init(struct hisi_hba *hisi_hba) for (i = 0; i < hisi_hba->slot_index_count; ++i) hisi_sas_slot_index_clear(hisi_hba, i); } + +void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task, + struct hisi_sas_slot *slot) +{ + struct device *dev = &hisi_hba->pdev->dev; + + if (!slot->task) + return; + + if (!sas_protocol_ata(task->task_proto)) + if (slot->n_elem) + dma_unmap_sg(dev, task->scatter, slot->n_elem, + task->data_dir); + + if (slot->command_table) + dma_pool_free(hisi_hba->command_table_pool, + slot->command_table, slot->command_table_dma); + + if (slot->status_buffer) + dma_pool_free(hisi_hba->status_buffer_pool, + slot->status_buffer, slot->status_buffer_dma); + + if (slot->sge_page) + dma_pool_free(hisi_hba->sge_page_pool, slot->sge_page, + slot->sge_page_dma); + + list_del_init(&slot->entry); + task->lldd_task = NULL; + slot->task = NULL; + slot->port = NULL; + hisi_sas_slot_index_free(hisi_hba, slot->idx); + memset(slot, 0, sizeof(*slot)); +} +EXPORT_SYMBOL_GPL(hisi_sas_slot_task_free); + static int hisi_sas_task_prep_ssp(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot, int is_tmf, struct hisi_sas_tmf_task *tmf) diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 07b9750..6711c0a 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -498,6 +498,28 @@ static void init_id_frame_v1_hw(struct hisi_hba *hisi_hba) config_id_frame_v1_hw(hisi_hba, i); } + +static void free_device_v1_hw(struct hisi_hba *hisi_hba, + struct hisi_sas_device *sas_dev) +{ + u64 dev_id = sas_dev->device_id; + struct hisi_sas_itct *itct = &hisi_hba->itct[dev_id]; + u32 qw0, reg_val = hisi_sas_read32(hisi_hba, CFG_AGING_TIME); + + reg_val |= CFG_AGING_TIME_ITCT_REL_MSK; + hisi_sas_write32(hisi_hba, CFG_AGING_TIME, reg_val); + + /* free itct */ + udelay(1); + reg_val = hisi_sas_read32(hisi_hba, CFG_AGING_TIME); + reg_val &= ~CFG_AGING_TIME_ITCT_REL_MSK; + hisi_sas_write32(hisi_hba, CFG_AGING_TIME, reg_val); + + qw0 = cpu_to_le64(itct->qw0); + qw0 &= ~ITCT_HDR_VALID_MSK; + itct->qw0 = cpu_to_le64(qw0); +} + static int reset_hw_v1_hw(struct hisi_hba *hisi_hba) { int i; @@ -932,6 +954,253 @@ static int prep_ssp_v1_hw(struct hisi_hba *hisi_hba, return 0; } +/* by default, task resp is complete */ +static void slot_err_v1_hw(struct hisi_hba *hisi_hba, + struct sas_task *task, + struct hisi_sas_slot *slot) +{ + struct task_status_struct *ts = &task->task_status; + struct hisi_sas_err_record *err_record = slot->status_buffer; + struct device *dev = &hisi_hba->pdev->dev; + + switch (task->task_proto) { + case SAS_PROTOCOL_SSP: + { + int error = -1; + u32 dma_err_type = cpu_to_le32(err_record->dma_err_type); + u32 dma_tx_err_type = ((dma_err_type & + ERR_HDR_DMA_TX_ERR_TYPE_MSK)) >> + ERR_HDR_DMA_TX_ERR_TYPE_OFF; + u32 dma_rx_err_type = ((dma_err_type & + ERR_HDR_DMA_RX_ERR_TYPE_MSK)) >> + ERR_HDR_DMA_RX_ERR_TYPE_OFF; + u32 trans_tx_fail_type = + cpu_to_le32(err_record->trans_tx_fail_type); + u32 trans_rx_fail_type = + cpu_to_le32(err_record->trans_rx_fail_type); + + if (dma_tx_err_type) { + /* dma tx err */ + error = ffs(dma_tx_err_type) + - 1 + DMA_TX_ERR_BASE; + } else if (dma_rx_err_type) { + /* dma rx err */ + error = ffs(dma_rx_err_type) + - 1 + DMA_RX_ERR_BASE; + } else if (trans_tx_fail_type) { + /* trans tx err */ + error = ffs(trans_tx_fail_type) + - 1 + TRANS_TX_FAIL_BASE; + } else if (trans_rx_fail_type) { + /* trans rx err */ + error = ffs(trans_rx_fail_type) + - 1 + TRANS_RX_FAIL_BASE; + } + + switch (error) { + case DMA_TX_DATA_UNDERFLOW_ERR: + case DMA_RX_DATA_UNDERFLOW_ERR: + { + ts->residual = 0; + ts->stat = SAS_DATA_UNDERRUN; + break; + } + case DMA_TX_DATA_SGL_OVERFLOW_ERR: + case DMA_TX_DIF_SGL_OVERFLOW_ERR: + case DMA_TX_XFER_RDY_LENGTH_OVERFLOW_ERR: + case DMA_RX_DATA_OVERFLOW_ERR: + case TRANS_RX_FRAME_OVERRUN_ERR: + case TRANS_RX_LINK_BUF_OVERRUN_ERR: + { + ts->stat = SAS_DATA_OVERRUN; + ts->residual = 0; + break; + } + case TRANS_TX_PHY_NOT_ENABLE_ERR: + { + ts->stat = SAS_PHY_DOWN; + break; + } + case TRANS_TX_OPEN_REJCT_WRONG_DEST_ERR: + case TRANS_TX_OPEN_REJCT_ZONE_VIOLATION_ERR: + case TRANS_TX_OPEN_REJCT_BY_OTHER_ERR: + case TRANS_TX_OPEN_REJCT_AIP_TIMEOUT_ERR: + case TRANS_TX_OPEN_REJCT_STP_BUSY_ERR: + case TRANS_TX_OPEN_REJCT_PROTOCOL_NOT_SUPPORT_ERR: + case TRANS_TX_OPEN_REJCT_RATE_NOT_SUPPORT_ERR: + case TRANS_TX_OPEN_REJCT_BAD_DEST_ERR: + case TRANS_TX_OPEN_BREAK_RECEIVE_ERR: + case TRANS_TX_OPEN_REJCT_PATHWAY_BLOCKED_ERR: + case TRANS_TX_OPEN_REJCT_NO_DEST_ERR: + case TRANS_TX_OPEN_RETRY_ERR: + { + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_UNKNOWN; + break; + } + case TRANS_TX_OPEN_TIMEOUT_ERR: + { + ts->stat = SAS_OPEN_TO; + break; + } + case TRANS_TX_NAK_RECEIVE_ERR: + case TRANS_TX_ACK_NAK_TIMEOUT_ERR: + { + ts->stat = SAS_NAK_R_ERR; + break; + } + default: + { + ts->stat = SAM_STAT_CHECK_CONDITION; + break; + } + } + } + break; + case SAS_PROTOCOL_SMP: + ts->stat = SAM_STAT_CHECK_CONDITION; + break; + + case SAS_PROTOCOL_SATA: + case SAS_PROTOCOL_STP: + case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: + { + dev_err(dev, "slot err: SATA/STP not supported"); + } + break; + default: + break; + } + +} + +static int slot_complete_v1_hw(struct hisi_hba *hisi_hba, + struct hisi_sas_slot *slot, int abort) +{ + struct sas_task *task = slot->task; + struct hisi_sas_device *sas_dev; + struct device *dev = &hisi_hba->pdev->dev; + struct task_status_struct *ts; + struct domain_device *device; + enum exec_status sts; + struct hisi_sas_complete_v1_hdr *complete_queue = + (struct hisi_sas_complete_v1_hdr *) + hisi_hba->complete_hdr[slot->cmplt_queue]; + struct hisi_sas_complete_v1_hdr *complete_hdr; + u32 cmplt_hdr_data; + + complete_hdr = &complete_queue[slot->cmplt_queue_slot]; + cmplt_hdr_data = le32_to_cpu(complete_hdr->data); + + if (unlikely(!task || !task->lldd_task || !task->dev)) + return -EINVAL; + + ts = &task->task_status; + device = task->dev; + sas_dev = device->lldd_dev; + + task->task_state_flags &= + ~(SAS_TASK_STATE_PENDING | SAS_TASK_AT_INITIATOR); + task->task_state_flags |= SAS_TASK_STATE_DONE; + + memset(ts, 0, sizeof(*ts)); + ts->resp = SAS_TASK_COMPLETE; + + if (unlikely(!sas_dev || abort)) { + if (!sas_dev) + dev_dbg(dev, "slot complete: port has not device\n"); + ts->stat = SAS_PHY_DOWN; + goto out; + } + + if (cmplt_hdr_data & CMPLT_HDR_IO_CFG_ERR_MSK) { + u32 info_reg = hisi_sas_read32(hisi_hba, HGC_INVLD_DQE_INFO); + + if (info_reg & HGC_INVLD_DQE_INFO_DQ_MSK) + dev_err(dev, "slot complete: [%d:%d] has dq IPTT err", + slot->cmplt_queue, slot->cmplt_queue_slot); + + if (info_reg & HGC_INVLD_DQE_INFO_TYPE_MSK) + dev_err(dev, "slot complete: [%d:%d] has dq type err", + slot->cmplt_queue, slot->cmplt_queue_slot); + + if (info_reg & HGC_INVLD_DQE_INFO_FORCE_MSK) + dev_err(dev, "slot complete: [%d:%d] has dq force phy err", + slot->cmplt_queue, slot->cmplt_queue_slot); + + if (info_reg & HGC_INVLD_DQE_INFO_PHY_MSK) + dev_err(dev, "slot complete: [%d:%d] has dq phy id err", + slot->cmplt_queue, slot->cmplt_queue_slot); + + if (info_reg & HGC_INVLD_DQE_INFO_ABORT_MSK) + dev_err(dev, "slot complete: [%d:%d] has dq abort flag err", + slot->cmplt_queue, slot->cmplt_queue_slot); + + if (info_reg & HGC_INVLD_DQE_INFO_IPTT_OF_MSK) + dev_err(dev, "slot complete: [%d:%d] has dq IPTT or ICT err", + slot->cmplt_queue, slot->cmplt_queue_slot); + + if (info_reg & HGC_INVLD_DQE_INFO_SSP_ERR_MSK) + dev_err(dev, "slot complete: [%d:%d] has dq SSP frame type err", + slot->cmplt_queue, slot->cmplt_queue_slot); + + if (info_reg & HGC_INVLD_DQE_INFO_OFL_MSK) + dev_err(dev, "slot complete: [%d:%d] has dq order frame len err", + slot->cmplt_queue, slot->cmplt_queue_slot); + + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_UNKNOWN; + goto out; + } + + if (cmplt_hdr_data & CMPLT_HDR_ERR_RCRD_XFRD_MSK) { + if (!(cmplt_hdr_data & CMPLT_HDR_CMD_CMPLT_MSK) || + !(cmplt_hdr_data & CMPLT_HDR_RSPNS_XFRD_MSK)) + ts->stat = SAS_DATA_OVERRUN; + else + slot_err_v1_hw(hisi_hba, task, slot); + + goto out; + } + + switch (task->task_proto) { + case SAS_PROTOCOL_SSP: + { + struct ssp_response_iu *iu = slot->status_buffer + + sizeof(struct hisi_sas_err_record); + sas_ssp_task_response(dev, task, iu); + break; + } + case SAS_PROTOCOL_SATA: + case SAS_PROTOCOL_STP: + case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: + dev_err(dev, "slot complete: SATA/STP not supported"); + break; + + default: + ts->stat = SAM_STAT_CHECK_CONDITION; + break; + } + + if (!slot->port->port_attached) { + dev_err(dev, "slot complete: port %d has removed\n", + slot->port->sas_port.id); + ts->stat = SAS_PHY_DOWN; + } + +out: + if (sas_dev && sas_dev->running_req) + sas_dev->running_req--; + + hisi_sas_slot_task_free(hisi_hba, task, slot); + sts = ts->stat; + + if (task->task_done) + task->task_done(task); + + return sts; +} + /* Interrupts */ static irqreturn_t int_phyup_v1_hw(int irq_no, void *p) { @@ -1011,9 +1280,61 @@ end: return res; } + +static irqreturn_t cq_interrupt_v1_hw(int irq, void *p) +{ + struct hisi_sas_cq *cq = p; + struct hisi_hba *hisi_hba = cq->hisi_hba; + struct hisi_sas_slot *slot; + int queue = cq->id; + struct hisi_sas_complete_v1_hdr *complete_queue = + (struct hisi_sas_complete_v1_hdr *) + hisi_hba->complete_hdr[queue]; + u32 irq_value, rd_point, wr_point; + + irq_value = hisi_sas_read32(hisi_hba, OQ_INT_SRC); + + hisi_sas_write32(hisi_hba, OQ_INT_SRC, 1 << queue); + + rd_point = hisi_sas_read32(hisi_hba, + COMPL_Q_0_RD_PTR + (0x14 * queue)); + wr_point = hisi_sas_read32(hisi_hba, + COMPL_Q_0_WR_PTR + (0x14 * queue)); + + while (rd_point != wr_point) { + struct hisi_sas_complete_v1_hdr *complete_hdr; + int idx; + u32 cmplt_hdr_data; + + complete_hdr = &complete_queue[rd_point]; + cmplt_hdr_data = cpu_to_le32(complete_hdr->data); + idx = (cmplt_hdr_data & CMPLT_HDR_IPTT_MSK) >> + CMPLT_HDR_IPTT_OFF; + slot = &hisi_hba->slot_info[idx]; + + /* The completion queue and queue slot index are not + * necessarily the same as the delivery queue and + * queue slot index. + */ + slot->cmplt_queue_slot = rd_point; + slot->cmplt_queue = queue; + slot_complete_v1_hw(hisi_hba, slot, 0); + + if (++rd_point >= HISI_SAS_QUEUE_SLOTS) + rd_point = 0; + } + + /* update rd_point */ + hisi_sas_write32(hisi_hba, COMPL_Q_0_RD_PTR + (0x14 * queue), rd_point); + + return IRQ_HANDLED; +} + static const char phy_int_names[HISI_SAS_PHY_INT_NR][32] = { {"Phy Up"}, }; + +static const char cq_int_name[32] = "cq"; static irq_handler_t phy_interrupts[HISI_SAS_PHY_INT_NR] = { int_phyup_v1_hw, }; @@ -1056,6 +1377,28 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) } } } + + idx = hisi_hba->n_phy * HISI_SAS_PHY_INT_NR; + for (i = 0; i < hisi_hba->queue_count; i++, idx++) { + irq = irq_of_parse_and_map(np, idx); + if (!irq) { + dev_err(dev, "irq init: could not map cq interrupt %d\n", + idx); + return -ENOENT; + } + (void)snprintf(&int_names[idx * HISI_SAS_NAME_LEN], + HISI_SAS_NAME_LEN, + "%s %s:%d", dev_name(dev), cq_int_name, i); + rc = devm_request_irq(dev, irq, cq_interrupt_v1_hw, 0, + &int_names[idx * HISI_SAS_NAME_LEN], + &hisi_hba->cq[i]); + if (rc) { + dev_err(dev, "irq init: could not request cq interrupt %d, rc=%d\n", + irq, rc); + return -ENOENT; + } + } + return 0; } @@ -1110,9 +1453,11 @@ static int hisi_sas_v1_init(struct hisi_hba *hisi_hba) static const struct hisi_sas_hw hisi_sas_v1_hw = { .hw_init = hisi_sas_v1_init, .sl_notify = sl_notify_v1_hw, + .free_device = free_device_v1_hw, .prep_ssp = prep_ssp_v1_hw, .get_free_slot = get_free_slot_v1_hw, .start_delivery = start_delivery_v1_hw, + .slot_complete = slot_complete_v1_hw, .complete_hdr_size = sizeof(struct hisi_sas_complete_v1_hdr), }; -- cgit v0.10.2 From abda97c2fe874cd8826fe25a77f66c75bcc7b5cd Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:51 +0800 Subject: hisi_sas: Add dev_found and dev_gone Add functions to deal with lldd_dev_found and lldd_dev_gone. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index fe4055b..999f319 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -39,6 +39,7 @@ #define HISI_SAS_NAME_LEN 32 +struct hisi_hba; enum { PORT_TYPE_SAS = (1U << 1), @@ -49,6 +50,13 @@ enum dev_status { HISI_SAS_DEV_NORMAL, HISI_SAS_DEV_EH, }; + +enum hisi_sas_dev_type { + HISI_SAS_DEV_TYPE_STP = 0, + HISI_SAS_DEV_TYPE_SSP, + HISI_SAS_DEV_TYPE_SATA, +}; + struct hisi_sas_phy { struct hisi_hba *hisi_hba; struct hisi_sas_port *port; @@ -81,6 +89,9 @@ struct hisi_sas_cq { struct hisi_sas_device { enum sas_device_type dev_type; + struct hisi_hba *hisi_hba; + struct domain_device *sas_device; + u64 attached_phy; u64 device_id; u64 running_req; u8 dev_status; @@ -113,6 +124,8 @@ struct hisi_sas_tmf_task { struct hisi_sas_hw { int (*hw_init)(struct hisi_hba *hisi_hba); + void (*setup_itct)(struct hisi_hba *hisi_hba, + struct hisi_sas_device *device); void (*sl_notify)(struct hisi_hba *hisi_hba, int phy_no); int (*get_free_slot)(struct hisi_hba *hisi_hba, int *q, int *s); void (*start_delivery)(struct hisi_hba *hisi_hba); diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index ddbd2b71..d8af4c6 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -12,6 +12,9 @@ #include "hisi_sas.h" #define DRV_NAME "hisi_sas" +#define DEV_IS_EXPANDER(type) \ + ((type == SAS_EDGE_EXPANDER_DEVICE) || \ + (type == SAS_FANOUT_EXPANDER_DEVICE)) #define DEV_IS_GONE(dev) \ ((!dev) || (dev->dev_type == SAS_PHY_UNUSED)) @@ -325,6 +328,72 @@ static void hisi_sas_bytes_dmaed(struct hisi_hba *hisi_hba, int phy_no) sas_ha->notify_port_event(sas_phy, PORTE_BYTES_DMAED); } +static struct hisi_sas_device *hisi_sas_alloc_dev(struct domain_device *device) +{ + struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); + struct hisi_sas_device *sas_dev = NULL; + int i; + + spin_lock(&hisi_hba->lock); + for (i = 0; i < HISI_SAS_MAX_DEVICES; i++) { + if (hisi_hba->devices[i].dev_type == SAS_PHY_UNUSED) { + hisi_hba->devices[i].device_id = i; + sas_dev = &hisi_hba->devices[i]; + sas_dev->dev_status = HISI_SAS_DEV_NORMAL; + sas_dev->dev_type = device->dev_type; + sas_dev->hisi_hba = hisi_hba; + sas_dev->sas_device = device; + break; + } + } + spin_unlock(&hisi_hba->lock); + + return sas_dev; +} + +static int hisi_sas_dev_found(struct domain_device *device) +{ + struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); + struct domain_device *parent_dev = device->parent; + struct hisi_sas_device *sas_dev; + struct device *dev = &hisi_hba->pdev->dev; + + sas_dev = hisi_sas_alloc_dev(device); + if (!sas_dev) { + dev_err(dev, "fail alloc dev: max support %d devices\n", + HISI_SAS_MAX_DEVICES); + return -EINVAL; + } + + device->lldd_dev = sas_dev; + hisi_hba->hw->setup_itct(hisi_hba, sas_dev); + + if (parent_dev && DEV_IS_EXPANDER(parent_dev->dev_type)) { + int phy_no; + u8 phy_num = parent_dev->ex_dev.num_phys; + struct ex_phy *phy; + + for (phy_no = 0; phy_no < phy_num; phy_no++) { + phy = &parent_dev->ex_dev.ex_phy[phy_no]; + if (SAS_ADDR(phy->attached_sas_addr) == + SAS_ADDR(device->sas_addr)) { + sas_dev->attached_phy = phy_no; + break; + } + } + + if (phy_no == phy_num) { + dev_info(dev, "dev found: no attached " + "dev:%016llx at ex:%016llx\n", + SAS_ADDR(device->sas_addr), + SAS_ADDR(parent_dev->sas_addr)); + return -EINVAL; + } + } + + return 0; +} + static void hisi_sas_phyup_work(struct work_struct *work) { struct hisi_sas_phy *phy = @@ -362,6 +431,23 @@ static void hisi_sas_phy_init(struct hisi_hba *hisi_hba, int phy_no) INIT_WORK(&phy->phyup_ws, hisi_sas_phyup_work); } +static void hisi_sas_dev_gone(struct domain_device *device) +{ + struct hisi_sas_device *sas_dev = device->lldd_dev; + struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); + struct device *dev = &hisi_hba->pdev->dev; + u64 dev_id = sas_dev->device_id; + + dev_info(dev, "found dev[%lld:%x] is gone\n", + sas_dev->device_id, sas_dev->dev_type); + + hisi_hba->hw->free_device(hisi_hba, sas_dev); + device->lldd_dev = NULL; + memset(sas_dev, 0, sizeof(*sas_dev)); + sas_dev->device_id = dev_id; + sas_dev->dev_type = SAS_PHY_UNUSED; + sas_dev->dev_status = HISI_SAS_DEV_NORMAL; +} static int hisi_sas_queue_command(struct sas_task *task, gfp_t gfp_flags) { @@ -390,6 +476,8 @@ static struct scsi_host_template hisi_sas_sht = { }; static struct sas_domain_function_template hisi_sas_transport_ops = { + .lldd_dev_found = hisi_sas_dev_found, + .lldd_dev_gone = hisi_sas_dev_gone, .lldd_execute_task = hisi_sas_queue_command, }; diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 6711c0a..530e771 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -498,6 +498,46 @@ static void init_id_frame_v1_hw(struct hisi_hba *hisi_hba) config_id_frame_v1_hw(hisi_hba, i); } +static void setup_itct_v1_hw(struct hisi_hba *hisi_hba, + struct hisi_sas_device *sas_dev) +{ + struct domain_device *device = sas_dev->sas_device; + struct device *dev = &hisi_hba->pdev->dev; + u64 qw0, device_id = sas_dev->device_id; + struct hisi_sas_itct *itct = &hisi_hba->itct[device_id]; + + memset(itct, 0, sizeof(*itct)); + + /* qw0 */ + qw0 = 0; + switch (sas_dev->dev_type) { + case SAS_END_DEVICE: + case SAS_EDGE_EXPANDER_DEVICE: + case SAS_FANOUT_EXPANDER_DEVICE: + qw0 = HISI_SAS_DEV_TYPE_SSP << ITCT_HDR_DEV_TYPE_OFF; + break; + default: + dev_warn(dev, "setup itct: unsupported dev type (%d)\n", + sas_dev->dev_type); + } + + qw0 |= ((1 << ITCT_HDR_VALID_OFF) | + (1 << ITCT_HDR_AWT_CONTROL_OFF) | + (device->max_linkrate << ITCT_HDR_MAX_CONN_RATE_OFF) | + (1 << ITCT_HDR_VALID_LINK_NUM_OFF) | + (device->port->id << ITCT_HDR_PORT_ID_OFF)); + itct->qw0 = cpu_to_le64(qw0); + + /* qw1 */ + memcpy(&itct->sas_addr, device->sas_addr, SAS_ADDR_SIZE); + itct->sas_addr = __swab64(itct->sas_addr); + + /* qw2 */ + itct->qw2 = cpu_to_le64((500 < ITCT_HDR_IT_NEXUS_LOSS_TL_OFF) | + (0xff00 < ITCT_HDR_BUS_INACTIVE_TL_OFF) | + (0xff00 < ITCT_HDR_MAX_CONN_TL_OFF) | + (0xff00 < ITCT_HDR_REJ_OPEN_TL_OFF)); +} static void free_device_v1_hw(struct hisi_hba *hisi_hba, struct hisi_sas_device *sas_dev) @@ -1452,6 +1492,7 @@ static int hisi_sas_v1_init(struct hisi_hba *hisi_hba) static const struct hisi_sas_hw hisi_sas_v1_hw = { .hw_init = hisi_sas_v1_init, + .setup_itct = setup_itct_v1_hw, .sl_notify = sl_notify_v1_hw, .free_device = free_device_v1_hw, .prep_ssp = prep_ssp_v1_hw, -- cgit v0.10.2 From 184a4635340be6e0e804240ff889c3c82d6e4745 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:52 +0800 Subject: hisi_sas: Add abnormal irq handler Add abnormal irq handler. This handler is concerned with phy down event. Also add port formed and port deformed handlers. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 999f319..e5ee3c9 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -136,6 +136,7 @@ struct hisi_sas_hw { struct hisi_sas_slot *slot, int abort); void (*free_device)(struct hisi_hba *hisi_hba, struct hisi_sas_device *dev); + int (*get_wideport_bitmap)(struct hisi_hba *hisi_hba, int port_id); int complete_hdr_size; }; @@ -330,6 +331,7 @@ extern int hisi_sas_probe(struct platform_device *pdev, const struct hisi_sas_hw *ops); extern int hisi_sas_remove(struct platform_device *pdev); +extern void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy); extern void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task, struct hisi_sas_slot *slot); diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index d8af4c6..1797851 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -431,6 +431,72 @@ static void hisi_sas_phy_init(struct hisi_hba *hisi_hba, int phy_no) INIT_WORK(&phy->phyup_ws, hisi_sas_phyup_work); } +static void hisi_sas_port_notify_formed(struct asd_sas_phy *sas_phy) +{ + struct sas_ha_struct *sas_ha = sas_phy->ha; + struct hisi_hba *hisi_hba = sas_ha->lldd_ha; + struct hisi_sas_phy *phy = sas_phy->lldd_phy; + struct asd_sas_port *sas_port = sas_phy->port; + struct hisi_sas_port *port = &hisi_hba->port[sas_phy->id]; + unsigned long flags; + + if (!sas_port) + return; + + spin_lock_irqsave(&hisi_hba->lock, flags); + port->port_attached = 1; + port->id = phy->port_id; + phy->port = port; + sas_port->lldd_port = port; + spin_unlock_irqrestore(&hisi_hba->lock, flags); +} + +static void hisi_sas_do_release_task(struct hisi_hba *hisi_hba, int phy_no, + struct domain_device *device) +{ + struct hisi_sas_phy *phy; + struct hisi_sas_port *port; + struct hisi_sas_slot *slot, *slot2; + struct device *dev = &hisi_hba->pdev->dev; + + phy = &hisi_hba->phy[phy_no]; + port = phy->port; + if (!port) + return; + + list_for_each_entry_safe(slot, slot2, &port->list, entry) { + struct sas_task *task; + + task = slot->task; + if (device && task->dev != device) + continue; + + dev_info(dev, "Release slot [%d:%d], task [%p]:\n", + slot->dlvry_queue, slot->dlvry_queue_slot, task); + hisi_hba->hw->slot_complete(hisi_hba, slot, 1); + } +} + +static void hisi_sas_port_notify_deformed(struct asd_sas_phy *sas_phy) +{ + struct domain_device *device; + struct hisi_sas_phy *phy = sas_phy->lldd_phy; + struct asd_sas_port *sas_port = sas_phy->port; + + list_for_each_entry(device, &sas_port->dev_list, dev_list_node) + hisi_sas_do_release_task(phy->hisi_hba, sas_phy->id, device); +} + +static void hisi_sas_release_task(struct hisi_hba *hisi_hba, + struct domain_device *device) +{ + struct asd_sas_port *port = device->port; + struct asd_sas_phy *sas_phy; + + list_for_each_entry(sas_phy, &port->phy_list, port_phy_el) + hisi_sas_do_release_task(hisi_hba, sas_phy->id, device); +} + static void hisi_sas_dev_gone(struct domain_device *device) { struct hisi_sas_device *sas_dev = device->lldd_dev; @@ -454,6 +520,56 @@ static int hisi_sas_queue_command(struct sas_task *task, gfp_t gfp_flags) return hisi_sas_task_exec(task, gfp_flags, 0, NULL); } + +static void hisi_sas_port_formed(struct asd_sas_phy *sas_phy) +{ + hisi_sas_port_notify_formed(sas_phy); +} + +static void hisi_sas_port_deformed(struct asd_sas_phy *sas_phy) +{ + hisi_sas_port_notify_deformed(sas_phy); +} + +static void hisi_sas_phy_disconnected(struct hisi_sas_phy *phy) +{ + phy->phy_attached = 0; + phy->phy_type = 0; + phy->port = NULL; +} + +void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy) +{ + struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; + struct asd_sas_phy *sas_phy = &phy->sas_phy; + struct sas_ha_struct *sas_ha = &hisi_hba->sha; + + if (rdy) { + /* Phy down but ready */ + hisi_sas_bytes_dmaed(hisi_hba, phy_no); + hisi_sas_port_notify_formed(sas_phy); + } else { + struct hisi_sas_port *port = phy->port; + + /* Phy down and not ready */ + sas_ha->notify_phy_event(sas_phy, PHYE_LOSS_OF_SIGNAL); + sas_phy_disconnected(sas_phy); + + if (port) { + if (phy->phy_type & PORT_TYPE_SAS) { + int port_id = port->id; + + if (!hisi_hba->hw->get_wideport_bitmap(hisi_hba, + port_id)) + port->port_attached = 0; + } else if (phy->phy_type & PORT_TYPE_SATA) + port->port_attached = 0; + } + hisi_sas_phy_disconnected(phy); + } +} +EXPORT_SYMBOL_GPL(hisi_sas_phy_down); + static struct scsi_transport_template *hisi_sas_stt; static struct scsi_host_template hisi_sas_sht = { @@ -479,6 +595,8 @@ static struct sas_domain_function_template hisi_sas_transport_ops = { .lldd_dev_found = hisi_sas_dev_found, .lldd_dev_gone = hisi_sas_dev_gone, .lldd_execute_task = hisi_sas_queue_command, + .lldd_port_formed = hisi_sas_port_formed, + .lldd_port_deformed = hisi_sas_port_deformed, }; static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost) diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 530e771..1723dd4 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -810,6 +810,18 @@ static void sl_notify_v1_hw(struct hisi_hba *hisi_hba, int phy_no) hisi_sas_phy_write32(hisi_hba, phy_no, SL_CONTROL, sl_control); } +static int get_wideport_bitmap_v1_hw(struct hisi_hba *hisi_hba, int port_id) +{ + int i, bitmap = 0; + u32 phy_port_num_ma = hisi_sas_read32(hisi_hba, PHY_PORT_NUM_MA); + + for (i = 0; i < hisi_hba->n_phy; i++) + if (((phy_port_num_ma >> (i * 4)) & 0xf) == port_id) + bitmap |= 1 << i; + + return bitmap; +} + /** * This function allocates across all queues to load balance. * Slots are allocated from queues in a round-robin fashion. @@ -1321,6 +1333,61 @@ end: return res; } +static irqreturn_t int_abnormal_v1_hw(int irq, void *p) +{ + struct hisi_sas_phy *phy = p; + struct hisi_hba *hisi_hba = phy->hisi_hba; + struct device *dev = &hisi_hba->pdev->dev; + struct asd_sas_phy *sas_phy = &phy->sas_phy; + u32 irq_value, irq_mask_old; + int phy_no = sas_phy->id; + + /* mask_int0 */ + irq_mask_old = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT0_MSK); + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0_MSK, 0x3fffff); + + /* read int0 */ + irq_value = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT0); + + if (irq_value & CHL_INT0_PHYCTRL_NOTRDY_MSK) { + u32 phy_state = hisi_sas_read32(hisi_hba, PHY_STATE); + + hisi_sas_phy_down(hisi_hba, phy_no, + (phy_state & 1 << phy_no) ? 1 : 0); + } + + if (irq_value & CHL_INT0_ID_TIMEOUT_MSK) + dev_dbg(dev, "abnormal: ID_TIMEOUT phy%d identify timeout\n", + phy_no); + + if (irq_value & CHL_INT0_DWS_LOST_MSK) + dev_dbg(dev, "abnormal: DWS_LOST phy%d dws lost\n", phy_no); + + if (irq_value & CHL_INT0_SN_FAIL_NGR_MSK) + dev_dbg(dev, "abnormal: SN_FAIL_NGR phy%d sn fail ngr\n", + phy_no); + + if (irq_value & CHL_INT0_SL_IDAF_FAIL_MSK || + irq_value & CHL_INT0_SL_OPAF_FAIL_MSK) + dev_dbg(dev, "abnormal: SL_ID/OPAF_FAIL phy%d check adr frm err\n", + phy_no); + + if (irq_value & CHL_INT0_SL_PS_FAIL_OFF) + dev_dbg(dev, "abnormal: SL_PS_FAIL phy%d fail\n", phy_no); + + /* write to zero */ + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, irq_value); + + if (irq_value & CHL_INT0_PHYCTRL_NOTRDY_MSK) + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0_MSK, + 0x3fffff & ~CHL_INT0_MSK_PHYCTRL_NOTRDY_MSK); + else + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0_MSK, + irq_mask_old); + + return IRQ_HANDLED; +} + static irqreturn_t cq_interrupt_v1_hw(int irq, void *p) { struct hisi_sas_cq *cq = p; @@ -1372,11 +1439,13 @@ static irqreturn_t cq_interrupt_v1_hw(int irq, void *p) static const char phy_int_names[HISI_SAS_PHY_INT_NR][32] = { {"Phy Up"}, + {"Abnormal"}, }; static const char cq_int_name[32] = "cq"; static irq_handler_t phy_interrupts[HISI_SAS_PHY_INT_NR] = { int_phyup_v1_hw, + int_abnormal_v1_hw }; static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) @@ -1499,6 +1568,7 @@ static const struct hisi_sas_hw hisi_sas_v1_hw = { .get_free_slot = get_free_slot_v1_hw, .start_delivery = start_delivery_v1_hw, .slot_complete = slot_complete_v1_hw, + .get_wideport_bitmap = get_wideport_bitmap_v1_hw, .complete_hdr_size = sizeof(struct hisi_sas_complete_v1_hdr), }; -- cgit v0.10.2 From dc5da4cf8e4c29f82e4ead8cf4d4dad61c78fab9 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:53 +0800 Subject: hisi_sas: Add bcast interrupt handler This is for expander broadcast event. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 1723dd4..ad50aed 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -1333,6 +1333,35 @@ end: return res; } +static irqreturn_t int_bcast_v1_hw(int irq, void *p) +{ + struct hisi_sas_phy *phy = p; + struct hisi_hba *hisi_hba = phy->hisi_hba; + struct asd_sas_phy *sas_phy = &phy->sas_phy; + struct sas_ha_struct *sha = &hisi_hba->sha; + struct device *dev = &hisi_hba->pdev->dev; + int phy_no = sas_phy->id; + u32 irq_value; + irqreturn_t res = IRQ_HANDLED; + + irq_value = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT2); + + if (!(irq_value & CHL_INT2_SL_RX_BC_ACK_MSK)) { + dev_err(dev, "bcast: irq_value = %x not set enable bit", + irq_value); + res = IRQ_NONE; + goto end; + } + + sha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); + +end: + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2, + CHL_INT2_SL_RX_BC_ACK_MSK); + + return res; +} + static irqreturn_t int_abnormal_v1_hw(int irq, void *p) { struct hisi_sas_phy *phy = p; @@ -1438,12 +1467,14 @@ static irqreturn_t cq_interrupt_v1_hw(int irq, void *p) } static const char phy_int_names[HISI_SAS_PHY_INT_NR][32] = { + {"Bcast"}, {"Phy Up"}, {"Abnormal"}, }; static const char cq_int_name[32] = "cq"; static irq_handler_t phy_interrupts[HISI_SAS_PHY_INT_NR] = { + int_bcast_v1_hw, int_phyup_v1_hw, int_abnormal_v1_hw }; -- cgit v0.10.2 From 66ee999b4e43e15182beb458689ec61b5715d568 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:54 +0800 Subject: hisi_sas: Add smp protocol support Add support for smp function, which allows devices attached by expander to be controlled. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index e5ee3c9..f34f73b 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -36,6 +36,7 @@ (((sizeof(union hisi_sas_command_table)+3)/4)*4) #define HISI_SAS_MAX_SSP_RESP_SZ (sizeof(struct ssp_frame_hdr) + 1024) +#define HISI_SAS_MAX_SMP_RESP_SZ 1028 #define HISI_SAS_NAME_LEN 32 @@ -132,6 +133,8 @@ struct hisi_sas_hw { int (*prep_ssp)(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot, int is_tmf, struct hisi_sas_tmf_task *tmf); + int (*prep_smp)(struct hisi_hba *hisi_hba, + struct hisi_sas_slot *slot); int (*slot_complete)(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot, int abort); void (*free_device)(struct hisi_hba *hisi_hba, diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 1797851..406ffa0 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -98,6 +98,12 @@ void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task, } EXPORT_SYMBOL_GPL(hisi_sas_slot_task_free); +static int hisi_sas_task_prep_smp(struct hisi_hba *hisi_hba, + struct hisi_sas_slot *slot) +{ + return hisi_hba->hw->prep_smp(hisi_hba, slot); +} + static int hisi_sas_task_prep_ssp(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot, int is_tmf, struct hisi_sas_tmf_task *tmf) @@ -215,6 +221,9 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_hba *hisi_hba, memset(slot->cmd_hdr, 0, sizeof(struct hisi_sas_cmd_hdr)); switch (task->task_proto) { + case SAS_PROTOCOL_SMP: + rc = hisi_sas_task_prep_smp(hisi_hba, slot); + break; case SAS_PROTOCOL_SSP: rc = hisi_sas_task_prep_ssp(hisi_hba, slot, is_tmf, tmf); break; diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index ad50aed..64b17a1 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -903,6 +903,74 @@ static int prep_prd_sge_v1_hw(struct hisi_hba *hisi_hba, return 0; } +static int prep_smp_v1_hw(struct hisi_hba *hisi_hba, + struct hisi_sas_slot *slot) +{ + struct sas_task *task = slot->task; + struct hisi_sas_cmd_hdr *hdr = slot->cmd_hdr; + struct domain_device *device = task->dev; + struct device *dev = &hisi_hba->pdev->dev; + struct hisi_sas_port *port = slot->port; + struct scatterlist *sg_req, *sg_resp; + struct hisi_sas_device *sas_dev = device->lldd_dev; + dma_addr_t req_dma_addr; + unsigned int req_len, resp_len; + int elem, rc; + + /* + * DMA-map SMP request, response buffers + */ + /* req */ + sg_req = &task->smp_task.smp_req; + elem = dma_map_sg(dev, sg_req, 1, DMA_TO_DEVICE); + if (!elem) + return -ENOMEM; + req_len = sg_dma_len(sg_req); + req_dma_addr = sg_dma_address(sg_req); + + /* resp */ + sg_resp = &task->smp_task.smp_resp; + elem = dma_map_sg(dev, sg_resp, 1, DMA_FROM_DEVICE); + if (!elem) { + rc = -ENOMEM; + goto err_out_req; + } + resp_len = sg_dma_len(sg_resp); + if ((req_len & 0x3) || (resp_len & 0x3)) { + rc = -EINVAL; + goto err_out_resp; + } + + /* create header */ + /* dw0 */ + hdr->dw0 = cpu_to_le32((port->id << CMD_HDR_PORT_OFF) | + (1 << CMD_HDR_PRIORITY_OFF) | /* high pri */ + (1 << CMD_HDR_MODE_OFF) | /* ini mode */ + (2 << CMD_HDR_CMD_OFF)); /* smp */ + + /* map itct entry */ + hdr->dw1 = cpu_to_le32(sas_dev->device_id << CMD_HDR_DEVICE_ID_OFF); + + /* dw2 */ + hdr->dw2 = cpu_to_le32((((req_len-4)/4) << CMD_HDR_CFL_OFF) | + (HISI_SAS_MAX_SMP_RESP_SZ/4 << + CMD_HDR_MRFL_OFF)); + + hdr->transfer_tags = cpu_to_le32(slot->idx << CMD_HDR_IPTT_OFF); + + hdr->cmd_table_addr = cpu_to_le64(req_dma_addr); + hdr->sts_buffer_addr = cpu_to_le64(slot->status_buffer_dma); + + return 0; + +err_out_resp: + dma_unmap_sg(dev, &slot->task->smp_task.smp_resp, 1, + DMA_FROM_DEVICE); +err_out_req: + dma_unmap_sg(dev, &slot->task->smp_task.smp_req, 1, + DMA_TO_DEVICE); + return rc; +} static int prep_ssp_v1_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot, int is_tmf, @@ -1223,6 +1291,25 @@ static int slot_complete_v1_hw(struct hisi_hba *hisi_hba, sas_ssp_task_response(dev, task, iu); break; } + case SAS_PROTOCOL_SMP: + { + void *to; + struct scatterlist *sg_resp = &task->smp_task.smp_resp; + + ts->stat = SAM_STAT_GOOD; + to = kmap_atomic(sg_page(sg_resp)); + + dma_unmap_sg(dev, &task->smp_task.smp_resp, 1, + DMA_FROM_DEVICE); + dma_unmap_sg(dev, &task->smp_task.smp_req, 1, + DMA_TO_DEVICE); + memcpy(to + sg_resp->offset, + slot->status_buffer + + sizeof(struct hisi_sas_err_record), + sg_dma_len(sg_resp)); + kunmap_atomic(to); + break; + } case SAS_PROTOCOL_SATA: case SAS_PROTOCOL_STP: case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: @@ -1595,6 +1682,7 @@ static const struct hisi_sas_hw hisi_sas_v1_hw = { .setup_itct = setup_itct_v1_hw, .sl_notify = sl_notify_v1_hw, .free_device = free_device_v1_hw, + .prep_smp = prep_smp_v1_hw, .prep_ssp = prep_ssp_v1_hw, .get_free_slot = get_free_slot_v1_hw, .start_delivery = start_delivery_v1_hw, -- cgit v0.10.2 From 701f75ecd95130ab8a283fe5f44ba963a737d5f7 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:55 +0800 Subject: hisi_sas: Add scan finished and start Add functions for scsi host template scan_finished and scan_start methods. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index f34f73b..15adeca 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -156,6 +156,7 @@ struct hisi_hba { u8 sas_addr[SAS_ADDR_SIZE]; int n_phy; + int scan_finished; spinlock_t lock; struct timer_list timer; diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 406ffa0..63ebaf3 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -403,6 +403,29 @@ static int hisi_sas_dev_found(struct domain_device *device) return 0; } +static void hisi_sas_scan_start(struct Scsi_Host *shost) +{ + struct hisi_hba *hisi_hba = shost_priv(shost); + int i; + + for (i = 0; i < hisi_hba->n_phy; ++i) + hisi_sas_bytes_dmaed(hisi_hba, i); + + hisi_hba->scan_finished = 1; +} + +static int hisi_sas_scan_finished(struct Scsi_Host *shost, unsigned long time) +{ + struct hisi_hba *hisi_hba = shost_priv(shost); + struct sas_ha_struct *sha = &hisi_hba->sha; + + if (hisi_hba->scan_finished == 0) + return 0; + + sas_drain_work(sha); + return 1; +} + static void hisi_sas_phyup_work(struct work_struct *work) { struct hisi_sas_phy *phy = @@ -587,6 +610,8 @@ static struct scsi_host_template hisi_sas_sht = { .queuecommand = sas_queuecommand, .target_alloc = sas_target_alloc, .slave_configure = sas_slave_configure, + .scan_finished = hisi_sas_scan_finished, + .scan_start = hisi_sas_scan_start, .change_queue_depth = sas_change_queue_depth, .bios_param = sas_bios_param, .can_queue = 1, -- cgit v0.10.2 From 0efff300c72df76476d5d48d13a069ee04974ab3 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:56 +0800 Subject: hisi_sas: Add tmf methods Add function methods for tmf's. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 63ebaf3..4ee90eb 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -553,6 +553,309 @@ static int hisi_sas_queue_command(struct sas_task *task, gfp_t gfp_flags) } +static void hisi_sas_task_done(struct sas_task *task) +{ + if (!del_timer(&task->slow_task->timer)) + return; + complete(&task->slow_task->completion); +} + +static void hisi_sas_tmf_timedout(unsigned long data) +{ + struct sas_task *task = (struct sas_task *)data; + + task->task_state_flags |= SAS_TASK_STATE_ABORTED; + complete(&task->slow_task->completion); +} + +#define TASK_TIMEOUT 20 +#define TASK_RETRY 3 +static int hisi_sas_exec_internal_tmf_task(struct domain_device *device, + void *parameter, u32 para_len, + struct hisi_sas_tmf_task *tmf) +{ + struct hisi_sas_device *sas_dev = device->lldd_dev; + struct hisi_hba *hisi_hba = sas_dev->hisi_hba; + struct device *dev = &hisi_hba->pdev->dev; + struct sas_task *task; + int res, retry; + + for (retry = 0; retry < TASK_RETRY; retry++) { + task = sas_alloc_slow_task(GFP_KERNEL); + if (!task) + return -ENOMEM; + + task->dev = device; + task->task_proto = device->tproto; + + memcpy(&task->ssp_task, parameter, para_len); + task->task_done = hisi_sas_task_done; + + task->slow_task->timer.data = (unsigned long) task; + task->slow_task->timer.function = hisi_sas_tmf_timedout; + task->slow_task->timer.expires = jiffies + TASK_TIMEOUT*HZ; + add_timer(&task->slow_task->timer); + + res = hisi_sas_task_exec(task, GFP_KERNEL, 1, tmf); + + if (res) { + del_timer(&task->slow_task->timer); + dev_err(dev, "abort tmf: executing internal task failed: %d\n", + res); + goto ex_err; + } + + wait_for_completion(&task->slow_task->completion); + res = TMF_RESP_FUNC_FAILED; + /* Even TMF timed out, return direct. */ + if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) { + if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { + dev_err(dev, "abort tmf: TMF task[%d] timeout\n", + tmf->tag_of_task_to_be_managed); + if (task->lldd_task) { + struct hisi_sas_slot *slot = + task->lldd_task; + + hisi_sas_slot_task_free(hisi_hba, + task, slot); + } + + goto ex_err; + } + } + + if (task->task_status.resp == SAS_TASK_COMPLETE && + task->task_status.stat == SAM_STAT_GOOD) { + res = TMF_RESP_FUNC_COMPLETE; + break; + } + + if (task->task_status.resp == SAS_TASK_COMPLETE && + task->task_status.stat == SAS_DATA_UNDERRUN) { + /* no error, but return the number of bytes of + * underrun + */ + dev_warn(dev, "abort tmf: task to dev %016llx " + "resp: 0x%x sts 0x%x underrun\n", + SAS_ADDR(device->sas_addr), + task->task_status.resp, + task->task_status.stat); + res = task->task_status.residual; + break; + } + + if (task->task_status.resp == SAS_TASK_COMPLETE && + task->task_status.stat == SAS_DATA_OVERRUN) { + dev_warn(dev, "abort tmf: blocked task error\n"); + res = -EMSGSIZE; + break; + } + + dev_warn(dev, "abort tmf: task to dev " + "%016llx resp: 0x%x status 0x%x\n", + SAS_ADDR(device->sas_addr), task->task_status.resp, + task->task_status.stat); + sas_free_task(task); + task = NULL; + } +ex_err: + WARN_ON(retry == TASK_RETRY); + sas_free_task(task); + return res; +} + +static int hisi_sas_debug_issue_ssp_tmf(struct domain_device *device, + u8 *lun, struct hisi_sas_tmf_task *tmf) +{ + struct sas_ssp_task ssp_task; + + if (!(device->tproto & SAS_PROTOCOL_SSP)) + return TMF_RESP_FUNC_ESUPP; + + memcpy(ssp_task.LUN, lun, 8); + + return hisi_sas_exec_internal_tmf_task(device, &ssp_task, + sizeof(ssp_task), tmf); +} + +static int hisi_sas_abort_task(struct sas_task *task) +{ + struct scsi_lun lun; + struct hisi_sas_tmf_task tmf_task; + struct domain_device *device = task->dev; + struct hisi_sas_device *sas_dev = device->lldd_dev; + struct hisi_hba *hisi_hba = dev_to_hisi_hba(task->dev); + struct device *dev = &hisi_hba->pdev->dev; + int rc = TMF_RESP_FUNC_FAILED; + unsigned long flags; + + if (!sas_dev) { + dev_warn(dev, "Device has been removed\n"); + return TMF_RESP_FUNC_FAILED; + } + + spin_lock_irqsave(&task->task_state_lock, flags); + if (task->task_state_flags & SAS_TASK_STATE_DONE) { + spin_unlock_irqrestore(&task->task_state_lock, flags); + rc = TMF_RESP_FUNC_COMPLETE; + goto out; + } + + spin_unlock_irqrestore(&task->task_state_lock, flags); + sas_dev->dev_status = HISI_SAS_DEV_EH; + if (task->lldd_task && task->task_proto & SAS_PROTOCOL_SSP) { + struct scsi_cmnd *cmnd = task->uldd_task; + struct hisi_sas_slot *slot = task->lldd_task; + u32 tag = slot->idx; + + int_to_scsilun(cmnd->device->lun, &lun); + tmf_task.tmf = TMF_ABORT_TASK; + tmf_task.tag_of_task_to_be_managed = cpu_to_le16(tag); + + rc = hisi_sas_debug_issue_ssp_tmf(task->dev, lun.scsi_lun, + &tmf_task); + + /* if successful, clear the task and callback forwards.*/ + if (rc == TMF_RESP_FUNC_COMPLETE) { + if (task->lldd_task) { + struct hisi_sas_slot *slot; + + slot = &hisi_hba->slot_info + [tmf_task.tag_of_task_to_be_managed]; + spin_lock_irqsave(&hisi_hba->lock, flags); + hisi_hba->hw->slot_complete(hisi_hba, slot, 1); + spin_unlock_irqrestore(&hisi_hba->lock, flags); + } + } + + } else if (task->task_proto & SAS_PROTOCOL_SATA || + task->task_proto & SAS_PROTOCOL_STP) { + if (task->dev->dev_type == SAS_SATA_DEV) { + struct hisi_slot_info *slot = task->lldd_task; + + dev_notice(dev, "abort task: hba=%p task=%p slot=%p\n", + hisi_hba, task, slot); + task->task_state_flags |= SAS_TASK_STATE_ABORTED; + rc = TMF_RESP_FUNC_COMPLETE; + goto out; + } + + } + +out: + if (rc != TMF_RESP_FUNC_COMPLETE) + dev_notice(dev, "abort task: rc=%d\n", rc); + return rc; +} + +static int hisi_sas_abort_task_set(struct domain_device *device, u8 *lun) +{ + struct hisi_sas_tmf_task tmf_task; + int rc = TMF_RESP_FUNC_FAILED; + + tmf_task.tmf = TMF_ABORT_TASK_SET; + rc = hisi_sas_debug_issue_ssp_tmf(device, lun, &tmf_task); + + return rc; +} + +static int hisi_sas_clear_aca(struct domain_device *device, u8 *lun) +{ + int rc = TMF_RESP_FUNC_FAILED; + struct hisi_sas_tmf_task tmf_task; + + tmf_task.tmf = TMF_CLEAR_ACA; + rc = hisi_sas_debug_issue_ssp_tmf(device, lun, &tmf_task); + + return rc; +} + +static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device) +{ + struct sas_phy *phy = sas_get_local_phy(device); + int rc, reset_type = (device->dev_type == SAS_SATA_DEV || + (device->tproto & SAS_PROTOCOL_STP)) ? 0 : 1; + rc = sas_phy_reset(phy, reset_type); + sas_put_local_phy(phy); + msleep(2000); + return rc; +} + +static int hisi_sas_I_T_nexus_reset(struct domain_device *device) +{ + struct hisi_sas_device *sas_dev = device->lldd_dev; + struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); + unsigned long flags; + int rc = TMF_RESP_FUNC_FAILED; + + if (sas_dev->dev_status != HISI_SAS_DEV_EH) + return TMF_RESP_FUNC_FAILED; + sas_dev->dev_status = HISI_SAS_DEV_NORMAL; + + rc = hisi_sas_debug_I_T_nexus_reset(device); + + spin_lock_irqsave(&hisi_hba->lock, flags); + hisi_sas_release_task(hisi_hba, device); + spin_unlock_irqrestore(&hisi_hba->lock, flags); + + return 0; +} + +static int hisi_sas_lu_reset(struct domain_device *device, u8 *lun) +{ + struct hisi_sas_tmf_task tmf_task; + struct hisi_sas_device *sas_dev = device->lldd_dev; + struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); + struct device *dev = &hisi_hba->pdev->dev; + unsigned long flags; + int rc = TMF_RESP_FUNC_FAILED; + + tmf_task.tmf = TMF_LU_RESET; + sas_dev->dev_status = HISI_SAS_DEV_EH; + rc = hisi_sas_debug_issue_ssp_tmf(device, lun, &tmf_task); + if (rc == TMF_RESP_FUNC_COMPLETE) { + spin_lock_irqsave(&hisi_hba->lock, flags); + hisi_sas_release_task(hisi_hba, device); + spin_unlock_irqrestore(&hisi_hba->lock, flags); + } + + /* If failed, fall-through I_T_Nexus reset */ + dev_err(dev, "lu_reset: for device[%llx]:rc= %d\n", + sas_dev->device_id, rc); + return rc; +} + +static int hisi_sas_query_task(struct sas_task *task) +{ + struct scsi_lun lun; + struct hisi_sas_tmf_task tmf_task; + int rc = TMF_RESP_FUNC_FAILED; + + if (task->lldd_task && task->task_proto & SAS_PROTOCOL_SSP) { + struct scsi_cmnd *cmnd = task->uldd_task; + struct domain_device *device = task->dev; + struct hisi_sas_slot *slot = task->lldd_task; + u32 tag = slot->idx; + + int_to_scsilun(cmnd->device->lun, &lun); + tmf_task.tmf = TMF_QUERY_TASK; + tmf_task.tag_of_task_to_be_managed = cpu_to_le16(tag); + + rc = hisi_sas_debug_issue_ssp_tmf(device, + lun.scsi_lun, + &tmf_task); + switch (rc) { + /* The task is still in Lun, release it then */ + case TMF_RESP_FUNC_SUCC: + /* The task is not in Lun or failed, reset the phy */ + case TMF_RESP_FUNC_FAILED: + case TMF_RESP_FUNC_COMPLETE: + break; + } + } + return rc; +} + static void hisi_sas_port_formed(struct asd_sas_phy *sas_phy) { hisi_sas_port_notify_formed(sas_phy); @@ -629,6 +932,12 @@ static struct sas_domain_function_template hisi_sas_transport_ops = { .lldd_dev_found = hisi_sas_dev_found, .lldd_dev_gone = hisi_sas_dev_gone, .lldd_execute_task = hisi_sas_queue_command, + .lldd_abort_task = hisi_sas_abort_task, + .lldd_abort_task_set = hisi_sas_abort_task_set, + .lldd_clear_aca = hisi_sas_clear_aca, + .lldd_I_T_nexus_reset = hisi_sas_I_T_nexus_reset, + .lldd_lu_reset = hisi_sas_lu_reset, + .lldd_query_task = hisi_sas_query_task, .lldd_port_formed = hisi_sas_port_formed, .lldd_port_deformed = hisi_sas_port_deformed, }; -- cgit v0.10.2 From e4189d539f78f335f57266d2c3a848cadbd3a00f Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:57 +0800 Subject: hisi_sas: Add control phy handler Add method for lldd_control_phy. Currently link rate control and spinup hold is unsupported. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 15adeca..5b790c9 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -137,6 +137,9 @@ struct hisi_sas_hw { struct hisi_sas_slot *slot); int (*slot_complete)(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot, int abort); + void (*phy_enable)(struct hisi_hba *hisi_hba, int phy_no); + void (*phy_disable)(struct hisi_hba *hisi_hba, int phy_no); + void (*phy_hard_reset)(struct hisi_hba *hisi_hba, int phy_no); void (*free_device)(struct hisi_hba *hisi_hba, struct hisi_sas_device *dev); int (*get_wideport_bitmap)(struct hisi_hba *hisi_hba, int port_id); diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 4ee90eb..1377625 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -552,6 +552,34 @@ static int hisi_sas_queue_command(struct sas_task *task, gfp_t gfp_flags) return hisi_sas_task_exec(task, gfp_flags, 0, NULL); } +static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func, + void *funcdata) +{ + struct sas_ha_struct *sas_ha = sas_phy->ha; + struct hisi_hba *hisi_hba = sas_ha->lldd_ha; + int phy_no = sas_phy->id; + + switch (func) { + case PHY_FUNC_HARD_RESET: + hisi_hba->hw->phy_hard_reset(hisi_hba, phy_no); + break; + + case PHY_FUNC_LINK_RESET: + hisi_hba->hw->phy_enable(hisi_hba, phy_no); + hisi_hba->hw->phy_hard_reset(hisi_hba, phy_no); + break; + + case PHY_FUNC_DISABLE: + hisi_hba->hw->phy_disable(hisi_hba, phy_no); + break; + + case PHY_FUNC_SET_LINK_RATE: + case PHY_FUNC_RELEASE_SPINUP_HOLD: + default: + return -EOPNOTSUPP; + } + return 0; +} static void hisi_sas_task_done(struct sas_task *task) { @@ -932,6 +960,7 @@ static struct sas_domain_function_template hisi_sas_transport_ops = { .lldd_dev_found = hisi_sas_dev_found, .lldd_dev_gone = hisi_sas_dev_gone, .lldd_execute_task = hisi_sas_queue_command, + .lldd_control_phy = hisi_sas_control_phy, .lldd_abort_task = hisi_sas_abort_task, .lldd_abort_task_set = hisi_sas_abort_task_set, .lldd_clear_aca = hisi_sas_clear_aca, diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 64b17a1..a95259c 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -764,6 +764,14 @@ static void enable_phy_v1_hw(struct hisi_hba *hisi_hba, int phy_no) hisi_sas_phy_write32(hisi_hba, phy_no, PHY_CFG, cfg); } +static void disable_phy_v1_hw(struct hisi_hba *hisi_hba, int phy_no) +{ + u32 cfg = hisi_sas_phy_read32(hisi_hba, phy_no, PHY_CFG); + + cfg &= ~PHY_CFG_ENA_MSK; + hisi_sas_phy_write32(hisi_hba, phy_no, PHY_CFG, cfg); +} + static void start_phy_v1_hw(struct hisi_hba *hisi_hba, int phy_no) { config_id_frame_v1_hw(hisi_hba, phy_no); @@ -772,6 +780,18 @@ static void start_phy_v1_hw(struct hisi_hba *hisi_hba, int phy_no) enable_phy_v1_hw(hisi_hba, phy_no); } +static void stop_phy_v1_hw(struct hisi_hba *hisi_hba, int phy_no) +{ + disable_phy_v1_hw(hisi_hba, phy_no); +} + +static void phy_hard_reset_v1_hw(struct hisi_hba *hisi_hba, int phy_no) +{ + stop_phy_v1_hw(hisi_hba, phy_no); + msleep(100); + start_phy_v1_hw(hisi_hba, phy_no); +} + static void start_phys_v1_hw(unsigned long data) { struct hisi_hba *hisi_hba = (struct hisi_hba *)data; @@ -1687,6 +1707,9 @@ static const struct hisi_sas_hw hisi_sas_v1_hw = { .get_free_slot = get_free_slot_v1_hw, .start_delivery = start_delivery_v1_hw, .slot_complete = slot_complete_v1_hw, + .phy_enable = enable_phy_v1_hw, + .phy_disable = disable_phy_v1_hw, + .phy_hard_reset = phy_hard_reset_v1_hw, .get_wideport_bitmap = get_wideport_bitmap_v1_hw, .complete_hdr_size = sizeof(struct hisi_sas_complete_v1_hdr), }; -- cgit v0.10.2 From ff165289f9121c7f5ac2f9273aef5f47e84625da Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:58 +0800 Subject: hisi_sas: Add fatal irq handler Add handlers for fatal interrupts. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index a95259c..e29b7c7 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -1573,6 +1573,93 @@ static irqreturn_t cq_interrupt_v1_hw(int irq, void *p) return IRQ_HANDLED; } +static irqreturn_t fatal_ecc_int_v1_hw(int irq, void *p) +{ + struct hisi_hba *hisi_hba = p; + struct device *dev = &hisi_hba->pdev->dev; + u32 ecc_int = hisi_sas_read32(hisi_hba, SAS_ECC_INTR); + + if (ecc_int & SAS_ECC_INTR_DQ_ECC1B_MSK) { + u32 ecc_err = hisi_sas_read32(hisi_hba, HGC_ECC_ERR); + + panic("%s: Fatal DQ 1b ECC interrupt (0x%x)\n", + dev_name(dev), ecc_err); + } + + if (ecc_int & SAS_ECC_INTR_DQ_ECCBAD_MSK) { + u32 addr = (hisi_sas_read32(hisi_hba, HGC_DQ_ECC_ADDR) & + HGC_DQ_ECC_ADDR_BAD_MSK) >> + HGC_DQ_ECC_ADDR_BAD_OFF; + + panic("%s: Fatal DQ RAM ECC interrupt @ 0x%08x\n", + dev_name(dev), addr); + } + + if (ecc_int & SAS_ECC_INTR_IOST_ECC1B_MSK) { + u32 ecc_err = hisi_sas_read32(hisi_hba, HGC_ECC_ERR); + + panic("%s: Fatal IOST 1b ECC interrupt (0x%x)\n", + dev_name(dev), ecc_err); + } + + if (ecc_int & SAS_ECC_INTR_IOST_ECCBAD_MSK) { + u32 addr = (hisi_sas_read32(hisi_hba, HGC_IOST_ECC_ADDR) & + HGC_IOST_ECC_ADDR_BAD_MSK) >> + HGC_IOST_ECC_ADDR_BAD_OFF; + + panic("%s: Fatal IOST RAM ECC interrupt @ 0x%08x\n", + dev_name(dev), addr); + } + + if (ecc_int & SAS_ECC_INTR_ITCT_ECCBAD_MSK) { + u32 addr = (hisi_sas_read32(hisi_hba, HGC_ITCT_ECC_ADDR) & + HGC_ITCT_ECC_ADDR_BAD_MSK) >> + HGC_ITCT_ECC_ADDR_BAD_OFF; + + panic("%s: Fatal TCT RAM ECC interrupt @ 0x%08x\n", + dev_name(dev), addr); + } + + if (ecc_int & SAS_ECC_INTR_ITCT_ECC1B_MSK) { + u32 ecc_err = hisi_sas_read32(hisi_hba, HGC_ECC_ERR); + + panic("%s: Fatal ITCT 1b ECC interrupt (0x%x)\n", + dev_name(dev), ecc_err); + } + + hisi_sas_write32(hisi_hba, SAS_ECC_INTR, ecc_int | 0x3f); + + return IRQ_HANDLED; +} + +static irqreturn_t fatal_axi_int_v1_hw(int irq, void *p) +{ + struct hisi_hba *hisi_hba = p; + struct device *dev = &hisi_hba->pdev->dev; + u32 axi_int = hisi_sas_read32(hisi_hba, ENT_INT_SRC2); + u32 axi_info = hisi_sas_read32(hisi_hba, HGC_AXI_FIFO_ERR_INFO); + + if (axi_int & ENT_INT_SRC2_DQ_CFG_ERR_MSK) + panic("%s: Fatal DQ_CFG_ERR interrupt (0x%x)\n", + dev_name(dev), axi_info); + + if (axi_int & ENT_INT_SRC2_CQ_CFG_ERR_MSK) + panic("%s: Fatal CQ_CFG_ERR interrupt (0x%x)\n", + dev_name(dev), axi_info); + + if (axi_int & ENT_INT_SRC2_AXI_WRONG_INT_MSK) + panic("%s: Fatal AXI_WRONG_INT interrupt (0x%x)\n", + dev_name(dev), axi_info); + + if (axi_int & ENT_INT_SRC2_AXI_OVERLF_INT_MSK) + panic("%s: Fatal AXI_OVERLF_INT incorrect interrupt (0x%x)\n", + dev_name(dev), axi_info); + + hisi_sas_write32(hisi_hba, ENT_INT_SRC2, axi_int | 0x30000000); + + return IRQ_HANDLED; +} + static const char phy_int_names[HISI_SAS_PHY_INT_NR][32] = { {"Bcast"}, {"Phy Up"}, @@ -1580,12 +1667,22 @@ static const char phy_int_names[HISI_SAS_PHY_INT_NR][32] = { }; static const char cq_int_name[32] = "cq"; +static const char fatal_int_name[HISI_SAS_FATAL_INT_NR][32] = { + "fatal ecc", + "fatal axi" +}; + static irq_handler_t phy_interrupts[HISI_SAS_PHY_INT_NR] = { int_bcast_v1_hw, int_phyup_v1_hw, int_abnormal_v1_hw }; +static irq_handler_t fatal_interrupts[HISI_SAS_MAX_QUEUES] = { + fatal_ecc_int_v1_hw, + fatal_axi_int_v1_hw +}; + static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) { struct device *dev = &hisi_hba->pdev->dev; @@ -1646,6 +1743,28 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) } } + idx = (hisi_hba->n_phy * HISI_SAS_PHY_INT_NR) + hisi_hba->queue_count; + for (i = 0; i < HISI_SAS_FATAL_INT_NR; i++, idx++) { + irq = irq_of_parse_and_map(np, idx); + if (!irq) { + dev_err(dev, "irq init: could not map fatal interrupt %d\n", + idx); + return -ENOENT; + } + (void)snprintf(&int_names[idx * HISI_SAS_NAME_LEN], + HISI_SAS_NAME_LEN, + "%s %s:%d", dev_name(dev), fatal_int_name[i], i); + rc = devm_request_irq(dev, irq, fatal_interrupts[i], 0, + &int_names[idx * HISI_SAS_NAME_LEN], + hisi_hba); + if (rc) { + dev_err(dev, + "irq init: could not request fatal interrupt %d, rc=%d\n", + irq, rc); + return -ENOENT; + } + } + return 0; } -- cgit v0.10.2 From 16c6c252f0ac8256e38d36a3de7c59d5d27efdc3 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:59 +0800 Subject: MAINTAINERS: Add maintainer for HiSi SAS driver Add maintainer for HiSilicon SAS driver. Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/MAINTAINERS b/MAINTAINERS index ea17512..d2f94e2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5035,6 +5035,13 @@ F: include/uapi/linux/if_hippi.h F: net/802/hippi.c F: drivers/net/hippi/ +HISILICON SAS Controller +M: John Garry +W: http://www.hisilicon.com +S: Supported +F: drivers/scsi/hisi_sas/ +F: Documentation/devicetree/bindings/scsi/hisilicon-sas.txt + HOST AP DRIVER M: Jouni Malinen L: hostap@shmoo.com (subscribers-only) -- cgit v0.10.2 From 8c77dca011125b795bfa1c86f85a80132feee578 Mon Sep 17 00:00:00 2001 From: John Garry Date: Thu, 19 Nov 2015 20:23:59 +0800 Subject: hisi_sas: Remove dependency on of_irq_count Originally the driver would use of_irq_count to calculate how much memory is required for storing the interrupt names, since the number of interrupt sources for the controller is variable. Since of_irq_count cannot be used by the driver, use fixed names. Signed-off-by: John Garry Signed-off-by: Zhangfei Gao Acked-by: Rob Herring Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 5b790c9..30a9ab9 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -38,8 +38,6 @@ #define HISI_SAS_MAX_SSP_RESP_SZ (sizeof(struct ssp_frame_hdr) + 1024) #define HISI_SAS_MAX_SMP_RESP_SZ 1028 -#define HISI_SAS_NAME_LEN 32 - struct hisi_hba; enum { @@ -178,7 +176,6 @@ struct hisi_hba { int queue_count; int queue; - char *int_names; struct hisi_sas_slot *slot_prep; struct dma_pool *sge_page_pool; diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 1377625..2929018 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -1160,7 +1160,6 @@ static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev, struct device *dev = &pdev->dev; struct device_node *np = pdev->dev.of_node; struct property *sas_addr_prop; - int num; shost = scsi_host_alloc(&hisi_sas_sht, sizeof(*hisi_hba)); if (!shost) @@ -1197,13 +1196,6 @@ static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev, if (of_property_read_u32(np, "queue-count", &hisi_hba->queue_count)) goto err_out; - num = of_irq_count(np); - hisi_hba->int_names = devm_kcalloc(dev, num, - HISI_SAS_NAME_LEN, - GFP_KERNEL); - if (!hisi_hba->int_names) - goto err_out; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); hisi_hba->regs = devm_ioremap_resource(dev, res); if (IS_ERR(hisi_hba->regs)) diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index e29b7c7..0ed2f92 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -1660,18 +1660,6 @@ static irqreturn_t fatal_axi_int_v1_hw(int irq, void *p) return IRQ_HANDLED; } -static const char phy_int_names[HISI_SAS_PHY_INT_NR][32] = { - {"Bcast"}, - {"Phy Up"}, - {"Abnormal"}, -}; - -static const char cq_int_name[32] = "cq"; -static const char fatal_int_name[HISI_SAS_FATAL_INT_NR][32] = { - "fatal ecc", - "fatal axi" -}; - static irq_handler_t phy_interrupts[HISI_SAS_PHY_INT_NR] = { int_bcast_v1_hw, int_phyup_v1_hw, @@ -1687,7 +1675,6 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) { struct device *dev = &hisi_hba->pdev->dev; struct device_node *np = dev->of_node; - char *int_names = hisi_hba->int_names; int i, j, irq, rc, idx; if (!np) @@ -1706,13 +1693,8 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) return -ENOENT; } - (void)snprintf(&int_names[idx * HISI_SAS_NAME_LEN], - HISI_SAS_NAME_LEN, - "%s %s:%d", dev_name(dev), - phy_int_names[j], i); rc = devm_request_irq(dev, irq, phy_interrupts[j], 0, - &int_names[idx * HISI_SAS_NAME_LEN], - phy); + DRV_NAME " phy", phy); if (rc) { dev_err(dev, "irq init: could not request " "phy interrupt %d, rc=%d\n", @@ -1730,12 +1712,9 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) idx); return -ENOENT; } - (void)snprintf(&int_names[idx * HISI_SAS_NAME_LEN], - HISI_SAS_NAME_LEN, - "%s %s:%d", dev_name(dev), cq_int_name, i); + rc = devm_request_irq(dev, irq, cq_interrupt_v1_hw, 0, - &int_names[idx * HISI_SAS_NAME_LEN], - &hisi_hba->cq[i]); + DRV_NAME " cq", &hisi_hba->cq[i]); if (rc) { dev_err(dev, "irq init: could not request cq interrupt %d, rc=%d\n", irq, rc); @@ -1751,12 +1730,9 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) idx); return -ENOENT; } - (void)snprintf(&int_names[idx * HISI_SAS_NAME_LEN], - HISI_SAS_NAME_LEN, - "%s %s:%d", dev_name(dev), fatal_int_name[i], i); + rc = devm_request_irq(dev, irq, fatal_interrupts[i], 0, - &int_names[idx * HISI_SAS_NAME_LEN], - hisi_hba); + DRV_NAME " fatal", hisi_hba); if (rc) { dev_err(dev, "irq init: could not request fatal interrupt %d, rc=%d\n", -- cgit v0.10.2 From 494131124f04252bb3f91c0801bfe796d49971ef Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 20 Nov 2015 17:38:28 +0100 Subject: scsi: use sector_div instead of do_div do_div is the wrong way to divide a sector_t, as it is less efficient when sector_t is 32-bit wide. With the upcoming do_div optimizations, the kernel starts warning about this: drivers/scsi/scsi_debug.c: In function 'dif_store': include/asm-generic/div64.h:207:28: warning: comparison of distinct pointer types lacks a cast This changes the code to use sector_div instead, which always produces optimal code. Signed-off-by: Arnd Bergmann Reviewed-by: Hannes Reinicke Reviewed-by: Sagi Grimberg Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index dfcc45b..ec622ba 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -678,7 +678,7 @@ static void *fake_store(unsigned long long lba) static struct sd_dif_tuple *dif_store(sector_t sector) { - sector = do_div(sector, sdebug_store_sectors); + sector = sector_div(sector, sdebug_store_sectors); return dif_storep + sector; } @@ -2780,7 +2780,7 @@ static unsigned long lba_to_map_index(sector_t lba) lba += scsi_debug_unmap_granularity - scsi_debug_unmap_alignment; } - do_div(lba, scsi_debug_unmap_granularity); + sector_div(lba, scsi_debug_unmap_granularity); return lba; } -- cgit v0.10.2 From fe0798c5e150be8f06959250076d3864477e74c2 Mon Sep 17 00:00:00 2001 From: Fengguang Wu Date: Tue, 10 Nov 2015 13:59:06 +0800 Subject: aacraid: aac_release_resources() can be static Signed-off-by: Fengguang Wu Reviewed-by: Johannes Thumshirn Reviewed-by: Mahesh Rajashekhara Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 3b6e5c6..76eaa38 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -1318,7 +1318,7 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) } #if (defined(CONFIG_PM)) -void aac_release_resources(struct aac_dev *aac) +static void aac_release_resources(struct aac_dev *aac) { int i; -- cgit v0.10.2 From 09e2b0b14690fb13ccfc04af49f156df3e25b152 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 9 Nov 2015 13:24:28 +0100 Subject: scsi: rescan VPD attributes The VPD page information might change, so we need to be able to update it. This patch implements a VPD page rescan whenever the 'rescan' sysfs attribute is triggered. Signed-off-by: Hannes Reinecke Reviewed-by: Johannes Thumshirn Reviewed-by: Shane Seymour Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index d07fb65..b1bf42b 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -782,7 +782,7 @@ void scsi_attach_vpd(struct scsi_device *sdev) int vpd_len = SCSI_VPD_PG_LEN; int pg80_supported = 0; int pg83_supported = 0; - unsigned char *vpd_buf; + unsigned char __rcu *vpd_buf, *orig_vpd_buf = NULL; if (sdev->skip_vpd_pages) return; @@ -828,8 +828,16 @@ retry_pg80: kfree(vpd_buf); goto retry_pg80; } + mutex_lock(&sdev->inquiry_mutex); + orig_vpd_buf = sdev->vpd_pg80; sdev->vpd_pg80_len = result; - sdev->vpd_pg80 = vpd_buf; + rcu_assign_pointer(sdev->vpd_pg80, vpd_buf); + mutex_unlock(&sdev->inquiry_mutex); + synchronize_rcu(); + if (orig_vpd_buf) { + kfree(orig_vpd_buf); + orig_vpd_buf = NULL; + } vpd_len = SCSI_VPD_PG_LEN; } @@ -849,8 +857,14 @@ retry_pg83: kfree(vpd_buf); goto retry_pg83; } + mutex_lock(&sdev->inquiry_mutex); + orig_vpd_buf = sdev->vpd_pg83; sdev->vpd_pg83_len = result; - sdev->vpd_pg83 = vpd_buf; + rcu_assign_pointer(sdev->vpd_pg83, vpd_buf); + mutex_unlock(&sdev->inquiry_mutex); + synchronize_rcu(); + if (orig_vpd_buf) + kfree(orig_vpd_buf); } } diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 8324539..a1c195d 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -236,6 +236,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget, INIT_LIST_HEAD(&sdev->starved_entry); INIT_LIST_HEAD(&sdev->event_list); spin_lock_init(&sdev->list_lock); + mutex_init(&sdev->inquiry_mutex); INIT_WORK(&sdev->event_work, scsi_evt_thread); INIT_WORK(&sdev->requeue_work, scsi_requeue_run_queue); @@ -1516,6 +1517,9 @@ EXPORT_SYMBOL(scsi_add_device); void scsi_rescan_device(struct device *dev) { device_lock(dev); + + scsi_attach_vpd(to_scsi_device(dev)); + if (dev->driver && try_module_get(dev->driver->owner)) { struct scsi_driver *drv = to_scsi_driver(dev->driver); diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 8d23122..158f1b5 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -760,11 +760,15 @@ show_vpd_##_page(struct file *filp, struct kobject *kobj, \ { \ struct device *dev = container_of(kobj, struct device, kobj); \ struct scsi_device *sdev = to_scsi_device(dev); \ + int ret; \ if (!sdev->vpd_##_page) \ return -EINVAL; \ - return memory_read_from_buffer(buf, count, &off, \ - sdev->vpd_##_page, \ + rcu_read_lock(); \ + ret = memory_read_from_buffer(buf, count, &off, \ + rcu_dereference(sdev->vpd_##_page), \ sdev->vpd_##_page##_len); \ + rcu_read_unlock(); \ + return ret; \ } \ static struct bin_attribute dev_attr_vpd_##_page = { \ .attr = {.name = __stringify(vpd_##_page), .mode = S_IRUGO }, \ diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c index dcb0d76..e234da7 100644 --- a/drivers/scsi/ses.c +++ b/drivers/scsi/ses.c @@ -554,17 +554,22 @@ static void ses_match_to_enclosure(struct enclosure_device *edev, struct scsi_device *sdev) { unsigned char *desc; + unsigned char __rcu *vpd_pg83; struct efd efd = { .addr = 0, }; ses_enclosure_data_process(edev, to_scsi_device(edev->edev.parent), 0); - if (!sdev->vpd_pg83_len) + rcu_read_lock(); + vpd_pg83 = rcu_dereference(sdev->vpd_pg83); + if (!vpd_pg83) { + rcu_read_unlock(); return; + } - desc = sdev->vpd_pg83 + 4; - while (desc < sdev->vpd_pg83 + sdev->vpd_pg83_len) { + desc = vpd_pg83 + 4; + while (desc < vpd_pg83 + sdev->vpd_pg83_len) { enum scsi_protocol proto = desc[0] >> 4; u8 code_set = desc[0] & 0x0f; u8 piv = desc[1] & 0x80; @@ -578,6 +583,7 @@ static void ses_match_to_enclosure(struct enclosure_device *edev, desc += len + 4; } + rcu_read_unlock(); if (efd.addr) { efd.dev = &sdev->sdev_gendev; diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index fe89d7c..bde4077 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -109,6 +109,7 @@ struct scsi_device { char type; char scsi_level; char inq_periph_qual; /* PQ from INQUIRY data */ + struct mutex inquiry_mutex; unsigned char inquiry_len; /* valid bytes in 'inquiry' */ unsigned char * inquiry; /* INQUIRY response data */ const char * vendor; /* [back_compat] point into 'inquiry' ... */ @@ -117,9 +118,9 @@ struct scsi_device { #define SCSI_VPD_PG_LEN 255 int vpd_pg83_len; - unsigned char *vpd_pg83; + unsigned char __rcu *vpd_pg83; int vpd_pg80_len; - unsigned char *vpd_pg80; + unsigned char __rcu *vpd_pg80; unsigned char current_tag; /* current tag */ struct scsi_target *sdev_target; /* used only for single_lun */ -- cgit v0.10.2 From fa785f0a984d863a24d2f288b68757188a50261b Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 26 Nov 2015 20:22:50 +0200 Subject: scsi_debug: check for bigger value first Even for signed types we have to check for bigger positive value first. Otherwise it will be never happened. Signed-off-by: Andy Shevchenko Acked-by: Douglas Gilbert Reviewed-by: Johannes Thumshirn Reviewed-by: Ewan Milne Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index ec622ba..1bea1ad 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -4846,10 +4846,10 @@ static int __init scsi_debug_init(void) /* play around with geometry, don't waste too much on track 0 */ sdebug_heads = 8; sdebug_sectors_per = 32; - if (scsi_debug_dev_size_mb >= 16) - sdebug_heads = 32; - else if (scsi_debug_dev_size_mb >= 256) + if (scsi_debug_dev_size_mb >= 256) sdebug_heads = 64; + else if (scsi_debug_dev_size_mb >= 16) + sdebug_heads = 32; sdebug_cylinders_per = (unsigned long)sdebug_capacity / (sdebug_sectors_per * sdebug_heads); if (sdebug_cylinders_per >= 1024) { -- cgit v0.10.2 From 4cd38e388d547807e89b4bc51a57bdd5fc5ef7df Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Fri, 20 Nov 2015 13:33:04 -0800 Subject: scsi_transport_fc: Introduce scsi_host_{get,put}() Use scsi_host_{get,put}() instead of open-coding these functions. Compile-tested only. [mkp: Dropped CC:stable and fixed James Smart's email address] Signed-off-by: Bart Van Assche Reviewed-by: Christoph Hellwig Reviewed-by: Johannes Thumshirn Cc: Christoph Hellwig Cc: Hannes Reinecke Cc: James Smart Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 24eaaf6..8a88226 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -2586,7 +2586,7 @@ fc_rport_final_delete(struct work_struct *work) transport_remove_device(dev); device_del(dev); transport_destroy_device(dev); - put_device(&shost->shost_gendev); /* for fc_host->rport list */ + scsi_host_put(shost); /* for fc_host->rport list */ put_device(dev); /* for self-reference */ } @@ -2650,7 +2650,7 @@ fc_rport_create(struct Scsi_Host *shost, int channel, else rport->scsi_target_id = -1; list_add_tail(&rport->peers, &fc_host->rports); - get_device(&shost->shost_gendev); /* for fc_host->rport list */ + scsi_host_get(shost); /* for fc_host->rport list */ spin_unlock_irqrestore(shost->host_lock, flags); @@ -2685,7 +2685,7 @@ delete_rport: transport_destroy_device(dev); spin_lock_irqsave(shost->host_lock, flags); list_del(&rport->peers); - put_device(&shost->shost_gendev); /* for fc_host->rport list */ + scsi_host_put(shost); /* for fc_host->rport list */ spin_unlock_irqrestore(shost->host_lock, flags); put_device(dev->parent); kfree(rport); @@ -3383,7 +3383,7 @@ fc_vport_setup(struct Scsi_Host *shost, int channel, struct device *pdev, fc_host->npiv_vports_inuse++; vport->number = fc_host->next_vport_number++; list_add_tail(&vport->peers, &fc_host->vports); - get_device(&shost->shost_gendev); /* for fc_host->vport list */ + scsi_host_get(shost); /* for fc_host->vport list */ spin_unlock_irqrestore(shost->host_lock, flags); @@ -3441,7 +3441,7 @@ delete_vport: transport_destroy_device(dev); spin_lock_irqsave(shost->host_lock, flags); list_del(&vport->peers); - put_device(&shost->shost_gendev); /* for fc_host->vport list */ + scsi_host_put(shost); /* for fc_host->vport list */ fc_host->npiv_vports_inuse--; spin_unlock_irqrestore(shost->host_lock, flags); put_device(dev->parent); @@ -3504,7 +3504,7 @@ fc_vport_terminate(struct fc_vport *vport) vport->flags |= FC_VPORT_DELETED; list_del(&vport->peers); fc_host->npiv_vports_inuse--; - put_device(&shost->shost_gendev); /* for fc_host->vport list */ + scsi_host_put(shost); /* for fc_host->vport list */ } spin_unlock_irqrestore(shost->host_lock, flags); -- cgit v0.10.2 From 251e2d25bfb72b69edd414abfa42a41191d9657a Mon Sep 17 00:00:00 2001 From: Ching Huang Date: Wed, 25 Nov 2015 19:36:02 +0800 Subject: arcmsr: fixed getting wrong configuration data Fixed getting wrong configuration data of adapter type B and type D. Signed-off-by: Ching Huang Reviewed-by: Hannes Reinicke Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 333db59..397cdd5 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -2694,15 +2694,15 @@ static bool arcmsr_hbaB_get_config(struct AdapterControlBlock *acb) acb->firm_model, acb->firm_version); - acb->signature = readl(®->message_rwbuffer[1]); + acb->signature = readl(®->message_rwbuffer[0]); /*firm_signature,1,00-03*/ - acb->firm_request_len = readl(®->message_rwbuffer[2]); + acb->firm_request_len = readl(®->message_rwbuffer[1]); /*firm_request_len,1,04-07*/ - acb->firm_numbers_queue = readl(®->message_rwbuffer[3]); + acb->firm_numbers_queue = readl(®->message_rwbuffer[2]); /*firm_numbers_queue,2,08-11*/ - acb->firm_sdram_size = readl(®->message_rwbuffer[4]); + acb->firm_sdram_size = readl(®->message_rwbuffer[3]); /*firm_sdram_size,3,12-15*/ - acb->firm_hd_channels = readl(®->message_rwbuffer[5]); + acb->firm_hd_channels = readl(®->message_rwbuffer[4]); /*firm_ide_channels,4,16-19*/ acb->firm_cfg_version = readl(®->message_rwbuffer[25]); /*firm_cfg_version,25,100-103*/ /*firm_ide_channels,4,16-19*/ @@ -2880,15 +2880,15 @@ static bool arcmsr_hbaD_get_config(struct AdapterControlBlock *acb) iop_device_map++; count--; } - acb->signature = readl(®->msgcode_rwbuffer[1]); + acb->signature = readl(®->msgcode_rwbuffer[0]); /*firm_signature,1,00-03*/ - acb->firm_request_len = readl(®->msgcode_rwbuffer[2]); + acb->firm_request_len = readl(®->msgcode_rwbuffer[1]); /*firm_request_len,1,04-07*/ - acb->firm_numbers_queue = readl(®->msgcode_rwbuffer[3]); + acb->firm_numbers_queue = readl(®->msgcode_rwbuffer[2]); /*firm_numbers_queue,2,08-11*/ - acb->firm_sdram_size = readl(®->msgcode_rwbuffer[4]); + acb->firm_sdram_size = readl(®->msgcode_rwbuffer[3]); /*firm_sdram_size,3,12-15*/ - acb->firm_hd_channels = readl(®->msgcode_rwbuffer[5]); + acb->firm_hd_channels = readl(®->msgcode_rwbuffer[4]); /*firm_hd_channels,4,16-19*/ acb->firm_cfg_version = readl(®->msgcode_rwbuffer[25]); pr_notice("Areca RAID Controller%d: Model %s, F/W %s\n", -- cgit v0.10.2 From 98f90debc2b64a40a416dd9794ac2d8de6b43af2 Mon Sep 17 00:00:00 2001 From: Ching Huang Date: Wed, 25 Nov 2015 19:41:23 +0800 Subject: arcmsr: fixes not release allocated resource Releasing allocated resource if get configuration data failed. Signed-off-by: Ching Huang Reviewed-by: Johannes Thumshirn Reviewed-by: Hannes Reinicke Reviewed-by: Tomas Henzl Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 397cdd5..41f9a00 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -2664,7 +2664,7 @@ static bool arcmsr_hbaB_get_config(struct AdapterControlBlock *acb) if (!arcmsr_hbaB_wait_msgint_ready(acb)) { printk(KERN_NOTICE "arcmsr%d: wait 'get adapter firmware \ miscellaneous data' timeout \n", acb->host->host_no); - return false; + goto err_free_dma; } count = 8; while (count){ @@ -2707,6 +2707,10 @@ static bool arcmsr_hbaB_get_config(struct AdapterControlBlock *acb) acb->firm_cfg_version = readl(®->message_rwbuffer[25]); /*firm_cfg_version,25,100-103*/ /*firm_ide_channels,4,16-19*/ return true; +err_free_dma: + dma_free_coherent(&acb->pdev->dev, acb->roundup_ccbsize, + acb->dma_coherent2, acb->dma_coherent_handle2); + return false; } static bool arcmsr_hbaC_get_config(struct AdapterControlBlock *pACB) -- cgit v0.10.2 From d662ad246256e33eb9b25c8e801f4487527f2bfe Mon Sep 17 00:00:00 2001 From: Ching Huang Date: Wed, 25 Nov 2015 19:45:16 +0800 Subject: arcmsr: make code more readable [mkp: Fixed checkpatch whitespace warning] Signed-off-by: Ching Huang Reviewed-by: Johannes Thumshirn Reviewed-by: Hannes Reinicke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h index 3bcaaac..48931bd 100644 --- a/drivers/scsi/arcmsr/arcmsr.h +++ b/drivers/scsi/arcmsr/arcmsr.h @@ -288,6 +288,9 @@ struct FIRMWARE_INFO #define ARCMSR_MESSAGE_RBUFFER 0x0000ff00 /* iop message_rwbuffer for message command */ #define ARCMSR_MESSAGE_RWBUFFER 0x0000fa00 + +#define MEM_BASE0(x) (u32 __iomem *)((unsigned long)acb->mem_base0 + x) +#define MEM_BASE1(x) (u32 __iomem *)((unsigned long)acb->mem_base1 + x) /* ************************************************************************ ** SPEC. for Areca HBC adapter diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 41f9a00..077c3ec 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -2649,13 +2649,13 @@ static bool arcmsr_hbaB_get_config(struct AdapterControlBlock *acb) acb->dma_coherent2 = dma_coherent; reg = (struct MessageUnit_B *)dma_coherent; acb->pmuB = reg; - reg->drv2iop_doorbell= (uint32_t __iomem *)((unsigned long)acb->mem_base0 + ARCMSR_DRV2IOP_DOORBELL); - reg->drv2iop_doorbell_mask = (uint32_t __iomem *)((unsigned long)acb->mem_base0 + ARCMSR_DRV2IOP_DOORBELL_MASK); - reg->iop2drv_doorbell = (uint32_t __iomem *)((unsigned long)acb->mem_base0 + ARCMSR_IOP2DRV_DOORBELL); - reg->iop2drv_doorbell_mask = (uint32_t __iomem *)((unsigned long)acb->mem_base0 + ARCMSR_IOP2DRV_DOORBELL_MASK); - reg->message_wbuffer = (uint32_t __iomem *)((unsigned long)acb->mem_base1 + ARCMSR_MESSAGE_WBUFFER); - reg->message_rbuffer = (uint32_t __iomem *)((unsigned long)acb->mem_base1 + ARCMSR_MESSAGE_RBUFFER); - reg->message_rwbuffer = (uint32_t __iomem *)((unsigned long)acb->mem_base1 + ARCMSR_MESSAGE_RWBUFFER); + reg->drv2iop_doorbell = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL); + reg->drv2iop_doorbell_mask = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_MASK); + reg->iop2drv_doorbell = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL); + reg->iop2drv_doorbell_mask = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_MASK); + reg->message_wbuffer = MEM_BASE1(ARCMSR_MESSAGE_WBUFFER); + reg->message_rbuffer = MEM_BASE1(ARCMSR_MESSAGE_RBUFFER); + reg->message_rwbuffer = MEM_BASE1(ARCMSR_MESSAGE_RWBUFFER); iop_firm_model = (char __iomem *)(®->message_rwbuffer[15]); /*firm_model,15,60-67*/ iop_firm_version = (char __iomem *)(®->message_rwbuffer[17]); /*firm_version,17,68-83*/ iop_device_map = (char __iomem *)(®->message_rwbuffer[21]); /*firm_version,21,84-99*/ -- cgit v0.10.2 From 7e315ffd49b906fc545b8e0312eedeed738796c9 Mon Sep 17 00:00:00 2001 From: Ching Huang Date: Wed, 25 Nov 2015 19:49:33 +0800 Subject: arcmsr: adds code to support new Areca adapter ARC1203 Support Areca's new PCIe to SATA RAID adapter ARC1203. Signed-off-by: Ching Huang Reviewed-by: Johannes Thumshirn Reviewed-by: Hannes Reinicke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h index 48931bd..9c5a2a8 100644 --- a/drivers/scsi/arcmsr/arcmsr.h +++ b/drivers/scsi/arcmsr/arcmsr.h @@ -74,6 +74,9 @@ struct device_attribute; #ifndef PCI_DEVICE_ID_ARECA_1214 #define PCI_DEVICE_ID_ARECA_1214 0x1214 #endif +#ifndef PCI_DEVICE_ID_ARECA_1203 + #define PCI_DEVICE_ID_ARECA_1203 0x1203 +#endif /* ********************************************************************************** ** @@ -245,6 +248,12 @@ struct FIRMWARE_INFO /* window of "instruction flags" from iop to driver */ #define ARCMSR_IOP2DRV_DOORBELL 0x00020408 #define ARCMSR_IOP2DRV_DOORBELL_MASK 0x0002040C +/* window of "instruction flags" from iop to driver */ +#define ARCMSR_IOP2DRV_DOORBELL_1203 0x00021870 +#define ARCMSR_IOP2DRV_DOORBELL_MASK_1203 0x00021874 +/* window of "instruction flags" from driver to iop */ +#define ARCMSR_DRV2IOP_DOORBELL_1203 0x00021878 +#define ARCMSR_DRV2IOP_DOORBELL_MASK_1203 0x0002187C /* ARECA FLAG LANGUAGE */ /* ioctl transfer */ #define ARCMSR_IOP2DRV_DATA_WRITE_OK 0x00000001 diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 077c3ec..881be34 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -114,6 +114,7 @@ static void arcmsr_hardware_reset(struct AdapterControlBlock *acb); static const char *arcmsr_info(struct Scsi_Host *); static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb); static void arcmsr_free_irq(struct pci_dev *, struct AdapterControlBlock *); +static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb); static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev, int queue_depth) { if (queue_depth > ARCMSR_MAX_CMD_PERLUN) @@ -157,6 +158,8 @@ static struct pci_device_id arcmsr_device_id_table[] = { .driver_data = ACB_ADAPTER_TYPE_B}, {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1202), .driver_data = ACB_ADAPTER_TYPE_B}, + {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1203), + .driver_data = ACB_ADAPTER_TYPE_B}, {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1210), .driver_data = ACB_ADAPTER_TYPE_A}, {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1214), @@ -2621,7 +2624,7 @@ static bool arcmsr_hbaA_get_config(struct AdapterControlBlock *acb) } static bool arcmsr_hbaB_get_config(struct AdapterControlBlock *acb) { - struct MessageUnit_B *reg = acb->pmuB; + struct MessageUnit_B *reg; struct pci_dev *pdev = acb->pdev; void *dma_coherent; dma_addr_t dma_coherent_handle; @@ -2649,10 +2652,17 @@ static bool arcmsr_hbaB_get_config(struct AdapterControlBlock *acb) acb->dma_coherent2 = dma_coherent; reg = (struct MessageUnit_B *)dma_coherent; acb->pmuB = reg; - reg->drv2iop_doorbell = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL); - reg->drv2iop_doorbell_mask = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_MASK); - reg->iop2drv_doorbell = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL); - reg->iop2drv_doorbell_mask = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_MASK); + if (acb->pdev->device == PCI_DEVICE_ID_ARECA_1203) { + reg->drv2iop_doorbell = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_1203); + reg->drv2iop_doorbell_mask = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_MASK_1203); + reg->iop2drv_doorbell = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_1203); + reg->iop2drv_doorbell_mask = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_MASK_1203); + } else { + reg->drv2iop_doorbell = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL); + reg->drv2iop_doorbell_mask = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_MASK); + reg->iop2drv_doorbell = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL); + reg->iop2drv_doorbell_mask = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_MASK); + } reg->message_wbuffer = MEM_BASE1(ARCMSR_MESSAGE_WBUFFER); reg->message_rbuffer = MEM_BASE1(ARCMSR_MESSAGE_RBUFFER); reg->message_rwbuffer = MEM_BASE1(ARCMSR_MESSAGE_RWBUFFER); @@ -2660,6 +2670,12 @@ static bool arcmsr_hbaB_get_config(struct AdapterControlBlock *acb) iop_firm_version = (char __iomem *)(®->message_rwbuffer[17]); /*firm_version,17,68-83*/ iop_device_map = (char __iomem *)(®->message_rwbuffer[21]); /*firm_version,21,84-99*/ + arcmsr_wait_firmware_ready(acb); + writel(ARCMSR_MESSAGE_START_DRIVER_MODE, reg->drv2iop_doorbell); + if (!arcmsr_hbaB_wait_msgint_ready(acb)) { + printk(KERN_ERR "arcmsr%d: can't set driver mode.\n", acb->host->host_no); + goto err_free_dma; + } writel(ARCMSR_MESSAGE_GET_CONFIG, reg->drv2iop_doorbell); if (!arcmsr_hbaB_wait_msgint_ready(acb)) { printk(KERN_NOTICE "arcmsr%d: wait 'get adapter firmware \ @@ -4002,6 +4018,7 @@ static const char *arcmsr_info(struct Scsi_Host *host) case PCI_DEVICE_ID_ARECA_1160: case PCI_DEVICE_ID_ARECA_1170: case PCI_DEVICE_ID_ARECA_1201: + case PCI_DEVICE_ID_ARECA_1203: case PCI_DEVICE_ID_ARECA_1220: case PCI_DEVICE_ID_ARECA_1230: case PCI_DEVICE_ID_ARECA_1260: -- cgit v0.10.2 From d15dd55d049ccae9a1061e08ad377f9c799b8a3a Mon Sep 17 00:00:00 2001 From: Ching Huang Date: Wed, 25 Nov 2015 19:52:15 +0800 Subject: arcmsr: changes driver version number Changes driver version number. Signed-off-by: Ching Huang Reviewed-by: Johannes Thumshirn Reviewed-by: Hannes Reinicke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h index 9c5a2a8..2356777 100644 --- a/drivers/scsi/arcmsr/arcmsr.h +++ b/drivers/scsi/arcmsr/arcmsr.h @@ -52,7 +52,7 @@ struct device_attribute; #define ARCMSR_MAX_FREECCB_NUM 320 #define ARCMSR_MAX_OUTSTANDING_CMD 255 #endif -#define ARCMSR_DRIVER_VERSION "v1.30.00.04-20140919" +#define ARCMSR_DRIVER_VERSION "v1.30.00.21-20151019" #define ARCMSR_SCSI_INITIATOR_ID 255 #define ARCMSR_MAX_XFER_SECTORS 512 #define ARCMSR_MAX_XFER_SECTORS_B 4096 -- cgit v0.10.2 From f75ab39a4be08b996ca19002bd7b54df8fdb8d10 Mon Sep 17 00:00:00 2001 From: Ching Huang Date: Thu, 26 Nov 2015 19:33:56 +0800 Subject: arcmsr: more readability improvements Signed-off-by: Ching Huang Reviewed-by: Tomas Henzl Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 881be34..a0c98bf 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -2814,53 +2814,32 @@ static bool arcmsr_hbaD_get_config(struct AdapterControlBlock *acb) acb->dma_coherent2 = dma_coherent2; reg = (struct MessageUnit_D *)dma_coherent2; acb->pmuD = reg; - reg->chip_id = acb->mem_base0 + ARCMSR_ARC1214_CHIP_ID; - reg->cpu_mem_config = acb->mem_base0 + - ARCMSR_ARC1214_CPU_MEMORY_CONFIGURATION; - reg->i2o_host_interrupt_mask = acb->mem_base0 + - ARCMSR_ARC1214_I2_HOST_INTERRUPT_MASK; - reg->sample_at_reset = acb->mem_base0 + ARCMSR_ARC1214_SAMPLE_RESET; - reg->reset_request = acb->mem_base0 + ARCMSR_ARC1214_RESET_REQUEST; - reg->host_int_status = acb->mem_base0 + - ARCMSR_ARC1214_MAIN_INTERRUPT_STATUS; - reg->pcief0_int_enable = acb->mem_base0 + - ARCMSR_ARC1214_PCIE_F0_INTERRUPT_ENABLE; - reg->inbound_msgaddr0 = acb->mem_base0 + - ARCMSR_ARC1214_INBOUND_MESSAGE0; - reg->inbound_msgaddr1 = acb->mem_base0 + - ARCMSR_ARC1214_INBOUND_MESSAGE1; - reg->outbound_msgaddr0 = acb->mem_base0 + - ARCMSR_ARC1214_OUTBOUND_MESSAGE0; - reg->outbound_msgaddr1 = acb->mem_base0 + - ARCMSR_ARC1214_OUTBOUND_MESSAGE1; - reg->inbound_doorbell = acb->mem_base0 + - ARCMSR_ARC1214_INBOUND_DOORBELL; - reg->outbound_doorbell = acb->mem_base0 + - ARCMSR_ARC1214_OUTBOUND_DOORBELL; - reg->outbound_doorbell_enable = acb->mem_base0 + - ARCMSR_ARC1214_OUTBOUND_DOORBELL_ENABLE; - reg->inboundlist_base_low = acb->mem_base0 + - ARCMSR_ARC1214_INBOUND_LIST_BASE_LOW; - reg->inboundlist_base_high = acb->mem_base0 + - ARCMSR_ARC1214_INBOUND_LIST_BASE_HIGH; - reg->inboundlist_write_pointer = acb->mem_base0 + - ARCMSR_ARC1214_INBOUND_LIST_WRITE_POINTER; - reg->outboundlist_base_low = acb->mem_base0 + - ARCMSR_ARC1214_OUTBOUND_LIST_BASE_LOW; - reg->outboundlist_base_high = acb->mem_base0 + - ARCMSR_ARC1214_OUTBOUND_LIST_BASE_HIGH; - reg->outboundlist_copy_pointer = acb->mem_base0 + - ARCMSR_ARC1214_OUTBOUND_LIST_COPY_POINTER; - reg->outboundlist_read_pointer = acb->mem_base0 + - ARCMSR_ARC1214_OUTBOUND_LIST_READ_POINTER; - reg->outboundlist_interrupt_cause = acb->mem_base0 + - ARCMSR_ARC1214_OUTBOUND_INTERRUPT_CAUSE; - reg->outboundlist_interrupt_enable = acb->mem_base0 + - ARCMSR_ARC1214_OUTBOUND_INTERRUPT_ENABLE; - reg->message_wbuffer = acb->mem_base0 + ARCMSR_ARC1214_MESSAGE_WBUFFER; - reg->message_rbuffer = acb->mem_base0 + ARCMSR_ARC1214_MESSAGE_RBUFFER; - reg->msgcode_rwbuffer = acb->mem_base0 + - ARCMSR_ARC1214_MESSAGE_RWBUFFER; + reg->chip_id = MEM_BASE0(ARCMSR_ARC1214_CHIP_ID); + reg->cpu_mem_config = MEM_BASE0(ARCMSR_ARC1214_CPU_MEMORY_CONFIGURATION); + reg->i2o_host_interrupt_mask = MEM_BASE0(ARCMSR_ARC1214_I2_HOST_INTERRUPT_MASK); + reg->sample_at_reset = MEM_BASE0(ARCMSR_ARC1214_SAMPLE_RESET); + reg->reset_request = MEM_BASE0(ARCMSR_ARC1214_RESET_REQUEST); + reg->host_int_status = MEM_BASE0(ARCMSR_ARC1214_MAIN_INTERRUPT_STATUS); + reg->pcief0_int_enable = MEM_BASE0(ARCMSR_ARC1214_PCIE_F0_INTERRUPT_ENABLE); + reg->inbound_msgaddr0 = MEM_BASE0(ARCMSR_ARC1214_INBOUND_MESSAGE0); + reg->inbound_msgaddr1 = MEM_BASE0(ARCMSR_ARC1214_INBOUND_MESSAGE1); + reg->outbound_msgaddr0 = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_MESSAGE0); + reg->outbound_msgaddr1 = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_MESSAGE1); + reg->inbound_doorbell = MEM_BASE0(ARCMSR_ARC1214_INBOUND_DOORBELL); + reg->outbound_doorbell = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_DOORBELL); + reg->outbound_doorbell_enable = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_DOORBELL_ENABLE); + reg->inboundlist_base_low = MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_BASE_LOW); + reg->inboundlist_base_high = MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_BASE_HIGH); + reg->inboundlist_write_pointer = MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_WRITE_POINTER); + reg->outboundlist_base_low = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_BASE_LOW); + reg->outboundlist_base_high = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_BASE_HIGH); + reg->outboundlist_copy_pointer = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_COPY_POINTER); + reg->outboundlist_read_pointer = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_READ_POINTER); + reg->outboundlist_interrupt_cause = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_INTERRUPT_CAUSE); + reg->outboundlist_interrupt_enable = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_INTERRUPT_ENABLE); + reg->message_wbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_WBUFFER); + reg->message_rbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_RBUFFER); + reg->msgcode_rwbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_RWBUFFER); iop_firm_model = (char __iomem *)(®->msgcode_rwbuffer[15]); iop_firm_version = (char __iomem *)(®->msgcode_rwbuffer[17]); iop_device_map = (char __iomem *)(®->msgcode_rwbuffer[21]); -- cgit v0.10.2 From 02040670aaa0f125259ad8f9f5f30e4d138a65ae Mon Sep 17 00:00:00 2001 From: Ching Huang Date: Thu, 26 Nov 2015 19:41:15 +0800 Subject: arcmsr: Split dma resource allocation to a new function Split dma resource allocation and io register assignment from get_config to a new function arcmsr_alloc_io_queue. Signed-off-by: Ching Huang Reviewed-by: Tomas Henzl Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index a0c98bf..7640498 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -498,6 +498,91 @@ static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb) } } +static bool arcmsr_alloc_io_queue(struct AdapterControlBlock *acb) +{ + bool rtn = true; + void *dma_coherent; + dma_addr_t dma_coherent_handle; + struct pci_dev *pdev = acb->pdev; + + switch (acb->adapter_type) { + case ACB_ADAPTER_TYPE_B: { + struct MessageUnit_B *reg; + acb->roundup_ccbsize = roundup(sizeof(struct MessageUnit_B), 32); + dma_coherent = dma_zalloc_coherent(&pdev->dev, acb->roundup_ccbsize, + &dma_coherent_handle, GFP_KERNEL); + if (!dma_coherent) { + pr_notice("arcmsr%d: DMA allocation failed\n", acb->host->host_no); + return false; + } + acb->dma_coherent_handle2 = dma_coherent_handle; + acb->dma_coherent2 = dma_coherent; + reg = (struct MessageUnit_B *)dma_coherent; + acb->pmuB = reg; + if (acb->pdev->device == PCI_DEVICE_ID_ARECA_1203) { + reg->drv2iop_doorbell = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_1203); + reg->drv2iop_doorbell_mask = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_MASK_1203); + reg->iop2drv_doorbell = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_1203); + reg->iop2drv_doorbell_mask = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_MASK_1203); + } else { + reg->drv2iop_doorbell = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL); + reg->drv2iop_doorbell_mask = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_MASK); + reg->iop2drv_doorbell = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL); + reg->iop2drv_doorbell_mask = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_MASK); + } + reg->message_wbuffer = MEM_BASE1(ARCMSR_MESSAGE_WBUFFER); + reg->message_rbuffer = MEM_BASE1(ARCMSR_MESSAGE_RBUFFER); + reg->message_rwbuffer = MEM_BASE1(ARCMSR_MESSAGE_RWBUFFER); + } + break; + case ACB_ADAPTER_TYPE_D: { + struct MessageUnit_D *reg; + + acb->roundup_ccbsize = roundup(sizeof(struct MessageUnit_D), 32); + dma_coherent = dma_zalloc_coherent(&pdev->dev, acb->roundup_ccbsize, + &dma_coherent_handle, GFP_KERNEL); + if (!dma_coherent) { + pr_notice("arcmsr%d: DMA allocation failed\n", acb->host->host_no); + return false; + } + acb->dma_coherent_handle2 = dma_coherent_handle; + acb->dma_coherent2 = dma_coherent; + reg = (struct MessageUnit_D *)dma_coherent; + acb->pmuD = reg; + reg->chip_id = MEM_BASE0(ARCMSR_ARC1214_CHIP_ID); + reg->cpu_mem_config = MEM_BASE0(ARCMSR_ARC1214_CPU_MEMORY_CONFIGURATION); + reg->i2o_host_interrupt_mask = MEM_BASE0(ARCMSR_ARC1214_I2_HOST_INTERRUPT_MASK); + reg->sample_at_reset = MEM_BASE0(ARCMSR_ARC1214_SAMPLE_RESET); + reg->reset_request = MEM_BASE0(ARCMSR_ARC1214_RESET_REQUEST); + reg->host_int_status = MEM_BASE0(ARCMSR_ARC1214_MAIN_INTERRUPT_STATUS); + reg->pcief0_int_enable = MEM_BASE0(ARCMSR_ARC1214_PCIE_F0_INTERRUPT_ENABLE); + reg->inbound_msgaddr0 = MEM_BASE0(ARCMSR_ARC1214_INBOUND_MESSAGE0); + reg->inbound_msgaddr1 = MEM_BASE0(ARCMSR_ARC1214_INBOUND_MESSAGE1); + reg->outbound_msgaddr0 = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_MESSAGE0); + reg->outbound_msgaddr1 = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_MESSAGE1); + reg->inbound_doorbell = MEM_BASE0(ARCMSR_ARC1214_INBOUND_DOORBELL); + reg->outbound_doorbell = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_DOORBELL); + reg->outbound_doorbell_enable = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_DOORBELL_ENABLE); + reg->inboundlist_base_low = MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_BASE_LOW); + reg->inboundlist_base_high = MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_BASE_HIGH); + reg->inboundlist_write_pointer = MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_WRITE_POINTER); + reg->outboundlist_base_low = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_BASE_LOW); + reg->outboundlist_base_high = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_BASE_HIGH); + reg->outboundlist_copy_pointer = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_COPY_POINTER); + reg->outboundlist_read_pointer = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_READ_POINTER); + reg->outboundlist_interrupt_cause = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_INTERRUPT_CAUSE); + reg->outboundlist_interrupt_enable = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_INTERRUPT_ENABLE); + reg->message_wbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_WBUFFER); + reg->message_rbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_RBUFFER); + reg->msgcode_rwbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_RWBUFFER); + } + break; + default: + break; + } + return rtn; +} + static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb) { struct pci_dev *pdev = acb->pdev; @@ -742,9 +827,12 @@ static int arcmsr_probe(struct pci_dev *pdev, const struct pci_device_id *id) if(!error){ goto pci_release_regs; } + error = arcmsr_alloc_io_queue(acb); + if (!error) + goto unmap_pci_region; error = arcmsr_get_firmware_spec(acb); if(!error){ - goto unmap_pci_region; + goto free_hbb_mu; } error = arcmsr_alloc_ccb_pool(acb); if(error){ @@ -2624,10 +2712,7 @@ static bool arcmsr_hbaA_get_config(struct AdapterControlBlock *acb) } static bool arcmsr_hbaB_get_config(struct AdapterControlBlock *acb) { - struct MessageUnit_B *reg; - struct pci_dev *pdev = acb->pdev; - void *dma_coherent; - dma_addr_t dma_coherent_handle; + struct MessageUnit_B *reg = acb->pmuB; char *acb_firm_model = acb->firm_model; char *acb_firm_version = acb->firm_version; char *acb_device_map = acb->device_map; @@ -2639,33 +2724,6 @@ static bool arcmsr_hbaB_get_config(struct AdapterControlBlock *acb) /*firm_version,21,84-99*/ int count; - acb->roundup_ccbsize = roundup(sizeof(struct MessageUnit_B), 32); - dma_coherent = dma_alloc_coherent(&pdev->dev, acb->roundup_ccbsize, - &dma_coherent_handle, GFP_KERNEL); - if (!dma_coherent){ - printk(KERN_NOTICE - "arcmsr%d: dma_alloc_coherent got error for hbb mu\n", - acb->host->host_no); - return false; - } - acb->dma_coherent_handle2 = dma_coherent_handle; - acb->dma_coherent2 = dma_coherent; - reg = (struct MessageUnit_B *)dma_coherent; - acb->pmuB = reg; - if (acb->pdev->device == PCI_DEVICE_ID_ARECA_1203) { - reg->drv2iop_doorbell = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_1203); - reg->drv2iop_doorbell_mask = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_MASK_1203); - reg->iop2drv_doorbell = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_1203); - reg->iop2drv_doorbell_mask = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_MASK_1203); - } else { - reg->drv2iop_doorbell = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL); - reg->drv2iop_doorbell_mask = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_MASK); - reg->iop2drv_doorbell = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL); - reg->iop2drv_doorbell_mask = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_MASK); - } - reg->message_wbuffer = MEM_BASE1(ARCMSR_MESSAGE_WBUFFER); - reg->message_rbuffer = MEM_BASE1(ARCMSR_MESSAGE_RBUFFER); - reg->message_rwbuffer = MEM_BASE1(ARCMSR_MESSAGE_RWBUFFER); iop_firm_model = (char __iomem *)(®->message_rwbuffer[15]); /*firm_model,15,60-67*/ iop_firm_version = (char __iomem *)(®->message_rwbuffer[17]); /*firm_version,17,68-83*/ iop_device_map = (char __iomem *)(®->message_rwbuffer[21]); /*firm_version,21,84-99*/ @@ -2674,13 +2732,13 @@ static bool arcmsr_hbaB_get_config(struct AdapterControlBlock *acb) writel(ARCMSR_MESSAGE_START_DRIVER_MODE, reg->drv2iop_doorbell); if (!arcmsr_hbaB_wait_msgint_ready(acb)) { printk(KERN_ERR "arcmsr%d: can't set driver mode.\n", acb->host->host_no); - goto err_free_dma; + return false; } writel(ARCMSR_MESSAGE_GET_CONFIG, reg->drv2iop_doorbell); if (!arcmsr_hbaB_wait_msgint_ready(acb)) { printk(KERN_NOTICE "arcmsr%d: wait 'get adapter firmware \ miscellaneous data' timeout \n", acb->host->host_no); - goto err_free_dma; + return false; } count = 8; while (count){ @@ -2723,10 +2781,6 @@ static bool arcmsr_hbaB_get_config(struct AdapterControlBlock *acb) acb->firm_cfg_version = readl(®->message_rwbuffer[25]); /*firm_cfg_version,25,100-103*/ /*firm_ide_channels,4,16-19*/ return true; -err_free_dma: - dma_free_coherent(&acb->pdev->dev, acb->roundup_ccbsize, - acb->dma_coherent2, acb->dma_coherent_handle2); - return false; } static bool arcmsr_hbaC_get_config(struct AdapterControlBlock *pACB) @@ -2797,49 +2851,8 @@ static bool arcmsr_hbaD_get_config(struct AdapterControlBlock *acb) char __iomem *iop_firm_version; char __iomem *iop_device_map; u32 count; - struct MessageUnit_D *reg; - void *dma_coherent2; - dma_addr_t dma_coherent_handle2; - struct pci_dev *pdev = acb->pdev; + struct MessageUnit_D *reg = acb->pmuD; - acb->roundup_ccbsize = roundup(sizeof(struct MessageUnit_D), 32); - dma_coherent2 = dma_alloc_coherent(&pdev->dev, acb->roundup_ccbsize, - &dma_coherent_handle2, GFP_KERNEL); - if (!dma_coherent2) { - pr_notice("DMA allocation failed...\n"); - return false; - } - memset(dma_coherent2, 0, acb->roundup_ccbsize); - acb->dma_coherent_handle2 = dma_coherent_handle2; - acb->dma_coherent2 = dma_coherent2; - reg = (struct MessageUnit_D *)dma_coherent2; - acb->pmuD = reg; - reg->chip_id = MEM_BASE0(ARCMSR_ARC1214_CHIP_ID); - reg->cpu_mem_config = MEM_BASE0(ARCMSR_ARC1214_CPU_MEMORY_CONFIGURATION); - reg->i2o_host_interrupt_mask = MEM_BASE0(ARCMSR_ARC1214_I2_HOST_INTERRUPT_MASK); - reg->sample_at_reset = MEM_BASE0(ARCMSR_ARC1214_SAMPLE_RESET); - reg->reset_request = MEM_BASE0(ARCMSR_ARC1214_RESET_REQUEST); - reg->host_int_status = MEM_BASE0(ARCMSR_ARC1214_MAIN_INTERRUPT_STATUS); - reg->pcief0_int_enable = MEM_BASE0(ARCMSR_ARC1214_PCIE_F0_INTERRUPT_ENABLE); - reg->inbound_msgaddr0 = MEM_BASE0(ARCMSR_ARC1214_INBOUND_MESSAGE0); - reg->inbound_msgaddr1 = MEM_BASE0(ARCMSR_ARC1214_INBOUND_MESSAGE1); - reg->outbound_msgaddr0 = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_MESSAGE0); - reg->outbound_msgaddr1 = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_MESSAGE1); - reg->inbound_doorbell = MEM_BASE0(ARCMSR_ARC1214_INBOUND_DOORBELL); - reg->outbound_doorbell = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_DOORBELL); - reg->outbound_doorbell_enable = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_DOORBELL_ENABLE); - reg->inboundlist_base_low = MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_BASE_LOW); - reg->inboundlist_base_high = MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_BASE_HIGH); - reg->inboundlist_write_pointer = MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_WRITE_POINTER); - reg->outboundlist_base_low = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_BASE_LOW); - reg->outboundlist_base_high = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_BASE_HIGH); - reg->outboundlist_copy_pointer = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_COPY_POINTER); - reg->outboundlist_read_pointer = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_READ_POINTER); - reg->outboundlist_interrupt_cause = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_INTERRUPT_CAUSE); - reg->outboundlist_interrupt_enable = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_INTERRUPT_ENABLE); - reg->message_wbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_WBUFFER); - reg->message_rbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_RBUFFER); - reg->msgcode_rwbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_RWBUFFER); iop_firm_model = (char __iomem *)(®->msgcode_rwbuffer[15]); iop_firm_version = (char __iomem *)(®->msgcode_rwbuffer[17]); iop_device_map = (char __iomem *)(®->msgcode_rwbuffer[21]); @@ -2854,8 +2867,6 @@ static bool arcmsr_hbaD_get_config(struct AdapterControlBlock *acb) if (!arcmsr_hbaD_wait_msgint_ready(acb)) { pr_notice("arcmsr%d: wait get adapter firmware " "miscellaneous data timeout\n", acb->host->host_no); - dma_free_coherent(&acb->pdev->dev, acb->roundup_ccbsize, - acb->dma_coherent2, acb->dma_coherent_handle2); return false; } count = 8; -- cgit v0.10.2 From 15d2639704b828db0506a416eda010178e1fd816 Mon Sep 17 00:00:00 2001 From: Ching Huang Date: Thu, 26 Nov 2015 19:44:55 +0800 Subject: arcmsr: change driver version to v1.30.00.22-20151126 Change driver version to v1.30.00.22-20151126 Signed-off-by: Ching Huang Reviewed-by: Tomas Henzl Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h index 2356777..cf99f8c 100644 --- a/drivers/scsi/arcmsr/arcmsr.h +++ b/drivers/scsi/arcmsr/arcmsr.h @@ -52,7 +52,7 @@ struct device_attribute; #define ARCMSR_MAX_FREECCB_NUM 320 #define ARCMSR_MAX_OUTSTANDING_CMD 255 #endif -#define ARCMSR_DRIVER_VERSION "v1.30.00.21-20151019" +#define ARCMSR_DRIVER_VERSION "v1.30.00.22-20151126" #define ARCMSR_SCSI_INITIATOR_ID 255 #define ARCMSR_MAX_XFER_SECTORS 512 #define ARCMSR_MAX_XFER_SECTORS_B 4096 -- cgit v0.10.2 From bad9764cfaaa15bc4263824b33956f15267442c6 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Sat, 28 Nov 2015 16:33:56 +0000 Subject: scsi: ufs: fix spelling mistake in error message Minor issue, fix spelling mistake, Intialization -> Initialization Signed-off-by: Colin Ian King Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c index 9714f2a..d2a7b12 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.c +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c @@ -333,7 +333,7 @@ int ufshcd_pltfrm_init(struct platform_device *pdev, err = ufshcd_init(hba, mmio_base, irq); if (err) { - dev_err(dev, "Intialization failed\n"); + dev_err(dev, "Initialization failed\n"); goto out_disable_rpm; } -- cgit v0.10.2 From 7789cd39274c51bf475411fe22a8ee7255082809 Mon Sep 17 00:00:00 2001 From: Luis de Bethencourt Date: Mon, 30 Nov 2015 14:32:17 +0000 Subject: mvsas: fix misleading indentation Fix a smatch warning: drivers/scsi/mvsas/mv_sas.c:740 mvs_task_prep() warn: curly braces intended? The code is correct, the indention is misleading. When the device is not ready we want to return SAS_PHY_DOWN. But current indentation makes it look like we only do so in the else branch of if (mvi_dev). Signed-off-by: Luis de Bethencourt Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c index 9c78074..e712fe7 100644 --- a/drivers/scsi/mvsas/mv_sas.c +++ b/drivers/scsi/mvsas/mv_sas.c @@ -737,8 +737,8 @@ static int mvs_task_prep(struct sas_task *task, struct mvs_info *mvi, int is_tmf mv_dprintk("device %016llx not ready.\n", SAS_ADDR(dev->sas_addr)); - rc = SAS_PHY_DOWN; - return rc; + rc = SAS_PHY_DOWN; + return rc; } tei.port = dev->port->lldd_port; if (tei.port && !tei.port->port_attached && !tmf) { -- cgit v0.10.2 From 41f95dd2efd80a611c8566888fcdcb5d399ea474 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:41 +0100 Subject: scsi_dh: move 'dh_state' sysfs attribute to generic code As scsi_dh.c is now always compiled in we should be moving the 'dh_state' attribute to the generic code. Reviewed-by: Christoph Hellwig Reviewed-by: Johannes Thumshirn Signed-off-by: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/scsi_dh.c b/drivers/scsi/scsi_dh.c index e7649ed..54d446c 100644 --- a/drivers/scsi/scsi_dh.c +++ b/drivers/scsi/scsi_dh.c @@ -153,76 +153,11 @@ static void scsi_dh_handler_detach(struct scsi_device *sdev) module_put(sdev->handler->module); } -/* - * Functions for sysfs attribute 'dh_state' - */ -static ssize_t -store_dh_state(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct scsi_device *sdev = to_scsi_device(dev); - struct scsi_device_handler *scsi_dh; - int err = -EINVAL; - - if (sdev->sdev_state == SDEV_CANCEL || - sdev->sdev_state == SDEV_DEL) - return -ENODEV; - - if (!sdev->handler) { - /* - * Attach to a device handler - */ - scsi_dh = scsi_dh_lookup(buf); - if (!scsi_dh) - return err; - err = scsi_dh_handler_attach(sdev, scsi_dh); - } else { - if (!strncmp(buf, "detach", 6)) { - /* - * Detach from a device handler - */ - sdev_printk(KERN_WARNING, sdev, - "can't detach handler %s.\n", - sdev->handler->name); - err = -EINVAL; - } else if (!strncmp(buf, "activate", 8)) { - /* - * Activate a device handler - */ - if (sdev->handler->activate) - err = sdev->handler->activate(sdev, NULL, NULL); - else - err = 0; - } - } - - return err<0?err:count; -} - -static ssize_t -show_dh_state(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct scsi_device *sdev = to_scsi_device(dev); - - if (!sdev->handler) - return snprintf(buf, 20, "detached\n"); - - return snprintf(buf, 20, "%s\n", sdev->handler->name); -} - -static struct device_attribute scsi_dh_state_attr = - __ATTR(dh_state, S_IRUGO | S_IWUSR, show_dh_state, - store_dh_state); - int scsi_dh_add_device(struct scsi_device *sdev) { struct scsi_device_handler *devinfo = NULL; const char *drv; - int err; - - err = device_create_file(&sdev->sdev_gendev, &scsi_dh_state_attr); - if (err) - return err; + int err = 0; drv = scsi_dh_find_driver(sdev); if (drv) @@ -238,11 +173,6 @@ void scsi_dh_release_device(struct scsi_device *sdev) scsi_dh_handler_detach(sdev); } -void scsi_dh_remove_device(struct scsi_device *sdev) -{ - device_remove_file(&sdev->sdev_gendev, &scsi_dh_state_attr); -} - /* * scsi_register_device_handler - register a device handler personality * module. diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index 4d01cdb..27b4d0a 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h @@ -174,12 +174,11 @@ extern struct async_domain scsi_sd_probe_domain; #ifdef CONFIG_SCSI_DH int scsi_dh_add_device(struct scsi_device *sdev); void scsi_dh_release_device(struct scsi_device *sdev); -void scsi_dh_remove_device(struct scsi_device *sdev); #else static inline int scsi_dh_add_device(struct scsi_device *sdev) { return 0; } static inline void scsi_dh_release_device(struct scsi_device *sdev) { } -static inline void scsi_dh_remove_device(struct scsi_device *sdev) { } #endif +static inline void scsi_dh_remove_device(struct scsi_device *sdev) { } /* * internal scsi timeout functions: for use by mid-layer and transport diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 158f1b5..fc3cd26 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -904,6 +905,60 @@ sdev_show_function(queue_depth, "%d\n"); static DEVICE_ATTR(queue_depth, S_IRUGO | S_IWUSR, sdev_show_queue_depth, sdev_store_queue_depth); +#ifdef CONFIG_SCSI_DH +static ssize_t +sdev_show_dh_state(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct scsi_device *sdev = to_scsi_device(dev); + + if (!sdev->handler) + return snprintf(buf, 20, "detached\n"); + + return snprintf(buf, 20, "%s\n", sdev->handler->name); +} + +static ssize_t +sdev_store_dh_state(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct scsi_device *sdev = to_scsi_device(dev); + int err = -EINVAL; + + if (sdev->sdev_state == SDEV_CANCEL || + sdev->sdev_state == SDEV_DEL) + return -ENODEV; + + if (!sdev->handler) { + /* + * Attach to a device handler + */ + err = scsi_dh_attach(sdev->request_queue, buf); + } else if (!strncmp(buf, "activate", 8)) { + /* + * Activate a device handler + */ + if (sdev->handler->activate) + err = sdev->handler->activate(sdev, NULL, NULL); + else + err = 0; + } else if (!strncmp(buf, "detach", 6)) { + /* + * Detach from a device handler + */ + sdev_printk(KERN_WARNING, sdev, + "can't detach handler %s.\n", + sdev->handler->name); + err = -EINVAL; + } + + return err < 0 ? err : count; +} + +static DEVICE_ATTR(dh_state, S_IRUGO | S_IWUSR, sdev_show_dh_state, + sdev_store_dh_state); +#endif + static ssize_t sdev_show_queue_ramp_up_period(struct device *dev, struct device_attribute *attr, @@ -973,6 +1028,9 @@ static struct attribute *scsi_sdev_attrs[] = { &dev_attr_modalias.attr, &dev_attr_queue_depth.attr, &dev_attr_queue_type.attr, +#ifdef CONFIG_SCSI_DH + &dev_attr_dh_state.attr, +#endif &dev_attr_queue_ramp_up_period.attr, REF_EVT(media_change), REF_EVT(inquiry_change_reported), -- cgit v0.10.2 From 221255aee67ec1c752001080aafec0c4e9390d95 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:42 +0100 Subject: scsi: ignore errors from scsi_dh_add_device() device handler initialisation might fail due to a number of reasons. But as device_handlers are optional this shouldn't cause us to disable the device entirely. So just ignore errors from scsi_dh_add_device(). Reviewed-by: Johannes Thumshirn Reviewed-by: Christoph Hellwig Signed-off-by: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index fc3cd26..d015374 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -1120,11 +1120,12 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) } error = scsi_dh_add_device(sdev); - if (error) { + if (error) + /* + * device_handler is optional, so any error can be ignored + */ sdev_printk(KERN_INFO, sdev, "failed to add device handler: %d\n", error); - return error; - } device_enable_async_suspend(&sdev->sdev_dev); error = device_add(&sdev->sdev_dev); -- cgit v0.10.2 From db5a6a601ba93c69dd320a0625ce492543c37748 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:43 +0100 Subject: scsi_dh_alua: Disable ALUA handling for non-disk devices Non-disk devices might support ALUA, but the firmware implementation is untested and frequently broken. As we're don't actually need it disable ALUA support for non-disk device for now. Signed-off-by: Hannes Reinecke Reviewed-by: Bart Van Assche Reviewed-by: Christoph Hellwig Reviewed-by: Martin K. Petersen Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index cc2773b..7d01ef0 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -320,6 +320,18 @@ static int alua_check_tpgs(struct scsi_device *sdev, struct alua_dh_data *h) { int err = SCSI_DH_OK; + /* + * ALUA support for non-disk devices is fraught with + * difficulties, so disable it for now. + */ + if (sdev->type != TYPE_DISK) { + h->tpgs = TPGS_MODE_NONE; + sdev_printk(KERN_INFO, sdev, + "%s: disable for non-disk devices\n", + ALUA_DH_NAME); + return SCSI_DH_DEV_UNSUPP; + } + h->tpgs = scsi_device_tpgs(sdev); switch (h->tpgs) { case TPGS_MODE_EXPLICIT|TPGS_MODE_IMPLICIT: -- cgit v0.10.2 From 9b80dcec411e8937d94d7ca09da08ed6ca95e6ba Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:44 +0100 Subject: scsi_dh_alua: Use vpd_pg83 information The SCSI device now has the VPD page 0x83 information attached, so there is no need to query it again. [mkp: Fixed a checkpatch warning] Signed-off-by: Hannes Reinecke Reviewed-by: Martin K. Petersen Reviewed-by: Christoph Hellwig Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index 7d01ef0..87c5ba8 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -131,43 +131,6 @@ static struct request *get_alua_req(struct scsi_device *sdev, } /* - * submit_vpd_inquiry - Issue an INQUIRY VPD page 0x83 command - * @sdev: sdev the command should be sent to - */ -static int submit_vpd_inquiry(struct scsi_device *sdev, struct alua_dh_data *h) -{ - struct request *rq; - int err = SCSI_DH_RES_TEMP_UNAVAIL; - - rq = get_alua_req(sdev, h->buff, h->bufflen, READ); - if (!rq) - goto done; - - /* Prepare the command. */ - rq->cmd[0] = INQUIRY; - rq->cmd[1] = 1; - rq->cmd[2] = 0x83; - rq->cmd[4] = h->bufflen; - rq->cmd_len = COMMAND_SIZE(INQUIRY); - - rq->sense = h->sense; - memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE); - rq->sense_len = h->senselen = 0; - - err = blk_execute_rq(rq->q, NULL, rq, 1); - if (err == -EIO) { - sdev_printk(KERN_INFO, sdev, - "%s: evpd inquiry failed with %x\n", - ALUA_DH_NAME, rq->errors); - h->senselen = rq->sense_len; - err = SCSI_DH_IO; - } - blk_put_request(rq); -done: - return err; -} - -/* * submit_rtpg - Issue a REPORT TARGET GROUP STATES command * @sdev: sdev the command should be sent to */ @@ -359,43 +322,29 @@ static int alua_check_tpgs(struct scsi_device *sdev, struct alua_dh_data *h) } /* - * alua_vpd_inquiry - Evaluate INQUIRY vpd page 0x83 + * alua_check_vpd - Evaluate INQUIRY vpd page 0x83 * @sdev: device to be checked * * Extract the relative target port and the target port group * descriptor from the list of identificators. */ -static int alua_vpd_inquiry(struct scsi_device *sdev, struct alua_dh_data *h) +static int alua_check_vpd(struct scsi_device *sdev, struct alua_dh_data *h) { - int len; - unsigned err; unsigned char *d; + unsigned char __rcu *vpd_pg83; - retry: - err = submit_vpd_inquiry(sdev, h); - - if (err != SCSI_DH_OK) - return err; - - /* Check if vpd page exceeds initial buffer */ - len = (h->buff[2] << 8) + h->buff[3] + 4; - if (len > h->bufflen) { - /* Resubmit with the correct length */ - if (realloc_buffer(h, len)) { - sdev_printk(KERN_WARNING, sdev, - "%s: kmalloc buffer failed\n", - ALUA_DH_NAME); - /* Temporary failure, bypass */ - return SCSI_DH_DEV_TEMP_BUSY; - } - goto retry; + rcu_read_lock(); + if (!rcu_dereference(sdev->vpd_pg83)) { + rcu_read_unlock(); + return SCSI_DH_DEV_UNSUPP; } /* - * Now look for the correct descriptor. + * Look for the correct descriptor. */ - d = h->buff + 4; - while (d < h->buff + len) { + vpd_pg83 = rcu_dereference(sdev->vpd_pg83); + d = vpd_pg83 + 4; + while (d < vpd_pg83 + sdev->vpd_pg83_len) { switch (d[1] & 0xf) { case 0x4: /* Relative target port */ @@ -410,6 +359,7 @@ static int alua_vpd_inquiry(struct scsi_device *sdev, struct alua_dh_data *h) } d += d[3] + 4; } + rcu_read_unlock(); if (h->group_id == -1) { /* @@ -422,14 +372,13 @@ static int alua_vpd_inquiry(struct scsi_device *sdev, struct alua_dh_data *h) ALUA_DH_NAME); h->state = TPGS_STATE_OPTIMIZED; h->tpgs = TPGS_MODE_NONE; - err = SCSI_DH_DEV_UNSUPP; - } else { - sdev_printk(KERN_INFO, sdev, - "%s: port group %02x rel port %02x\n", - ALUA_DH_NAME, h->group_id, h->rel_port); + return SCSI_DH_DEV_UNSUPP; } + sdev_printk(KERN_INFO, sdev, + "%s: port group %02x rel port %02x\n", + ALUA_DH_NAME, h->group_id, h->rel_port); - return err; + return 0; } static char print_alua_state(int state) @@ -692,7 +641,7 @@ static int alua_initialize(struct scsi_device *sdev, struct alua_dh_data *h) if (err != SCSI_DH_OK) goto out; - err = alua_vpd_inquiry(sdev, h); + err = alua_check_vpd(sdev, h); if (err != SCSI_DH_OK) goto out; -- cgit v0.10.2 From 6cc05d451cfa876014ef607516f730623e317987 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:45 +0100 Subject: scsi_dh_alua: improved logging Issue different logging messages if ALUA is not supported or the TPGS setting is invalid. Signed-off-by: Hannes Reinecke Reviewed-by: Martin K. Petersen Reviewed-by: Christoph Hellwig Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index 87c5ba8..31a971f 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -310,12 +310,18 @@ static int alua_check_tpgs(struct scsi_device *sdev, struct alua_dh_data *h) sdev_printk(KERN_INFO, sdev, "%s: supports implicit TPGS\n", ALUA_DH_NAME); break; - default: - h->tpgs = TPGS_MODE_NONE; + case TPGS_MODE_NONE: sdev_printk(KERN_INFO, sdev, "%s: not supported\n", ALUA_DH_NAME); err = SCSI_DH_DEV_UNSUPP; break; + default: + sdev_printk(KERN_INFO, sdev, + "%s: unsupported TPGS setting %d\n", + ALUA_DH_NAME, h->tpgs); + h->tpgs = TPGS_MODE_NONE; + err = SCSI_DH_DEV_UNSUPP; + break; } return err; -- cgit v0.10.2 From d3692a3d13e8ee2e371907d67d585d42297b4d66 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:46 +0100 Subject: scsi_dh_alua: sanitze sense code handling The only check for a valid sense code is calling scsi_normalize_sense() and check the return value. So drop the pointless checks and rely on scsi_normalize_sense() to figure out if the sense code is valid. With that we can also remove the 'senselen' field. Signed-off-by: Hannes Reinecke Reviewed-by: Johannes Thumshirn Reviewed-by: Bart van Assche Reviewed-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index 31a971f..0bbde13 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -73,7 +73,6 @@ struct alua_dh_data { int bufflen; unsigned char transition_tmo; unsigned char sense[SCSI_SENSE_BUFFERSIZE]; - int senselen; struct scsi_device *sdev; activate_complete callback_fn; void *callback_data; @@ -158,14 +157,13 @@ static unsigned submit_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, rq->sense = h->sense; memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE); - rq->sense_len = h->senselen = 0; + rq->sense_len = 0; err = blk_execute_rq(rq->q, NULL, rq, 1); if (err == -EIO) { sdev_printk(KERN_INFO, sdev, "%s: rtpg failed with %x\n", ALUA_DH_NAME, rq->errors); - h->senselen = rq->sense_len; err = SCSI_DH_IO; } blk_put_request(rq); @@ -194,9 +192,8 @@ static void stpg_endio(struct request *req, int error) goto done; } - if (req->sense_len > 0) { - err = scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE, - &sense_hdr); + if (scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE, + &sense_hdr)) { if (!err) { err = SCSI_DH_IO; goto done; @@ -265,7 +262,7 @@ static unsigned submit_stpg(struct alua_dh_data *h) rq->sense = h->sense; memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE); - rq->sense_len = h->senselen = 0; + rq->sense_len = 0; rq->end_io_data = h; blk_execute_rq_nowait(rq->q, NULL, rq, 1, stpg_endio); @@ -514,10 +511,9 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_ retry: err = submit_rtpg(sdev, h, rtpg_ext_hdr_req); - if (err == SCSI_DH_IO && h->senselen > 0) { - err = scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE, - &sense_hdr); - if (!err) + if (err == SCSI_DH_IO) { + if (!scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE, + &sense_hdr)) return SCSI_DH_IO; /* -- cgit v0.10.2 From 80bd68d6bf06bc8851db4b93ee6cb067115098c0 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:47 +0100 Subject: scsi_dh_alua: use standard logging functions Use standard logging functions instead of hand-crafted ones. Signed-off-by: Hannes Reinecke Reviewed-by: Ewan Milne Reviewed-by: Bart Van Assche Reviewed-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index 0bbde13..6382499 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -194,19 +195,14 @@ static void stpg_endio(struct request *req, int error) if (scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE, &sense_hdr)) { - if (!err) { - err = SCSI_DH_IO; - goto done; - } err = alua_check_sense(h->sdev, &sense_hdr); if (err == ADD_TO_MLQUEUE) { err = SCSI_DH_RETRY; goto done; } - sdev_printk(KERN_INFO, h->sdev, - "%s: stpg sense code: %02x/%02x/%02x\n", - ALUA_DH_NAME, sense_hdr.sense_key, - sense_hdr.asc, sense_hdr.ascq); + sdev_printk(KERN_INFO, h->sdev, "%s: stpg failed\n", + ALUA_DH_NAME); + scsi_print_sense_hdr(h->sdev, ALUA_DH_NAME, &sense_hdr); err = SCSI_DH_IO; } else if (error) err = SCSI_DH_IO; @@ -532,13 +528,16 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_ } err = alua_check_sense(sdev, &sense_hdr); - if (err == ADD_TO_MLQUEUE && time_before(jiffies, expiry)) + if (err == ADD_TO_MLQUEUE && time_before(jiffies, expiry)) { + sdev_printk(KERN_ERR, sdev, "%s: rtpg retry\n", + ALUA_DH_NAME); + scsi_print_sense_hdr(sdev, ALUA_DH_NAME, &sense_hdr); goto retry; - sdev_printk(KERN_INFO, sdev, - "%s: rtpg sense code %02x/%02x/%02x\n", - ALUA_DH_NAME, sense_hdr.sense_key, - sense_hdr.asc, sense_hdr.ascq); - err = SCSI_DH_IO; + } + sdev_printk(KERN_ERR, sdev, "%s: rtpg failed\n", + ALUA_DH_NAME); + scsi_print_sense_hdr(sdev, ALUA_DH_NAME, &sense_hdr); + return SCSI_DH_IO; } if (err != SCSI_DH_OK) return err; -- cgit v0.10.2 From 5597cafc7aabc6ba1d218a334090988cb37c016a Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:48 +0100 Subject: scsi_dh_alua: return standard SCSI return codes in submit_rtpg Fixup submit_rtpg() to always return a standard SCSI return code. Signed-off-by: Hannes Reinecke Reviewed-by: Ewan Milne Reviewed-by: Johannes Thumshirn Reviewed-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index 6382499..e28abf0 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -138,11 +138,13 @@ static unsigned submit_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, bool rtpg_ext_hdr_req) { struct request *rq; - int err = SCSI_DH_RES_TEMP_UNAVAIL; + int err = 0; rq = get_alua_req(sdev, h->buff, h->bufflen, READ); - if (!rq) + if (!rq) { + err = DRIVER_BUSY << 24; goto done; + } /* Prepare the command. */ rq->cmd[0] = MAINTENANCE_IN; @@ -160,13 +162,9 @@ static unsigned submit_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE); rq->sense_len = 0; - err = blk_execute_rq(rq->q, NULL, rq, 1); - if (err == -EIO) { - sdev_printk(KERN_INFO, sdev, - "%s: rtpg failed with %x\n", - ALUA_DH_NAME, rq->errors); - err = SCSI_DH_IO; - } + blk_execute_rq(rq->q, NULL, rq, 1); + if (rq->errors) + err = rq->errors; blk_put_request(rq); done: return err; @@ -493,7 +491,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_ struct scsi_sense_hdr sense_hdr; int len, k, off, valid_states = 0; unsigned char *ucp; - unsigned err; + unsigned err, retval; bool rtpg_ext_hdr_req = 1; unsigned long expiry, interval = 0; unsigned int tpg_desc_tbl_off; @@ -505,12 +503,17 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_ expiry = round_jiffies_up(jiffies + h->transition_tmo * HZ); retry: - err = submit_rtpg(sdev, h, rtpg_ext_hdr_req); - - if (err == SCSI_DH_IO) { + retval = submit_rtpg(sdev, h, rtpg_ext_hdr_req); + if (retval) { if (!scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE, - &sense_hdr)) + &sense_hdr)) { + sdev_printk(KERN_INFO, sdev, + "%s: rtpg failed, result %d\n", + ALUA_DH_NAME, retval); + if (driver_byte(retval) == DRIVER_BUSY) + return SCSI_DH_DEV_TEMP_BUSY; return SCSI_DH_IO; + } /* * submit_rtpg() has failed on existing arrays @@ -539,8 +542,6 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_ scsi_print_sense_hdr(sdev, ALUA_DH_NAME, &sense_hdr); return SCSI_DH_IO; } - if (err != SCSI_DH_OK) - return err; len = (h->buff[0] << 24) + (h->buff[1] << 16) + (h->buff[2] << 8) + h->buff[3] + 4; -- cgit v0.10.2 From dac173ee7e16cb51fc033a2ec9aae38576684735 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:49 +0100 Subject: scsi_dh_alua: fixup description of stpg_endio() Fixup copy-and-paste error in the description of stpg_endio(). Signed-off-by: Hannes Reinecke Reviewed-by: Christoph Hellwig Reviewed-by: Johannes Thumshirn Reviewed-by: Martin K. Petersen Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index e28abf0..fdf6557 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -171,13 +171,11 @@ done: } /* - * alua_stpg - Evaluate SET TARGET GROUP STATES + * stpg_endio - Evaluate SET TARGET GROUP STATES * @sdev: the device to be evaluated * @state: the new target group state * - * Send a SET TARGET GROUP STATES command to the device. - * We only have to test here if we should resubmit the command; - * any other error is assumed as a failure. + * Evaluate a SET TARGET GROUP STATES command response. */ static void stpg_endio(struct request *req, int error) { -- cgit v0.10.2 From 095077ad37043574ce7a3978e92c89f535a6612c Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:50 +0100 Subject: scsi: remove scsi_show_sense_hdr() Last caller is gone, so remove it. Signed-off-by: Hannes Reinecke Reviewed-by: Bart Van Assche Reviewed-by: Christoph Hellwig Reviewed-by: Martin K. Petersen Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen diff --git a/include/scsi/scsi_dbg.h b/include/scsi/scsi_dbg.h index f8170e9..56710e0 100644 --- a/include/scsi/scsi_dbg.h +++ b/include/scsi/scsi_dbg.h @@ -12,8 +12,6 @@ extern size_t __scsi_format_command(char *, size_t, const unsigned char *, size_t); extern void scsi_show_extd_sense(const struct scsi_device *, const char *, unsigned char, unsigned char); -extern void scsi_show_sense_hdr(const struct scsi_device *, const char *, - const struct scsi_sense_hdr *); extern void scsi_print_sense_hdr(const struct scsi_device *, const char *, const struct scsi_sense_hdr *); extern void scsi_print_sense(const struct scsi_cmnd *); -- cgit v0.10.2 From 6c4fc04491754834d5b5be189ee8f49a1d92b433 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:51 +0100 Subject: scsi_dh_alua: use flag for RTPG extended header We should be using a flag when RTPG extended header is not supported, that saves us sending RTPG twice for older arrays. Signed-off-by: Hannes Reinecke Reviewed-by: Bart Van Assche Reviewed-by: Christoph Hellwig Reviewed-by: Martin K. Petersen Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index fdf6557..d99fc14 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -59,8 +59,9 @@ #define ALUA_FAILOVER_TIMEOUT 60 #define ALUA_FAILOVER_RETRIES 5 -/* flags passed from user level */ +/* device handler flags */ #define ALUA_OPTIMIZE_STPG 1 +#define ALUA_RTPG_EXT_HDR_UNSUPP 2 struct alua_dh_data { int group_id; @@ -134,8 +135,7 @@ static struct request *get_alua_req(struct scsi_device *sdev, * submit_rtpg - Issue a REPORT TARGET GROUP STATES command * @sdev: sdev the command should be sent to */ -static unsigned submit_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, - bool rtpg_ext_hdr_req) +static unsigned submit_rtpg(struct scsi_device *sdev, struct alua_dh_data *h) { struct request *rq; int err = 0; @@ -148,7 +148,7 @@ static unsigned submit_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, /* Prepare the command. */ rq->cmd[0] = MAINTENANCE_IN; - if (rtpg_ext_hdr_req) + if (!(h->flags & ALUA_RTPG_EXT_HDR_UNSUPP)) rq->cmd[1] = MI_REPORT_TARGET_PGS | MI_EXT_HDR_PARAM_FMT; else rq->cmd[1] = MI_REPORT_TARGET_PGS; @@ -490,7 +490,6 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_ int len, k, off, valid_states = 0; unsigned char *ucp; unsigned err, retval; - bool rtpg_ext_hdr_req = 1; unsigned long expiry, interval = 0; unsigned int tpg_desc_tbl_off; unsigned char orig_transition_tmo; @@ -501,7 +500,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_ expiry = round_jiffies_up(jiffies + h->transition_tmo * HZ); retry: - retval = submit_rtpg(sdev, h, rtpg_ext_hdr_req); + retval = submit_rtpg(sdev, h); if (retval) { if (!scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE, &sense_hdr)) { @@ -521,10 +520,10 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_ * The retry without rtpg_ext_hdr_req set * handles this. */ - if (rtpg_ext_hdr_req == 1 && + if (!(h->flags & ALUA_RTPG_EXT_HDR_UNSUPP) && sense_hdr.sense_key == ILLEGAL_REQUEST && sense_hdr.asc == 0x24 && sense_hdr.ascq == 0) { - rtpg_ext_hdr_req = 0; + h->flags |= ALUA_RTPG_EXT_HDR_UNSUPP; goto retry; } -- cgit v0.10.2 From a7089770b95902854f48b3bc7bec026dc8403286 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:52 +0100 Subject: scsi_dh_alua: use unaligned access macros Use 'get_unaligned_XX' and 'put_unaligned_XX' instead of open-coding it. Signed-off-by: Hannes Reinecke Reviewed-by: Martin K. Petersen Reviewed-by: Christoph Hellwig Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index d99fc14..1c8e538 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -152,10 +153,7 @@ static unsigned submit_rtpg(struct scsi_device *sdev, struct alua_dh_data *h) rq->cmd[1] = MI_REPORT_TARGET_PGS | MI_EXT_HDR_PARAM_FMT; else rq->cmd[1] = MI_REPORT_TARGET_PGS; - rq->cmd[6] = (h->bufflen >> 24) & 0xff; - rq->cmd[7] = (h->bufflen >> 16) & 0xff; - rq->cmd[8] = (h->bufflen >> 8) & 0xff; - rq->cmd[9] = h->bufflen & 0xff; + put_unaligned_be32(h->bufflen, &rq->cmd[6]); rq->cmd_len = COMMAND_SIZE(MAINTENANCE_IN); rq->sense = h->sense; @@ -236,8 +234,7 @@ static unsigned submit_stpg(struct alua_dh_data *h) /* Prepare the data buffer */ memset(h->buff, 0, stpg_len); h->buff[4] = TPGS_STATE_OPTIMIZED & 0x0f; - h->buff[6] = (h->group_id >> 8) & 0xff; - h->buff[7] = h->group_id & 0xff; + put_unaligned_be16(h->group_id, &h->buff[6]); rq = get_alua_req(sdev, h->buff, stpg_len, WRITE); if (!rq) @@ -246,10 +243,7 @@ static unsigned submit_stpg(struct alua_dh_data *h) /* Prepare the command. */ rq->cmd[0] = MAINTENANCE_OUT; rq->cmd[1] = MO_SET_TARGET_PGS; - rq->cmd[6] = (stpg_len >> 24) & 0xff; - rq->cmd[7] = (stpg_len >> 16) & 0xff; - rq->cmd[8] = (stpg_len >> 8) & 0xff; - rq->cmd[9] = stpg_len & 0xff; + put_unaligned_be32(stpg_len, &rq->cmd[6]); rq->cmd_len = COMMAND_SIZE(MAINTENANCE_OUT); rq->sense = h->sense; @@ -343,11 +337,11 @@ static int alua_check_vpd(struct scsi_device *sdev, struct alua_dh_data *h) switch (d[1] & 0xf) { case 0x4: /* Relative target port */ - h->rel_port = (d[6] << 8) + d[7]; + h->rel_port = get_unaligned_be16(&d[6]); break; case 0x5: /* Target port group */ - h->group_id = (d[6] << 8) + d[7]; + h->group_id = get_unaligned_be16(&d[6]); break; default: break; @@ -540,8 +534,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_ return SCSI_DH_IO; } - len = (h->buff[0] << 24) + (h->buff[1] << 16) + - (h->buff[2] << 8) + h->buff[3] + 4; + len = get_unaligned_be32(&h->buff[0]) + 4; if (len > h->bufflen) { /* Resubmit with the correct length */ @@ -576,7 +569,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_ k < len; k += off, ucp += off) { - if (h->group_id == (ucp[2] << 8) + ucp[3]) { + if (h->group_id == get_unaligned_be16(&ucp[2])) { h->state = ucp[0] & 0x0f; h->pref = ucp[0] >> 7; valid_states = ucp[1]; -- cgit v0.10.2 From ad0ea64c53f5808e29784812fbb0c300f3a89d39 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:53 +0100 Subject: scsi_dh_alua: rework alua_check_tpgs() to return the tpgs mode Instead of returning an error code in alua_check_tpgs() we should rather return the tpgs mode directly and have a cleaner syntax. Signed-off-by: Hannes Reinecke Reviewed-by: Johannes Thumshirn Reviewed-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index 1c8e538..7a34ffb 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -262,24 +262,23 @@ static unsigned submit_stpg(struct alua_dh_data *h) * Examine the TPGS setting of the sdev to find out if ALUA * is supported. */ -static int alua_check_tpgs(struct scsi_device *sdev, struct alua_dh_data *h) +static int alua_check_tpgs(struct scsi_device *sdev) { - int err = SCSI_DH_OK; + int tpgs = TPGS_MODE_NONE; /* * ALUA support for non-disk devices is fraught with * difficulties, so disable it for now. */ if (sdev->type != TYPE_DISK) { - h->tpgs = TPGS_MODE_NONE; sdev_printk(KERN_INFO, sdev, "%s: disable for non-disk devices\n", ALUA_DH_NAME); - return SCSI_DH_DEV_UNSUPP; + return tpgs; } - h->tpgs = scsi_device_tpgs(sdev); - switch (h->tpgs) { + tpgs = scsi_device_tpgs(sdev); + switch (tpgs) { case TPGS_MODE_EXPLICIT|TPGS_MODE_IMPLICIT: sdev_printk(KERN_INFO, sdev, "%s: supports implicit and explicit TPGS\n", @@ -296,18 +295,16 @@ static int alua_check_tpgs(struct scsi_device *sdev, struct alua_dh_data *h) case TPGS_MODE_NONE: sdev_printk(KERN_INFO, sdev, "%s: not supported\n", ALUA_DH_NAME); - err = SCSI_DH_DEV_UNSUPP; break; default: sdev_printk(KERN_INFO, sdev, "%s: unsupported TPGS setting %d\n", - ALUA_DH_NAME, h->tpgs); - h->tpgs = TPGS_MODE_NONE; - err = SCSI_DH_DEV_UNSUPP; + ALUA_DH_NAME, tpgs); + tpgs = TPGS_MODE_NONE; break; } - return err; + return tpgs; } /* @@ -627,10 +624,10 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_ */ static int alua_initialize(struct scsi_device *sdev, struct alua_dh_data *h) { - int err; + int err = SCSI_DH_DEV_UNSUPP; - err = alua_check_tpgs(sdev, h); - if (err != SCSI_DH_OK) + h->tpgs = alua_check_tpgs(sdev); + if (h->tpgs == TPGS_MODE_NONE) goto out; err = alua_check_vpd(sdev, h); -- cgit v0.10.2 From e2d817db32027c25a1702f667fbf0bf6a73fc68c Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:54 +0100 Subject: scsi_dh_alua: simplify sense code handling Most sense code is already handled in the generic code, so we shouldn't be adding special cases here. However, when doing so we need to check for unit attention whenever we're sending an internal command. Signed-off-by: Hannes Reinecke Reviewed-by: Ewan Milne Reviewed-by: Christoph Hellwig Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index 7a34ffb..39654b1 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -85,7 +85,6 @@ struct alua_dh_data { #define ALUA_POLICY_SWITCH_ALL 1 static char print_alua_state(int); -static int alua_check_sense(struct scsi_device *, struct scsi_sense_hdr *); static int realloc_buffer(struct alua_dh_data *h, unsigned len) { @@ -189,8 +188,13 @@ static void stpg_endio(struct request *req, int error) if (scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE, &sense_hdr)) { - err = alua_check_sense(h->sdev, &sense_hdr); - if (err == ADD_TO_MLQUEUE) { + if (sense_hdr.sense_key == NOT_READY && + sense_hdr.asc == 0x04 && sense_hdr.ascq == 0x0a) { + /* ALUA state transition already in progress */ + err = SCSI_DH_OK; + goto done; + } + if (sense_hdr.sense_key == UNIT_ATTENTION) { err = SCSI_DH_RETRY; goto done; } @@ -399,28 +403,6 @@ static int alua_check_sense(struct scsi_device *sdev, * LUN Not Accessible - ALUA state transition */ return ADD_TO_MLQUEUE; - if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x0b) - /* - * LUN Not Accessible -- Target port in standby state - */ - return SUCCESS; - if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x0c) - /* - * LUN Not Accessible -- Target port in unavailable state - */ - return SUCCESS; - if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x12) - /* - * LUN Not Ready -- Offline - */ - return SUCCESS; - if (sdev->allow_restart && - sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x02) - /* - * if the device is not started, we need to wake - * the error handler to start the motor - */ - return FAILED; break; case UNIT_ATTENTION: if (sense_hdr->asc == 0x29 && sense_hdr->ascq == 0x00) @@ -517,9 +499,16 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_ h->flags |= ALUA_RTPG_EXT_HDR_UNSUPP; goto retry; } - - err = alua_check_sense(sdev, &sense_hdr); - if (err == ADD_TO_MLQUEUE && time_before(jiffies, expiry)) { + /* + * Retry on ALUA state transition or if any + * UNIT ATTENTION occurred. + */ + if (sense_hdr.sense_key == NOT_READY && + sense_hdr.asc == 0x04 && sense_hdr.ascq == 0x0a) + err = SCSI_DH_RETRY; + else if (sense_hdr.sense_key == UNIT_ATTENTION) + err = SCSI_DH_RETRY; + if (err == SCSI_DH_RETRY && time_before(jiffies, expiry)) { sdev_printk(KERN_ERR, sdev, "%s: rtpg retry\n", ALUA_DH_NAME); scsi_print_sense_hdr(sdev, ALUA_DH_NAME, &sense_hdr); -- cgit v0.10.2 From 9983bed3907c379d1d30b7509bb0a871ed655f9d Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:55 +0100 Subject: scsi: Add scsi_vpd_lun_id() Add a function scsi_vpd_lun_id() to return a unique device identifcation based on the designation descriptors of VPD page 0x83. As devices might implement several descriptors the order of preference is: - NAA IEE Registered Extended - EUI-64 based 16-byte - EUI-64 based 12-byte - NAA IEEE Registered - NAA IEEE Extended A SCSI name string descriptor is preferred to all of them if the identification is longer than 16 bytes. The returned unique device identification will be formatted as a SCSI Name string to avoid clashes between different designator types. [mkp: Fixed up kernel doc comment from Johannes] Signed-off-by: Hannes Reinecke Reviewed-by: Ewan Milne Reviewed-by: Johannes Thumshirn Reviewed-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index dd8ad2a..e352c2b 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -3154,3 +3154,143 @@ void sdev_enable_disk_events(struct scsi_device *sdev) atomic_dec(&sdev->disk_events_disable_depth); } EXPORT_SYMBOL(sdev_enable_disk_events); + +/** + * scsi_vpd_lun_id - return a unique device identification + * @sdev: SCSI device + * @id: buffer for the identification + * @id_len: length of the buffer + * + * Copies a unique device identification into @id based + * on the information in the VPD page 0x83 of the device. + * The string will be formatted as a SCSI name string. + * + * Returns the length of the identification or error on failure. + * If the identifier is longer than the supplied buffer the actual + * identifier length is returned and the buffer is not zero-padded. + */ +int scsi_vpd_lun_id(struct scsi_device *sdev, char *id, size_t id_len) +{ + u8 cur_id_type = 0xff; + u8 cur_id_size = 0; + unsigned char *d, *cur_id_str; + unsigned char __rcu *vpd_pg83; + int id_size = -EINVAL; + + rcu_read_lock(); + vpd_pg83 = rcu_dereference(sdev->vpd_pg83); + if (!vpd_pg83) { + rcu_read_unlock(); + return -ENXIO; + } + + /* + * Look for the correct descriptor. + * Order of preference for lun descriptor: + * - SCSI name string + * - NAA IEEE Registered Extended + * - EUI-64 based 16-byte + * - EUI-64 based 12-byte + * - NAA IEEE Registered + * - NAA IEEE Extended + * as longer descriptors reduce the likelyhood + * of identification clashes. + */ + + /* The id string must be at least 20 bytes + terminating NULL byte */ + if (id_len < 21) { + rcu_read_unlock(); + return -EINVAL; + } + + memset(id, 0, id_len); + d = vpd_pg83 + 4; + while (d < vpd_pg83 + sdev->vpd_pg83_len) { + /* Skip designators not referring to the LUN */ + if ((d[1] & 0x30) != 0x00) + goto next_desig; + + switch (d[1] & 0xf) { + case 0x2: + /* EUI-64 */ + if (cur_id_size > d[3]) + break; + /* Prefer NAA IEEE Registered Extended */ + if (cur_id_type == 0x3 && + cur_id_size == d[3]) + break; + cur_id_size = d[3]; + cur_id_str = d + 4; + cur_id_type = d[1] & 0xf; + switch (cur_id_size) { + case 8: + id_size = snprintf(id, id_len, + "eui.%8phN", + cur_id_str); + break; + case 12: + id_size = snprintf(id, id_len, + "eui.%12phN", + cur_id_str); + break; + case 16: + id_size = snprintf(id, id_len, + "eui.%16phN", + cur_id_str); + break; + default: + cur_id_size = 0; + break; + } + break; + case 0x3: + /* NAA */ + if (cur_id_size > d[3]) + break; + cur_id_size = d[3]; + cur_id_str = d + 4; + cur_id_type = d[1] & 0xf; + switch (cur_id_size) { + case 8: + id_size = snprintf(id, id_len, + "naa.%8phN", + cur_id_str); + break; + case 16: + id_size = snprintf(id, id_len, + "naa.%16phN", + cur_id_str); + break; + default: + cur_id_size = 0; + break; + } + break; + case 0x8: + /* SCSI name string */ + if (cur_id_size + 4 > d[3]) + break; + /* Prefer others for truncated descriptor */ + if (cur_id_size && d[3] > id_len) + break; + cur_id_size = id_size = d[3]; + cur_id_str = d + 4; + cur_id_type = d[1] & 0xf; + if (cur_id_size >= id_len) + cur_id_size = id_len - 1; + memcpy(id, cur_id_str, cur_id_size); + /* Decrease priority for truncated descriptor */ + if (cur_id_size != id_size) + cur_id_size = 6; + break; + default: + break; + } +next_desig: + d += d[3] + 4; + } + rcu_read_unlock(); + + return id_size; +} +EXPORT_SYMBOL(scsi_vpd_lun_id); diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index bde4077..4c49cfa 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -415,6 +415,7 @@ static inline int scsi_execute_req(struct scsi_device *sdev, } extern void sdev_disable_disk_events(struct scsi_device *sdev); extern void sdev_enable_disk_events(struct scsi_device *sdev); +extern int scsi_vpd_lun_id(struct scsi_device *, char *, size_t); #ifdef CONFIG_PM extern int scsi_autopm_get_device(struct scsi_device *); -- cgit v0.10.2 From 248d4fe95f232010846bc648ce92e40b07544c5d Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:56 +0100 Subject: scsi: export 'wwid' to sysfs Use scsi_vpd_lun_id() to export the world-wide unique id (wwid) to sysfs. Note that this is the 'best' wwid according to the rules in scsi_vpd_lun_id(), not every possible wwid presented by the drive. Signed-off-by: Hannes Reinecke Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index d015374..ef36053 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -905,6 +905,22 @@ sdev_show_function(queue_depth, "%d\n"); static DEVICE_ATTR(queue_depth, S_IRUGO | S_IWUSR, sdev_show_queue_depth, sdev_store_queue_depth); +static ssize_t +sdev_show_wwid(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct scsi_device *sdev = to_scsi_device(dev); + ssize_t count; + + count = scsi_vpd_lun_id(sdev, buf, PAGE_SIZE); + if (count > 0) { + buf[count] = '\n'; + count++; + } + return count; +} +static DEVICE_ATTR(wwid, S_IRUGO, sdev_show_wwid, NULL); + #ifdef CONFIG_SCSI_DH static ssize_t sdev_show_dh_state(struct device *dev, struct device_attribute *attr, @@ -1028,6 +1044,7 @@ static struct attribute *scsi_sdev_attrs[] = { &dev_attr_modalias.attr, &dev_attr_queue_depth.attr, &dev_attr_queue_type.attr, + &dev_attr_wwid.attr, #ifdef CONFIG_SCSI_DH &dev_attr_dh_state.attr, #endif -- cgit v0.10.2 From a8aa3978588a4fa2d9edabc151adedd97bbed091 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:57 +0100 Subject: scsi: Add scsi_vpd_tpg_id() Implement scsi_vpd_tpg_id() to extract the target port group id and the relative port id from SCSI VPD page 0x83. Reviewed-by: Johannes Thumshirn Reviewed-by: Christoph Hellwig Signed-off-by: Hannes Reinecke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index e352c2b..fa6b2c4 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -3294,3 +3295,50 @@ next_desig: return id_size; } EXPORT_SYMBOL(scsi_vpd_lun_id); + +/* + * scsi_vpd_tpg_id - return a target port group identifier + * @sdev: SCSI device + * + * Returns the Target Port Group identifier from the information + * froom VPD page 0x83 of the device. + * + * Returns the identifier or error on failure. + */ +int scsi_vpd_tpg_id(struct scsi_device *sdev, int *rel_id) +{ + unsigned char *d; + unsigned char __rcu *vpd_pg83; + int group_id = -EAGAIN, rel_port = -1; + + rcu_read_lock(); + vpd_pg83 = rcu_dereference(sdev->vpd_pg83); + if (!vpd_pg83) { + rcu_read_unlock(); + return -ENXIO; + } + + d = sdev->vpd_pg83 + 4; + while (d < sdev->vpd_pg83 + sdev->vpd_pg83_len) { + switch (d[1] & 0xf) { + case 0x4: + /* Relative target port */ + rel_port = get_unaligned_be16(&d[6]); + break; + case 0x5: + /* Target port group */ + group_id = get_unaligned_be16(&d[6]); + break; + default: + break; + } + d += d[3] + 4; + } + rcu_read_unlock(); + + if (group_id >= 0 && rel_id && rel_port != -1) + *rel_id = rel_port; + + return group_id; +} +EXPORT_SYMBOL(scsi_vpd_tpg_id); diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 4c49cfa..f63a167 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -416,6 +416,7 @@ static inline int scsi_execute_req(struct scsi_device *sdev, extern void sdev_disable_disk_events(struct scsi_device *sdev); extern void sdev_enable_disk_events(struct scsi_device *sdev); extern int scsi_vpd_lun_id(struct scsi_device *, char *, size_t); +extern int scsi_vpd_tpg_id(struct scsi_device *, int *); #ifdef CONFIG_PM extern int scsi_autopm_get_device(struct scsi_device *); -- cgit v0.10.2 From 83ea0e5e3501decac0afdff25bba2ca1e78f79cc Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:58 +0100 Subject: scsi_dh_alua: use scsi_vpd_tpg_id() Use the common function 'scsi_vpd_tpg_id()' instead of open-coding it in scsi_dh_alua. [mkp: Applied by hand] Signed-off-by: Hannes Reinecke Reviewed-by: Johannes Thumshirn Reviewed-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index 39654b1..f100cbb 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -322,36 +322,10 @@ static int alua_check_vpd(struct scsi_device *sdev, struct alua_dh_data *h) { unsigned char *d; unsigned char __rcu *vpd_pg83; + int rel_port = -1, group_id; - rcu_read_lock(); - if (!rcu_dereference(sdev->vpd_pg83)) { - rcu_read_unlock(); - return SCSI_DH_DEV_UNSUPP; - } - - /* - * Look for the correct descriptor. - */ - vpd_pg83 = rcu_dereference(sdev->vpd_pg83); - d = vpd_pg83 + 4; - while (d < vpd_pg83 + sdev->vpd_pg83_len) { - switch (d[1] & 0xf) { - case 0x4: - /* Relative target port */ - h->rel_port = get_unaligned_be16(&d[6]); - break; - case 0x5: - /* Target port group */ - h->group_id = get_unaligned_be16(&d[6]); - break; - default: - break; - } - d += d[3] + 4; - } - rcu_read_unlock(); - - if (h->group_id == -1) { + group_id = scsi_vpd_tpg_id(sdev, &rel_port); + if (group_id < 0) { /* * Internal error; TPGS supported but required * VPD identification descriptors not present. @@ -360,10 +334,11 @@ static int alua_check_vpd(struct scsi_device *sdev, struct alua_dh_data *h) sdev_printk(KERN_INFO, sdev, "%s: No target port descriptors found\n", ALUA_DH_NAME); - h->state = TPGS_STATE_OPTIMIZED; - h->tpgs = TPGS_MODE_NONE; return SCSI_DH_DEV_UNSUPP; } + h->state = TPGS_STATE_OPTIMIZED; + h->group_id = group_id; + sdev_printk(KERN_INFO, sdev, "%s: port group %02x rel port %02x\n", ALUA_DH_NAME, h->group_id, h->rel_port); -- cgit v0.10.2 From 889d0d42667c998a099028f845c0be074acb4b90 Mon Sep 17 00:00:00 2001 From: Anil Gurumurthy Date: Thu, 26 Nov 2015 03:54:45 -0500 Subject: bfa: Update copyright messages Signed-off-by: Sudarsana Kalluru Signed-off-by: Anil Gurumurthy Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/bfa/bfa.h b/drivers/scsi/bfa/bfa.h index 4ad7e36..7d0337b 100644 --- a/drivers/scsi/bfa/bfa.h +++ b/drivers/scsi/bfa/bfa.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c index e3f67b0..f157a37 100644 --- a/drivers/scsi/bfa/bfa_core.c +++ b/drivers/scsi/bfa/bfa_core.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_cs.h b/drivers/scsi/bfa/bfa_cs.h index 91a8aa3..c8bb20a 100644 --- a/drivers/scsi/bfa/bfa_cs.h +++ b/drivers/scsi/bfa/bfa_cs.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_defs.h b/drivers/scsi/bfa/bfa_defs.h index 877b86d..da4f705 100644 --- a/drivers/scsi/bfa/bfa_defs.h +++ b/drivers/scsi/bfa/bfa_defs.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_defs_fcs.h b/drivers/scsi/bfa/bfa_defs_fcs.h index 06f0a16..5185ae3 100644 --- a/drivers/scsi/bfa/bfa_defs_fcs.h +++ b/drivers/scsi/bfa/bfa_defs_fcs.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_defs_svc.h b/drivers/scsi/bfa/bfa_defs_svc.h index 638f441f..fd2fa24 100644 --- a/drivers/scsi/bfa/bfa_defs_svc.h +++ b/drivers/scsi/bfa/bfa_defs_svc.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_fc.h b/drivers/scsi/bfa/bfa_fc.h index 64069a0..7142309 100644 --- a/drivers/scsi/bfa/bfa_fc.h +++ b/drivers/scsi/bfa/bfa_fc.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_fcbuild.c b/drivers/scsi/bfa/bfa_fcbuild.c index dce787f..6f670d3 100644 --- a/drivers/scsi/bfa/bfa_fcbuild.c +++ b/drivers/scsi/bfa/bfa_fcbuild.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_fcbuild.h b/drivers/scsi/bfa/bfa_fcbuild.h index 03c753d..85e3c58 100644 --- a/drivers/scsi/bfa/bfa_fcbuild.h +++ b/drivers/scsi/bfa/bfa_fcbuild.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_fcpim.c b/drivers/scsi/bfa/bfa_fcpim.c index d7385d1..3881a72 100644 --- a/drivers/scsi/bfa/bfa_fcpim.c +++ b/drivers/scsi/bfa/bfa_fcpim.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_fcpim.h b/drivers/scsi/bfa/bfa_fcpim.h index e693af6..0c37062 100644 --- a/drivers/scsi/bfa/bfa_fcpim.h +++ b/drivers/scsi/bfa/bfa_fcpim.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_fcs.c b/drivers/scsi/bfa/bfa_fcs.c index 0f19455..043d3c0 100644 --- a/drivers/scsi/bfa/bfa_fcs.c +++ b/drivers/scsi/bfa/bfa_fcs.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_fcs.h b/drivers/scsi/bfa/bfa_fcs.h index 42bcb97..30b4555 100644 --- a/drivers/scsi/bfa/bfa_fcs.h +++ b/drivers/scsi/bfa/bfa_fcs.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_fcs_fcpim.c b/drivers/scsi/bfa/bfa_fcs_fcpim.c index 6dc7926..4fd20d9 100644 --- a/drivers/scsi/bfa/bfa_fcs_fcpim.c +++ b/drivers/scsi/bfa/bfa_fcs_fcpim.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c index ff75ef8..d823792 100644 --- a/drivers/scsi/bfa/bfa_fcs_lport.c +++ b/drivers/scsi/bfa/bfa_fcs_lport.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_fcs_rport.c b/drivers/scsi/bfa/bfa_fcs_rport.c index 2035b0d..5559faa 100644 --- a/drivers/scsi/bfa/bfa_fcs_rport.c +++ b/drivers/scsi/bfa/bfa_fcs_rport.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_hw_cb.c b/drivers/scsi/bfa/bfa_hw_cb.c index ea24d4c..e3648d9 100644 --- a/drivers/scsi/bfa/bfa_hw_cb.c +++ b/drivers/scsi/bfa/bfa_hw_cb.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_hw_ct.c b/drivers/scsi/bfa/bfa_hw_ct.c index 637527f..f19bc44 100644 --- a/drivers/scsi/bfa/bfa_hw_ct.c +++ b/drivers/scsi/bfa/bfa_hw_ct.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c index 98f7e8c..e9a7c64 100644 --- a/drivers/scsi/bfa/bfa_ioc.c +++ b/drivers/scsi/bfa/bfa_ioc.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_ioc.h b/drivers/scsi/bfa/bfa_ioc.h index a38aafa0..0d6e165 100644 --- a/drivers/scsi/bfa/bfa_ioc.h +++ b/drivers/scsi/bfa/bfa_ioc.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_ioc_cb.c b/drivers/scsi/bfa/bfa_ioc_cb.c index 453c2f5..10a0042 100644 --- a/drivers/scsi/bfa/bfa_ioc_cb.c +++ b/drivers/scsi/bfa/bfa_ioc_cb.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_ioc_ct.c b/drivers/scsi/bfa/bfa_ioc_ct.c index bd53150..1e5fa61 100644 --- a/drivers/scsi/bfa/bfa_ioc_ct.c +++ b/drivers/scsi/bfa/bfa_ioc_ct.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_modules.h b/drivers/scsi/bfa/bfa_modules.h index a14c784..5b02415 100644 --- a/drivers/scsi/bfa/bfa_modules.h +++ b/drivers/scsi/bfa/bfa_modules.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_plog.h b/drivers/scsi/bfa/bfa_plog.h index 1c9baa6..4fdba6f 100644 --- a/drivers/scsi/bfa/bfa_plog.h +++ b/drivers/scsi/bfa/bfa_plog.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_port.c b/drivers/scsi/bfa/bfa_port.c index 8ea7697..314548a 100644 --- a/drivers/scsi/bfa/bfa_port.c +++ b/drivers/scsi/bfa/bfa_port.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_port.h b/drivers/scsi/bfa/bfa_port.h index 2fcab6b..ba715ce 100644 --- a/drivers/scsi/bfa/bfa_port.h +++ b/drivers/scsi/bfa/bfa_port.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_svc.c b/drivers/scsi/bfa/bfa_svc.c index 625225f..93e588f 100644 --- a/drivers/scsi/bfa/bfa_svc.c +++ b/drivers/scsi/bfa/bfa_svc.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfa_svc.h b/drivers/scsi/bfa/bfa_svc.h index ef07365..efb0497 100644 --- a/drivers/scsi/bfa/bfa_svc.h +++ b/drivers/scsi/bfa/bfa_svc.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c index cc3b9d3..f298b2e 100644 --- a/drivers/scsi/bfa/bfad.c +++ b/drivers/scsi/bfa/bfad.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c index 40be670..66cca48 100644 --- a/drivers/scsi/bfa/bfad_attr.c +++ b/drivers/scsi/bfa/bfad_attr.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c index 023b9d4..b9d1460 100644 --- a/drivers/scsi/bfa/bfad_bsg.c +++ b/drivers/scsi/bfa/bfad_bsg.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfad_bsg.h b/drivers/scsi/bfa/bfad_bsg.h index 90abef6..59aca80 100644 --- a/drivers/scsi/bfa/bfad_bsg.h +++ b/drivers/scsi/bfa/bfad_bsg.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfad_debugfs.c b/drivers/scsi/bfa/bfad_debugfs.c index 74a307c..62b11d4 100644 --- a/drivers/scsi/bfa/bfad_debugfs.c +++ b/drivers/scsi/bfa/bfad_debugfs.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfad_drv.h b/drivers/scsi/bfa/bfad_drv.h index 8b97877..58fee34 100644 --- a/drivers/scsi/bfa/bfad_drv.h +++ b/drivers/scsi/bfa/bfad_drv.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c index 299c6f8..efcb247 100644 --- a/drivers/scsi/bfa/bfad_im.c +++ b/drivers/scsi/bfa/bfad_im.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfad_im.h b/drivers/scsi/bfa/bfad_im.h index f6c1023..31434df 100644 --- a/drivers/scsi/bfa/bfad_im.h +++ b/drivers/scsi/bfa/bfad_im.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfi.h b/drivers/scsi/bfa/bfi.h index 9ef91f9..54c93ef 100644 --- a/drivers/scsi/bfa/bfi.h +++ b/drivers/scsi/bfa/bfi.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfi_ms.h b/drivers/scsi/bfa/bfi_ms.h index 1a3fe5a..8699be4 100644 --- a/drivers/scsi/bfa/bfi_ms.h +++ b/drivers/scsi/bfa/bfi_ms.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * diff --git a/drivers/scsi/bfa/bfi_reg.h b/drivers/scsi/bfa/bfi_reg.h index 99133bc..7d071a4 100644 --- a/drivers/scsi/bfa/bfi_reg.h +++ b/drivers/scsi/bfa/bfi_reg.h @@ -1,7 +1,8 @@ /* - * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. + * Copyright (c) 2014- QLogic Corporation. * All rights reserved - * www.brocade.com + * www.qlogic.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * -- cgit v0.10.2 From 3c3da12d3174891f61f0f2c672da095562f19b92 Mon Sep 17 00:00:00 2001 From: Anil Gurumurthy Date: Thu, 26 Nov 2015 03:54:00 -0500 Subject: bfa: Fix for crash when bfa_itnim is NULL Fix a very corner case when the port gets disconnected and the BFA and FCS layers clean up references to the IT nexus. During this window if a task management command is issued by the SCSI-ML and ends up referencing a NULL itnim, it could lead to a crash. Signed-off-by: Sudarsana Kalluru Signed-off-by: Anil Gurumurthy Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c index efcb247..2c0cf8a 100644 --- a/drivers/scsi/bfa/bfad_im.c +++ b/drivers/scsi/bfa/bfad_im.c @@ -272,6 +272,19 @@ bfad_im_target_reset_send(struct bfad_s *bfad, struct scsi_cmnd *cmnd, cmnd->host_scribble = NULL; cmnd->SCp.Status = 0; bfa_itnim = bfa_fcs_itnim_get_halitn(&itnim->fcs_itnim); + /* + * bfa_itnim can be NULL if the port gets disconnected and the bfa + * and fcs layers have cleaned up their nexus with the targets and + * the same has not been cleaned up by the shim + */ + if (bfa_itnim == NULL) { + bfa_tskim_free(tskim); + BFA_LOG(KERN_ERR, bfad, bfa_log_level, + "target reset, bfa_itnim is NULL\n"); + rc = BFA_STATUS_FAILED; + goto out; + } + memset(&scsilun, 0, sizeof(scsilun)); bfa_tskim_start(tskim, bfa_itnim, scsilun, FCP_TM_TARGET_RESET, BFAD_TARGET_RESET_TMO); @@ -327,6 +340,19 @@ bfad_im_reset_lun_handler(struct scsi_cmnd *cmnd) cmnd->SCp.ptr = (char *)&wq; cmnd->SCp.Status = 0; bfa_itnim = bfa_fcs_itnim_get_halitn(&itnim->fcs_itnim); + /* + * bfa_itnim can be NULL if the port gets disconnected and the bfa + * and fcs layers have cleaned up their nexus with the targets and + * the same has not been cleaned up by the shim + */ + if (bfa_itnim == NULL) { + bfa_tskim_free(tskim); + BFA_LOG(KERN_ERR, bfad, bfa_log_level, + "lun reset, bfa_itnim is NULL\n"); + spin_unlock_irqrestore(&bfad->bfad_lock, flags); + rc = FAILED; + goto out; + } int_to_scsilun(cmnd->device->lun, &scsilun); bfa_tskim_start(tskim, bfa_itnim, scsilun, FCP_TM_LUN_RESET, BFAD_LUN_RESET_TMO); -- cgit v0.10.2 From 31e1d5695724829759c4b5d63cd643c9f01769cc Mon Sep 17 00:00:00 2001 From: Anil Gurumurthy Date: Thu, 26 Nov 2015 03:54:46 -0500 Subject: bfa: File header and user visible string changes Signed-off-by: Sudarsana Kalluru Signed-off-by: Anil Gurumurthy Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/bfa/bfa.h b/drivers/scsi/bfa/bfa.h index 7d0337b..0e119d8 100644 --- a/drivers/scsi/bfa/bfa.h +++ b/drivers/scsi/bfa/bfa.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c index f157a37..2ea0db4 100644 --- a/drivers/scsi/bfa/bfa_core.c +++ b/drivers/scsi/bfa/bfa_core.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_cs.h b/drivers/scsi/bfa/bfa_cs.h index c8bb20a..da9cf65 100644 --- a/drivers/scsi/bfa/bfa_cs.h +++ b/drivers/scsi/bfa/bfa_cs.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_defs.h b/drivers/scsi/bfa/bfa_defs.h index da4f705..5dc3782 100644 --- a/drivers/scsi/bfa/bfa_defs.h +++ b/drivers/scsi/bfa/bfa_defs.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_defs_fcs.h b/drivers/scsi/bfa/bfa_defs_fcs.h index 5185ae3..5815a90 100644 --- a/drivers/scsi/bfa/bfa_defs_fcs.h +++ b/drivers/scsi/bfa/bfa_defs_fcs.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_defs_svc.h b/drivers/scsi/bfa/bfa_defs_svc.h index fd2fa24..e81707f 100644 --- a/drivers/scsi/bfa/bfa_defs_svc.h +++ b/drivers/scsi/bfa/bfa_defs_svc.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_fc.h b/drivers/scsi/bfa/bfa_fc.h index 7142309..18b7304 100644 --- a/drivers/scsi/bfa/bfa_fc.h +++ b/drivers/scsi/bfa/bfa_fc.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_fcbuild.c b/drivers/scsi/bfa/bfa_fcbuild.c index 6f670d3..b8dadc9 100644 --- a/drivers/scsi/bfa/bfa_fcbuild.c +++ b/drivers/scsi/bfa/bfa_fcbuild.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_fcbuild.h b/drivers/scsi/bfa/bfa_fcbuild.h index 85e3c58..b109a88 100644 --- a/drivers/scsi/bfa/bfa_fcbuild.h +++ b/drivers/scsi/bfa/bfa_fcbuild.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_fcpim.c b/drivers/scsi/bfa/bfa_fcpim.c index 3881a72..20982e7 100644 --- a/drivers/scsi/bfa/bfa_fcpim.c +++ b/drivers/scsi/bfa/bfa_fcpim.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_fcpim.h b/drivers/scsi/bfa/bfa_fcpim.h index 0c37062..e93921d 100644 --- a/drivers/scsi/bfa/bfa_fcpim.h +++ b/drivers/scsi/bfa/bfa_fcpim.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_fcs.c b/drivers/scsi/bfa/bfa_fcs.c index 043d3c0..1e7e139 100644 --- a/drivers/scsi/bfa/bfa_fcs.c +++ b/drivers/scsi/bfa/bfa_fcs.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_fcs.h b/drivers/scsi/bfa/bfa_fcs.h index 30b4555..06dc215 100644 --- a/drivers/scsi/bfa/bfa_fcs.h +++ b/drivers/scsi/bfa/bfa_fcs.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as @@ -634,7 +634,7 @@ void bfa_fcs_fcpim_uf_recv(struct bfa_fcs_itnim_s *itnim, /* * HBA Attribute Block : BFA internal representation. Note : Some variable - * sizes have been trimmed to suit BFA For Ex : Model will be "Brocade". Based + * sizes have been trimmed to suit BFA For Ex : Model will be "QLogic ". Based * on this the size has been reduced to 16 bytes from the standard's 64 bytes. */ struct bfa_fcs_fdmi_hba_attr_s { diff --git a/drivers/scsi/bfa/bfa_fcs_fcpim.c b/drivers/scsi/bfa/bfa_fcs_fcpim.c index 4fd20d9..4f089d7 100644 --- a/drivers/scsi/bfa/bfa_fcs_fcpim.c +++ b/drivers/scsi/bfa/bfa_fcs_fcpim.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c index d823792..7733ad5 100644 --- a/drivers/scsi/bfa/bfa_fcs_lport.c +++ b/drivers/scsi/bfa/bfa_fcs_lport.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as @@ -2654,7 +2654,7 @@ bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi, strncpy(hba_attr->node_sym_name.symname, port->port_cfg.node_sym_name.symname, BFA_SYMNAME_MAXLEN); - strcpy(hba_attr->vendor_info, "BROCADE"); + strcpy(hba_attr->vendor_info, "QLogic"); hba_attr->num_ports = cpu_to_be32(bfa_ioc_get_nports(&port->fcs->bfa->ioc)); hba_attr->fabric_name = port->fabric->lps->pr_nwwn; diff --git a/drivers/scsi/bfa/bfa_fcs_rport.c b/drivers/scsi/bfa/bfa_fcs_rport.c index 5559faa..de50349 100644 --- a/drivers/scsi/bfa/bfa_fcs_rport.c +++ b/drivers/scsi/bfa/bfa_fcs_rport.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_hw_cb.c b/drivers/scsi/bfa/bfa_hw_cb.c index e3648d9..c4a0c0e 100644 --- a/drivers/scsi/bfa/bfa_hw_cb.c +++ b/drivers/scsi/bfa/bfa_hw_cb.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_hw_ct.c b/drivers/scsi/bfa/bfa_hw_ct.c index f19bc44..b0ff378 100644 --- a/drivers/scsi/bfa/bfa_hw_ct.c +++ b/drivers/scsi/bfa/bfa_hw_ct.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c index e9a7c64..251e2ff 100644 --- a/drivers/scsi/bfa/bfa_ioc.c +++ b/drivers/scsi/bfa/bfa_ioc.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as @@ -2698,7 +2698,7 @@ bfa_ioc_reset_fwstate(struct bfa_ioc_s *ioc) bfa_ioc_set_alt_ioc_fwstate(ioc, BFI_IOC_UNINIT); } -#define BFA_MFG_NAME "Brocade" +#define BFA_MFG_NAME "QLogic" void bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc, struct bfa_adapter_attr_s *ad_attr) diff --git a/drivers/scsi/bfa/bfa_ioc.h b/drivers/scsi/bfa/bfa_ioc.h index 0d6e165..713745d 100644 --- a/drivers/scsi/bfa/bfa_ioc.h +++ b/drivers/scsi/bfa/bfa_ioc.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_ioc_cb.c b/drivers/scsi/bfa/bfa_ioc_cb.c index 10a0042..f1b80da 100644 --- a/drivers/scsi/bfa/bfa_ioc_cb.c +++ b/drivers/scsi/bfa/bfa_ioc_cb.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_ioc_ct.c b/drivers/scsi/bfa/bfa_ioc_ct.c index 1e5fa61..651a8fb 100644 --- a/drivers/scsi/bfa/bfa_ioc_ct.c +++ b/drivers/scsi/bfa/bfa_ioc_ct.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_modules.h b/drivers/scsi/bfa/bfa_modules.h index 5b02415..53135f2 100644 --- a/drivers/scsi/bfa/bfa_modules.h +++ b/drivers/scsi/bfa/bfa_modules.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_plog.h b/drivers/scsi/bfa/bfa_plog.h index 4fdba6f..da570c0 100644 --- a/drivers/scsi/bfa/bfa_plog.h +++ b/drivers/scsi/bfa/bfa_plog.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_port.c b/drivers/scsi/bfa/bfa_port.c index 314548a..da1721e 100644 --- a/drivers/scsi/bfa/bfa_port.c +++ b/drivers/scsi/bfa/bfa_port.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_port.h b/drivers/scsi/bfa/bfa_port.h index ba715ce..26dc1bf 100644 --- a/drivers/scsi/bfa/bfa_port.h +++ b/drivers/scsi/bfa/bfa_port.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_svc.c b/drivers/scsi/bfa/bfa_svc.c index 93e588f..12de292 100644 --- a/drivers/scsi/bfa/bfa_svc.c +++ b/drivers/scsi/bfa/bfa_svc.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfa_svc.h b/drivers/scsi/bfa/bfa_svc.h index efb0497..ea2278b 100644 --- a/drivers/scsi/bfa/bfa_svc.h +++ b/drivers/scsi/bfa/bfa_svc.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c index f298b2e..9d253cb 100644 --- a/drivers/scsi/bfa/bfad.c +++ b/drivers/scsi/bfa/bfad.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as @@ -131,13 +131,9 @@ MODULE_PARM_DESC(bfa_linkup_delay, "Link up delay, default=30 secs for " "boot port. Otherwise 10 secs in RHEL4 & 0 for " "[RHEL5, SLES10, ESX40] Range[>0]"); module_param(msix_disable_cb, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(msix_disable_cb, "Disable Message Signaled Interrupts " - "for Brocade-415/425/815/825 cards, default=0, " - " Range[false:0|true:1]"); +MODULE_PARM_DESC(msix_disable_cb, "Disable Message Signaled Interrupts for QLogic-415/425/815/825 cards, default=0 Range[false:0|true:1]"); module_param(msix_disable_ct, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(msix_disable_ct, "Disable Message Signaled Interrupts " - "if possible for Brocade-1010/1020/804/1007/902/1741 " - "cards, default=0, Range[false:0|true:1]"); +MODULE_PARM_DESC(msix_disable_ct, "Disable Message Signaled Interrupts if possible for QLogic-1010/1020/804/1007/902/1741 cards, default=0, Range[false:0|true:1]"); module_param(fdmi_enable, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(fdmi_enable, "Enables fdmi registration, default=1, " "Range[false:0|true:1]"); @@ -839,8 +835,7 @@ bfad_drv_init(struct bfad_s *bfad) printk(KERN_WARNING "bfad%d bfad_hal_mem_alloc failure\n", bfad->inst_no); printk(KERN_WARNING - "Not enough memory to attach all Brocade HBA ports, %s", - "System may need more memory.\n"); + "Not enough memory to attach all QLogic BR-series HBA ports. System may need more memory.\n"); return BFA_STATUS_FAILED; } @@ -1711,7 +1706,7 @@ bfad_init(void) { int error = 0; - printk(KERN_INFO "Brocade BFA FC/FCOE SCSI driver - version: %s\n", + pr_info("QLogic BR-series BFA FC/FCOE SCSI driver - version: %s\n", BFAD_DRIVER_VERSION); if (num_sgpgs > 0) @@ -1818,6 +1813,6 @@ bfad_free_fwimg(void) module_init(bfad_init); module_exit(bfad_exit); MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Brocade Fibre Channel HBA Driver" BFAD_PROTO_NAME); -MODULE_AUTHOR("Brocade Communications Systems, Inc."); +MODULE_DESCRIPTION("QLogic BR-series Fibre Channel HBA Driver" BFAD_PROTO_NAME); +MODULE_AUTHOR("QLogic Corporation"); MODULE_VERSION(BFAD_DRIVER_VERSION); diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c index 66cca48..13db3b7 100644 --- a/drivers/scsi/bfa/bfad_attr.c +++ b/drivers/scsi/bfa/bfad_attr.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as @@ -751,65 +751,65 @@ bfad_im_model_desc_show(struct device *dev, struct device_attribute *attr, bfa_get_adapter_model(&bfad->bfa, model); nports = bfa_get_nports(&bfad->bfa); - if (!strcmp(model, "Brocade-425")) + if (!strcmp(model, "QLogic-425")) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 4Gbps PCIe dual port FC HBA"); - else if (!strcmp(model, "Brocade-825")) + "QLogic BR-series 4Gbps PCIe dual port FC HBA"); + else if (!strcmp(model, "QLogic-825")) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 8Gbps PCIe dual port FC HBA"); - else if (!strcmp(model, "Brocade-42B")) + "QLogic BR-series 8Gbps PCIe dual port FC HBA"); + else if (!strcmp(model, "QLogic-42B")) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 4Gbps PCIe dual port FC HBA for HP"); - else if (!strcmp(model, "Brocade-82B")) + "QLogic BR-series 4Gbps PCIe dual port FC HBA for HP"); + else if (!strcmp(model, "QLogic-82B")) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 8Gbps PCIe dual port FC HBA for HP"); - else if (!strcmp(model, "Brocade-1010")) + "QLogic BR-series 8Gbps PCIe dual port FC HBA for HP"); + else if (!strcmp(model, "QLogic-1010")) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 10Gbps single port CNA"); - else if (!strcmp(model, "Brocade-1020")) + "QLogic BR-series 10Gbps single port CNA"); + else if (!strcmp(model, "QLogic-1020")) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 10Gbps dual port CNA"); - else if (!strcmp(model, "Brocade-1007")) + "QLogic BR-series 10Gbps dual port CNA"); + else if (!strcmp(model, "QLogic-1007")) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 10Gbps CNA for IBM Blade Center"); - else if (!strcmp(model, "Brocade-415")) + "QLogic BR-series 10Gbps CNA for IBM Blade Center"); + else if (!strcmp(model, "QLogic-415")) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 4Gbps PCIe single port FC HBA"); - else if (!strcmp(model, "Brocade-815")) + "QLogic BR-series 4Gbps PCIe single port FC HBA"); + else if (!strcmp(model, "QLogic-815")) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 8Gbps PCIe single port FC HBA"); - else if (!strcmp(model, "Brocade-41B")) + "QLogic BR-series 8Gbps PCIe single port FC HBA"); + else if (!strcmp(model, "QLogic-41B")) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 4Gbps PCIe single port FC HBA for HP"); - else if (!strcmp(model, "Brocade-81B")) + "QLogic BR-series 4Gbps PCIe single port FC HBA for HP"); + else if (!strcmp(model, "QLogic-81B")) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 8Gbps PCIe single port FC HBA for HP"); - else if (!strcmp(model, "Brocade-804")) + "QLogic BR-series 8Gbps PCIe single port FC HBA for HP"); + else if (!strcmp(model, "QLogic-804")) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 8Gbps FC HBA for HP Bladesystem C-class"); - else if (!strcmp(model, "Brocade-1741")) + "QLogic BR-series 8Gbps FC HBA for HP Bladesystem C-class"); + else if (!strcmp(model, "QLogic-1741")) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 10Gbps CNA for Dell M-Series Blade Servers"); - else if (strstr(model, "Brocade-1860")) { + "QLogic BR-series 10Gbps CNA for Dell M-Series Blade Servers"); + else if (strstr(model, "QLogic-1860")) { if (nports == 1 && bfa_ioc_is_cna(&bfad->bfa.ioc)) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 10Gbps single port CNA"); + "QLogic BR-series 10Gbps single port CNA"); else if (nports == 1 && !bfa_ioc_is_cna(&bfad->bfa.ioc)) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 16Gbps PCIe single port FC HBA"); + "QLogic BR-series 16Gbps PCIe single port FC HBA"); else if (nports == 2 && bfa_ioc_is_cna(&bfad->bfa.ioc)) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 10Gbps dual port CNA"); + "QLogic BR-series 10Gbps dual port CNA"); else if (nports == 2 && !bfa_ioc_is_cna(&bfad->bfa.ioc)) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 16Gbps PCIe dual port FC HBA"); - } else if (!strcmp(model, "Brocade-1867")) { + "QLogic BR-series 16Gbps PCIe dual port FC HBA"); + } else if (!strcmp(model, "QLogic-1867")) { if (nports == 1 && !bfa_ioc_is_cna(&bfad->bfa.ioc)) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 16Gbps PCIe single port FC HBA for IBM"); + "QLogic BR-series 16Gbps PCIe single port FC HBA for IBM"); else if (nports == 2 && !bfa_ioc_is_cna(&bfad->bfa.ioc)) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 16Gbps PCIe dual port FC HBA for IBM"); + "QLogic BR-series 16Gbps PCIe dual port FC HBA for IBM"); } else snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, "Invalid Model"); diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c index b9d1460..d1ad020 100644 --- a/drivers/scsi/bfa/bfad_bsg.c +++ b/drivers/scsi/bfa/bfad_bsg.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfad_bsg.h b/drivers/scsi/bfa/bfad_bsg.h index 59aca80..917e140 100644 --- a/drivers/scsi/bfa/bfad_bsg.h +++ b/drivers/scsi/bfa/bfad_bsg.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfad_debugfs.c b/drivers/scsi/bfa/bfad_debugfs.c index 62b11d4..8dcd8c7 100644 --- a/drivers/scsi/bfa/bfad_debugfs.c +++ b/drivers/scsi/bfa/bfad_debugfs.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfad_drv.h b/drivers/scsi/bfa/bfad_drv.h index 58fee34..8001459 100644 --- a/drivers/scsi/bfa/bfad_drv.h +++ b/drivers/scsi/bfa/bfad_drv.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c index 2c0cf8a..6c805e1 100644 --- a/drivers/scsi/bfa/bfad_im.c +++ b/drivers/scsi/bfa/bfad_im.c @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as @@ -186,7 +186,7 @@ bfad_im_info(struct Scsi_Host *shost) memset(bfa_buf, 0, sizeof(bfa_buf)); snprintf(bfa_buf, sizeof(bfa_buf), - "Brocade FC/FCOE Adapter, " "hwpath: %s driver: %s", + "QLogic BR-series FC/FCOE Adapter, hwpath: %s driver: %s", bfad->pci_name, BFAD_DRIVER_VERSION); return bfa_buf; diff --git a/drivers/scsi/bfa/bfad_im.h b/drivers/scsi/bfa/bfad_im.h index 31434df..836fdc2 100644 --- a/drivers/scsi/bfa/bfad_im.h +++ b/drivers/scsi/bfa/bfad_im.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfi.h b/drivers/scsi/bfa/bfi.h index 54c93ef..97600dc 100644 --- a/drivers/scsi/bfa/bfi.h +++ b/drivers/scsi/bfa/bfi.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfi_ms.h b/drivers/scsi/bfa/bfi_ms.h index 8699be4..ae5bfe0 100644 --- a/drivers/scsi/bfa/bfi_ms.h +++ b/drivers/scsi/bfa/bfi_ms.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as diff --git a/drivers/scsi/bfa/bfi_reg.h b/drivers/scsi/bfa/bfi_reg.h index 7d071a4..fd5b876 100644 --- a/drivers/scsi/bfa/bfi_reg.h +++ b/drivers/scsi/bfa/bfi_reg.h @@ -4,7 +4,7 @@ * All rights reserved * www.qlogic.com * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as @@ -17,7 +17,7 @@ */ /* - * bfi_reg.h ASIC register defines for all Brocade adapter ASICs + * bfi_reg.h ASIC register defines for all QLogic BR-series adapter ASICs */ #ifndef __BFI_REG_H__ -- cgit v0.10.2 From 08c2315015561d2292cddcbad8967deab86af4d5 Mon Sep 17 00:00:00 2001 From: Anil Gurumurthy Date: Thu, 26 Nov 2015 03:54:47 -0500 Subject: bfa: Update driver version to 3.2.25.0 Signed-off-by: Sudarsana Kalluru Signed-off-by: Anil Gurumurthy Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/bfa/bfad_drv.h b/drivers/scsi/bfa/bfad_drv.h index 8001459..f9e8620 100644 --- a/drivers/scsi/bfa/bfad_drv.h +++ b/drivers/scsi/bfa/bfad_drv.h @@ -58,7 +58,7 @@ #ifdef BFA_DRIVER_VERSION #define BFAD_DRIVER_VERSION BFA_DRIVER_VERSION #else -#define BFAD_DRIVER_VERSION "3.2.23.0" +#define BFAD_DRIVER_VERSION "3.2.25.0" #endif #define BFAD_PROTO_NAME FCPI_NAME -- cgit v0.10.2 From 23211c1e7ad7693e0f518383890308f42f3cc10d Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 3 Dec 2015 07:57:35 +0100 Subject: scsi_dh_alua: Remove stale variables With commit 83ea0e5e3501 ("scsi_dh_alua: use scsi_vpd_tpg_id()") these variables became obsolete, but weren't removed. [mkp: Fixed checkpatch warning] Signed-off-by: Hannes Reinecke Reviewed-by: Johannes Thumshirn Reviewed-by: Christoph Hellwig Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index f100cbb..5a328bf 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -320,8 +320,6 @@ static int alua_check_tpgs(struct scsi_device *sdev) */ static int alua_check_vpd(struct scsi_device *sdev, struct alua_dh_data *h) { - unsigned char *d; - unsigned char __rcu *vpd_pg83; int rel_port = -1, group_id; group_id = scsi_vpd_tpg_id(sdev, &rel_port); -- cgit v0.10.2 From e37390bee6fe7dfbe507a9d50cdc11344b53fa08 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 2 Dec 2015 17:26:28 -0600 Subject: cxlflash: a couple off by one bugs The "> MAX_CONTEXT" should be ">= MAX_CONTEXT". Otherwise we go one step beyond the end of the cfg->ctx_tbl[] array. Signed-off-by: Dan Carpenter Reviewed-by: Manoj Kumar Reviewed-by: Johannes Thumshirn Acked-by: Matthew R. Ochs Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/cxlflash/superpipe.c b/drivers/scsi/cxlflash/superpipe.c index cac2e6a..34b21a0 100644 --- a/drivers/scsi/cxlflash/superpipe.c +++ b/drivers/scsi/cxlflash/superpipe.c @@ -1380,7 +1380,7 @@ static int cxlflash_disk_attach(struct scsi_device *sdev, } ctxid = cxl_process_element(ctx); - if (unlikely((ctxid > MAX_CONTEXT) || (ctxid < 0))) { + if (unlikely((ctxid >= MAX_CONTEXT) || (ctxid < 0))) { dev_err(dev, "%s: ctxid (%d) invalid!\n", __func__, ctxid); rc = -EPERM; goto err2; @@ -1508,7 +1508,7 @@ static int recover_context(struct cxlflash_cfg *cfg, struct ctx_info *ctxi) } ctxid = cxl_process_element(ctx); - if (unlikely((ctxid > MAX_CONTEXT) || (ctxid < 0))) { + if (unlikely((ctxid >= MAX_CONTEXT) || (ctxid < 0))) { dev_err(dev, "%s: ctxid (%d) invalid!\n", __func__, ctxid); rc = -EPERM; goto err1; -- cgit v0.10.2 From 21891a452a42afc2313f1e3a69040e46c1d068c1 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Thu, 3 Dec 2015 15:18:49 -0600 Subject: cxlflash: drop unlikely before IS_ERR_OR_NULL IS_ERR_OR_NULL already contain an unlikely compiler flag. Drop it. Signed-off-by: Geliang Tang Acked-by: Manoj Kumar Acked-by: Matthew R. Ochs Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/cxlflash/superpipe.c b/drivers/scsi/cxlflash/superpipe.c index 34b21a0..f4020db 100644 --- a/drivers/scsi/cxlflash/superpipe.c +++ b/drivers/scsi/cxlflash/superpipe.c @@ -1372,7 +1372,7 @@ static int cxlflash_disk_attach(struct scsi_device *sdev, } ctx = cxl_dev_context_init(cfg->dev); - if (unlikely(IS_ERR_OR_NULL(ctx))) { + if (IS_ERR_OR_NULL(ctx)) { dev_err(dev, "%s: Could not initialize context %p\n", __func__, ctx); rc = -ENODEV; @@ -1500,7 +1500,7 @@ static int recover_context(struct cxlflash_cfg *cfg, struct ctx_info *ctxi) struct afu *afu = cfg->afu; ctx = cxl_dev_context_init(cfg->dev); - if (unlikely(IS_ERR_OR_NULL(ctx))) { + if (IS_ERR_OR_NULL(ctx)) { dev_err(dev, "%s: Could not initialize context %p\n", __func__, ctx); rc = -ENODEV; -- cgit v0.10.2 From c965853ab06b3e8a9d024d86730b373c333fc6f3 Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Thu, 3 Dec 2015 08:27:59 -0500 Subject: VMW_PVSCSI: Fix the issue of DMA-API related warnings. The driver is missing calls to pci_dma_mapping_error() after performing the DMA mapping, which caused DMA-API warning to show up in dmesg's output. Though that happens only when DMA_API_DEBUG option is enabled. This change fixes the issue and makes pvscsi_map_buffers() function more robust. Signed-off-by: Arvind Kumar Cc: Josh Boyer Reviewed-by: Thomas Hellstrom Signed-off-by: Josh Boyer Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/vmw_pvscsi.c b/drivers/scsi/vmw_pvscsi.c index 0f133c1..6164634 100644 --- a/drivers/scsi/vmw_pvscsi.c +++ b/drivers/scsi/vmw_pvscsi.c @@ -349,9 +349,9 @@ static void pvscsi_create_sg(struct pvscsi_ctx *ctx, * Map all data buffers for a command into PCI space and * setup the scatter/gather list if needed. */ -static void pvscsi_map_buffers(struct pvscsi_adapter *adapter, - struct pvscsi_ctx *ctx, struct scsi_cmnd *cmd, - struct PVSCSIRingReqDesc *e) +static int pvscsi_map_buffers(struct pvscsi_adapter *adapter, + struct pvscsi_ctx *ctx, struct scsi_cmnd *cmd, + struct PVSCSIRingReqDesc *e) { unsigned count; unsigned bufflen = scsi_bufflen(cmd); @@ -360,18 +360,30 @@ static void pvscsi_map_buffers(struct pvscsi_adapter *adapter, e->dataLen = bufflen; e->dataAddr = 0; if (bufflen == 0) - return; + return 0; sg = scsi_sglist(cmd); count = scsi_sg_count(cmd); if (count != 0) { int segs = scsi_dma_map(cmd); - if (segs > 1) { + + if (segs == -ENOMEM) { + scmd_printk(KERN_ERR, cmd, + "vmw_pvscsi: Failed to map cmd sglist for DMA.\n"); + return -ENOMEM; + } else if (segs > 1) { pvscsi_create_sg(ctx, sg, segs); e->flags |= PVSCSI_FLAG_CMD_WITH_SG_LIST; ctx->sglPA = pci_map_single(adapter->dev, ctx->sgl, SGL_SIZE, PCI_DMA_TODEVICE); + if (pci_dma_mapping_error(adapter->dev, ctx->sglPA)) { + scmd_printk(KERN_ERR, cmd, + "vmw_pvscsi: Failed to map ctx sglist for DMA.\n"); + scsi_dma_unmap(cmd); + ctx->sglPA = 0; + return -ENOMEM; + } e->dataAddr = ctx->sglPA; } else e->dataAddr = sg_dma_address(sg); @@ -382,8 +394,15 @@ static void pvscsi_map_buffers(struct pvscsi_adapter *adapter, */ ctx->dataPA = pci_map_single(adapter->dev, sg, bufflen, cmd->sc_data_direction); + if (pci_dma_mapping_error(adapter->dev, ctx->dataPA)) { + scmd_printk(KERN_ERR, cmd, + "vmw_pvscsi: Failed to map direct data buffer for DMA.\n"); + return -ENOMEM; + } e->dataAddr = ctx->dataPA; } + + return 0; } static void pvscsi_unmap_buffers(const struct pvscsi_adapter *adapter, @@ -690,6 +709,12 @@ static int pvscsi_queue_ring(struct pvscsi_adapter *adapter, ctx->sensePA = pci_map_single(adapter->dev, cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE, PCI_DMA_FROMDEVICE); + if (pci_dma_mapping_error(adapter->dev, ctx->sensePA)) { + scmd_printk(KERN_ERR, cmd, + "vmw_pvscsi: Failed to map sense buffer for DMA.\n"); + ctx->sensePA = 0; + return -ENOMEM; + } e->senseAddr = ctx->sensePA; e->senseLen = SCSI_SENSE_BUFFERSIZE; } else { @@ -711,7 +736,15 @@ static int pvscsi_queue_ring(struct pvscsi_adapter *adapter, else e->flags = 0; - pvscsi_map_buffers(adapter, ctx, cmd, e); + if (pvscsi_map_buffers(adapter, ctx, cmd, e) != 0) { + if (cmd->sense_buffer) { + pci_unmap_single(adapter->dev, ctx->sensePA, + SCSI_SENSE_BUFFERSIZE, + PCI_DMA_FROMDEVICE); + ctx->sensePA = 0; + } + return -ENOMEM; + } e->context = pvscsi_map_context(adapter, ctx); diff --git a/drivers/scsi/vmw_pvscsi.h b/drivers/scsi/vmw_pvscsi.h index ee16f0c..12712c9 100644 --- a/drivers/scsi/vmw_pvscsi.h +++ b/drivers/scsi/vmw_pvscsi.h @@ -26,7 +26,7 @@ #include -#define PVSCSI_DRIVER_VERSION_STRING "1.0.5.0-k" +#define PVSCSI_DRIVER_VERSION_STRING "1.0.6.0-k" #define PVSCSI_MAX_NUM_SG_ENTRIES_PER_SEGMENT 128 -- cgit v0.10.2 From f8aea701b77c26732f151aab4f0a70e62eb53d86 Mon Sep 17 00:00:00 2001 From: Long Li Date: Fri, 4 Dec 2015 00:07:24 -0800 Subject: storvsc: add logging for error/warning messages Introduce a logging level for storvsc to log certain error/warning messages. Those messages are helpful in some environments, e.g. Microsoft Azure, for customer support and troubleshooting purposes. Signed-off-by: Long Li Acked-by: K. Y. Srinivasan Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 3fba42a..c41f674 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -164,6 +164,26 @@ static int sense_buffer_size = PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE; */ static int vmstor_proto_version; +#define STORVSC_LOGGING_NONE 0 +#define STORVSC_LOGGING_ERROR 1 +#define STORVSC_LOGGING_WARN 2 + +static int logging_level = STORVSC_LOGGING_ERROR; +module_param(logging_level, int, S_IRUGO|S_IWUSR); +MODULE_PARM_DESC(logging_level, + "Logging level, 0 - None, 1 - Error (default), 2 - Warning."); + +static inline bool do_logging(int level) +{ + return logging_level >= level; +} + +#define storvsc_log(dev, level, fmt, ...) \ +do { \ + if (do_logging(level)) \ + dev_warn(&(dev)->device, fmt, ##__VA_ARGS__); \ +} while (0) + struct vmscsi_win8_extension { /* * The following were added in Windows 8 @@ -941,7 +961,8 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request) if (scmnd->result) { if (scsi_normalize_sense(scmnd->sense_buffer, - SCSI_SENSE_BUFFERSIZE, &sense_hdr)) + SCSI_SENSE_BUFFERSIZE, &sense_hdr) && + do_logging(STORVSC_LOGGING_ERROR)) scsi_print_sense_hdr(scmnd->device, "storvsc", &sense_hdr); } @@ -995,6 +1016,13 @@ static void storvsc_on_io_completion(struct hv_device *device, stor_pkt->vm_srb.sense_info_length = vstor_packet->vm_srb.sense_info_length; + if (vstor_packet->vm_srb.scsi_status != 0 || + vstor_packet->vm_srb.srb_status != SRB_STATUS_SUCCESS) + storvsc_log(device, STORVSC_LOGGING_WARN, + "cmd 0x%x scsi status 0x%x srb status 0x%x\n", + stor_pkt->vm_srb.cdb[0], + vstor_packet->vm_srb.scsi_status, + vstor_packet->vm_srb.srb_status); if ((vstor_packet->vm_srb.scsi_status & 0xFF) == 0x02) { /* CHECK_CONDITION */ @@ -1002,6 +1030,10 @@ static void storvsc_on_io_completion(struct hv_device *device, SRB_STATUS_AUTOSENSE_VALID) { /* autosense data available */ + storvsc_log(device, STORVSC_LOGGING_WARN, + "stor pkt %p autosense data valid - len %d\n", + request, vstor_packet->vm_srb.sense_info_length); + memcpy(request->cmd->sense_buffer, vstor_packet->vm_srb.sense_data, vstor_packet->vm_srb.sense_info_length); -- cgit v0.10.2 From 9a2fcad8dce219df6cac3db91f373080f017856a Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Tue, 8 Dec 2015 15:25:16 +0100 Subject: osd: fix signed char versus %02x issue If char is signed and one of these bytes happen to have a value outside the ascii range, the corresponding output will consist of "ffffff" followed by the two hex chars that were actually intended. One way to fix it would be to change the casts to (u8*) aka (unsigned char*), but it is much simpler (and generates smaller code) to use the %ph extension which was created for such short hexdumps. Signed-off-by: Rasmus Villemoes Acked-by: Boaz Harrosh Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c index 0cccd60..d8a2b51 100644 --- a/drivers/scsi/osd/osd_initiator.c +++ b/drivers/scsi/osd/osd_initiator.c @@ -170,10 +170,7 @@ static int _osd_get_print_system_info(struct osd_dev *od, /* FIXME: Where are the time utilities */ pFirst = get_attrs[a++].val_ptr; - OSD_INFO("CLOCK [0x%02x%02x%02x%02x%02x%02x]\n", - ((char *)pFirst)[0], ((char *)pFirst)[1], - ((char *)pFirst)[2], ((char *)pFirst)[3], - ((char *)pFirst)[4], ((char *)pFirst)[5]); + OSD_INFO("CLOCK [0x%6phN]\n", pFirst); if (a < nelem) { /* IBM-OSD-SIM bug, Might not have it */ unsigned len = get_attrs[a].len; -- cgit v0.10.2 From 9c9d18e7a680f3eceeb891e24709eda817ef738e Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 9 Dec 2015 13:48:36 +0300 Subject: hisi_sas: fix error codes in hisi_sas_task_prep() There were a couple cases where the error codes weren't set and also I changed the success return to "return 0;" which is the same as "return rc;" but more explicit. Fixes: 42e7a69368a5 ('hisi_sas: Add ssp command functio') Signed-off-by: Dan Carpenter Tested-by: John Garry Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 2929018..99b1950 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -208,15 +208,19 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_hba *hisi_hba, slot->status_buffer = dma_pool_alloc(hisi_hba->status_buffer_pool, GFP_ATOMIC, &slot->status_buffer_dma); - if (!slot->status_buffer) + if (!slot->status_buffer) { + rc = -ENOMEM; goto err_out_slot_buf; + } memset(slot->status_buffer, 0, HISI_SAS_STATUS_BUF_SZ); slot->command_table = dma_pool_alloc(hisi_hba->command_table_pool, GFP_ATOMIC, &slot->command_table_dma); - if (!slot->command_table) + if (!slot->command_table) { + rc = -ENOMEM; goto err_out_status_buf; + } memset(slot->command_table, 0, HISI_SAS_COMMAND_TABLE_SZ); memset(slot->cmd_hdr, 0, sizeof(struct hisi_sas_cmd_hdr)); @@ -254,7 +258,7 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_hba *hisi_hba, sas_dev->running_req++; ++(*pass); - return rc; + return 0; err_out_sge: dma_pool_free(hisi_hba->sge_page_pool, slot->sge_page, -- cgit v0.10.2 From df2d8213d9e3f636f8273847cf906ded3535ec2f Mon Sep 17 00:00:00 2001 From: John Garry Date: Fri, 11 Dec 2015 20:03:21 +0800 Subject: hisi_sas: use platform_get_irq() It is preferred that drivers use platform_get_irq() instead of irq_of_parse_and_map(), so replace. Signed-off-by: John Garry Acked-by: Rob Herring Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 30a9ab9..5af2e41 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 0ed2f92..d543811 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -1673,19 +1673,16 @@ static irq_handler_t fatal_interrupts[HISI_SAS_MAX_QUEUES] = { static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) { - struct device *dev = &hisi_hba->pdev->dev; - struct device_node *np = dev->of_node; + struct platform_device *pdev = hisi_hba->pdev; + struct device *dev = &pdev->dev; int i, j, irq, rc, idx; - if (!np) - return -ENOENT; - for (i = 0; i < hisi_hba->n_phy; i++) { struct hisi_sas_phy *phy = &hisi_hba->phy[i]; idx = i * HISI_SAS_PHY_INT_NR; for (j = 0; j < HISI_SAS_PHY_INT_NR; j++, idx++) { - irq = irq_of_parse_and_map(np, idx); + irq = platform_get_irq(pdev, idx); if (!irq) { dev_err(dev, "irq init: fail map phy interrupt %d\n", @@ -1706,7 +1703,7 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) idx = hisi_hba->n_phy * HISI_SAS_PHY_INT_NR; for (i = 0; i < hisi_hba->queue_count; i++, idx++) { - irq = irq_of_parse_and_map(np, idx); + irq = platform_get_irq(pdev, idx); if (!irq) { dev_err(dev, "irq init: could not map cq interrupt %d\n", idx); @@ -1724,7 +1721,7 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) idx = (hisi_hba->n_phy * HISI_SAS_PHY_INT_NR) + hisi_hba->queue_count; for (i = 0; i < HISI_SAS_FATAL_INT_NR; i++, idx++) { - irq = irq_of_parse_and_map(np, idx); + irq = platform_get_irq(pdev, idx); if (!irq) { dev_err(dev, "irq init: could not map fatal interrupt %d\n", idx); -- cgit v0.10.2 From 3b91d09c1ca69a69c470efe5fbf346e3e90181d5 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Wed, 9 Dec 2015 11:12:03 -0800 Subject: scsi_transport_sas: add is_sas_attached() function Adds a function designed to be callable any time (regardless of whether the transport attributes are configured or not) which returns true if the device is attached over a SAS transport. The design of this function is that transport specific functions can be embedded within a if (is_sas_attached(sdev)) { ... } which would be compiled out (and thus eliminate the symbols) if SAS is not configured. Reviewed-by: Hannes Reinecke Signed-off-by: James Bottomley diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index 30d26e3..b17f763 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c @@ -341,6 +341,22 @@ static int do_sas_phy_delete(struct device *dev, void *data) } /** + * is_sas_attached - check if device is SAS attached + * @sdev: scsi device to check + * + * returns true if the device is SAS attached + */ +int is_sas_attached(struct scsi_device *sdev) +{ + struct Scsi_Host *shost = sdev->host; + + return shost->transportt->host_attrs.ac.class == + &sas_host_class.class; +} +EXPORT_SYMBOL(is_sas_attached); + + +/** * sas_remove_children - tear down a devices SAS data structures * @dev: device belonging to the sas object * diff --git a/include/scsi/scsi_transport_sas.h b/include/scsi/scsi_transport_sas.h index 0bd71e2..a8fdd10 100644 --- a/include/scsi/scsi_transport_sas.h +++ b/include/scsi/scsi_transport_sas.h @@ -10,6 +10,15 @@ struct scsi_transport_template; struct sas_rphy; struct request; +#if !IS_ENABLED(CONFIG_SCSI_SAS_ATTRS) +static inline int is_sas_attached(struct scsi_device *sdev) +{ + return 0; +} +#else +extern int is_sas_attached(struct scsi_device *sdev); +#endif + static inline int sas_protocol_ata(enum sas_protocol proto) { return ((proto & SAS_PROTOCOL_SATA) || -- cgit v0.10.2 From bcf508c13385e74972f5cc06d8471d5c100395b0 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Wed, 9 Dec 2015 11:13:35 -0800 Subject: scsi_transport_sas: add function to get SAS endpoint address For a device known to be SAS connected, this will return the endpoint address. This is useful for getting the SAS address of SATA devices. Reviewed-by: Hannes Reinecke Signed-off-by: James Bottomley diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index b17f763..80520e2 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c @@ -383,6 +383,20 @@ void sas_remove_host(struct Scsi_Host *shost) EXPORT_SYMBOL(sas_remove_host); /** + * sas_get_address - return the SAS address of the device + * @sdev: scsi device + * + * Returns the SAS address of the scsi device + */ +u64 sas_get_address(struct scsi_device *sdev) +{ + struct sas_end_device *rdev = sas_sdev_to_rdev(sdev); + + return rdev->rphy.identify.sas_address; +} +EXPORT_SYMBOL(sas_get_address); + +/** * sas_tlr_supported - checking TLR bit in vpd 0x90 * @sdev: scsi device struct * diff --git a/include/scsi/scsi_transport_sas.h b/include/scsi/scsi_transport_sas.h index a8fdd10..13c0b2b 100644 --- a/include/scsi/scsi_transport_sas.h +++ b/include/scsi/scsi_transport_sas.h @@ -189,6 +189,7 @@ extern int sas_phy_add(struct sas_phy *); extern void sas_phy_delete(struct sas_phy *); extern int scsi_is_sas_phy(const struct device *); +u64 sas_get_address(struct scsi_device *); unsigned int sas_tlr_supported(struct scsi_device *); unsigned int sas_is_tlr_enabled(struct scsi_device *); void sas_disable_tlr(struct scsi_device *); -- cgit v0.10.2 From 3f8d6f2a0797e8c650a47e5c1b5c2601a46f4293 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Wed, 9 Dec 2015 12:56:07 -0800 Subject: ses: fix discovery of SATA devices in SAS enclosures The current discovery routines use the VPD 0x83 inquiry page to find the device SAS address and match it to the end point in the enclosure. This doesn't work for SATA devices because expanders (or hosts) simply make up an endpoint address for STP and thus the address returned by the VPD page never matches. Instead of doing this, for SAS attached devices, match by the direct endpoint address instead. Signed-off-by: James Bottomley diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 64eed87..90cd7cd 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -194,6 +194,7 @@ config CHR_DEV_SCH config SCSI_ENCLOSURE tristate "SCSI Enclosure Support" depends on SCSI && ENCLOSURE_SERVICES + depends on m || SCSI_SAS_ATTRS != m help Enclosures are devices sitting on or in SCSI backplanes that manage devices. If you have a disk cage, the chances are that diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c index 044d064..53ef1cb 100644 --- a/drivers/scsi/ses.c +++ b/drivers/scsi/ses.c @@ -34,6 +34,8 @@ #include #include +#include + struct ses_device { unsigned char *page1; unsigned char *page1_types; @@ -579,31 +581,15 @@ static void ses_enclosure_data_process(struct enclosure_device *edev, static void ses_match_to_enclosure(struct enclosure_device *edev, struct scsi_device *sdev) { - unsigned char *desc; struct efd efd = { .addr = 0, }; ses_enclosure_data_process(edev, to_scsi_device(edev->edev.parent), 0); - if (!sdev->vpd_pg83_len) - return; - - desc = sdev->vpd_pg83 + 4; - while (desc < sdev->vpd_pg83 + sdev->vpd_pg83_len) { - enum scsi_protocol proto = desc[0] >> 4; - u8 code_set = desc[0] & 0x0f; - u8 piv = desc[1] & 0x80; - u8 assoc = (desc[1] & 0x30) >> 4; - u8 type = desc[1] & 0x0f; - u8 len = desc[3]; - - if (piv && code_set == 1 && assoc == 1 - && proto == SCSI_PROTOCOL_SAS && type == 3 && len == 8) - efd.addr = get_unaligned_be64(&desc[4]); + if (is_sas_attached(sdev)) + efd.addr = sas_get_address(sdev); - desc += len + 4; - } if (efd.addr) { efd.dev = &sdev->sdev_gendev; -- cgit v0.10.2 From f5cb5304eb26d307c9b30269fb0e007e0b262b7d Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 16 Dec 2015 18:11:52 -0500 Subject: lpfc: Fix FCF Infinite loop in lpfc_sli4_fcf_rr_next_index_get. Fix FCF Infinite loop in lpfc_sli4_fcf_rr_next_index_get. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Reviewed-by: Hannes Reinicke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index f9585cd..6aae828 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -16173,7 +16173,7 @@ fail_fcf_read: } /** - * lpfc_check_next_fcf_pri + * lpfc_check_next_fcf_pri_level * phba pointer to the lpfc_hba struct for this port. * This routine is called from the lpfc_sli4_fcf_rr_next_index_get * routine when the rr_bmask is empty. The FCF indecies are put into the @@ -16329,8 +16329,12 @@ next_priority: if (next_fcf_index < LPFC_SLI4_FCF_TBL_INDX_MAX && phba->fcf.fcf_pri[next_fcf_index].fcf_rec.flag & - LPFC_FCF_FLOGI_FAILED) + LPFC_FCF_FLOGI_FAILED) { + if (list_is_singular(&phba->fcf.fcf_pri_list)) + return LPFC_FCOE_FCF_NEXT_NONE; + goto next_priority; + } lpfc_printf_log(phba, KERN_INFO, LOG_FIP, "2845 Get next roundrobin failover FCF (x%x)\n", -- cgit v0.10.2 From d6de08cc46269899988b4f40acc7337279693d4b Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 16 Dec 2015 18:11:53 -0500 Subject: lpfc: Fix the FLOGI discovery logic to comply with T11 standards Fix the FLOGI discovery logic to comply with T11 standards We weren't properly setting fabric parameters, such as R_A_TOV and E_D_TOV, when we registered the vfi object in default configs and pt2pt configs. Revise to now pass service params with the values to the firmware and ensure they are reset on link bounce. Required reworking the call sequence in the discovery threads. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Reviewed-by: Hannes Reinicke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index b0e6fe4..80d3c74 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -72,6 +72,7 @@ void lpfc_cancel_all_vport_retry_delay_timer(struct lpfc_hba *); void lpfc_retry_pport_discovery(struct lpfc_hba *); void lpfc_release_rpi(struct lpfc_hba *, struct lpfc_vport *, uint16_t); +void lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index b6fa257..f6dd15b 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -455,9 +455,9 @@ int lpfc_issue_reg_vfi(struct lpfc_vport *vport) { struct lpfc_hba *phba = vport->phba; - LPFC_MBOXQ_t *mboxq; + LPFC_MBOXQ_t *mboxq = NULL; struct lpfc_nodelist *ndlp; - struct lpfc_dmabuf *dmabuf; + struct lpfc_dmabuf *dmabuf = NULL; int rc = 0; /* move forward in case of SLI4 FC port loopback test and pt2pt mode */ @@ -471,25 +471,33 @@ lpfc_issue_reg_vfi(struct lpfc_vport *vport) } } - dmabuf = kzalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); - if (!dmabuf) { + mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); + if (!mboxq) { rc = -ENOMEM; goto fail; } - dmabuf->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &dmabuf->phys); - if (!dmabuf->virt) { - rc = -ENOMEM; - goto fail_free_dmabuf; - } - mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); - if (!mboxq) { - rc = -ENOMEM; - goto fail_free_coherent; + /* Supply CSP's only if we are fabric connect or pt-to-pt connect */ + if ((vport->fc_flag & FC_FABRIC) || (vport->fc_flag & FC_PT2PT)) { + dmabuf = kzalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); + if (!dmabuf) { + rc = -ENOMEM; + goto fail; + } + dmabuf->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &dmabuf->phys); + if (!dmabuf->virt) { + rc = -ENOMEM; + goto fail; + } + memcpy(dmabuf->virt, &phba->fc_fabparam, + sizeof(struct serv_parm)); } + vport->port_state = LPFC_FABRIC_CFG_LINK; - memcpy(dmabuf->virt, &phba->fc_fabparam, sizeof(vport->fc_sparam)); - lpfc_reg_vfi(mboxq, vport, dmabuf->phys); + if (dmabuf) + lpfc_reg_vfi(mboxq, vport, dmabuf->phys); + else + lpfc_reg_vfi(mboxq, vport, 0); mboxq->mbox_cmpl = lpfc_mbx_cmpl_reg_vfi; mboxq->vport = vport; @@ -497,17 +505,19 @@ lpfc_issue_reg_vfi(struct lpfc_vport *vport) rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT); if (rc == MBX_NOT_FINISHED) { rc = -ENXIO; - goto fail_free_mbox; + goto fail; } return 0; -fail_free_mbox: - mempool_free(mboxq, phba->mbox_mem_pool); -fail_free_coherent: - lpfc_mbuf_free(phba, dmabuf->virt, dmabuf->phys); -fail_free_dmabuf: - kfree(dmabuf); fail: + if (mboxq) + mempool_free(mboxq, phba->mbox_mem_pool); + if (dmabuf) { + if (dmabuf->virt) + lpfc_mbuf_free(phba, dmabuf->virt, dmabuf->phys); + kfree(dmabuf); + } + lpfc_vport_set_state(vport, FC_VPORT_FAILED); lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, "0289 Issue Register VFI failed: Err %d\n", rc); @@ -711,9 +721,10 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, * For FC we need to do some special processing because of the SLI * Port's default settings of the Common Service Parameters. */ - if (phba->sli4_hba.lnk_info.lnk_tp == LPFC_LNK_TYPE_FC) { + if ((phba->sli_rev == LPFC_SLI_REV4) && + (phba->sli4_hba.lnk_info.lnk_tp == LPFC_LNK_TYPE_FC)) { /* If physical FC port changed, unreg VFI and ALL VPIs / RPIs */ - if ((phba->sli_rev == LPFC_SLI_REV4) && fabric_param_changed) + if (fabric_param_changed) lpfc_unregister_fcf_prep(phba); /* This should just update the VFI CSPs*/ @@ -824,13 +835,21 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, spin_lock_irq(shost->host_lock); vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP); + vport->fc_flag |= FC_PT2PT; spin_unlock_irq(shost->host_lock); - phba->fc_edtov = FF_DEF_EDTOV; - phba->fc_ratov = FF_DEF_RATOV; + /* If physical FC port changed, unreg VFI and ALL VPIs / RPIs */ + if ((phba->sli_rev == LPFC_SLI_REV4) && phba->fc_topology_changed) { + lpfc_unregister_fcf_prep(phba); + + spin_lock_irq(shost->host_lock); + vport->fc_flag &= ~FC_VFI_REGISTERED; + spin_unlock_irq(shost->host_lock); + phba->fc_topology_changed = 0; + } + rc = memcmp(&vport->fc_portname, &sp->portName, sizeof(vport->fc_portname)); - memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm)); if (rc >= 0) { /* This side will initiate the PLOGI */ @@ -839,38 +858,14 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, spin_unlock_irq(shost->host_lock); /* - * N_Port ID cannot be 0, set our to LocalID the other - * side will be RemoteID. + * N_Port ID cannot be 0, set our Id to LocalID + * the other side will be RemoteID. */ /* not equal */ if (rc) vport->fc_myDID = PT2PT_LocalID; - mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); - if (!mbox) - goto fail; - - lpfc_config_link(phba, mbox); - - mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; - mbox->vport = vport; - rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); - if (rc == MBX_NOT_FINISHED) { - mempool_free(mbox, phba->mbox_mem_pool); - goto fail; - } - - /* - * For SLI4, the VFI/VPI are registered AFTER the - * Nport with the higher WWPN sends the PLOGI with - * an assigned NPortId. - */ - - /* not equal */ - if ((phba->sli_rev == LPFC_SLI_REV4) && rc) - lpfc_issue_reg_vfi(vport); - /* Decrement ndlp reference count indicating that ndlp can be * safely released when other references to it are done. */ @@ -912,29 +907,20 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, /* If we are pt2pt with another NPort, force NPIV off! */ phba->sli3_options &= ~LPFC_SLI3_NPIV_ENABLED; - spin_lock_irq(shost->host_lock); - vport->fc_flag |= FC_PT2PT; - spin_unlock_irq(shost->host_lock); - /* If physical FC port changed, unreg VFI and ALL VPIs / RPIs */ - if ((phba->sli_rev == LPFC_SLI_REV4) && phba->fc_topology_changed) { - lpfc_unregister_fcf_prep(phba); + mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); + if (!mbox) + goto fail; - /* The FC_VFI_REGISTERED flag will get clear in the cmpl - * handler for unreg_vfi, but if we don't force the - * FC_VFI_REGISTERED flag then the reg_vfi mailbox could be - * built with the update bit set instead of just the vp bit to - * change the Nport ID. We need to have the vp set and the - * Upd cleared on topology changes. - */ - spin_lock_irq(shost->host_lock); - vport->fc_flag &= ~FC_VFI_REGISTERED; - spin_unlock_irq(shost->host_lock); - phba->fc_topology_changed = 0; - lpfc_issue_reg_vfi(vport); + lpfc_config_link(phba, mbox); + + mbox->mbox_cmpl = lpfc_mbx_cmpl_local_config_link; + mbox->vport = vport; + rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); + if (rc == MBX_NOT_FINISHED) { + mempool_free(mbox, phba->mbox_mem_pool); + goto fail; } - /* Start discovery - this should just do CLEAR_LA */ - lpfc_disc_start(vport); return 0; fail: return -ENXIO; @@ -1157,6 +1143,7 @@ flogifail: spin_lock_irq(&phba->hbalock); phba->fcf.fcf_flag &= ~FCF_DISCOVERY; spin_unlock_irq(&phba->hbalock); + lpfc_nlp_put(ndlp); if (!lpfc_error_lost_link(irsp)) { @@ -3898,6 +3885,7 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag, IOCB_t *oldcmd; struct lpfc_iocbq *elsiocb; uint8_t *pcmd; + struct serv_parm *sp; uint16_t cmdsize; int rc; ELS_PKT *els_pkt_ptr; @@ -3927,6 +3915,7 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag, "Issue ACC: did:x%x flg:x%x", ndlp->nlp_DID, ndlp->nlp_flag, 0); break; + case ELS_CMD_FLOGI: case ELS_CMD_PLOGI: cmdsize = (sizeof(struct serv_parm) + sizeof(uint32_t)); elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, @@ -3944,10 +3933,34 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag, *((uint32_t *) (pcmd)) = ELS_CMD_ACC; pcmd += sizeof(uint32_t); - memcpy(pcmd, &vport->fc_sparam, sizeof(struct serv_parm)); + sp = (struct serv_parm *)pcmd; + + if (flag == ELS_CMD_FLOGI) { + /* Copy the received service parameters back */ + memcpy(sp, &phba->fc_fabparam, + sizeof(struct serv_parm)); + + /* Clear the F_Port bit */ + sp->cmn.fPort = 0; + + /* Mark all class service parameters as invalid */ + sp->cls1.classValid = 0; + sp->cls2.classValid = 0; + sp->cls3.classValid = 0; + sp->cls4.classValid = 0; + + /* Copy our worldwide names */ + memcpy(&sp->portName, &vport->fc_sparam.portName, + sizeof(struct lpfc_name)); + memcpy(&sp->nodeName, &vport->fc_sparam.nodeName, + sizeof(struct lpfc_name)); + } else { + memcpy(pcmd, &vport->fc_sparam, + sizeof(struct serv_parm)); + } lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP, - "Issue ACC PLOGI: did:x%x flg:x%x", + "Issue ACC FLOGI/PLOGI: did:x%x flg:x%x", ndlp->nlp_DID, ndlp->nlp_flag, 0); break; case ELS_CMD_PRLO: @@ -5739,7 +5752,6 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, IOCB_t *icmd = &cmdiocb->iocb; struct serv_parm *sp; LPFC_MBOXQ_t *mbox; - struct ls_rjt stat; uint32_t cmd, did; int rc; uint32_t fc_flag = 0; @@ -5765,135 +5777,92 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, return 1; } - if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3, 1))) { - /* For a FLOGI we accept, then if our portname is greater - * then the remote portname we initiate Nport login. - */ + (void) lpfc_check_sparm(vport, ndlp, sp, CLASS3, 1); - rc = memcmp(&vport->fc_portname, &sp->portName, - sizeof(struct lpfc_name)); - if (!rc) { - if (phba->sli_rev < LPFC_SLI_REV4) { - mbox = mempool_alloc(phba->mbox_mem_pool, - GFP_KERNEL); - if (!mbox) - return 1; - lpfc_linkdown(phba); - lpfc_init_link(phba, mbox, - phba->cfg_topology, - phba->cfg_link_speed); - mbox->u.mb.un.varInitLnk.lipsr_AL_PA = 0; - mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; - mbox->vport = vport; - rc = lpfc_sli_issue_mbox(phba, mbox, - MBX_NOWAIT); - lpfc_set_loopback_flag(phba); - if (rc == MBX_NOT_FINISHED) - mempool_free(mbox, phba->mbox_mem_pool); - return 1; - } else { - /* abort the flogi coming back to ourselves - * due to external loopback on the port. - */ - lpfc_els_abort_flogi(phba); - return 0; - } - } else if (rc > 0) { /* greater than */ - spin_lock_irq(shost->host_lock); - vport->fc_flag |= FC_PT2PT_PLOGI; - spin_unlock_irq(shost->host_lock); + /* + * If our portname is greater than the remote portname, + * then we initiate Nport login. + */ - /* If we have the high WWPN we can assign our own - * myDID; otherwise, we have to WAIT for a PLOGI - * from the remote NPort to find out what it - * will be. - */ - vport->fc_myDID = PT2PT_LocalID; - } else - vport->fc_myDID = PT2PT_RemoteID; + rc = memcmp(&vport->fc_portname, &sp->portName, + sizeof(struct lpfc_name)); - /* - * The vport state should go to LPFC_FLOGI only - * AFTER we issue a FLOGI, not receive one. + if (!rc) { + if (phba->sli_rev < LPFC_SLI_REV4) { + mbox = mempool_alloc(phba->mbox_mem_pool, + GFP_KERNEL); + if (!mbox) + return 1; + lpfc_linkdown(phba); + lpfc_init_link(phba, mbox, + phba->cfg_topology, + phba->cfg_link_speed); + mbox->u.mb.un.varInitLnk.lipsr_AL_PA = 0; + mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; + mbox->vport = vport; + rc = lpfc_sli_issue_mbox(phba, mbox, + MBX_NOWAIT); + lpfc_set_loopback_flag(phba); + if (rc == MBX_NOT_FINISHED) + mempool_free(mbox, phba->mbox_mem_pool); + return 1; + } + + /* abort the flogi coming back to ourselves + * due to external loopback on the port. */ + lpfc_els_abort_flogi(phba); + return 0; + + } else if (rc > 0) { /* greater than */ spin_lock_irq(shost->host_lock); - fc_flag = vport->fc_flag; - port_state = vport->port_state; - vport->fc_flag |= FC_PT2PT; - vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP); + vport->fc_flag |= FC_PT2PT_PLOGI; spin_unlock_irq(shost->host_lock); - lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, - "3311 Rcv Flogi PS x%x new PS x%x " - "fc_flag x%x new fc_flag x%x\n", - port_state, vport->port_state, - fc_flag, vport->fc_flag); - /* - * We temporarily set fc_myDID to make it look like we are - * a Fabric. This is done just so we end up with the right - * did / sid on the FLOGI ACC rsp. + /* If we have the high WWPN we can assign our own + * myDID; otherwise, we have to WAIT for a PLOGI + * from the remote NPort to find out what it + * will be. */ - did = vport->fc_myDID; - vport->fc_myDID = Fabric_DID; - + vport->fc_myDID = PT2PT_LocalID; } else { - /* Reject this request because invalid parameters */ - stat.un.b.lsRjtRsvd0 = 0; - stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; - stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS; - stat.un.b.vendorUnique = 0; - - /* - * We temporarily set fc_myDID to make it look like we are - * a Fabric. This is done just so we end up with the right - * did / sid on the FLOGI LS_RJT rsp. - */ - did = vport->fc_myDID; - vport->fc_myDID = Fabric_DID; - - lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, - NULL); + vport->fc_myDID = PT2PT_RemoteID; + } - /* Now lets put fc_myDID back to what its supposed to be */ - vport->fc_myDID = did; + /* + * The vport state should go to LPFC_FLOGI only + * AFTER we issue a FLOGI, not receive one. + */ + spin_lock_irq(shost->host_lock); + fc_flag = vport->fc_flag; + port_state = vport->port_state; + vport->fc_flag |= FC_PT2PT; + vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP); + spin_unlock_irq(shost->host_lock); + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "3311 Rcv Flogi PS x%x new PS x%x " + "fc_flag x%x new fc_flag x%x\n", + port_state, vport->port_state, + fc_flag, vport->fc_flag); - return 1; - } + /* + * We temporarily set fc_myDID to make it look like we are + * a Fabric. This is done just so we end up with the right + * did / sid on the FLOGI ACC rsp. + */ + did = vport->fc_myDID; + vport->fc_myDID = Fabric_DID; - /* send our FLOGI first */ - if (vport->port_state < LPFC_FLOGI) { - vport->fc_myDID = 0; - lpfc_initial_flogi(vport); - vport->fc_myDID = Fabric_DID; - } + memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm)); /* Send back ACC */ - lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL); + lpfc_els_rsp_acc(vport, ELS_CMD_FLOGI, cmdiocb, ndlp, NULL); /* Now lets put fc_myDID back to what its supposed to be */ vport->fc_myDID = did; - if (!(vport->fc_flag & FC_PT2PT_PLOGI)) { - - mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); - if (!mbox) - goto fail; - - lpfc_config_link(phba, mbox); - - mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; - mbox->vport = vport; - rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); - if (rc == MBX_NOT_FINISHED) { - mempool_free(mbox, phba->mbox_mem_pool); - goto fail; - } - } - return 0; -fail: - return 1; } /** @@ -7345,7 +7314,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, /* reject till our FLOGI completes */ if ((vport->port_state < LPFC_FABRIC_CFG_LINK) && - (cmd != ELS_CMD_FLOGI)) { + (cmd != ELS_CMD_FLOGI)) { rjt_err = LSRJT_UNABLE_TPC; rjt_exp = LSEXP_NOTHING_MORE; goto lsrjt; @@ -7381,6 +7350,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, rjt_exp = LSEXP_NOTHING_MORE; break; } + if (vport->port_state < LPFC_DISC_AUTH) { if (!(phba->pport->fc_flag & FC_PT2PT) || (phba->pport->fc_flag & FC_PT2PT_PLOGI)) { diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index bfc2442..c96532c 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -1083,7 +1083,7 @@ out: } -static void +void lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) { struct lpfc_vport *vport = pmb->vport; @@ -1113,8 +1113,10 @@ lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) /* Start discovery by sending a FLOGI. port_state is identically * LPFC_FLOGI while waiting for FLOGI cmpl */ - if (vport->port_state != LPFC_FLOGI || vport->fc_flag & FC_PT2PT_PLOGI) + if (vport->port_state != LPFC_FLOGI) lpfc_initial_flogi(vport); + else if (vport->fc_flag & FC_PT2PT) + lpfc_disc_start(vport); return; out: @@ -2963,8 +2965,10 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) out_free_mem: mempool_free(mboxq, phba->mbox_mem_pool); - lpfc_mbuf_free(phba, dmabuf->virt, dmabuf->phys); - kfree(dmabuf); + if (dmabuf) { + lpfc_mbuf_free(phba, dmabuf->virt, dmabuf->phys); + kfree(dmabuf); + } return; } diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index ed9a2c8..daeda6d 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -280,38 +280,12 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, uint32_t *lp; IOCB_t *icmd; struct serv_parm *sp; + uint32_t ed_tov; LPFC_MBOXQ_t *mbox; struct ls_rjt stat; int rc; memset(&stat, 0, sizeof (struct ls_rjt)); - if (vport->port_state <= LPFC_FDISC) { - /* Before responding to PLOGI, check for pt2pt mode. - * If we are pt2pt, with an outstanding FLOGI, abort - * the FLOGI and resend it first. - */ - if (vport->fc_flag & FC_PT2PT) { - lpfc_els_abort_flogi(phba); - if (!(vport->fc_flag & FC_PT2PT_PLOGI)) { - /* If the other side is supposed to initiate - * the PLOGI anyway, just ACC it now and - * move on with discovery. - */ - phba->fc_edtov = FF_DEF_EDTOV; - phba->fc_ratov = FF_DEF_RATOV; - /* Start discovery - this should just do - CLEAR_LA */ - lpfc_disc_start(vport); - } else - lpfc_initial_flogi(vport); - } else { - stat.un.b.lsRjtRsnCode = LSRJT_LOGICAL_BSY; - stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE; - lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, - ndlp, NULL); - return 0; - } - } pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; lp = (uint32_t *) pcmd->virt; sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); @@ -404,30 +378,46 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, /* Check for Nport to NPort pt2pt protocol */ if ((vport->fc_flag & FC_PT2PT) && !(vport->fc_flag & FC_PT2PT_PLOGI)) { - /* rcv'ed PLOGI decides what our NPortId will be */ vport->fc_myDID = icmd->un.rcvels.parmRo; - mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); - if (mbox == NULL) - goto out; - lpfc_config_link(phba, mbox); - mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; - mbox->vport = vport; - rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); - if (rc == MBX_NOT_FINISHED) { - mempool_free(mbox, phba->mbox_mem_pool); - goto out; + + ed_tov = be32_to_cpu(sp->cmn.e_d_tov); + if (sp->cmn.edtovResolution) { + /* E_D_TOV ticks are in nanoseconds */ + ed_tov = (phba->fc_edtov + 999999) / 1000000; } + /* - * For SLI4, the VFI/VPI are registered AFTER the - * Nport with the higher WWPN sends us a PLOGI with - * our assigned NPortId. + * For pt-to-pt, use the larger EDTOV + * RATOV = 2 * EDTOV */ + if (ed_tov > phba->fc_edtov) + phba->fc_edtov = ed_tov; + phba->fc_ratov = (2 * phba->fc_edtov) / 1000; + + memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm)); + + /* Issue config_link / reg_vfi to account for updated TOV's */ + if (phba->sli_rev == LPFC_SLI_REV4) lpfc_issue_reg_vfi(vport); + else { + mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); + if (mbox == NULL) + goto out; + lpfc_config_link(phba, mbox); + mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; + mbox->vport = vport; + rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); + if (rc == MBX_NOT_FINISHED) { + mempool_free(mbox, phba->mbox_mem_pool); + goto out; + } + } lpfc_can_disctmo(vport); } + mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!mbox) goto out; @@ -1038,7 +1028,9 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport, uint32_t *lp; IOCB_t *irsp; struct serv_parm *sp; + uint32_t ed_tov; LPFC_MBOXQ_t *mbox; + int rc; cmdiocb = (struct lpfc_iocbq *) arg; rspiocb = cmdiocb->context_un.rsp_iocb; @@ -1053,6 +1045,16 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport, if (irsp->ulpStatus) goto out; + mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); + if (!mbox) { + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "0133 PLOGI: no memory for reg_login " + "Data: x%x x%x x%x x%x\n", + ndlp->nlp_DID, ndlp->nlp_state, + ndlp->nlp_flag, ndlp->nlp_rpi); + goto out; + } + pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; prsp = list_get_first(&pcmd->list, struct lpfc_dmabuf, list); @@ -1094,14 +1096,38 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport, ndlp->nlp_maxframe = ((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | sp->cmn.bbRcvSizeLsb; - mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); - if (!mbox) { - lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, - "0133 PLOGI: no memory for reg_login " - "Data: x%x x%x x%x x%x\n", - ndlp->nlp_DID, ndlp->nlp_state, - ndlp->nlp_flag, ndlp->nlp_rpi); - goto out; + if ((vport->fc_flag & FC_PT2PT) && + (vport->fc_flag & FC_PT2PT_PLOGI)) { + ed_tov = be32_to_cpu(sp->cmn.e_d_tov); + if (sp->cmn.edtovResolution) { + /* E_D_TOV ticks are in nanoseconds */ + ed_tov = (phba->fc_edtov + 999999) / 1000000; + } + + /* + * Use the larger EDTOV + * RATOV = 2 * EDTOV for pt-to-pt + */ + if (ed_tov > phba->fc_edtov) + phba->fc_edtov = ed_tov; + phba->fc_ratov = (2 * phba->fc_edtov) / 1000; + + memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm)); + + /* Issue config_link / reg_vfi to account for updated TOV's */ + if (phba->sli_rev == LPFC_SLI_REV4) { + lpfc_issue_reg_vfi(vport); + } else { + lpfc_config_link(phba, mbox); + + mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; + mbox->vport = vport; + rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); + if (rc == MBX_NOT_FINISHED) { + mempool_free(mbox, phba->mbox_mem_pool); + goto out; + } + } } lpfc_unreg_rpi(vport, ndlp); -- cgit v0.10.2 From 4b7789b71c916f79a3366da080101014473234c3 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 16 Dec 2015 18:11:55 -0500 Subject: lpfc: Fix RegLogin failed error seen on Lancer FC during port bounce Fix RegLogin failed error seen on Lancer FC during port bounce Fix the statemachine and ref counting. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Reviewed-by: Hannes Reinicke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index f6dd15b..d508378 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -3779,14 +3779,17 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, lpfc_nlp_set_state(vport, ndlp, NLP_STE_REG_LOGIN_ISSUE); } + + ndlp->nlp_flag |= NLP_REG_LOGIN_SEND; if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT) != MBX_NOT_FINISHED) goto out; - else - /* Decrement the ndlp reference count we - * set for this failed mailbox command. - */ - lpfc_nlp_put(ndlp); + + /* Decrement the ndlp reference count we + * set for this failed mailbox command. + */ + lpfc_nlp_put(ndlp); + ndlp->nlp_flag &= ~NLP_REG_LOGIN_SEND; /* ELS rsp: Cannot issue reg_login for */ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, @@ -3843,6 +3846,7 @@ out: * the routine lpfc_els_free_iocb. */ cmdiocb->context1 = NULL; + } lpfc_els_free_iocb(phba, cmdiocb); diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index c96532c..d3668aa 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -3452,10 +3452,10 @@ lpfc_mbx_cmpl_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) spin_lock_irq(shost->host_lock); ndlp->nlp_flag &= ~NLP_IGNR_REG_CMPL; spin_unlock_irq(shost->host_lock); - } else - /* Good status, call state machine */ - lpfc_disc_state_machine(vport, ndlp, pmb, - NLP_EVT_CMPL_REG_LOGIN); + } + + /* Call state machine */ + lpfc_disc_state_machine(vport, ndlp, pmb, NLP_EVT_CMPL_REG_LOGIN); lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index daeda6d..9e571dd 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -2325,6 +2325,9 @@ lpfc_cmpl_reglogin_npr_node(struct lpfc_vport *vport, if (vport->phba->sli_rev < LPFC_SLI_REV4) ndlp->nlp_rpi = mb->un.varWords[0]; ndlp->nlp_flag |= NLP_RPI_REGISTERED; + if (ndlp->nlp_flag & NLP_LOGO_ACC) { + lpfc_unreg_rpi(vport, ndlp); + } } else { if (ndlp->nlp_flag & NLP_NODEV_REMOVE) { lpfc_drop_node(vport, ndlp); -- cgit v0.10.2 From 6690e0d4fc5cccf74534abe0c9f9a69032bc02f0 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 16 Dec 2015 18:11:56 -0500 Subject: lpfc: Fix driver crash when module parameter lpfc_fcp_io_channel set to 16 Fix driver crash when module parameter lpfc_fcp_io_channel set to 16 Signed-off-by: Dick Kennedy Signed-off-by: James Smart Reviewed-by: Hannes Reinicke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index db9446c..5915407 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -8833,9 +8833,12 @@ found: * already mapped to this phys_id. */ if (cpup->irq != LPFC_VECTOR_MAP_EMPTY) { - chann[saved_chann] = - cpup->channel_id; - saved_chann++; + if (saved_chann <= + LPFC_FCP_IO_CHAN_MAX) { + chann[saved_chann] = + cpup->channel_id; + saved_chann++; + } goto out; } -- cgit v0.10.2 From c90261dcd86e4eb5c9c1627fde037e902db8aefa Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 16 Dec 2015 18:11:57 -0500 Subject: lpfc: Fix crash in fcp command completion path. Fix crash in fcp command completion path. Missed null check. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Reviewed-by: Hannes Reinicke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 4679ed4..ab446f8 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -3908,9 +3908,9 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, uint32_t logit = LOG_FCP; /* Sanity check on return of outstanding command */ - if (!(lpfc_cmd->pCmd)) - return; cmd = lpfc_cmd->pCmd; + if (!cmd) + return; shost = cmd->device->host; lpfc_cmd->result = (pIocbOut->iocb.un.ulpWord[4] & IOERR_PARAM_MASK); -- cgit v0.10.2 From 4258e98ee3862ca7036654b43c839ab7668043e0 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 16 Dec 2015 18:11:58 -0500 Subject: lpfc: Modularize and cleanup FDMI code in driver Modularize, cleanup, add comments - for FDMI code in driver Note: I don't like the comments with leading # - but as we have a lot if present, I'm deferring to handle it in one big fix later. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Reviewed-by: Hannes Reinicke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index ceee9a3..90a3ca5 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -386,7 +386,6 @@ struct lpfc_vport { uint32_t work_port_events; /* Timeout to be handled */ #define WORKER_DISC_TMO 0x1 /* vport: Discovery timeout */ #define WORKER_ELS_TMO 0x2 /* vport: ELS timeout */ -#define WORKER_FDMI_TMO 0x4 /* vport: FDMI timeout */ #define WORKER_DELAYED_DISC_TMO 0x8 /* vport: delayed discovery */ #define WORKER_MBOX_TMO 0x100 /* hba: MBOX timeout */ @@ -396,7 +395,6 @@ struct lpfc_vport { #define WORKER_RAMP_UP_QUEUE 0x1000 /* hba: Increase Q depth */ #define WORKER_SERVICE_TXQ 0x2000 /* hba: IOCBs on the txq */ - struct timer_list fc_fdmitmo; struct timer_list els_tmofunc; struct timer_list delayed_disc_tmo; @@ -405,6 +403,7 @@ struct lpfc_vport { uint8_t load_flag; #define FC_LOADING 0x1 /* HBA in process of loading drvr */ #define FC_UNLOADING 0x2 /* HBA in process of unloading drvr */ +#define FC_ALLOW_FDMI 0x4 /* port is ready for FDMI requests */ /* Vport Config Parameters */ uint32_t cfg_scan_down; uint32_t cfg_lun_queue_depth; @@ -414,10 +413,6 @@ struct lpfc_vport { uint32_t cfg_peer_port_login; uint32_t cfg_fcp_class; uint32_t cfg_use_adisc; - uint32_t cfg_fdmi_on; -#define LPFC_FDMI_SUPPORT 1 /* bit 0 - FDMI supported? */ -#define LPFC_FDMI_REG_DELAY 2 /* bit 1 - 60 sec registration delay */ -#define LPFC_FDMI_ALL_ATTRIB 4 /* bit 2 - register ALL attributes? */ uint32_t cfg_discovery_threads; uint32_t cfg_log_verbose; uint32_t cfg_max_luns; @@ -443,6 +438,10 @@ struct lpfc_vport { unsigned long rcv_buffer_time_stamp; uint32_t vport_flag; #define STATIC_VPORT 1 + + uint16_t fdmi_num_disc; + uint32_t fdmi_hba_mask; + uint32_t fdmi_port_mask; }; struct hbq_s { @@ -755,6 +754,11 @@ struct lpfc_hba { #define LPFC_DELAY_INIT_LINK 1 /* layered driver hold off */ #define LPFC_DELAY_INIT_LINK_INDEFINITELY 2 /* wait, manual intervention */ uint32_t cfg_enable_dss; + uint32_t cfg_fdmi_on; +#define LPFC_FDMI_NO_SUPPORT 0 /* FDMI not supported */ +#define LPFC_FDMI_SUPPORT 1 /* FDMI supported? */ +#define LPFC_FDMI_SMART_SAN 2 /* SmartSAN supported */ + uint32_t cfg_enable_SmartSAN; lpfc_vpd_t vpd; /* vital product data */ struct pci_dev *pcidev; diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index f6446d7..5739c26 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -4572,19 +4572,27 @@ LPFC_ATTR_R(multi_ring_type, FC_TYPE_IP, 1, 255, "Identifies TYPE for additional ring configuration"); /* -# lpfc_fdmi_on: controls FDMI support. -# Set NOT Set -# bit 0 = FDMI support no FDMI support -# LPFC_FDMI_SUPPORT just turns basic support on/off -# bit 1 = Register delay no register delay (60 seconds) -# LPFC_FDMI_REG_DELAY 60 sec registration delay after FDMI login -# bit 2 = All attributes Use a attribute subset -# LPFC_FDMI_ALL_ATTRIB applies to both port and HBA attributes -# Port attrutes subset: 1 thru 6 OR all: 1 thru 0xd 0x101 0x102 0x103 -# HBA attributes subset: 1 thru 0xb OR all: 1 thru 0xc -# Value range [0,7]. Default value is 0. +# lpfc_enable_SmartSAN: Sets up FDMI support for SmartSAN +# 0 = SmartSAN functionality disabled (default) +# 1 = SmartSAN functionality enabled +# This parameter will override the value of lpfc_fdmi_on module parameter. +# Value range is [0,1]. Default value is 0. */ -LPFC_VPORT_ATTR_RW(fdmi_on, 0, 0, 7, "Enable FDMI support"); +LPFC_ATTR_R(enable_SmartSAN, 0, 0, 1, "Enable SmartSAN functionality"); + +/* +# lpfc_fdmi_on: Controls FDMI support. +# 0 No FDMI support (default) +# 1 Traditional FDMI support +# 2 Smart SAN support +# If lpfc_enable_SmartSAN is set 1, the driver sets lpfc_fdmi_on to value 2 +# overwriting the current value. If lpfc_enable_SmartSAN is set 0, the +# driver uses the current value of lpfc_fdmi_on provided it has value 0 or 1. +# A value of 2 with lpfc_enable_SmartSAN set to 0 causes the driver to +# set lpfc_fdmi_on back to 1. +# Value range [0,2]. Default value is 0. +*/ +LPFC_ATTR_R(fdmi_on, 0, 0, 2, "Enable FDMI support"); /* # Specifies the maximum number of ELS cmds we can have outstanding (for @@ -4815,6 +4823,7 @@ struct device_attribute *lpfc_hba_attrs[] = { &dev_attr_lpfc_multi_ring_rctl, &dev_attr_lpfc_multi_ring_type, &dev_attr_lpfc_fdmi_on, + &dev_attr_lpfc_enable_SmartSAN, &dev_attr_lpfc_max_luns, &dev_attr_lpfc_enable_npiv, &dev_attr_lpfc_fcf_failover_policy, @@ -4887,7 +4896,6 @@ struct device_attribute *lpfc_vport_attrs[] = { &dev_attr_lpfc_fcp_class, &dev_attr_lpfc_use_adisc, &dev_attr_lpfc_first_burst_size, - &dev_attr_lpfc_fdmi_on, &dev_attr_lpfc_max_luns, &dev_attr_nport_evt_cnt, &dev_attr_npiv_info, @@ -5826,6 +5834,8 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) lpfc_enable_npiv_init(phba, lpfc_enable_npiv); lpfc_fcf_failover_policy_init(phba, lpfc_fcf_failover_policy); lpfc_enable_rrq_init(phba, lpfc_enable_rrq); + lpfc_fdmi_on_init(phba, lpfc_fdmi_on); + lpfc_enable_SmartSAN_init(phba, lpfc_enable_SmartSAN); lpfc_use_msi_init(phba, lpfc_use_msi); lpfc_fcp_imax_init(phba, lpfc_fcp_imax); lpfc_fcp_cpu_map_init(phba, lpfc_fcp_cpu_map); @@ -5846,6 +5856,15 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) phba->cfg_poll = 0; else phba->cfg_poll = lpfc_poll; + + /* Ensure fdmi_on and enable_SmartSAN don't conflict */ + if (phba->cfg_enable_SmartSAN) { + phba->cfg_fdmi_on = LPFC_FDMI_SMART_SAN; + } else { + if (phba->cfg_fdmi_on == LPFC_FDMI_SMART_SAN) + phba->cfg_fdmi_on = LPFC_FDMI_SUPPORT; + } + phba->cfg_soft_wwnn = 0L; phba->cfg_soft_wwpn = 0L; lpfc_sg_seg_cnt_init(phba, lpfc_sg_seg_cnt); @@ -5879,7 +5898,6 @@ lpfc_get_vport_cfgparam(struct lpfc_vport *vport) lpfc_use_adisc_init(vport, lpfc_use_adisc); lpfc_first_burst_size_init(vport, lpfc_first_burst_size); lpfc_max_scsicmpl_time_init(vport, lpfc_max_scsicmpl_time); - lpfc_fdmi_on_init(vport, lpfc_fdmi_on); lpfc_discovery_threads_init(vport, lpfc_discovery_threads); lpfc_max_luns_init(vport, lpfc_max_luns); lpfc_scan_down_init(vport, lpfc_scan_down); diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 80d3c74..4e55b35 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -168,9 +168,8 @@ void lpfc_ct_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *, struct lpfc_iocbq *); int lpfc_ct_handle_unsol_abort(struct lpfc_hba *, struct hbq_dmabuf *); int lpfc_ns_cmd(struct lpfc_vport *, int, uint8_t, uint32_t); -int lpfc_fdmi_cmd(struct lpfc_vport *, struct lpfc_nodelist *, int); -void lpfc_fdmi_tmo(unsigned long); -void lpfc_fdmi_timeout_handler(struct lpfc_vport *); +int lpfc_fdmi_cmd(struct lpfc_vport *, struct lpfc_nodelist *, int, uint32_t); +void lpfc_fdmi_num_disc_check(struct lpfc_vport *); void lpfc_delayed_disc_tmo(unsigned long); void lpfc_delayed_disc_timeout_handler(struct lpfc_vport *); diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 8fded1f..ac6e087 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -287,6 +287,17 @@ lpfc_ct_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *ctiocb) return 0; } +/** + * lpfc_gen_req - Build and issue a GEN_REQUEST command to the SLI Layer + * @vport: pointer to a host virtual N_Port data structure. + * @bmp: Pointer to BPL for SLI command + * @inp: Pointer to data buffer for response data. + * @outp: Pointer to data buffer that hold the CT command. + * @cmpl: completion routine to call when command completes + * @ndlp: Destination NPort nodelist entry + * + * This function as the final part for issuing a CT command. + */ static int lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp, struct lpfc_dmabuf *inp, struct lpfc_dmabuf *outp, @@ -311,7 +322,7 @@ lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp, icmd->un.genreq64.bdl.addrHigh = putPaddrHigh(bmp->phys); icmd->un.genreq64.bdl.addrLow = putPaddrLow(bmp->phys); icmd->un.genreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64; - icmd->un.genreq64.bdl.bdeSize = (num_entry * sizeof (struct ulp_bde64)); + icmd->un.genreq64.bdl.bdeSize = (num_entry * sizeof(struct ulp_bde64)); if (usr_flg) geniocb->context3 = NULL; @@ -370,6 +381,16 @@ lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp, return 0; } +/** + * lpfc_ct_cmd - Build and issue a CT command + * @vport: pointer to a host virtual N_Port data structure. + * @inmp: Pointer to data buffer for response data. + * @bmp: Pointer to BPL for SLI command + * @ndlp: Destination NPort nodelist entry + * @cmpl: completion routine to call when command completes + * + * This function is called for issuing a CT command. + */ static int lpfc_ct_cmd(struct lpfc_vport *vport, struct lpfc_dmabuf *inmp, struct lpfc_dmabuf *bmp, struct lpfc_nodelist *ndlp, @@ -453,7 +474,7 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size) Cnt -= 16; /* subtract length of CT header */ /* Loop through entire NameServer list of DIDs */ - while (Cnt >= sizeof (uint32_t)) { + while (Cnt >= sizeof(uint32_t)) { /* Get next DID from NameServer List */ CTentry = *ctptr++; Did = ((be32_to_cpu(CTentry)) & Mask_DID); @@ -558,7 +579,7 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size) } if (CTentry & (cpu_to_be32(SLI_CT_LAST_ENTRY))) goto nsout1; - Cnt -= sizeof (uint32_t); + Cnt -= sizeof(uint32_t); } ctptr = NULL; @@ -1146,7 +1167,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, /* fill in BDEs for command */ /* Allocate buffer for command payload */ - mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL); + mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); if (!mp) { rc=2; goto ns_cmd_exit; @@ -1160,7 +1181,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, } /* Allocate buffer for Buffer ptr list */ - bmp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL); + bmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); if (!bmp) { rc=4; goto ns_cmd_free_mpvirt; @@ -1204,7 +1225,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, bpl->tus.w = le32_to_cpu(bpl->tus.w); CtReq = (struct lpfc_sli_ct_request *) mp->virt; - memset(CtReq, 0, sizeof (struct lpfc_sli_ct_request)); + memset(CtReq, 0, sizeof(struct lpfc_sli_ct_request)); CtReq->RevisionId.bits.Revision = SLI_CT_REVISION; CtReq->RevisionId.bits.InId = 0; CtReq->FsType = SLI_CT_DIRECTORY_SERVICE; @@ -1244,7 +1265,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, cpu_to_be16(SLI_CTNS_RNN_ID); CtReq->un.rnn.PortId = cpu_to_be32(vport->fc_myDID); memcpy(CtReq->un.rnn.wwnn, &vport->fc_nodename, - sizeof (struct lpfc_name)); + sizeof(struct lpfc_name)); cmpl = lpfc_cmpl_ct_cmd_rnn_id; break; @@ -1264,7 +1285,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, CtReq->CommandResponse.bits.CmdRsp = cpu_to_be16(SLI_CTNS_RSNN_NN); memcpy(CtReq->un.rsnn.wwnn, &vport->fc_nodename, - sizeof (struct lpfc_name)); + sizeof(struct lpfc_name)); size = sizeof(CtReq->un.rsnn.symbname); CtReq->un.rsnn.len = lpfc_vport_symbolic_node_name(vport, @@ -1319,20 +1340,29 @@ ns_cmd_exit: return 1; } +/** + * lpfc_cmpl_ct_disc_fdmi - Handle a discovery FDMI completion + * @phba: Pointer to HBA context object. + * @cmdiocb: Pointer to the command IOCBQ. + * @rspiocb: Pointer to the response IOCBQ. + * + * This function to handle the completion of a driver initiated FDMI + * CT command issued during discovery. + */ static void -lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, - struct lpfc_iocbq * rspiocb) +lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, + struct lpfc_iocbq *rspiocb) { + struct lpfc_vport *vport = cmdiocb->vport; struct lpfc_dmabuf *inp = cmdiocb->context1; struct lpfc_dmabuf *outp = cmdiocb->context2; - struct lpfc_sli_ct_request *CTrsp = outp->virt; struct lpfc_sli_ct_request *CTcmd = inp->virt; - struct lpfc_nodelist *ndlp; + struct lpfc_sli_ct_request *CTrsp = outp->virt; uint16_t fdmi_cmd = CTcmd->CommandResponse.bits.CmdRsp; uint16_t fdmi_rsp = CTrsp->CommandResponse.bits.CmdRsp; - struct lpfc_vport *vport = cmdiocb->vport; IOCB_t *irsp = &rspiocb->iocb; - uint32_t latt; + struct lpfc_nodelist *ndlp; + uint32_t latt, cmd, err; latt = lpfc_els_chk_latt(vport); lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT, @@ -1340,91 +1370,1076 @@ lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, irsp->ulpStatus, irsp->un.ulpWord[4], latt); if (latt || irsp->ulpStatus) { + + /* Look for a retryable error */ + if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) { + switch ((irsp->un.ulpWord[4] & IOERR_PARAM_MASK)) { + case IOERR_SLI_ABORTED: + case IOERR_ABORT_IN_PROGRESS: + case IOERR_SEQUENCE_TIMEOUT: + case IOERR_ILLEGAL_FRAME: + case IOERR_NO_RESOURCES: + case IOERR_ILLEGAL_COMMAND: + cmdiocb->retry++; + if (cmdiocb->retry >= LPFC_FDMI_MAX_RETRY) + break; + + /* Retry the same FDMI command */ + err = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, + cmdiocb, 0); + if (err == IOCB_ERROR) + break; + return; + default: + break; + } + } + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, "0229 FDMI cmd %04x failed, latt = %d " "ulpStatus: x%x, rid x%x\n", be16_to_cpu(fdmi_cmd), latt, irsp->ulpStatus, irsp->un.ulpWord[4]); - goto fail_out; } + lpfc_ct_free_iocb(phba, cmdiocb); ndlp = lpfc_findnode_did(vport, FDMI_DID); if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) - goto fail_out; + return; + /* Check for a CT LS_RJT response */ + cmd = be16_to_cpu(fdmi_cmd); if (fdmi_rsp == cpu_to_be16(SLI_CT_RESPONSE_FS_RJT)) { /* FDMI rsp failed */ lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, - "0220 FDMI rsp failed Data: x%x\n", - be16_to_cpu(fdmi_cmd)); + "0220 FDMI cmd failed FS_RJT Data: x%x", cmd); + + /* Should we fallback to FDMI-2 / FDMI-1 ? */ + switch (cmd) { + case SLI_MGMT_RHBA: + if (vport->fdmi_hba_mask == LPFC_FDMI2_HBA_ATTR) { + /* Fallback to FDMI-1 */ + vport->fdmi_hba_mask = LPFC_FDMI1_HBA_ATTR; + vport->fdmi_port_mask = LPFC_FDMI1_PORT_ATTR; + /* Start over */ + lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA, 0); + } + return; + + case SLI_MGMT_RPRT: + if (vport->fdmi_port_mask == LPFC_FDMI2_PORT_ATTR) { + /* Fallback to FDMI-1 */ + vport->fdmi_port_mask = LPFC_FDMI1_PORT_ATTR; + /* Start over */ + lpfc_fdmi_cmd(vport, ndlp, cmd, 0); + } + if (vport->fdmi_port_mask == LPFC_FDMI2_SMART_ATTR) { + vport->fdmi_port_mask = LPFC_FDMI2_PORT_ATTR; + /* Retry the same command */ + lpfc_fdmi_cmd(vport, ndlp, cmd, 0); + } + return; + + case SLI_MGMT_RPA: + if (vport->fdmi_port_mask == LPFC_FDMI2_PORT_ATTR) { + /* Fallback to FDMI-1 */ + vport->fdmi_hba_mask = LPFC_FDMI1_HBA_ATTR; + vport->fdmi_port_mask = LPFC_FDMI1_PORT_ATTR; + /* Start over */ + lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA, 0); + } + if (vport->fdmi_port_mask == LPFC_FDMI2_SMART_ATTR) { + vport->fdmi_port_mask = LPFC_FDMI2_PORT_ATTR; + /* Retry the same command */ + lpfc_fdmi_cmd(vport, ndlp, cmd, 0); + } + return; + } } -fail_out: - lpfc_ct_free_iocb(phba, cmdiocb); + /* + * On success, need to cycle thru FDMI registration for discovery + * DHBA -> DPRT -> RHBA -> RPA (physical port) + * DPRT -> RPRT (vports) + */ + switch (cmd) { + case SLI_MGMT_RHBA: + lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPA, 0); + break; + + case SLI_MGMT_DHBA: + lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DPRT, 0); + break; + + case SLI_MGMT_DPRT: + if (vport->port_type == LPFC_PHYSICAL_PORT) + lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RHBA, 0); + else + lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPRT, 0); + break; + } + return; } -static void -lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, - struct lpfc_iocbq *rspiocb) + +/** + * lpfc_fdmi_num_disc_check - Check how many mapped NPorts we are connected to + * @vport: pointer to a host virtual N_Port data structure. + * + * Called from hbeat timeout routine to check if the number of discovered + * ports has changed. If so, re-register thar port Attribute. + */ +void +lpfc_fdmi_num_disc_check(struct lpfc_vport *vport) { - struct lpfc_vport *vport = cmdiocb->vport; - struct lpfc_dmabuf *inp = cmdiocb->context1; - struct lpfc_sli_ct_request *CTcmd = inp->virt; - uint16_t fdmi_cmd = CTcmd->CommandResponse.bits.CmdRsp; + struct lpfc_hba *phba = vport->phba; struct lpfc_nodelist *ndlp; + uint16_t cnt; - lpfc_cmpl_ct_cmd_fdmi(phba, cmdiocb, rspiocb); + if (!lpfc_is_link_up(phba)) + return; + + if (!(vport->fdmi_port_mask & LPFC_FDMI_PORT_ATTR_num_disc)) + return; + + cnt = lpfc_find_map_node(vport); + if (cnt == vport->fdmi_num_disc) + return; ndlp = lpfc_findnode_did(vport, FDMI_DID); if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) return; - /* - * Need to cycle thru FDMI registration for discovery - * DHBA -> DPRT -> RHBA -> RPA - */ - switch (be16_to_cpu(fdmi_cmd)) { - case SLI_MGMT_RHBA: - lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPA); - break; + if (vport->port_type == LPFC_PHYSICAL_PORT) { + lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPA, + LPFC_FDMI_PORT_ATTR_num_disc); + } else { + lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPRT, + LPFC_FDMI_PORT_ATTR_num_disc); + } +} - case SLI_MGMT_DHBA: - lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DPRT); - break; +/* Routines for all individual HBA attributes */ +int +lpfc_fdmi_hba_attr_wwnn(struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; - case SLI_MGMT_DPRT: - lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RHBA); + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, sizeof(struct lpfc_name)); + + memcpy(&ae->un.AttrWWN, &vport->fc_sparam.nodeName, + sizeof(struct lpfc_name)); + size = FOURBYTES + sizeof(struct lpfc_name); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_NODENAME); + return size; +} +int +lpfc_fdmi_hba_attr_manufacturer(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t len, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + strncpy(ae->un.AttrString, + "Emulex Corporation", + sizeof(ae->un.AttrString)); + len = strnlen(ae->un.AttrString, + sizeof(ae->un.AttrString)); + len += (len & 3) ? (4 - (len & 3)) : 4; + size = FOURBYTES + len; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_MANUFACTURER); + return size; +} + +int +lpfc_fdmi_hba_attr_sn(struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_hba *phba = vport->phba; + struct lpfc_fdmi_attr_entry *ae; + uint32_t len, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + strncpy(ae->un.AttrString, phba->SerialNumber, + sizeof(ae->un.AttrString)); + len = strnlen(ae->un.AttrString, + sizeof(ae->un.AttrString)); + len += (len & 3) ? (4 - (len & 3)) : 4; + size = FOURBYTES + len; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_SERIAL_NUMBER); + return size; +} + +int +lpfc_fdmi_hba_attr_model(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_hba *phba = vport->phba; + struct lpfc_fdmi_attr_entry *ae; + uint32_t len, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + strncpy(ae->un.AttrString, phba->ModelName, + sizeof(ae->un.AttrString)); + len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString)); + len += (len & 3) ? (4 - (len & 3)) : 4; + size = FOURBYTES + len; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_MODEL); + return size; +} + +int +lpfc_fdmi_hba_attr_description(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_hba *phba = vport->phba; + struct lpfc_fdmi_attr_entry *ae; + uint32_t len, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + strncpy(ae->un.AttrString, phba->ModelDesc, + sizeof(ae->un.AttrString)); + len = strnlen(ae->un.AttrString, + sizeof(ae->un.AttrString)); + len += (len & 3) ? (4 - (len & 3)) : 4; + size = FOURBYTES + len; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_MODEL_DESCRIPTION); + return size; +} + +int +lpfc_fdmi_hba_attr_hdw_ver(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_hba *phba = vport->phba; + lpfc_vpd_t *vp = &phba->vpd; + struct lpfc_fdmi_attr_entry *ae; + uint32_t i, j, incr, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + /* Convert JEDEC ID to ascii for hardware version */ + incr = vp->rev.biuRev; + for (i = 0; i < 8; i++) { + j = (incr & 0xf); + if (j <= 9) + ae->un.AttrString[7 - i] = + (char)((uint8_t) 0x30 + + (uint8_t) j); + else + ae->un.AttrString[7 - i] = + (char)((uint8_t) 0x61 + + (uint8_t) (j - 10)); + incr = (incr >> 4); + } + size = FOURBYTES + 8; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_HARDWARE_VERSION); + return size; +} + +int +lpfc_fdmi_hba_attr_drvr_ver(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t len, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + strncpy(ae->un.AttrString, lpfc_release_version, + sizeof(ae->un.AttrString)); + len = strnlen(ae->un.AttrString, + sizeof(ae->un.AttrString)); + len += (len & 3) ? (4 - (len & 3)) : 4; + size = FOURBYTES + len; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_DRIVER_VERSION); + return size; +} + +int +lpfc_fdmi_hba_attr_rom_ver(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_hba *phba = vport->phba; + struct lpfc_fdmi_attr_entry *ae; + uint32_t len, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + if (phba->sli_rev == LPFC_SLI_REV4) + lpfc_decode_firmware_rev(phba, ae->un.AttrString, 1); + else + strncpy(ae->un.AttrString, phba->OptionROMVersion, + sizeof(ae->un.AttrString)); + len = strnlen(ae->un.AttrString, + sizeof(ae->un.AttrString)); + len += (len & 3) ? (4 - (len & 3)) : 4; + size = FOURBYTES + len; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_OPTION_ROM_VERSION); + return size; +} + +int +lpfc_fdmi_hba_attr_fmw_ver(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_hba *phba = vport->phba; + struct lpfc_fdmi_attr_entry *ae; + uint32_t len, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + lpfc_decode_firmware_rev(phba, ae->un.AttrString, 1); + len = strnlen(ae->un.AttrString, + sizeof(ae->un.AttrString)); + len += (len & 3) ? (4 - (len & 3)) : 4; + size = FOURBYTES + len; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_FIRMWARE_VERSION); + return size; +} + +int +lpfc_fdmi_hba_attr_os_ver(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t len, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + snprintf(ae->un.AttrString, sizeof(ae->un.AttrString), "%s %s %s", + init_utsname()->sysname, + init_utsname()->release, + init_utsname()->version); + + len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString)); + len += (len & 3) ? (4 - (len & 3)) : 4; + size = FOURBYTES + len; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_OS_NAME_VERSION); + return size; +} + +int +lpfc_fdmi_hba_attr_ct_len(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + + ae->un.AttrInt = cpu_to_be32(LPFC_MAX_CT_SIZE); + size = FOURBYTES + sizeof(uint32_t); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_MAX_CT_PAYLOAD_LEN); + return size; +} + +int +lpfc_fdmi_hba_attr_symbolic_name(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t len, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + len = lpfc_vport_symbolic_node_name(vport, + ae->un.AttrString, 256); + len += (len & 3) ? (4 - (len & 3)) : 4; + size = FOURBYTES + len; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_SYM_NODENAME); + return size; +} + +int +lpfc_fdmi_hba_attr_vendor_info(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + + /* Nothing is defined for this currently */ + ae->un.AttrInt = cpu_to_be32(0); + size = FOURBYTES + sizeof(uint32_t); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_VENDOR_INFO); + return size; +} + +int +lpfc_fdmi_hba_attr_num_ports(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + + /* Each driver instance corresponds to a single port */ + ae->un.AttrInt = cpu_to_be32(1); + size = FOURBYTES + sizeof(uint32_t); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_NUM_PORTS); + return size; +} + +int +lpfc_fdmi_hba_attr_fabric_wwnn(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, sizeof(struct lpfc_name)); + + memcpy(&ae->un.AttrWWN, &vport->fabric_nodename, + sizeof(struct lpfc_name)); + size = FOURBYTES + sizeof(struct lpfc_name); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_FABRIC_WWNN); + return size; +} + +int +lpfc_fdmi_hba_attr_bios_ver(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_hba *phba = vport->phba; + struct lpfc_fdmi_attr_entry *ae; + uint32_t len, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + lpfc_decode_firmware_rev(phba, ae->un.AttrString, 1); + len = strnlen(ae->un.AttrString, + sizeof(ae->un.AttrString)); + len += (len & 3) ? (4 - (len & 3)) : 4; + size = FOURBYTES + len; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_BIOS_VERSION); + return size; +} + +int +lpfc_fdmi_hba_attr_bios_state(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + + /* Driver doesn't have access to this information */ + ae->un.AttrInt = cpu_to_be32(0); + size = FOURBYTES + sizeof(uint32_t); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_BIOS_STATE); + return size; +} + +int +lpfc_fdmi_hba_attr_vendor_id(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t len, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + strncpy(ae->un.AttrString, "EMULEX", + sizeof(ae->un.AttrString)); + len = strnlen(ae->un.AttrString, + sizeof(ae->un.AttrString)); + len += (len & 3) ? (4 - (len & 3)) : 4; + size = FOURBYTES + len; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RHBA_VENDOR_ID); + return size; +} + +/* Routines for all individual PORT attributes */ +int +lpfc_fdmi_port_attr_fc4type(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 32); + + ae->un.AttrTypes[3] = 0x02; /* Type 1 - ELS */ + ae->un.AttrTypes[2] = 0x01; /* Type 8 - FCP */ + ae->un.AttrTypes[7] = 0x01; /* Type 32 - CT */ + size = FOURBYTES + 32; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_FC4_TYPES); + return size; +} + +int +lpfc_fdmi_port_attr_support_speed(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_hba *phba = vport->phba; + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + + ae->un.AttrInt = 0; + if (phba->lmt & LMT_32Gb) + ae->un.AttrInt |= HBA_PORTSPEED_32GBIT; + if (phba->lmt & LMT_16Gb) + ae->un.AttrInt |= HBA_PORTSPEED_16GBIT; + if (phba->lmt & LMT_10Gb) + ae->un.AttrInt |= HBA_PORTSPEED_10GBIT; + if (phba->lmt & LMT_8Gb) + ae->un.AttrInt |= HBA_PORTSPEED_8GBIT; + if (phba->lmt & LMT_4Gb) + ae->un.AttrInt |= HBA_PORTSPEED_4GBIT; + if (phba->lmt & LMT_2Gb) + ae->un.AttrInt |= HBA_PORTSPEED_2GBIT; + if (phba->lmt & LMT_1Gb) + ae->un.AttrInt |= HBA_PORTSPEED_1GBIT; + ae->un.AttrInt = cpu_to_be32(ae->un.AttrInt); + size = FOURBYTES + sizeof(uint32_t); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_SPEED); + return size; +} + +int +lpfc_fdmi_port_attr_speed(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_hba *phba = vport->phba; + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + + switch (phba->fc_linkspeed) { + case LPFC_LINK_SPEED_1GHZ: + ae->un.AttrInt = HBA_PORTSPEED_1GBIT; + break; + case LPFC_LINK_SPEED_2GHZ: + ae->un.AttrInt = HBA_PORTSPEED_2GBIT; + break; + case LPFC_LINK_SPEED_4GHZ: + ae->un.AttrInt = HBA_PORTSPEED_4GBIT; + break; + case LPFC_LINK_SPEED_8GHZ: + ae->un.AttrInt = HBA_PORTSPEED_8GBIT; + break; + case LPFC_LINK_SPEED_10GHZ: + ae->un.AttrInt = HBA_PORTSPEED_10GBIT; + break; + case LPFC_LINK_SPEED_16GHZ: + ae->un.AttrInt = HBA_PORTSPEED_16GBIT; + break; + case LPFC_LINK_SPEED_32GHZ: + ae->un.AttrInt = HBA_PORTSPEED_32GBIT; + break; + default: + ae->un.AttrInt = HBA_PORTSPEED_UNKNOWN; break; } + ae->un.AttrInt = cpu_to_be32(ae->un.AttrInt); + size = FOURBYTES + sizeof(uint32_t); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_PORT_SPEED); + return size; +} + +int +lpfc_fdmi_port_attr_max_frame(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct serv_parm *hsp; + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + + hsp = (struct serv_parm *)&vport->fc_sparam; + ae->un.AttrInt = (((uint32_t) hsp->cmn.bbRcvSizeMsb) << 8) | + (uint32_t) hsp->cmn.bbRcvSizeLsb; + ae->un.AttrInt = cpu_to_be32(ae->un.AttrInt); + size = FOURBYTES + sizeof(uint32_t); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_MAX_FRAME_SIZE); + return size; +} + +int +lpfc_fdmi_port_attr_os_devname(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct Scsi_Host *shost = lpfc_shost_from_vport(vport); + struct lpfc_fdmi_attr_entry *ae; + uint32_t len, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + snprintf(ae->un.AttrString, sizeof(ae->un.AttrString), + "/sys/class/scsi_host/host%d", shost->host_no); + len = strnlen((char *)ae->un.AttrString, + sizeof(ae->un.AttrString)); + len += (len & 3) ? (4 - (len & 3)) : 4; + size = FOURBYTES + len; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_OS_DEVICE_NAME); + return size; +} + +int +lpfc_fdmi_port_attr_host_name(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t len, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + snprintf(ae->un.AttrString, sizeof(ae->un.AttrString), "%s", + init_utsname()->nodename); + + len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString)); + len += (len & 3) ? (4 - (len & 3)) : 4; + size = FOURBYTES + len; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_HOST_NAME); + return size; +} + +int +lpfc_fdmi_port_attr_wwnn(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, sizeof(struct lpfc_name)); + + memcpy(&ae->un.AttrWWN, &vport->fc_sparam.nodeName, + sizeof(struct lpfc_name)); + size = FOURBYTES + sizeof(struct lpfc_name); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_NODENAME); + return size; +} + +int +lpfc_fdmi_port_attr_wwpn(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, sizeof(struct lpfc_name)); + + memcpy(&ae->un.AttrWWN, &vport->fc_sparam.portName, + sizeof(struct lpfc_name)); + size = FOURBYTES + sizeof(struct lpfc_name); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_PORTNAME); + return size; +} + +int +lpfc_fdmi_port_attr_symbolic_name(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t len, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + len = lpfc_vport_symbolic_port_name(vport, ae->un.AttrString, 256); + len += (len & 3) ? (4 - (len & 3)) : 4; + size = FOURBYTES + len; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_SYM_PORTNAME); + return size; +} + +int +lpfc_fdmi_port_attr_port_type(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_hba *phba = vport->phba; + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) + ae->un.AttrInt = cpu_to_be32(LPFC_FDMI_PORTTYPE_NLPORT); + else + ae->un.AttrInt = cpu_to_be32(LPFC_FDMI_PORTTYPE_NPORT); + size = FOURBYTES + sizeof(uint32_t); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_PORT_TYPE); + return size; +} + +int +lpfc_fdmi_port_attr_class(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + ae->un.AttrInt = cpu_to_be32(FC_COS_CLASS2 | FC_COS_CLASS3); + size = FOURBYTES + sizeof(uint32_t); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_CLASS); + return size; +} + +int +lpfc_fdmi_port_attr_fabric_wwpn(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, sizeof(struct lpfc_name)); + + memcpy(&ae->un.AttrWWN, &vport->fabric_portname, + sizeof(struct lpfc_name)); + size = FOURBYTES + sizeof(struct lpfc_name); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_FABRICNAME); + return size; +} + +int +lpfc_fdmi_port_attr_active_fc4type(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 32); + + ae->un.AttrTypes[3] = 0x02; /* Type 1 - ELS */ + ae->un.AttrTypes[2] = 0x01; /* Type 8 - FCP */ + ae->un.AttrTypes[7] = 0x01; /* Type 32 - CT */ + size = FOURBYTES + 32; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_ACTIVE_FC4_TYPES); + return size; +} + +int +lpfc_fdmi_port_attr_port_state(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + /* Link Up - operational */ + ae->un.AttrInt = cpu_to_be32(LPFC_FDMI_PORTSTATE_ONLINE); + size = FOURBYTES + sizeof(uint32_t); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_PORT_STATE); + return size; +} + +int +lpfc_fdmi_port_attr_num_disc(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + vport->fdmi_num_disc = lpfc_find_map_node(vport); + ae->un.AttrInt = cpu_to_be32(vport->fdmi_num_disc); + size = FOURBYTES + sizeof(uint32_t); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_DISC_PORT); + return size; +} + +int +lpfc_fdmi_port_attr_nportid(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + ae->un.AttrInt = cpu_to_be32(vport->fc_myDID); + size = FOURBYTES + sizeof(uint32_t); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_PORT_ID); + return size; +} + +int +lpfc_fdmi_smart_attr_service(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t len, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + strncpy(ae->un.AttrString, "Smart SAN Initiator", + sizeof(ae->un.AttrString)); + len = strnlen(ae->un.AttrString, + sizeof(ae->un.AttrString)); + len += (len & 3) ? (4 - (len & 3)) : 4; + size = FOURBYTES + len; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_SMART_SERVICE); + return size; +} + +int +lpfc_fdmi_smart_attr_guid(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + memcpy(&ae->un.AttrString, &vport->fc_sparam.nodeName, + sizeof(struct lpfc_name)); + memcpy((((uint8_t *)&ae->un.AttrString) + + sizeof(struct lpfc_name)), + &vport->fc_sparam.portName, sizeof(struct lpfc_name)); + size = FOURBYTES + (2 * sizeof(struct lpfc_name)); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_SMART_GUID); + return size; +} + +int +lpfc_fdmi_smart_attr_version(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t len, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + strncpy(ae->un.AttrString, "Smart SAN Version 1.0", + sizeof(ae->un.AttrString)); + len = strnlen(ae->un.AttrString, + sizeof(ae->un.AttrString)); + len += (len & 3) ? (4 - (len & 3)) : 4; + size = FOURBYTES + len; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_SMART_VERSION); + return size; +} + +int +lpfc_fdmi_smart_attr_model(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_hba *phba = vport->phba; + struct lpfc_fdmi_attr_entry *ae; + uint32_t len, size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 256); + + strncpy(ae->un.AttrString, phba->ModelName, + sizeof(ae->un.AttrString)); + len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString)); + len += (len & 3) ? (4 - (len & 3)) : 4; + size = FOURBYTES + len; + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_SMART_MODEL); + return size; +} + +int +lpfc_fdmi_smart_attr_port_info(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + + /* SRIOV (type 3) is not supported */ + if (vport->vpi) + ae->un.AttrInt = cpu_to_be32(2); /* NPIV */ + else + ae->un.AttrInt = cpu_to_be32(1); /* Physical */ + size = FOURBYTES + sizeof(uint32_t); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_SMART_PORT_INFO); + return size; +} + +int +lpfc_fdmi_smart_attr_qos(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + ae->un.AttrInt = cpu_to_be32(0); + size = FOURBYTES + sizeof(uint32_t); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_SMART_QOS); + return size; +} + +int +lpfc_fdmi_smart_attr_security(struct lpfc_vport *vport, + struct lpfc_fdmi_attr_def *ad) +{ + struct lpfc_fdmi_attr_entry *ae; + uint32_t size; + + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + ae->un.AttrInt = cpu_to_be32(0); + size = FOURBYTES + sizeof(uint32_t); + ad->AttrLen = cpu_to_be16(size); + ad->AttrType = cpu_to_be16(RPRT_SMART_SECURITY); + return size; } +/* RHBA attribute jump table */ +int (*lpfc_fdmi_hba_action[]) + (struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad) = { + /* Action routine Mask bit Attribute type */ + lpfc_fdmi_hba_attr_wwnn, /* bit0 RHBA_NODENAME */ + lpfc_fdmi_hba_attr_manufacturer, /* bit1 RHBA_MANUFACTURER */ + lpfc_fdmi_hba_attr_sn, /* bit2 RHBA_SERIAL_NUMBER */ + lpfc_fdmi_hba_attr_model, /* bit3 RHBA_MODEL */ + lpfc_fdmi_hba_attr_description, /* bit4 RHBA_MODEL_DESCRIPTION */ + lpfc_fdmi_hba_attr_hdw_ver, /* bit5 RHBA_HARDWARE_VERSION */ + lpfc_fdmi_hba_attr_drvr_ver, /* bit6 RHBA_DRIVER_VERSION */ + lpfc_fdmi_hba_attr_rom_ver, /* bit7 RHBA_OPTION_ROM_VERSION */ + lpfc_fdmi_hba_attr_fmw_ver, /* bit8 RHBA_FIRMWARE_VERSION */ + lpfc_fdmi_hba_attr_os_ver, /* bit9 RHBA_OS_NAME_VERSION */ + lpfc_fdmi_hba_attr_ct_len, /* bit10 RHBA_MAX_CT_PAYLOAD_LEN */ + lpfc_fdmi_hba_attr_symbolic_name, /* bit11 RHBA_SYM_NODENAME */ + lpfc_fdmi_hba_attr_vendor_info, /* bit12 RHBA_VENDOR_INFO */ + lpfc_fdmi_hba_attr_num_ports, /* bit13 RHBA_NUM_PORTS */ + lpfc_fdmi_hba_attr_fabric_wwnn, /* bit14 RHBA_FABRIC_WWNN */ + lpfc_fdmi_hba_attr_bios_ver, /* bit15 RHBA_BIOS_VERSION */ + lpfc_fdmi_hba_attr_bios_state, /* bit16 RHBA_BIOS_STATE */ + lpfc_fdmi_hba_attr_vendor_id, /* bit17 RHBA_VENDOR_ID */ +}; + +/* RPA / RPRT attribute jump table */ +int (*lpfc_fdmi_port_action[]) + (struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad) = { + /* Action routine Mask bit Attribute type */ + lpfc_fdmi_port_attr_fc4type, /* bit0 RPRT_SUPPORT_FC4_TYPES */ + lpfc_fdmi_port_attr_support_speed, /* bit1 RPRT_SUPPORTED_SPEED */ + lpfc_fdmi_port_attr_speed, /* bit2 RPRT_PORT_SPEED */ + lpfc_fdmi_port_attr_max_frame, /* bit3 RPRT_MAX_FRAME_SIZE */ + lpfc_fdmi_port_attr_os_devname, /* bit4 RPRT_OS_DEVICE_NAME */ + lpfc_fdmi_port_attr_host_name, /* bit5 RPRT_HOST_NAME */ + lpfc_fdmi_port_attr_wwnn, /* bit6 RPRT_NODENAME */ + lpfc_fdmi_port_attr_wwpn, /* bit7 RPRT_PORTNAME */ + lpfc_fdmi_port_attr_symbolic_name, /* bit8 RPRT_SYM_PORTNAME */ + lpfc_fdmi_port_attr_port_type, /* bit9 RPRT_PORT_TYPE */ + lpfc_fdmi_port_attr_class, /* bit10 RPRT_SUPPORTED_CLASS */ + lpfc_fdmi_port_attr_fabric_wwpn, /* bit11 RPRT_FABRICNAME */ + lpfc_fdmi_port_attr_active_fc4type, /* bit12 RPRT_ACTIVE_FC4_TYPES */ + lpfc_fdmi_port_attr_port_state, /* bit13 RPRT_PORT_STATE */ + lpfc_fdmi_port_attr_num_disc, /* bit14 RPRT_DISC_PORT */ + lpfc_fdmi_port_attr_nportid, /* bit15 RPRT_PORT_ID */ + lpfc_fdmi_smart_attr_service, /* bit16 RPRT_SMART_SERVICE */ + lpfc_fdmi_smart_attr_guid, /* bit17 RPRT_SMART_GUID */ + lpfc_fdmi_smart_attr_version, /* bit18 RPRT_SMART_VERSION */ + lpfc_fdmi_smart_attr_model, /* bit19 RPRT_SMART_MODEL */ + lpfc_fdmi_smart_attr_port_info, /* bit20 RPRT_SMART_PORT_INFO */ + lpfc_fdmi_smart_attr_qos, /* bit21 RPRT_SMART_QOS */ + lpfc_fdmi_smart_attr_security, /* bit22 RPRT_SMART_SECURITY */ +}; +/** + * lpfc_fdmi_cmd - Build and send a FDMI cmd to the specified NPort + * @vport: pointer to a host virtual N_Port data structure. + * @ndlp: ndlp to send FDMI cmd to (if NULL use FDMI_DID) + * cmdcode: FDMI command to send + * mask: Mask of HBA or PORT Attributes to send + * + * Builds and sends a FDMI command using the CT subsystem. + */ int -lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, int cmdcode) +lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, + int cmdcode, uint32_t new_mask) { struct lpfc_hba *phba = vport->phba; struct lpfc_dmabuf *mp, *bmp; struct lpfc_sli_ct_request *CtReq; struct ulp_bde64 *bpl; + uint32_t bit_pos; uint32_t size; uint32_t rsp_size; + uint32_t mask; struct lpfc_fdmi_reg_hba *rh; struct lpfc_fdmi_port_entry *pe; struct lpfc_fdmi_reg_portattr *pab = NULL; struct lpfc_fdmi_attr_block *ab = NULL; - struct lpfc_fdmi_attr_entry *ae; - struct lpfc_fdmi_attr_def *ad; - void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *, - struct lpfc_iocbq *); + int (*func)(struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad); + void (*cmpl)(struct lpfc_hba *, struct lpfc_iocbq *, + struct lpfc_iocbq *); - if (ndlp == NULL) { - ndlp = lpfc_findnode_did(vport, FDMI_DID); - if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) - return 0; - cmpl = lpfc_cmpl_ct_cmd_fdmi; /* cmd interface */ - } else { - cmpl = lpfc_cmpl_ct_disc_fdmi; /* called from discovery */ - } + if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) + return 0; + + cmpl = lpfc_cmpl_ct_disc_fdmi; /* called from discovery */ /* fill in BDEs for command */ /* Allocate buffer for command payload */ @@ -1470,573 +2485,99 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, int cmdcode) switch (cmdcode) { case SLI_MGMT_RHAT: case SLI_MGMT_RHBA: - { - lpfc_vpd_t *vp = &phba->vpd; - uint32_t i, j, incr; - int len = 0; + rh = (struct lpfc_fdmi_reg_hba *)&CtReq->un.PortID; + /* HBA Identifier */ + memcpy(&rh->hi.PortName, &phba->pport->fc_sparam.portName, + sizeof(struct lpfc_name)); - rh = (struct lpfc_fdmi_reg_hba *)&CtReq->un.PortID; - /* HBA Identifier */ - memcpy(&rh->hi.PortName, &vport->fc_sparam.portName, + if (cmdcode == SLI_MGMT_RHBA) { + /* Registered Port List */ + /* One entry (port) per adapter */ + rh->rpl.EntryCnt = cpu_to_be32(1); + memcpy(&rh->rpl.pe, &phba->pport->fc_sparam.portName, sizeof(struct lpfc_name)); - if (cmdcode == SLI_MGMT_RHBA) { - /* Registered Port List */ - /* One entry (port) per adapter */ - rh->rpl.EntryCnt = cpu_to_be32(1); - memcpy(&rh->rpl.pe, &vport->fc_sparam.portName, - sizeof(struct lpfc_name)); - - /* point to the HBA attribute block */ - size = 2 * sizeof(struct lpfc_name) + - FOURBYTES; - } else { - size = sizeof(struct lpfc_name); - } - ab = (struct lpfc_fdmi_attr_block *) - ((uint8_t *)rh + size); - ab->EntryCnt = 0; - size += FOURBYTES; - - /* - * Point to beginning of first HBA attribute entry - */ - /* #1 HBA attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)rh + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(struct lpfc_name)); - ad->AttrType = cpu_to_be16(RHBA_NODENAME); - ad->AttrLen = cpu_to_be16(FOURBYTES - + sizeof(struct lpfc_name)); - memcpy(&ae->un.NodeName, &vport->fc_sparam.nodeName, - sizeof(struct lpfc_name)); - ab->EntryCnt++; - size += FOURBYTES + sizeof(struct lpfc_name); - if ((size + LPFC_FDMI_MAX_AE_SIZE) > - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto hba_out; - - /* #2 HBA attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)rh + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(ae->un.Manufacturer)); - ad->AttrType = cpu_to_be16(RHBA_MANUFACTURER); - strncpy(ae->un.Manufacturer, "Emulex Corporation", - sizeof(ae->un.Manufacturer)); - len = strnlen(ae->un.Manufacturer, - sizeof(ae->un.Manufacturer)); - len += (len & 3) ? (4 - (len & 3)) : 4; - ad->AttrLen = cpu_to_be16(FOURBYTES + len); - ab->EntryCnt++; - size += FOURBYTES + len; - if ((size + LPFC_FDMI_MAX_AE_SIZE) > - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto hba_out; - - /* #3 HBA attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)rh + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(ae->un.SerialNumber)); - ad->AttrType = cpu_to_be16(RHBA_SERIAL_NUMBER); - strncpy(ae->un.SerialNumber, phba->SerialNumber, - sizeof(ae->un.SerialNumber)); - len = strnlen(ae->un.SerialNumber, - sizeof(ae->un.SerialNumber)); - len += (len & 3) ? (4 - (len & 3)) : 4; - ad->AttrLen = cpu_to_be16(FOURBYTES + len); - ab->EntryCnt++; - size += FOURBYTES + len; - if ((size + LPFC_FDMI_MAX_AE_SIZE) > - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto hba_out; - - /* #4 HBA attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)rh + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(ae->un.Model)); - ad->AttrType = cpu_to_be16(RHBA_MODEL); - strncpy(ae->un.Model, phba->ModelName, - sizeof(ae->un.Model)); - len = strnlen(ae->un.Model, sizeof(ae->un.Model)); - len += (len & 3) ? (4 - (len & 3)) : 4; - ad->AttrLen = cpu_to_be16(FOURBYTES + len); - ab->EntryCnt++; - size += FOURBYTES + len; - if ((size + LPFC_FDMI_MAX_AE_SIZE) > - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto hba_out; - - /* #5 HBA attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)rh + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(ae->un.ModelDescription)); - ad->AttrType = cpu_to_be16(RHBA_MODEL_DESCRIPTION); - strncpy(ae->un.ModelDescription, phba->ModelDesc, - sizeof(ae->un.ModelDescription)); - len = strnlen(ae->un.ModelDescription, - sizeof(ae->un.ModelDescription)); - len += (len & 3) ? (4 - (len & 3)) : 4; - ad->AttrLen = cpu_to_be16(FOURBYTES + len); - ab->EntryCnt++; - size += FOURBYTES + len; - if ((size + 8) > (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto hba_out; - - /* #6 HBA attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)rh + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, 8); - ad->AttrType = cpu_to_be16(RHBA_HARDWARE_VERSION); - ad->AttrLen = cpu_to_be16(FOURBYTES + 8); - /* Convert JEDEC ID to ascii for hardware version */ - incr = vp->rev.biuRev; - for (i = 0; i < 8; i++) { - j = (incr & 0xf); - if (j <= 9) - ae->un.HardwareVersion[7 - i] = - (char)((uint8_t)0x30 + - (uint8_t)j); - else - ae->un.HardwareVersion[7 - i] = - (char)((uint8_t)0x61 + - (uint8_t)(j - 10)); - incr = (incr >> 4); + /* point to the HBA attribute block */ + size = 2 * sizeof(struct lpfc_name) + + FOURBYTES; + } else { + size = sizeof(struct lpfc_name); + } + ab = (struct lpfc_fdmi_attr_block *)((uint8_t *)rh + size); + ab->EntryCnt = 0; + size += FOURBYTES; + bit_pos = 0; + if (new_mask) + mask = new_mask; + else + mask = vport->fdmi_hba_mask; + + /* Mask will dictate what attributes to build in the request */ + while (mask) { + if (mask & 0x1) { + func = lpfc_fdmi_hba_action[bit_pos]; + size += func(vport, + (struct lpfc_fdmi_attr_def *) + ((uint8_t *)rh + size)); + ab->EntryCnt++; + if ((size + 256) > + (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) + goto hba_out; } - ab->EntryCnt++; - size += FOURBYTES + 8; - if ((size + LPFC_FDMI_MAX_AE_SIZE) > - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto hba_out; - - /* #7 HBA attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)rh + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(ae->un.DriverVersion)); - ad->AttrType = cpu_to_be16(RHBA_DRIVER_VERSION); - strncpy(ae->un.DriverVersion, lpfc_release_version, - sizeof(ae->un.DriverVersion)); - len = strnlen(ae->un.DriverVersion, - sizeof(ae->un.DriverVersion)); - len += (len & 3) ? (4 - (len & 3)) : 4; - ad->AttrLen = cpu_to_be16(FOURBYTES + len); - ab->EntryCnt++; - size += FOURBYTES + len; - if ((size + LPFC_FDMI_MAX_AE_SIZE) > - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto hba_out; - - /* #8 HBA attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)rh + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(ae->un.OptionROMVersion)); - ad->AttrType = cpu_to_be16(RHBA_OPTION_ROM_VERSION); - strncpy(ae->un.OptionROMVersion, phba->OptionROMVersion, - sizeof(ae->un.OptionROMVersion)); - len = strnlen(ae->un.OptionROMVersion, - sizeof(ae->un.OptionROMVersion)); - len += (len & 3) ? (4 - (len & 3)) : 4; - ad->AttrLen = cpu_to_be16(FOURBYTES + len); - ab->EntryCnt++; - size += FOURBYTES + len; - if ((size + LPFC_FDMI_MAX_AE_SIZE) > - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto hba_out; - - /* #9 HBA attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)rh + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(ae->un.FirmwareVersion)); - ad->AttrType = cpu_to_be16(RHBA_FIRMWARE_VERSION); - lpfc_decode_firmware_rev(phba, ae->un.FirmwareVersion, - 1); - len = strnlen(ae->un.FirmwareVersion, - sizeof(ae->un.FirmwareVersion)); - len += (len & 3) ? (4 - (len & 3)) : 4; - ad->AttrLen = cpu_to_be16(FOURBYTES + len); - ab->EntryCnt++; - size += FOURBYTES + len; - if ((size + LPFC_FDMI_MAX_AE_SIZE) > - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto hba_out; - - /* #10 HBA attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)rh + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(ae->un.OsNameVersion)); - ad->AttrType = cpu_to_be16(RHBA_OS_NAME_VERSION); - snprintf(ae->un.OsNameVersion, - sizeof(ae->un.OsNameVersion), - "%s %s %s", - init_utsname()->sysname, - init_utsname()->release, - init_utsname()->version); - len = strnlen(ae->un.OsNameVersion, - sizeof(ae->un.OsNameVersion)); - len += (len & 3) ? (4 - (len & 3)) : 4; - ad->AttrLen = cpu_to_be16(FOURBYTES + len); - ab->EntryCnt++; - size += FOURBYTES + len; - if ((size + 4) > (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto hba_out; - - /* #11 HBA attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)rh + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - ad->AttrType = - cpu_to_be16(RHBA_MAX_CT_PAYLOAD_LEN); - ad->AttrLen = cpu_to_be16(FOURBYTES + 4); - ae->un.MaxCTPayloadLen = cpu_to_be32(LPFC_MAX_CT_SIZE); - ab->EntryCnt++; - size += FOURBYTES + 4; - if ((size + LPFC_FDMI_MAX_AE_SIZE) > - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto hba_out; - - /* - * Currently switches don't seem to support the - * following extended HBA attributes. - */ - if (!(vport->cfg_fdmi_on & LPFC_FDMI_ALL_ATTRIB)) - goto hba_out; - - /* #12 HBA attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)rh + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(ae->un.NodeSymName)); - ad->AttrType = cpu_to_be16(RHBA_SYM_NODENAME); - len = lpfc_vport_symbolic_node_name(vport, - ae->un.NodeSymName, sizeof(ae->un.NodeSymName)); - len += (len & 3) ? (4 - (len & 3)) : 4; - ad->AttrLen = cpu_to_be16(FOURBYTES + len); - ab->EntryCnt++; - size += FOURBYTES + len; -hba_out: - ab->EntryCnt = cpu_to_be32(ab->EntryCnt); - /* Total size */ - size = GID_REQUEST_SZ - 4 + size; + mask = mask >> 1; + bit_pos++; } +hba_out: + ab->EntryCnt = cpu_to_be32(ab->EntryCnt); + /* Total size */ + size = GID_REQUEST_SZ - 4 + size; break; case SLI_MGMT_RPRT: case SLI_MGMT_RPA: - { - struct serv_parm *hsp; - int len = 0; - - if (cmdcode == SLI_MGMT_RPRT) { - rh = (struct lpfc_fdmi_reg_hba *) - &CtReq->un.PortID; - /* HBA Identifier */ - memcpy(&rh->hi.PortName, - &vport->fc_sparam.portName, - sizeof(struct lpfc_name)); - pab = (struct lpfc_fdmi_reg_portattr *) - &rh->rpl.EntryCnt; - } else - pab = (struct lpfc_fdmi_reg_portattr *) - &CtReq->un.PortID; - size = sizeof(struct lpfc_name) + FOURBYTES; - memcpy((uint8_t *)&pab->PortName, - (uint8_t *)&vport->fc_sparam.portName, + pab = (struct lpfc_fdmi_reg_portattr *)&CtReq->un.PortID; + if (cmdcode == SLI_MGMT_RPRT) { + rh = (struct lpfc_fdmi_reg_hba *)pab; + /* HBA Identifier */ + memcpy(&rh->hi.PortName, + &phba->pport->fc_sparam.portName, sizeof(struct lpfc_name)); - pab->ab.EntryCnt = 0; - - /* #1 Port attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)pab + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(ae->un.FC4Types)); - ad->AttrType = - cpu_to_be16(RPRT_SUPPORTED_FC4_TYPES); - ad->AttrLen = cpu_to_be16(FOURBYTES + 32); - ae->un.FC4Types[0] = 0x40; /* Type 1 - ELS */ - ae->un.FC4Types[1] = 0x80; /* Type 8 - FCP */ - ae->un.FC4Types[4] = 0x80; /* Type 32 - CT */ - pab->ab.EntryCnt++; - size += FOURBYTES + 32; - - /* #2 Port attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)pab + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_SPEED); - ad->AttrLen = cpu_to_be16(FOURBYTES + 4); - ae->un.SupportSpeed = 0; - if (phba->lmt & LMT_32Gb) - ae->un.SupportSpeed |= HBA_PORTSPEED_32GBIT; - if (phba->lmt & LMT_16Gb) - ae->un.SupportSpeed |= HBA_PORTSPEED_16GBIT; - if (phba->lmt & LMT_10Gb) - ae->un.SupportSpeed |= HBA_PORTSPEED_10GBIT; - if (phba->lmt & LMT_8Gb) - ae->un.SupportSpeed |= HBA_PORTSPEED_8GBIT; - if (phba->lmt & LMT_4Gb) - ae->un.SupportSpeed |= HBA_PORTSPEED_4GBIT; - if (phba->lmt & LMT_2Gb) - ae->un.SupportSpeed |= HBA_PORTSPEED_2GBIT; - if (phba->lmt & LMT_1Gb) - ae->un.SupportSpeed |= HBA_PORTSPEED_1GBIT; - ae->un.SupportSpeed = - cpu_to_be32(ae->un.SupportSpeed); - - pab->ab.EntryCnt++; - size += FOURBYTES + 4; - - /* #3 Port attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)pab + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - ad->AttrType = cpu_to_be16(RPRT_PORT_SPEED); - ad->AttrLen = cpu_to_be16(FOURBYTES + 4); - switch (phba->fc_linkspeed) { - case LPFC_LINK_SPEED_1GHZ: - ae->un.PortSpeed = HBA_PORTSPEED_1GBIT; - break; - case LPFC_LINK_SPEED_2GHZ: - ae->un.PortSpeed = HBA_PORTSPEED_2GBIT; - break; - case LPFC_LINK_SPEED_4GHZ: - ae->un.PortSpeed = HBA_PORTSPEED_4GBIT; - break; - case LPFC_LINK_SPEED_8GHZ: - ae->un.PortSpeed = HBA_PORTSPEED_8GBIT; - break; - case LPFC_LINK_SPEED_10GHZ: - ae->un.PortSpeed = HBA_PORTSPEED_10GBIT; - break; - case LPFC_LINK_SPEED_16GHZ: - ae->un.PortSpeed = HBA_PORTSPEED_16GBIT; - break; - case LPFC_LINK_SPEED_32GHZ: - ae->un.PortSpeed = HBA_PORTSPEED_32GBIT; - break; - default: - ae->un.PortSpeed = HBA_PORTSPEED_UNKNOWN; - break; - } - ae->un.PortSpeed = cpu_to_be32(ae->un.PortSpeed); - pab->ab.EntryCnt++; - size += FOURBYTES + 4; - - /* #4 Port attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)pab + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - ad->AttrType = cpu_to_be16(RPRT_MAX_FRAME_SIZE); - ad->AttrLen = cpu_to_be16(FOURBYTES + 4); - hsp = (struct serv_parm *)&vport->fc_sparam; - ae->un.MaxFrameSize = - (((uint32_t)hsp->cmn. - bbRcvSizeMsb) << 8) | (uint32_t)hsp->cmn. - bbRcvSizeLsb; - ae->un.MaxFrameSize = - cpu_to_be32(ae->un.MaxFrameSize); - pab->ab.EntryCnt++; - size += FOURBYTES + 4; - if ((size + LPFC_FDMI_MAX_AE_SIZE) > - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto port_out; - - /* #5 Port attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)pab + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(ae->un.OsDeviceName)); - ad->AttrType = cpu_to_be16(RPRT_OS_DEVICE_NAME); - strncpy((char *)ae->un.OsDeviceName, LPFC_DRIVER_NAME, - sizeof(ae->un.OsDeviceName)); - len = strnlen((char *)ae->un.OsDeviceName, - sizeof(ae->un.OsDeviceName)); - len += (len & 3) ? (4 - (len & 3)) : 4; - ad->AttrLen = cpu_to_be16(FOURBYTES + len); - pab->ab.EntryCnt++; - size += FOURBYTES + len; - if ((size + LPFC_FDMI_MAX_AE_SIZE) > - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto port_out; - - /* #6 Port attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)pab + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(ae->un.HostName)); - snprintf(ae->un.HostName, sizeof(ae->un.HostName), "%s", - init_utsname()->nodename); - ad->AttrType = cpu_to_be16(RPRT_HOST_NAME); - len = strnlen(ae->un.HostName, - sizeof(ae->un.HostName)); - len += (len & 3) ? (4 - (len & 3)) : 4; - ad->AttrLen = - cpu_to_be16(FOURBYTES + len); - pab->ab.EntryCnt++; - size += FOURBYTES + len; - if ((size + sizeof(struct lpfc_name)) > - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto port_out; + pab = (struct lpfc_fdmi_reg_portattr *) + ((uint8_t *)pab + sizeof(struct lpfc_name)); + } - /* - * Currently switches don't seem to support the - * following extended Port attributes. - */ - if (!(vport->cfg_fdmi_on & LPFC_FDMI_ALL_ATTRIB)) - goto port_out; - - /* #7 Port attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)pab + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(struct lpfc_name)); - ad->AttrType = cpu_to_be16(RPRT_NODENAME); - ad->AttrLen = cpu_to_be16(FOURBYTES - + sizeof(struct lpfc_name)); - memcpy(&ae->un.NodeName, &vport->fc_sparam.nodeName, - sizeof(struct lpfc_name)); - pab->ab.EntryCnt++; - size += FOURBYTES + sizeof(struct lpfc_name); - if ((size + sizeof(struct lpfc_name)) > - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto port_out; - - /* #8 Port attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)pab + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(struct lpfc_name)); - ad->AttrType = cpu_to_be16(RPRT_PORTNAME); - ad->AttrLen = cpu_to_be16(FOURBYTES - + sizeof(struct lpfc_name)); - memcpy(&ae->un.PortName, &vport->fc_sparam.portName, - sizeof(struct lpfc_name)); - pab->ab.EntryCnt++; - size += FOURBYTES + sizeof(struct lpfc_name); - if ((size + LPFC_FDMI_MAX_AE_SIZE) > - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto port_out; - - /* #9 Port attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)pab + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(ae->un.NodeSymName)); - ad->AttrType = cpu_to_be16(RPRT_SYM_PORTNAME); - len = lpfc_vport_symbolic_port_name(vport, - ae->un.NodeSymName, sizeof(ae->un.NodeSymName)); - len += (len & 3) ? (4 - (len & 3)) : 4; - ad->AttrLen = cpu_to_be16(FOURBYTES + len); - pab->ab.EntryCnt++; - size += FOURBYTES + len; - if ((size + 4) > (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto port_out; - - /* #10 Port attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)pab + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - ad->AttrType = cpu_to_be16(RPRT_PORT_TYPE); - ae->un.PortState = 0; - ad->AttrLen = cpu_to_be16(FOURBYTES + 4); - pab->ab.EntryCnt++; - size += FOURBYTES + 4; - if ((size + 4) > (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto port_out; - - /* #11 Port attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)pab + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_CLASS); - ae->un.SupportClass = - cpu_to_be32(FC_COS_CLASS2 | FC_COS_CLASS3); - ad->AttrLen = cpu_to_be16(FOURBYTES + 4); - pab->ab.EntryCnt++; - size += FOURBYTES + 4; - if ((size + sizeof(struct lpfc_name)) > - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto port_out; - - /* #12 Port attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)pab + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(struct lpfc_name)); - ad->AttrType = cpu_to_be16(RPRT_FABRICNAME); - ad->AttrLen = cpu_to_be16(FOURBYTES - + sizeof(struct lpfc_name)); - memcpy(&ae->un.FabricName, &vport->fabric_nodename, - sizeof(struct lpfc_name)); - pab->ab.EntryCnt++; - size += FOURBYTES + sizeof(struct lpfc_name); - if ((size + LPFC_FDMI_MAX_AE_SIZE) > - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto port_out; - - /* #13 Port attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)pab + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(ae->un.FC4Types)); - ad->AttrType = - cpu_to_be16(RPRT_ACTIVE_FC4_TYPES); - ad->AttrLen = cpu_to_be16(FOURBYTES + 32); - ae->un.FC4Types[0] = 0x40; /* Type 1 - ELS */ - ae->un.FC4Types[1] = 0x80; /* Type 8 - FCP */ - ae->un.FC4Types[4] = 0x80; /* Type 32 - CT */ - pab->ab.EntryCnt++; - size += FOURBYTES + 32; - if ((size + 4) > (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto port_out; - - /* #257 Port attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)pab + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - ad->AttrType = cpu_to_be16(RPRT_PORT_STATE); - ae->un.PortState = 0; - ad->AttrLen = cpu_to_be16(FOURBYTES + 4); - pab->ab.EntryCnt++; - size += FOURBYTES + 4; - if ((size + 4) > (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto port_out; - - /* #258 Port attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)pab + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - ad->AttrType = cpu_to_be16(RPRT_DISC_PORT); - ae->un.PortState = lpfc_find_map_node(vport); - ae->un.PortState = cpu_to_be32(ae->un.PortState); - ad->AttrLen = cpu_to_be16(FOURBYTES + 4); - pab->ab.EntryCnt++; - size += FOURBYTES + 4; - if ((size + 4) > (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) - goto port_out; - - /* #259 Port attribute entry */ - ad = (struct lpfc_fdmi_attr_def *) - ((uint8_t *)pab + size); - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - ad->AttrType = cpu_to_be16(RPRT_PORT_ID); - ae->un.PortId = cpu_to_be32(vport->fc_myDID); - ad->AttrLen = cpu_to_be16(FOURBYTES + 4); - pab->ab.EntryCnt++; - size += FOURBYTES + 4; -port_out: - pab->ab.EntryCnt = cpu_to_be32(pab->ab.EntryCnt); - /* Total size */ - size = GID_REQUEST_SZ - 4 + size; + memcpy((uint8_t *)&pab->PortName, + (uint8_t *)&vport->fc_sparam.portName, + sizeof(struct lpfc_name)); + size += sizeof(struct lpfc_name) + FOURBYTES; + pab->ab.EntryCnt = 0; + bit_pos = 0; + if (new_mask) + mask = new_mask; + else + mask = vport->fdmi_port_mask; + + /* Mask will dictate what attributes to build in the request */ + while (mask) { + if (mask & 0x1) { + func = lpfc_fdmi_port_action[bit_pos]; + size += func(vport, + (struct lpfc_fdmi_attr_def *) + ((uint8_t *)pab + size)); + pab->ab.EntryCnt++; + if ((size + 256) > + (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) + goto port_out; + } + mask = mask >> 1; + bit_pos++; } +port_out: + pab->ab.EntryCnt = cpu_to_be32(pab->ab.EntryCnt); + /* Total size */ + if (cmdcode == SLI_MGMT_RPRT) + size += sizeof(struct lpfc_name); + size = GID_REQUEST_SZ - 4 + size; break; case SLI_MGMT_GHAT: @@ -2158,41 +2699,6 @@ lpfc_delayed_disc_timeout_handler(struct lpfc_vport *vport) } void -lpfc_fdmi_tmo(unsigned long ptr) -{ - struct lpfc_vport *vport = (struct lpfc_vport *)ptr; - struct lpfc_hba *phba = vport->phba; - uint32_t tmo_posted; - unsigned long iflag; - - spin_lock_irqsave(&vport->work_port_lock, iflag); - tmo_posted = vport->work_port_events & WORKER_FDMI_TMO; - if (!tmo_posted) - vport->work_port_events |= WORKER_FDMI_TMO; - spin_unlock_irqrestore(&vport->work_port_lock, iflag); - - if (!tmo_posted) - lpfc_worker_wake_up(phba); - return; -} - -void -lpfc_fdmi_timeout_handler(struct lpfc_vport *vport) -{ - struct lpfc_nodelist *ndlp; - - ndlp = lpfc_findnode_did(vport, FDMI_DID); - if (ndlp && NLP_CHK_NODE_ACT(ndlp)) { - if (init_utsname()->nodename[0] != '\0') - lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA); - else - mod_timer(&vport->fc_fdmitmo, jiffies + - msecs_to_jiffies(1000 * 60)); - } - return; -} - -void lpfc_decode_firmware_rev(struct lpfc_hba *phba, char *fwrevision, int flag) { struct lpfc_sli *psli = &phba->sli; diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index d508378..3394648 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -688,6 +688,21 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, sp->cmn.bbRcvSizeLsb; fabric_param_changed = lpfc_check_clean_addr_bit(vport, sp); + if (fabric_param_changed) { + /* Reset FDMI attribute masks based on config parameter */ + if (phba->cfg_fdmi_on == LPFC_FDMI_NO_SUPPORT) { + vport->fdmi_hba_mask = 0; + vport->fdmi_port_mask = 0; + } else { + /* Setup appropriate attribute masks */ + vport->fdmi_hba_mask = LPFC_FDMI2_HBA_ATTR; + if (phba->cfg_fdmi_on == LPFC_FDMI_SMART_SAN) + vport->fdmi_port_mask = LPFC_FDMI2_SMART_ATTR; + else + vport->fdmi_port_mask = LPFC_FDMI2_PORT_ATTR; + } + + } memcpy(&vport->fabric_portname, &sp->portName, sizeof(struct lpfc_name)); memcpy(&vport->fabric_nodename, &sp->nodeName, @@ -4690,6 +4705,23 @@ lpfc_rdp_res_link_error(struct fc_rdp_link_error_status_desc *desc, desc->length = cpu_to_be32(sizeof(desc->info)); } +int +lpfc_rdp_res_fec_desc(struct fc_fec_rdp_desc *desc, READ_LNK_VAR *stat) +{ + if (bf_get(lpfc_read_link_stat_gec2, stat) == 0) + return 0; + desc->tag = cpu_to_be32(RDP_FEC_DESC_TAG); + + desc->info.CorrectedBlocks = + cpu_to_be32(stat->fecCorrBlkCount); + desc->info.UncorrectableBlocks = + cpu_to_be32(stat->fecUncorrBlkCount); + + desc->length = cpu_to_be32(sizeof(desc->info)); + + return sizeof(struct fc_fec_rdp_desc); +} + void lpfc_rdp_res_speed(struct fc_rdp_port_speed_desc *desc, struct lpfc_hba *phba) { @@ -4800,7 +4832,7 @@ lpfc_els_rdp_cmpl(struct lpfc_hba *phba, struct lpfc_rdp_context *rdp_context, struct ls_rjt *stat; struct fc_rdp_res_frame *rdp_res; uint32_t cmdsize; - int rc; + int rc, fec_size; if (status != SUCCESS) goto error; @@ -4840,8 +4872,9 @@ lpfc_els_rdp_cmpl(struct lpfc_hba *phba, struct lpfc_rdp_context *rdp_context, lpfc_rdp_res_diag_port_names(&rdp_res->diag_port_names_desc, phba); lpfc_rdp_res_attach_port_names(&rdp_res->attached_port_names_desc, vport, ndlp); - rdp_res->length = cpu_to_be32(RDP_DESC_PAYLOAD_SIZE); - + fec_size = lpfc_rdp_res_fec_desc(&rdp_res->fec_desc, + &rdp_context->link_stat); + rdp_res->length = cpu_to_be32(fec_size + RDP_DESC_PAYLOAD_SIZE); elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; phba->fc_stat.elsXmitACC++; @@ -7704,6 +7737,35 @@ lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, } } +void +lpfc_start_fdmi(struct lpfc_vport *vport) +{ + struct lpfc_hba *phba = vport->phba; + struct lpfc_nodelist *ndlp; + + /* If this is the first time, allocate an ndlp and initialize + * it. Otherwise, make sure the node is enabled and then do the + * login. + */ + ndlp = lpfc_findnode_did(vport, FDMI_DID); + if (!ndlp) { + ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); + if (ndlp) { + lpfc_nlp_init(vport, ndlp, FDMI_DID); + ndlp->nlp_type |= NLP_FABRIC; + } else { + return; + } + } + if (!NLP_CHK_NODE_ACT(ndlp)) + ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_NPR_NODE); + + if (ndlp) { + lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); + lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0); + } +} + /** * lpfc_do_scr_ns_plogi - Issue a plogi to the name server for scr * @phba: pointer to lpfc hba data structure. @@ -7720,7 +7782,7 @@ lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, void lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport) { - struct lpfc_nodelist *ndlp, *ndlp_fdmi; + struct lpfc_nodelist *ndlp; struct Scsi_Host *shost = lpfc_shost_from_vport(vport); /* @@ -7778,32 +7840,9 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport) return; } - if (vport->cfg_fdmi_on & LPFC_FDMI_SUPPORT) { - /* If this is the first time, allocate an ndlp and initialize - * it. Otherwise, make sure the node is enabled and then do the - * login. - */ - ndlp_fdmi = lpfc_findnode_did(vport, FDMI_DID); - if (!ndlp_fdmi) { - ndlp_fdmi = mempool_alloc(phba->nlp_mem_pool, - GFP_KERNEL); - if (ndlp_fdmi) { - lpfc_nlp_init(vport, ndlp_fdmi, FDMI_DID); - ndlp_fdmi->nlp_type |= NLP_FABRIC; - } else - return; - } - if (!NLP_CHK_NODE_ACT(ndlp_fdmi)) - ndlp_fdmi = lpfc_enable_node(vport, - ndlp_fdmi, - NLP_STE_NPR_NODE); - - if (ndlp_fdmi) { - lpfc_nlp_set_state(vport, ndlp_fdmi, - NLP_STE_PLOGI_ISSUE); - lpfc_issue_els_plogi(vport, ndlp_fdmi->nlp_DID, 0); - } - } + if ((phba->cfg_fdmi_on > LPFC_FDMI_NO_SUPPORT) && + (vport->load_flag & FC_ALLOW_FDMI)) + lpfc_start_fdmi(vport); } /** diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index d3668aa..1bad678 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -674,8 +674,6 @@ lpfc_work_done(struct lpfc_hba *phba) lpfc_mbox_timeout_handler(phba); if (work_port_events & WORKER_FABRIC_BLOCK_TMO) lpfc_unblock_fabric_iocbs(phba); - if (work_port_events & WORKER_FDMI_TMO) - lpfc_fdmi_timeout_handler(vport); if (work_port_events & WORKER_RAMP_DOWN_QUEUE) lpfc_ramp_down_queue_handler(phba); if (work_port_events & WORKER_DELAYED_DISC_TMO) @@ -5554,15 +5552,15 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) ndlp->nlp_usg_map, ndlp); /* * Start issuing Fabric-Device Management Interface (FDMI) command to - * 0xfffffa (FDMI well known port) or Delay issuing FDMI command if - * fdmi-on=2 (supporting RPA/hostnmae) + * 0xfffffa (FDMI well known port). + * DHBA -> DPRT -> RHBA -> RPA (physical port) + * DPRT -> RPRT (vports) */ - - if (vport->cfg_fdmi_on & LPFC_FDMI_REG_DELAY) - mod_timer(&vport->fc_fdmitmo, - jiffies + msecs_to_jiffies(1000 * 60)); + if (vport->port_type == LPFC_PHYSICAL_PORT) + lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA, 0); else - lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA); + lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DPRT, 0); + /* decrement the node reference count held for this callback * function. diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h index 2cce88e..dd20412 100644 --- a/drivers/scsi/lpfc/lpfc_hw.h +++ b/drivers/scsi/lpfc/lpfc_hw.h @@ -1097,6 +1097,18 @@ struct fc_rdp_port_name_desc { }; +struct fc_rdp_fec_info { + uint32_t CorrectedBlocks; + uint32_t UncorrectableBlocks; +}; + +#define RDP_FEC_DESC_TAG 0x00010005 +struct fc_fec_rdp_desc { + uint32_t tag; + uint32_t length; + struct fc_rdp_fec_info info; +}; + struct fc_rdp_link_error_status_payload_info { struct fc_link_status link_status; /* 24 bytes */ uint32_t port_type; /* bits 31-30 only */ @@ -1196,14 +1208,15 @@ struct fc_rdp_res_frame { struct fc_rdp_link_error_status_desc link_error_desc; /* Word 13-21 */ struct fc_rdp_port_name_desc diag_port_names_desc; /* Word 22-27 */ struct fc_rdp_port_name_desc attached_port_names_desc;/* Word 28-33 */ + struct fc_fec_rdp_desc fec_desc; /* FC Word 34 - 37 */ }; #define RDP_DESC_PAYLOAD_SIZE (sizeof(struct fc_rdp_link_service_desc) \ - + sizeof(struct fc_rdp_sfp_desc) \ - + sizeof(struct fc_rdp_port_speed_desc) \ - + sizeof(struct fc_rdp_link_error_status_desc) \ - + (sizeof(struct fc_rdp_port_name_desc) * 2)) + + sizeof(struct fc_rdp_sfp_desc) \ + + sizeof(struct fc_rdp_port_speed_desc) \ + + sizeof(struct fc_rdp_link_error_status_desc) \ + + (sizeof(struct fc_rdp_port_name_desc) * 2)) /******** FDMI ********/ @@ -1233,31 +1246,10 @@ struct lpfc_fdmi_attr_def { /* Defined in TLV format */ /* Attribute Entry */ struct lpfc_fdmi_attr_entry { union { - uint32_t VendorSpecific; - uint32_t SupportClass; - uint32_t SupportSpeed; - uint32_t PortSpeed; - uint32_t MaxFrameSize; - uint32_t MaxCTPayloadLen; - uint32_t PortState; - uint32_t PortId; - struct lpfc_name NodeName; - struct lpfc_name PortName; - struct lpfc_name FabricName; - uint8_t FC4Types[32]; - uint8_t Manufacturer[64]; - uint8_t SerialNumber[64]; - uint8_t Model[256]; - uint8_t ModelDescription[256]; - uint8_t HardwareVersion[256]; - uint8_t DriverVersion[256]; - uint8_t OptionROMVersion[256]; - uint8_t FirmwareVersion[256]; - uint8_t OsHostName[256]; - uint8_t NodeSymName[256]; - uint8_t OsDeviceName[256]; - uint8_t OsNameVersion[256]; - uint8_t HostName[256]; + uint32_t AttrInt; + uint8_t AttrTypes[32]; + uint8_t AttrString[256]; + struct lpfc_name AttrWWN; } un; }; @@ -1327,6 +1319,8 @@ struct lpfc_fdmi_reg_portattr { #define SLI_MGMT_DPRT 0x310 /* De-register Port */ #define SLI_MGMT_DPA 0x311 /* De-register Port attributes */ +#define LPFC_FDMI_MAX_RETRY 3 /* Max retries for a FDMI command */ + /* * HBA Attribute Types */ @@ -1342,6 +1336,39 @@ struct lpfc_fdmi_reg_portattr { #define RHBA_OS_NAME_VERSION 0xa /* 4 to 256 byte ASCII string */ #define RHBA_MAX_CT_PAYLOAD_LEN 0xb /* 32-bit unsigned int */ #define RHBA_SYM_NODENAME 0xc /* 4 to 256 byte ASCII string */ +#define RHBA_VENDOR_INFO 0xd /* 32-bit unsigned int */ +#define RHBA_NUM_PORTS 0xe /* 32-bit unsigned int */ +#define RHBA_FABRIC_WWNN 0xf /* 8 byte WWNN */ +#define RHBA_BIOS_VERSION 0x10 /* 4 to 256 byte ASCII string */ +#define RHBA_BIOS_STATE 0x11 /* 32-bit unsigned int */ +#define RHBA_VENDOR_ID 0xe0 /* 8 byte ASCII string */ + +/* Bit mask for all individual HBA attributes */ +#define LPFC_FDMI_HBA_ATTR_wwnn 0x00000001 +#define LPFC_FDMI_HBA_ATTR_manufacturer 0x00000002 +#define LPFC_FDMI_HBA_ATTR_sn 0x00000004 +#define LPFC_FDMI_HBA_ATTR_model 0x00000008 +#define LPFC_FDMI_HBA_ATTR_description 0x00000010 +#define LPFC_FDMI_HBA_ATTR_hdw_ver 0x00000020 +#define LPFC_FDMI_HBA_ATTR_drvr_ver 0x00000040 +#define LPFC_FDMI_HBA_ATTR_rom_ver 0x00000080 +#define LPFC_FDMI_HBA_ATTR_fmw_ver 0x00000100 +#define LPFC_FDMI_HBA_ATTR_os_ver 0x00000200 +#define LPFC_FDMI_HBA_ATTR_ct_len 0x00000400 +#define LPFC_FDMI_HBA_ATTR_symbolic_name 0x00000800 +#define LPFC_FDMI_HBA_ATTR_vendor_info 0x00001000 /* Not used */ +#define LPFC_FDMI_HBA_ATTR_num_ports 0x00002000 +#define LPFC_FDMI_HBA_ATTR_fabric_wwnn 0x00004000 +#define LPFC_FDMI_HBA_ATTR_bios_ver 0x00008000 +#define LPFC_FDMI_HBA_ATTR_bios_state 0x00010000 /* Not used */ +#define LPFC_FDMI_HBA_ATTR_vendor_id 0x00020000 + +/* Bit mask for FDMI-1 defined HBA attributes */ +#define LPFC_FDMI1_HBA_ATTR 0x000007ff + +/* Bit mask for FDMI-2 defined HBA attributes */ +/* Skip vendor_info and bios_state */ +#define LPFC_FDMI2_HBA_ATTR 0x0002efff /* * Port Attrubute Types @@ -1353,15 +1380,65 @@ struct lpfc_fdmi_reg_portattr { #define RPRT_OS_DEVICE_NAME 0x5 /* 4 to 256 byte ASCII string */ #define RPRT_HOST_NAME 0x6 /* 4 to 256 byte ASCII string */ #define RPRT_NODENAME 0x7 /* 8 byte WWNN */ -#define RPRT_PORTNAME 0x8 /* 8 byte WWNN */ +#define RPRT_PORTNAME 0x8 /* 8 byte WWPN */ #define RPRT_SYM_PORTNAME 0x9 /* 4 to 256 byte ASCII string */ #define RPRT_PORT_TYPE 0xa /* 32-bit unsigned int */ #define RPRT_SUPPORTED_CLASS 0xb /* 32-bit unsigned int */ -#define RPRT_FABRICNAME 0xc /* 8 byte Fabric WWNN */ +#define RPRT_FABRICNAME 0xc /* 8 byte Fabric WWPN */ #define RPRT_ACTIVE_FC4_TYPES 0xd /* 32 byte binary array */ #define RPRT_PORT_STATE 0x101 /* 32-bit unsigned int */ #define RPRT_DISC_PORT 0x102 /* 32-bit unsigned int */ #define RPRT_PORT_ID 0x103 /* 32-bit unsigned int */ +#define RPRT_SMART_SERVICE 0xf100 /* 4 to 256 byte ASCII string */ +#define RPRT_SMART_GUID 0xf101 /* 8 byte WWNN + 8 byte WWPN */ +#define RPRT_SMART_VERSION 0xf102 /* 4 to 256 byte ASCII string */ +#define RPRT_SMART_MODEL 0xf103 /* 4 to 256 byte ASCII string */ +#define RPRT_SMART_PORT_INFO 0xf104 /* 32-bit unsigned int */ +#define RPRT_SMART_QOS 0xf105 /* 32-bit unsigned int */ +#define RPRT_SMART_SECURITY 0xf106 /* 32-bit unsigned int */ + +/* Bit mask for all individual PORT attributes */ +#define LPFC_FDMI_PORT_ATTR_fc4type 0x00000001 +#define LPFC_FDMI_PORT_ATTR_support_speed 0x00000002 +#define LPFC_FDMI_PORT_ATTR_speed 0x00000004 +#define LPFC_FDMI_PORT_ATTR_max_frame 0x00000008 +#define LPFC_FDMI_PORT_ATTR_os_devname 0x00000010 +#define LPFC_FDMI_PORT_ATTR_host_name 0x00000020 +#define LPFC_FDMI_PORT_ATTR_wwnn 0x00000040 +#define LPFC_FDMI_PORT_ATTR_wwpn 0x00000080 +#define LPFC_FDMI_PORT_ATTR_symbolic_name 0x00000100 +#define LPFC_FDMI_PORT_ATTR_port_type 0x00000200 +#define LPFC_FDMI_PORT_ATTR_class 0x00000400 +#define LPFC_FDMI_PORT_ATTR_fabric_wwpn 0x00000800 +#define LPFC_FDMI_PORT_ATTR_port_state 0x00001000 +#define LPFC_FDMI_PORT_ATTR_active_fc4type 0x00002000 +#define LPFC_FDMI_PORT_ATTR_num_disc 0x00004000 +#define LPFC_FDMI_PORT_ATTR_nportid 0x00008000 +#define LPFC_FDMI_SMART_ATTR_service 0x00010000 /* Vendor specific */ +#define LPFC_FDMI_SMART_ATTR_guid 0x00020000 /* Vendor specific */ +#define LPFC_FDMI_SMART_ATTR_version 0x00040000 /* Vendor specific */ +#define LPFC_FDMI_SMART_ATTR_model 0x00080000 /* Vendor specific */ +#define LPFC_FDMI_SMART_ATTR_port_info 0x00100000 /* Vendor specific */ +#define LPFC_FDMI_SMART_ATTR_qos 0x00200000 /* Vendor specific */ +#define LPFC_FDMI_SMART_ATTR_security 0x00400000 /* Vendor specific */ + +/* Bit mask for FDMI-1 defined PORT attributes */ +#define LPFC_FDMI1_PORT_ATTR 0x0000003f + +/* Bit mask for FDMI-2 defined PORT attributes */ +#define LPFC_FDMI2_PORT_ATTR 0x0000ffff + +/* Bit mask for Smart SAN defined PORT attributes */ +#define LPFC_FDMI2_SMART_ATTR 0x007fffff + +/* Defines for PORT port state attribute */ +#define LPFC_FDMI_PORTSTATE_UNKNOWN 1 +#define LPFC_FDMI_PORTSTATE_ONLINE 2 + +/* Defines for PORT port type attribute */ +#define LPFC_FDMI_PORTTYPE_UNKNOWN 0 +#define LPFC_FDMI_PORTTYPE_NPORT 1 +#define LPFC_FDMI_PORTTYPE_NLPORT 2 /* * Begin HBA configuration parameters. @@ -2498,10 +2575,38 @@ typedef struct { /* Structure for MB Command READ_LINK_STAT (18) */ typedef struct { - uint32_t rsvd1; + uint32_t word0; + +#define lpfc_read_link_stat_rec_SHIFT 0 +#define lpfc_read_link_stat_rec_MASK 0x1 +#define lpfc_read_link_stat_rec_WORD word0 + +#define lpfc_read_link_stat_gec_SHIFT 1 +#define lpfc_read_link_stat_gec_MASK 0x1 +#define lpfc_read_link_stat_gec_WORD word0 + +#define lpfc_read_link_stat_w02oftow23of_SHIFT 2 +#define lpfc_read_link_stat_w02oftow23of_MASK 0x3FFFFF +#define lpfc_read_link_stat_w02oftow23of_WORD word0 + +#define lpfc_read_link_stat_rsvd_SHIFT 24 +#define lpfc_read_link_stat_rsvd_MASK 0x1F +#define lpfc_read_link_stat_rsvd_WORD word0 + +#define lpfc_read_link_stat_gec2_SHIFT 29 +#define lpfc_read_link_stat_gec2_MASK 0x1 +#define lpfc_read_link_stat_gec2_WORD word0 + +#define lpfc_read_link_stat_clrc_SHIFT 30 +#define lpfc_read_link_stat_clrc_MASK 0x1 +#define lpfc_read_link_stat_clrc_WORD word0 + +#define lpfc_read_link_stat_clof_SHIFT 31 +#define lpfc_read_link_stat_clof_MASK 0x1 +#define lpfc_read_link_stat_clof_WORD word0 + uint32_t linkFailureCnt; uint32_t lossSyncCnt; - uint32_t lossSignalCnt; uint32_t primSeqErrCnt; uint32_t invalidXmitWord; @@ -2509,6 +2614,19 @@ typedef struct { uint32_t primSeqTimeout; uint32_t elasticOverrun; uint32_t arbTimeout; + uint32_t advRecBufCredit; + uint32_t curRecBufCredit; + uint32_t advTransBufCredit; + uint32_t curTransBufCredit; + uint32_t recEofCount; + uint32_t recEofdtiCount; + uint32_t recEofniCount; + uint32_t recSofcount; + uint32_t rsvd1; + uint32_t rsvd2; + uint32_t recDrpXriCount; + uint32_t fecCorrBlkCount; + uint32_t fecUncorrBlkCount; } READ_LNK_VAR; /* Structure for MB Command REG_LOGIN (19) */ diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 5915407..d9753e3 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -1184,8 +1184,10 @@ lpfc_hb_timeout_handler(struct lpfc_hba *phba) vports = lpfc_create_vport_work_array(phba); if (vports != NULL) - for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) + for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { lpfc_rcv_seq_check_edtov(vports[i]); + lpfc_fdmi_num_disc_check(vports[i]); + } lpfc_destroy_vport_work_array(phba, vports); if ((phba->link_state == LPFC_HBA_ERROR) || @@ -1290,6 +1292,10 @@ lpfc_hb_timeout_handler(struct lpfc_hba *phba) jiffies + msecs_to_jiffies(1000 * LPFC_HB_MBOX_TIMEOUT)); } + } else { + mod_timer(&phba->hb_tmofunc, + jiffies + + msecs_to_jiffies(1000 * LPFC_HB_MBOX_INTERVAL)); } } @@ -2621,7 +2627,6 @@ void lpfc_stop_vport_timers(struct lpfc_vport *vport) { del_timer_sync(&vport->els_tmofunc); - del_timer_sync(&vport->fc_fdmitmo); del_timer_sync(&vport->delayed_disc_tmo); lpfc_can_disctmo(vport); return; @@ -3340,10 +3345,6 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev) vport->fc_disctmo.function = lpfc_disc_timeout; vport->fc_disctmo.data = (unsigned long)vport; - init_timer(&vport->fc_fdmitmo); - vport->fc_fdmitmo.function = lpfc_fdmi_tmo; - vport->fc_fdmitmo.data = (unsigned long)vport; - init_timer(&vport->els_tmofunc); vport->els_tmofunc.function = lpfc_els_timeout; vport->els_tmofunc.data = (unsigned long)vport; @@ -6159,6 +6160,20 @@ lpfc_create_shost(struct lpfc_hba *phba) /* Put reference to SCSI host to driver's device private data */ pci_set_drvdata(phba->pcidev, shost); + /* + * At this point we are fully registered with PSA. In addition, + * any initial discovery should be completed. + */ + vport->load_flag |= FC_ALLOW_FDMI; + if (phba->cfg_fdmi_on > LPFC_FDMI_NO_SUPPORT) { + + /* Setup appropriate attribute masks */ + vport->fdmi_hba_mask = LPFC_FDMI2_HBA_ATTR; + if (phba->cfg_fdmi_on == LPFC_FDMI_SMART_SAN) + vport->fdmi_port_mask = LPFC_FDMI2_SMART_ATTR; + else + vport->fdmi_port_mask = LPFC_FDMI2_PORT_ATTR; + } return 0; } diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c index 7690126..b3f85de 100644 --- a/drivers/scsi/lpfc/lpfc_vport.c +++ b/drivers/scsi/lpfc/lpfc_vport.c @@ -393,6 +393,14 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable) *(struct lpfc_vport **)fc_vport->dd_data = vport; vport->fc_vport = fc_vport; + /* At this point we are fully registered with SCSI Layer. */ + vport->load_flag |= FC_ALLOW_FDMI; + if (phba->cfg_fdmi_on > LPFC_FDMI_NO_SUPPORT) { + /* Setup appropriate attribute masks */ + vport->fdmi_hba_mask = phba->pport->fdmi_hba_mask; + vport->fdmi_port_mask = phba->pport->fdmi_port_mask; + } + /* * In SLI4, the vpi must be activated before it can be used * by the port. -- cgit v0.10.2 From 81e7517723fc17396ba91f59312b3177266ddbda Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 16 Dec 2015 18:11:59 -0500 Subject: lpfc: Fix RDP Speed reporting. Fix RDP Speed reporting. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Reviewed-by: Hannes Reinicke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 3394648..f7a2967 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -4730,28 +4730,25 @@ lpfc_rdp_res_speed(struct fc_rdp_port_speed_desc *desc, struct lpfc_hba *phba) desc->tag = cpu_to_be32(RDP_PORT_SPEED_DESC_TAG); - switch (phba->sli4_hba.link_state.speed) { - case LPFC_FC_LA_SPEED_1G: + switch (phba->fc_linkspeed) { + case LPFC_LINK_SPEED_1GHZ: rdp_speed = RDP_PS_1GB; break; - case LPFC_FC_LA_SPEED_2G: + case LPFC_LINK_SPEED_2GHZ: rdp_speed = RDP_PS_2GB; break; - case LPFC_FC_LA_SPEED_4G: + case LPFC_LINK_SPEED_4GHZ: rdp_speed = RDP_PS_4GB; break; - case LPFC_FC_LA_SPEED_8G: + case LPFC_LINK_SPEED_8GHZ: rdp_speed = RDP_PS_8GB; break; - case LPFC_FC_LA_SPEED_10G: + case LPFC_LINK_SPEED_10GHZ: rdp_speed = RDP_PS_10GB; break; - case LPFC_FC_LA_SPEED_16G: + case LPFC_LINK_SPEED_16GHZ: rdp_speed = RDP_PS_16GB; break; - case LPFC_FC_LA_SPEED_32G: - rdp_speed = RDP_PS_32GB; - break; default: rdp_speed = RDP_PS_UNKNOWN; break; -- cgit v0.10.2 From eb8d68c9930f7f9c8f3f4a6059b051b32077a735 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 16 Dec 2015 18:12:00 -0500 Subject: lpfc: Fix RDP ACC being too long. Fix RDP ACC being too long. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Reviewed-by: Hannes Reinicke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index f7a2967..817cdfc 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -4824,6 +4824,7 @@ lpfc_els_rdp_cmpl(struct lpfc_hba *phba, struct lpfc_rdp_context *rdp_context, struct lpfc_nodelist *ndlp = rdp_context->ndlp; struct lpfc_vport *vport = ndlp->vport; struct lpfc_iocbq *elsiocb; + struct ulp_bde64 *bpl; IOCB_t *icmd; uint8_t *pcmd; struct ls_rjt *stat; @@ -4833,6 +4834,8 @@ lpfc_els_rdp_cmpl(struct lpfc_hba *phba, struct lpfc_rdp_context *rdp_context, if (status != SUCCESS) goto error; + + /* This will change once we know the true size of the RDP payload */ cmdsize = sizeof(struct fc_rdp_res_frame); elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, @@ -4874,6 +4877,13 @@ lpfc_els_rdp_cmpl(struct lpfc_hba *phba, struct lpfc_rdp_context *rdp_context, rdp_res->length = cpu_to_be32(fec_size + RDP_DESC_PAYLOAD_SIZE); elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; + /* Now that we know the true size of the payload, update the BPL */ + bpl = (struct ulp_bde64 *) + (((struct lpfc_dmabuf *)(elsiocb->context3))->virt); + bpl->tus.f.bdeSize = (fec_size + RDP_DESC_PAYLOAD_SIZE + 8); + bpl->tus.f.bdeFlags = 0; + bpl->tus.w = le32_to_cpu(bpl->tus.w); + phba->fc_stat.elsXmitACC++; rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); if (rc == IOCB_ERROR) -- cgit v0.10.2 From 5afab6bbf3f026b7d50451acbfdc12300c5f4353 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 16 Dec 2015 18:12:01 -0500 Subject: lpfc: Make write check error processing more resilient Make write check error processing more resilient. Checks to catch writes that fw reports weren't fully complete yet SCSI status indicated fine needed correction. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Reviewed-by: Hannes Reinicke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index ab446f8..964a996 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -3676,6 +3676,7 @@ static void lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, struct lpfc_iocbq *rsp_iocb) { + struct lpfc_hba *phba = vport->phba; struct scsi_cmnd *cmnd = lpfc_cmd->pCmd; struct fcp_cmnd *fcpcmd = lpfc_cmd->fcp_cmnd; struct fcp_rsp *fcprsp = lpfc_cmd->fcp_rsp; @@ -3685,6 +3686,7 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, uint32_t *lp; uint32_t host_status = DID_OK; uint32_t rsplen = 0; + uint32_t fcpDl; uint32_t logit = LOG_FCP | LOG_FCP_ERROR; @@ -3755,13 +3757,14 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, fcprsp->rspInfo3); scsi_set_resid(cmnd, 0); + fcpDl = be32_to_cpu(fcpcmd->fcpDl); if (resp_info & RESID_UNDER) { scsi_set_resid(cmnd, be32_to_cpu(fcprsp->rspResId)); lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP_UNDER, "9025 FCP Read Underrun, expected %d, " "residual %d Data: x%x x%x x%x\n", - be32_to_cpu(fcpcmd->fcpDl), + fcpDl, scsi_get_resid(cmnd), fcpi_parm, cmnd->cmnd[0], cmnd->underflow); @@ -3777,7 +3780,7 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, LOG_FCP | LOG_FCP_ERROR, "9026 FCP Read Check Error " "and Underrun Data: x%x x%x x%x x%x\n", - be32_to_cpu(fcpcmd->fcpDl), + fcpDl, scsi_get_resid(cmnd), fcpi_parm, cmnd->cmnd[0]); scsi_set_resid(cmnd, scsi_bufflen(cmnd)); @@ -3812,13 +3815,25 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, * Check SLI validation that all the transfer was actually done * (fcpi_parm should be zero). Apply check only to reads. */ - } else if (fcpi_parm && (cmnd->sc_data_direction == DMA_FROM_DEVICE)) { + } else if (fcpi_parm) { lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP | LOG_FCP_ERROR, - "9029 FCP Read Check Error Data: " + "9029 FCP %s Check Error xri x%x Data: " "x%x x%x x%x x%x x%x\n", - be32_to_cpu(fcpcmd->fcpDl), - be32_to_cpu(fcprsp->rspResId), + ((cmnd->sc_data_direction == DMA_FROM_DEVICE) ? + "Read" : "Write"), + ((phba->sli_rev == LPFC_SLI_REV4) ? + lpfc_cmd->cur_iocbq.sli4_xritag : + rsp_iocb->iocb.ulpContext), + fcpDl, be32_to_cpu(fcprsp->rspResId), fcpi_parm, cmnd->cmnd[0], scsi_status); + + /* There is some issue with the LPe12000 that causes it + * to miscalculate the fcpi_parm and falsely trip this + * recovery logic. Detect this case and don't error when true. + */ + if (fcpi_parm > fcpDl) + goto out; + switch (scsi_status) { case SAM_STAT_GOOD: case SAM_STAT_CHECK_CONDITION: -- cgit v0.10.2 From a085e87c814567c94e5d375e7362f9f25030aac1 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 16 Dec 2015 18:12:02 -0500 Subject: lpfc: Use new FDMI speed definitions for 10G, 25G and 40G FCoE. Use new FDMI speed definitions for 10G, 25G and 40G FCoE. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Reviewed-by: Hannes Reinicke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 5739c26..343ae94 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -5255,7 +5255,7 @@ lpfc_get_host_speed(struct Scsi_Host *shost) spin_lock_irq(shost->host_lock); - if (lpfc_is_link_up(phba)) { + if ((lpfc_is_link_up(phba)) && (!(phba->hba_flag & HBA_FCOE_MODE))) { switch(phba->fc_linkspeed) { case LPFC_LINK_SPEED_1GHZ: fc_host_speed(shost) = FC_PORTSPEED_1GBIT; diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index ac6e087..79e261d 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -48,15 +48,26 @@ #include "lpfc_vport.h" #include "lpfc_debugfs.h" -/* FDMI Port Speed definitions */ -#define HBA_PORTSPEED_1GBIT 0x0001 /* 1 GBit/sec */ -#define HBA_PORTSPEED_2GBIT 0x0002 /* 2 GBit/sec */ -#define HBA_PORTSPEED_4GBIT 0x0008 /* 4 GBit/sec */ -#define HBA_PORTSPEED_10GBIT 0x0004 /* 10 GBit/sec */ -#define HBA_PORTSPEED_8GBIT 0x0010 /* 8 GBit/sec */ -#define HBA_PORTSPEED_16GBIT 0x0020 /* 16 GBit/sec */ -#define HBA_PORTSPEED_32GBIT 0x0040 /* 32 GBit/sec */ -#define HBA_PORTSPEED_UNKNOWN 0x0800 /* Unknown */ +/* FDMI Port Speed definitions - FC-GS-7 */ +#define HBA_PORTSPEED_1GFC 0x00000001 /* 1G FC */ +#define HBA_PORTSPEED_2GFC 0x00000002 /* 2G FC */ +#define HBA_PORTSPEED_4GFC 0x00000008 /* 4G FC */ +#define HBA_PORTSPEED_10GFC 0x00000004 /* 10G FC */ +#define HBA_PORTSPEED_8GFC 0x00000010 /* 8G FC */ +#define HBA_PORTSPEED_16GFC 0x00000020 /* 16G FC */ +#define HBA_PORTSPEED_32GFC 0x00000040 /* 32G FC */ +#define HBA_PORTSPEED_20GFC 0x00000080 /* 20G FC */ +#define HBA_PORTSPEED_40GFC 0x00000100 /* 40G FC */ +#define HBA_PORTSPEED_128GFC 0x00000200 /* 128G FC */ +#define HBA_PORTSPEED_64GFC 0x00000400 /* 64G FC */ +#define HBA_PORTSPEED_256GFC 0x00000800 /* 256G FC */ +#define HBA_PORTSPEED_UNKNOWN 0x00008000 /* Unknown */ +#define HBA_PORTSPEED_10GE 0x00010000 /* 10G E */ +#define HBA_PORTSPEED_40GE 0x00020000 /* 40G E */ +#define HBA_PORTSPEED_100GE 0x00040000 /* 100G E */ +#define HBA_PORTSPEED_25GE 0x00080000 /* 25G E */ +#define HBA_PORTSPEED_50GE 0x00100000 /* 50G E */ +#define HBA_PORTSPEED_400GE 0x00200000 /* 400G E */ #define FOURBYTES 4 @@ -1921,20 +1932,38 @@ lpfc_fdmi_port_attr_support_speed(struct lpfc_vport *vport, ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; ae->un.AttrInt = 0; - if (phba->lmt & LMT_32Gb) - ae->un.AttrInt |= HBA_PORTSPEED_32GBIT; - if (phba->lmt & LMT_16Gb) - ae->un.AttrInt |= HBA_PORTSPEED_16GBIT; - if (phba->lmt & LMT_10Gb) - ae->un.AttrInt |= HBA_PORTSPEED_10GBIT; - if (phba->lmt & LMT_8Gb) - ae->un.AttrInt |= HBA_PORTSPEED_8GBIT; - if (phba->lmt & LMT_4Gb) - ae->un.AttrInt |= HBA_PORTSPEED_4GBIT; - if (phba->lmt & LMT_2Gb) - ae->un.AttrInt |= HBA_PORTSPEED_2GBIT; - if (phba->lmt & LMT_1Gb) - ae->un.AttrInt |= HBA_PORTSPEED_1GBIT; + if (!(phba->hba_flag & HBA_FCOE_MODE)) { + if (phba->lmt & LMT_32Gb) + ae->un.AttrInt |= HBA_PORTSPEED_32GFC; + if (phba->lmt & LMT_16Gb) + ae->un.AttrInt |= HBA_PORTSPEED_16GFC; + if (phba->lmt & LMT_10Gb) + ae->un.AttrInt |= HBA_PORTSPEED_10GFC; + if (phba->lmt & LMT_8Gb) + ae->un.AttrInt |= HBA_PORTSPEED_8GFC; + if (phba->lmt & LMT_4Gb) + ae->un.AttrInt |= HBA_PORTSPEED_4GFC; + if (phba->lmt & LMT_2Gb) + ae->un.AttrInt |= HBA_PORTSPEED_2GFC; + if (phba->lmt & LMT_1Gb) + ae->un.AttrInt |= HBA_PORTSPEED_1GFC; + } else { + /* FCoE links support only one speed */ + switch (phba->fc_linkspeed) { + case LPFC_ASYNC_LINK_SPEED_10GBPS: + ae->un.AttrInt = HBA_PORTSPEED_10GE; + break; + case LPFC_ASYNC_LINK_SPEED_25GBPS: + ae->un.AttrInt = HBA_PORTSPEED_25GE; + break; + case LPFC_ASYNC_LINK_SPEED_40GBPS: + ae->un.AttrInt = HBA_PORTSPEED_40GE; + break; + case LPFC_ASYNC_LINK_SPEED_100GBPS: + ae->un.AttrInt = HBA_PORTSPEED_100GE; + break; + } + } ae->un.AttrInt = cpu_to_be32(ae->un.AttrInt); size = FOURBYTES + sizeof(uint32_t); ad->AttrLen = cpu_to_be16(size); @@ -1952,32 +1981,53 @@ lpfc_fdmi_port_attr_speed(struct lpfc_vport *vport, ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - switch (phba->fc_linkspeed) { - case LPFC_LINK_SPEED_1GHZ: - ae->un.AttrInt = HBA_PORTSPEED_1GBIT; - break; - case LPFC_LINK_SPEED_2GHZ: - ae->un.AttrInt = HBA_PORTSPEED_2GBIT; - break; - case LPFC_LINK_SPEED_4GHZ: - ae->un.AttrInt = HBA_PORTSPEED_4GBIT; - break; - case LPFC_LINK_SPEED_8GHZ: - ae->un.AttrInt = HBA_PORTSPEED_8GBIT; - break; - case LPFC_LINK_SPEED_10GHZ: - ae->un.AttrInt = HBA_PORTSPEED_10GBIT; - break; - case LPFC_LINK_SPEED_16GHZ: - ae->un.AttrInt = HBA_PORTSPEED_16GBIT; - break; - case LPFC_LINK_SPEED_32GHZ: - ae->un.AttrInt = HBA_PORTSPEED_32GBIT; - break; - default: - ae->un.AttrInt = HBA_PORTSPEED_UNKNOWN; - break; + if (!(phba->hba_flag & HBA_FCOE_MODE)) { + switch (phba->fc_linkspeed) { + case LPFC_LINK_SPEED_1GHZ: + ae->un.AttrInt = HBA_PORTSPEED_1GFC; + break; + case LPFC_LINK_SPEED_2GHZ: + ae->un.AttrInt = HBA_PORTSPEED_2GFC; + break; + case LPFC_LINK_SPEED_4GHZ: + ae->un.AttrInt = HBA_PORTSPEED_4GFC; + break; + case LPFC_LINK_SPEED_8GHZ: + ae->un.AttrInt = HBA_PORTSPEED_8GFC; + break; + case LPFC_LINK_SPEED_10GHZ: + ae->un.AttrInt = HBA_PORTSPEED_10GFC; + break; + case LPFC_LINK_SPEED_16GHZ: + ae->un.AttrInt = HBA_PORTSPEED_16GFC; + break; + case LPFC_LINK_SPEED_32GHZ: + ae->un.AttrInt = HBA_PORTSPEED_32GFC; + break; + default: + ae->un.AttrInt = HBA_PORTSPEED_UNKNOWN; + break; + } + } else { + switch (phba->fc_linkspeed) { + case LPFC_ASYNC_LINK_SPEED_10GBPS: + ae->un.AttrInt = HBA_PORTSPEED_10GE; + break; + case LPFC_ASYNC_LINK_SPEED_25GBPS: + ae->un.AttrInt = HBA_PORTSPEED_25GE; + break; + case LPFC_ASYNC_LINK_SPEED_40GBPS: + ae->un.AttrInt = HBA_PORTSPEED_40GE; + break; + case LPFC_ASYNC_LINK_SPEED_100GBPS: + ae->un.AttrInt = HBA_PORTSPEED_100GE; + break; + default: + ae->un.AttrInt = HBA_PORTSPEED_UNKNOWN; + break; + } } + ae->un.AttrInt = cpu_to_be32(ae->un.AttrInt); size = FOURBYTES + sizeof(uint32_t); ad->AttrLen = cpu_to_be16(size); diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 817cdfc..273a1db 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -4749,6 +4749,9 @@ lpfc_rdp_res_speed(struct fc_rdp_port_speed_desc *desc, struct lpfc_hba *phba) case LPFC_LINK_SPEED_16GHZ: rdp_speed = RDP_PS_16GB; break; + case LPFC_LINK_SPEED_32GHZ: + rdp_speed = RDP_PS_32GB; + break; default: rdp_speed = RDP_PS_UNKNOWN; break; diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 1bad678..c37d72e 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -3037,19 +3037,22 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la) uint32_t fc_flags = 0; spin_lock_irq(&phba->hbalock); - switch (bf_get(lpfc_mbx_read_top_link_spd, la)) { - case LPFC_LINK_SPEED_1GHZ: - case LPFC_LINK_SPEED_2GHZ: - case LPFC_LINK_SPEED_4GHZ: - case LPFC_LINK_SPEED_8GHZ: - case LPFC_LINK_SPEED_10GHZ: - case LPFC_LINK_SPEED_16GHZ: - case LPFC_LINK_SPEED_32GHZ: - phba->fc_linkspeed = bf_get(lpfc_mbx_read_top_link_spd, la); - break; - default: - phba->fc_linkspeed = LPFC_LINK_SPEED_UNKNOWN; - break; + phba->fc_linkspeed = bf_get(lpfc_mbx_read_top_link_spd, la); + + if (!(phba->hba_flag & HBA_FCOE_MODE)) { + switch (bf_get(lpfc_mbx_read_top_link_spd, la)) { + case LPFC_LINK_SPEED_1GHZ: + case LPFC_LINK_SPEED_2GHZ: + case LPFC_LINK_SPEED_4GHZ: + case LPFC_LINK_SPEED_8GHZ: + case LPFC_LINK_SPEED_10GHZ: + case LPFC_LINK_SPEED_16GHZ: + case LPFC_LINK_SPEED_32GHZ: + break; + default: + phba->fc_linkspeed = LPFC_LINK_SPEED_UNKNOWN; + break; + } } if (phba->fc_topology && diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index 33ec4fa..f13a76a 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h @@ -3317,6 +3317,7 @@ struct lpfc_acqe_link { #define LPFC_ASYNC_LINK_SPEED_20GBPS 0x5 #define LPFC_ASYNC_LINK_SPEED_25GBPS 0x6 #define LPFC_ASYNC_LINK_SPEED_40GBPS 0x7 +#define LPFC_ASYNC_LINK_SPEED_100GBPS 0x8 #define lpfc_acqe_link_duplex_SHIFT 16 #define lpfc_acqe_link_duplex_MASK 0x000000FF #define lpfc_acqe_link_duplex_WORD word0 diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index d9753e3..614f357 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -3710,49 +3710,6 @@ lpfc_sli4_parse_latt_type(struct lpfc_hba *phba, } /** - * lpfc_sli4_parse_latt_link_speed - Parse sli4 link-attention link speed - * @phba: pointer to lpfc hba data structure. - * @acqe_link: pointer to the async link completion queue entry. - * - * This routine is to parse the SLI4 link-attention link speed and translate - * it into the base driver's link-attention link speed coding. - * - * Return: Link-attention link speed in terms of base driver's coding. - **/ -static uint8_t -lpfc_sli4_parse_latt_link_speed(struct lpfc_hba *phba, - struct lpfc_acqe_link *acqe_link) -{ - uint8_t link_speed; - - switch (bf_get(lpfc_acqe_link_speed, acqe_link)) { - case LPFC_ASYNC_LINK_SPEED_ZERO: - case LPFC_ASYNC_LINK_SPEED_10MBPS: - case LPFC_ASYNC_LINK_SPEED_100MBPS: - link_speed = LPFC_LINK_SPEED_UNKNOWN; - break; - case LPFC_ASYNC_LINK_SPEED_1GBPS: - link_speed = LPFC_LINK_SPEED_1GHZ; - break; - case LPFC_ASYNC_LINK_SPEED_10GBPS: - link_speed = LPFC_LINK_SPEED_10GHZ; - break; - case LPFC_ASYNC_LINK_SPEED_20GBPS: - case LPFC_ASYNC_LINK_SPEED_25GBPS: - case LPFC_ASYNC_LINK_SPEED_40GBPS: - link_speed = LPFC_LINK_SPEED_UNKNOWN; - break; - default: - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "0483 Invalid link-attention link speed: x%x\n", - bf_get(lpfc_acqe_link_speed, acqe_link)); - link_speed = LPFC_LINK_SPEED_UNKNOWN; - break; - } - return link_speed; -} - -/** * lpfc_sli_port_speed_get - Get sli3 link speed code to link speed * @phba: pointer to lpfc hba data structure. * @@ -3768,27 +3725,35 @@ lpfc_sli_port_speed_get(struct lpfc_hba *phba) if (!lpfc_is_link_up(phba)) return 0; - switch (phba->fc_linkspeed) { - case LPFC_LINK_SPEED_1GHZ: - link_speed = 1000; - break; - case LPFC_LINK_SPEED_2GHZ: - link_speed = 2000; - break; - case LPFC_LINK_SPEED_4GHZ: - link_speed = 4000; - break; - case LPFC_LINK_SPEED_8GHZ: - link_speed = 8000; - break; - case LPFC_LINK_SPEED_10GHZ: - link_speed = 10000; - break; - case LPFC_LINK_SPEED_16GHZ: - link_speed = 16000; - break; - default: - link_speed = 0; + if (phba->sli_rev <= LPFC_SLI_REV3) { + switch (phba->fc_linkspeed) { + case LPFC_LINK_SPEED_1GHZ: + link_speed = 1000; + break; + case LPFC_LINK_SPEED_2GHZ: + link_speed = 2000; + break; + case LPFC_LINK_SPEED_4GHZ: + link_speed = 4000; + break; + case LPFC_LINK_SPEED_8GHZ: + link_speed = 8000; + break; + case LPFC_LINK_SPEED_10GHZ: + link_speed = 10000; + break; + case LPFC_LINK_SPEED_16GHZ: + link_speed = 16000; + break; + default: + link_speed = 0; + } + } else { + if (phba->sli4_hba.link_state.logical_speed) + link_speed = + phba->sli4_hba.link_state.logical_speed; + else + link_speed = phba->sli4_hba.link_state.speed; } return link_speed; } @@ -3984,7 +3949,7 @@ lpfc_sli4_async_link_evt(struct lpfc_hba *phba, la->eventTag = acqe_link->event_tag; bf_set(lpfc_mbx_read_top_att_type, la, att_type); bf_set(lpfc_mbx_read_top_link_spd, la, - lpfc_sli4_parse_latt_link_speed(phba, acqe_link)); + (bf_get(lpfc_acqe_link_speed, acqe_link))); /* Fake the the following irrelvant fields */ bf_set(lpfc_mbx_read_top_topology, la, LPFC_TOPOLOGY_PT_PT); diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 964a996..152b3c8 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -4461,15 +4461,7 @@ lpfc_info(struct Scsi_Host *host) phba->Port); } len = strlen(lpfcinfobuf); - if (phba->sli_rev <= LPFC_SLI_REV3) { - link_speed = lpfc_sli_port_speed_get(phba); - } else { - if (phba->sli4_hba.link_state.logical_speed) - link_speed = - phba->sli4_hba.link_state.logical_speed; - else - link_speed = phba->sli4_hba.link_state.speed; - } + link_speed = lpfc_sli_port_speed_get(phba); if (link_speed != 0) snprintf(lpfcinfobuf + len, 384-len, " Logical Link Speed: %d Mbps", link_speed); -- cgit v0.10.2 From 01c73bbcd7cc4f31f45a1b0caeacdba46acd9c9c Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 16 Dec 2015 18:12:03 -0500 Subject: lpfc: Fix mbox reuse in PLOGI completion Fix mbox reuse in PLOGI completion. Moved allocations so that buffer properly init'd. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Reviewed-by: Hannes Reinicke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index 9e571dd..193733e 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -1045,16 +1045,6 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport, if (irsp->ulpStatus) goto out; - mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); - if (!mbox) { - lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, - "0133 PLOGI: no memory for reg_login " - "Data: x%x x%x x%x x%x\n", - ndlp->nlp_DID, ndlp->nlp_state, - ndlp->nlp_flag, ndlp->nlp_rpi); - goto out; - } - pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; prsp = list_get_first(&pcmd->list, struct lpfc_dmabuf, list); @@ -1118,6 +1108,17 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport, if (phba->sli_rev == LPFC_SLI_REV4) { lpfc_issue_reg_vfi(vport); } else { + mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); + if (!mbox) { + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "0133 PLOGI: no memory " + "for config_link " + "Data: x%x x%x x%x x%x\n", + ndlp->nlp_DID, ndlp->nlp_state, + ndlp->nlp_flag, ndlp->nlp_rpi); + goto out; + } + lpfc_config_link(phba, mbox); mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; @@ -1132,6 +1133,16 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport, lpfc_unreg_rpi(vport, ndlp); + mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); + if (!mbox) { + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "0018 PLOGI: no memory for reg_login " + "Data: x%x x%x x%x x%x\n", + ndlp->nlp_DID, ndlp->nlp_state, + ndlp->nlp_flag, ndlp->nlp_rpi); + goto out; + } + if (lpfc_reg_rpi(phba, vport->vpi, irsp->un.elsreq64.remoteID, (uint8_t *) sp, mbox, ndlp->nlp_rpi) == 0) { switch (ndlp->nlp_DID) { -- cgit v0.10.2 From 4360ca9c24388e44cb0e14861a62fff43cf225c0 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 16 Dec 2015 18:12:04 -0500 Subject: lpfc: Fix external loopback failure. Fix external loopback failure. Rx sequence reassembly was incorrect. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Reviewed-by: Hannes Reinicke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 6aae828..92dfd6a 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -14842,10 +14842,12 @@ lpfc_fc_frame_add(struct lpfc_vport *vport, struct hbq_dmabuf *dmabuf) struct lpfc_dmabuf *h_buf; struct hbq_dmabuf *seq_dmabuf = NULL; struct hbq_dmabuf *temp_dmabuf = NULL; + uint8_t found = 0; INIT_LIST_HEAD(&dmabuf->dbuf.list); dmabuf->time_stamp = jiffies; new_hdr = (struct fc_frame_header *)dmabuf->hbuf.virt; + /* Use the hdr_buf to find the sequence that this frame belongs to */ list_for_each_entry(h_buf, &vport->rcv_buffer_list, list) { temp_hdr = (struct fc_frame_header *)h_buf->virt; @@ -14885,7 +14887,8 @@ lpfc_fc_frame_add(struct lpfc_vport *vport, struct hbq_dmabuf *dmabuf) return seq_dmabuf; } /* find the correct place in the sequence to insert this frame */ - list_for_each_entry_reverse(d_buf, &seq_dmabuf->dbuf.list, list) { + d_buf = list_entry(seq_dmabuf->dbuf.list.prev, typeof(*d_buf), list); + while (!found) { temp_dmabuf = container_of(d_buf, struct hbq_dmabuf, dbuf); temp_hdr = (struct fc_frame_header *)temp_dmabuf->hbuf.virt; /* @@ -14895,9 +14898,17 @@ lpfc_fc_frame_add(struct lpfc_vport *vport, struct hbq_dmabuf *dmabuf) if (be16_to_cpu(new_hdr->fh_seq_cnt) > be16_to_cpu(temp_hdr->fh_seq_cnt)) { list_add(&dmabuf->dbuf.list, &temp_dmabuf->dbuf.list); - return seq_dmabuf; + found = 1; + break; } + + if (&d_buf->list == &seq_dmabuf->dbuf.list) + break; + d_buf = list_entry(d_buf->list.prev, typeof(*d_buf), list); } + + if (found) + return seq_dmabuf; return NULL; } -- cgit v0.10.2 From 448193b5b5e2471fc90ea11e78c39bcfd167efb6 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 16 Dec 2015 18:12:05 -0500 Subject: lpfc: Add logging for misconfigured optics. Add logging for misconfigured optics acqe reported by fw. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Reviewed-by: Hannes Reinicke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index f13a76a..608f941 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h @@ -3448,23 +3448,50 @@ struct lpfc_acqe_fc_la { struct lpfc_acqe_misconfigured_event { struct { uint32_t word0; -#define lpfc_sli_misconfigured_port0_SHIFT 0 -#define lpfc_sli_misconfigured_port0_MASK 0x000000FF -#define lpfc_sli_misconfigured_port0_WORD word0 -#define lpfc_sli_misconfigured_port1_SHIFT 8 -#define lpfc_sli_misconfigured_port1_MASK 0x000000FF -#define lpfc_sli_misconfigured_port1_WORD word0 -#define lpfc_sli_misconfigured_port2_SHIFT 16 -#define lpfc_sli_misconfigured_port2_MASK 0x000000FF -#define lpfc_sli_misconfigured_port2_WORD word0 -#define lpfc_sli_misconfigured_port3_SHIFT 24 -#define lpfc_sli_misconfigured_port3_MASK 0x000000FF -#define lpfc_sli_misconfigured_port3_WORD word0 +#define lpfc_sli_misconfigured_port0_state_SHIFT 0 +#define lpfc_sli_misconfigured_port0_state_MASK 0x000000FF +#define lpfc_sli_misconfigured_port0_state_WORD word0 +#define lpfc_sli_misconfigured_port1_state_SHIFT 8 +#define lpfc_sli_misconfigured_port1_state_MASK 0x000000FF +#define lpfc_sli_misconfigured_port1_state_WORD word0 +#define lpfc_sli_misconfigured_port2_state_SHIFT 16 +#define lpfc_sli_misconfigured_port2_state_MASK 0x000000FF +#define lpfc_sli_misconfigured_port2_state_WORD word0 +#define lpfc_sli_misconfigured_port3_state_SHIFT 24 +#define lpfc_sli_misconfigured_port3_state_MASK 0x000000FF +#define lpfc_sli_misconfigured_port3_state_WORD word0 + uint32_t word1; +#define lpfc_sli_misconfigured_port0_op_SHIFT 0 +#define lpfc_sli_misconfigured_port0_op_MASK 0x00000001 +#define lpfc_sli_misconfigured_port0_op_WORD word1 +#define lpfc_sli_misconfigured_port0_severity_SHIFT 1 +#define lpfc_sli_misconfigured_port0_severity_MASK 0x00000003 +#define lpfc_sli_misconfigured_port0_severity_WORD word1 +#define lpfc_sli_misconfigured_port1_op_SHIFT 8 +#define lpfc_sli_misconfigured_port1_op_MASK 0x00000001 +#define lpfc_sli_misconfigured_port1_op_WORD word1 +#define lpfc_sli_misconfigured_port1_severity_SHIFT 9 +#define lpfc_sli_misconfigured_port1_severity_MASK 0x00000003 +#define lpfc_sli_misconfigured_port1_severity_WORD word1 +#define lpfc_sli_misconfigured_port2_op_SHIFT 16 +#define lpfc_sli_misconfigured_port2_op_MASK 0x00000001 +#define lpfc_sli_misconfigured_port2_op_WORD word1 +#define lpfc_sli_misconfigured_port2_severity_SHIFT 17 +#define lpfc_sli_misconfigured_port2_severity_MASK 0x00000003 +#define lpfc_sli_misconfigured_port2_severity_WORD word1 +#define lpfc_sli_misconfigured_port3_op_SHIFT 24 +#define lpfc_sli_misconfigured_port3_op_MASK 0x00000001 +#define lpfc_sli_misconfigured_port3_op_WORD word1 +#define lpfc_sli_misconfigured_port3_severity_SHIFT 25 +#define lpfc_sli_misconfigured_port3_severity_MASK 0x00000003 +#define lpfc_sli_misconfigured_port3_severity_WORD word1 } theEvent; #define LPFC_SLI_EVENT_STATUS_VALID 0x00 #define LPFC_SLI_EVENT_STATUS_NOT_PRESENT 0x01 #define LPFC_SLI_EVENT_STATUS_WRONG_TYPE 0x02 #define LPFC_SLI_EVENT_STATUS_UNSUPPORTED 0x03 +#define LPFC_SLI_EVENT_STATUS_UNQUALIFIED 0x04 +#define LPFC_SLI_EVENT_STATUS_UNCERTIFIED 0x05 }; struct lpfc_acqe_sli { diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 614f357..a544366 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -4079,22 +4079,18 @@ lpfc_sli4_async_sli_evt(struct lpfc_hba *phba, struct lpfc_acqe_sli *acqe_sli) char message[128]; uint8_t status; uint8_t evt_type; + uint8_t operational = 0; struct temp_event temp_event_data; struct lpfc_acqe_misconfigured_event *misconfigured; struct Scsi_Host *shost; evt_type = bf_get(lpfc_trailer_type, acqe_sli); - /* Special case Lancer */ - if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) != - LPFC_SLI_INTF_IF_TYPE_2) { - lpfc_printf_log(phba, KERN_INFO, LOG_SLI, - "2901 Async SLI event - Event Data1:x%08x Event Data2:" - "x%08x SLI Event Type:%d\n", - acqe_sli->event_data1, acqe_sli->event_data2, - evt_type); - return; - } + lpfc_printf_log(phba, KERN_INFO, LOG_SLI, + "2901 Async SLI event - Event Data1:x%08x Event Data2:" + "x%08x SLI Event Type:%d\n", + acqe_sli->event_data1, acqe_sli->event_data2, + evt_type); port_name = phba->Port[0]; if (port_name == 0x00) @@ -4140,29 +4136,46 @@ lpfc_sli4_async_sli_evt(struct lpfc_hba *phba, struct lpfc_acqe_sli *acqe_sli) /* fetch the status for this port */ switch (phba->sli4_hba.lnk_info.lnk_no) { case LPFC_LINK_NUMBER_0: - status = bf_get(lpfc_sli_misconfigured_port0, + status = bf_get(lpfc_sli_misconfigured_port0_state, + &misconfigured->theEvent); + operational = bf_get(lpfc_sli_misconfigured_port0_op, &misconfigured->theEvent); break; case LPFC_LINK_NUMBER_1: - status = bf_get(lpfc_sli_misconfigured_port1, + status = bf_get(lpfc_sli_misconfigured_port1_state, + &misconfigured->theEvent); + operational = bf_get(lpfc_sli_misconfigured_port1_op, &misconfigured->theEvent); break; case LPFC_LINK_NUMBER_2: - status = bf_get(lpfc_sli_misconfigured_port2, + status = bf_get(lpfc_sli_misconfigured_port2_state, + &misconfigured->theEvent); + operational = bf_get(lpfc_sli_misconfigured_port2_op, &misconfigured->theEvent); break; case LPFC_LINK_NUMBER_3: - status = bf_get(lpfc_sli_misconfigured_port3, + status = bf_get(lpfc_sli_misconfigured_port3_state, + &misconfigured->theEvent); + operational = bf_get(lpfc_sli_misconfigured_port3_op, &misconfigured->theEvent); break; default: - status = ~LPFC_SLI_EVENT_STATUS_VALID; - break; + lpfc_printf_log(phba, KERN_ERR, LOG_SLI, + "3296 " + "LPFC_SLI_EVENT_TYPE_MISCONFIGURED " + "event: Invalid link %d", + phba->sli4_hba.lnk_info.lnk_no); + return; } + /* Skip if optic state unchanged */ + if (phba->sli4_hba.lnk_info.optic_state == status) + return; + switch (status) { case LPFC_SLI_EVENT_STATUS_VALID: - return; /* no message if the sfp is okay */ + sprintf(message, "Physical Link is functional"); + break; case LPFC_SLI_EVENT_STATUS_NOT_PRESENT: sprintf(message, "Optics faulted/incorrectly " "installed/not installed - Reseat optics, " @@ -4177,15 +4190,26 @@ lpfc_sli4_async_sli_evt(struct lpfc_hba *phba, struct lpfc_acqe_sli *acqe_sli) sprintf(message, "Incompatible optics - Replace with " "compatible optics for card to function."); break; + case LPFC_SLI_EVENT_STATUS_UNQUALIFIED: + sprintf(message, "Unqualified optics - Replace with " + "Avago optics for Warranty and Technical " + "Support - Link is%s operational", + (operational) ? "" : " not"); + break; + case LPFC_SLI_EVENT_STATUS_UNCERTIFIED: + sprintf(message, "Uncertified optics - Replace with " + "Avago-certified optics to enable link " + "operation - Link is%s operational", + (operational) ? "" : " not"); + break; default: /* firmware is reporting a status we don't know about */ sprintf(message, "Unknown event status x%02x", status); break; } - + phba->sli4_hba.lnk_info.optic_state = status; lpfc_printf_log(phba, KERN_ERR, LOG_SLI, - "3176 Misconfigured Physical Port - " - "Port Name %c %s\n", port_name, message); + "3176 Port Name %c %s\n", port_name, message); break; case LPFC_SLI_EVENT_TYPE_REMOTE_DPORT: lpfc_printf_log(phba, KERN_INFO, LOG_SLI, @@ -5259,6 +5283,9 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) INIT_LIST_HEAD(&phba->sli4_hba.lpfc_vfi_blk_list); INIT_LIST_HEAD(&phba->lpfc_vpi_blk_list); + /* initialize optic_state to 0xFF */ + phba->sli4_hba.lnk_info.optic_state = 0xff; + /* Initialize the driver internal SLI layer lists. */ lpfc_sli_setup(phba); lpfc_sli_queue_setup(phba); diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index 1e916e1..cd780c2 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h @@ -442,6 +442,7 @@ struct lpfc_sli4_lnk_info { #define LPFC_LNK_GE 0x0 /* FCoE */ #define LPFC_LNK_FC 0x1 /* FC */ uint8_t lnk_no; + uint8_t optic_state; }; #define LPFC_SLI4_HANDLER_CNT (LPFC_FCP_IO_CHAN_MAX+ \ -- cgit v0.10.2 From 9be321819c43417432a8376428b90fe3fe3a3510 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 16 Dec 2015 18:12:06 -0500 Subject: lpfc: Delete unnecessary checks before the function call "mempool_destroy" The mempool_destroy() function tests whether its argument is NULL and then returns immediately. Thus the test around the calls is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: James Smart Reviewed-by: Hannes Reinicke Reviewed-by: Sebastian Herbszt Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c index 3fa6533..4fb3581 100644 --- a/drivers/scsi/lpfc/lpfc_mem.c +++ b/drivers/scsi/lpfc/lpfc_mem.c @@ -231,15 +231,13 @@ lpfc_mem_free(struct lpfc_hba *phba) if (phba->lpfc_hbq_pool) pci_pool_destroy(phba->lpfc_hbq_pool); phba->lpfc_hbq_pool = NULL; - - if (phba->rrq_pool) - mempool_destroy(phba->rrq_pool); + mempool_destroy(phba->rrq_pool); phba->rrq_pool = NULL; /* Free NLP memory pool */ mempool_destroy(phba->nlp_mem_pool); phba->nlp_mem_pool = NULL; - if (phba->sli_rev == LPFC_SLI_REV4 && phba->active_rrq_pool) { + if (phba->sli_rev == LPFC_SLI_REV4) { mempool_destroy(phba->active_rrq_pool); phba->active_rrq_pool = NULL; } -- cgit v0.10.2 From 699acd6220ea5b20b25d5eec0ab448827d745357 Mon Sep 17 00:00:00 2001 From: Punit Vara Date: Wed, 16 Dec 2015 18:12:07 -0500 Subject: lpfc: Use kzalloc instead of kmalloc This patch is to the lpfc_els.c which resolves following warning reported by coccicheck: WARNING: kzalloc should be used for rdp_context, instead of kmalloc/memset Signed-off-by: Punit Vara Signed-off-by: James Smart Reviewed-by: Hannes Reinicke Reviewed-by: Matthew R. Ochs Reviewed-by: Sebastian Herbszt Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 273a1db..7f5abb8 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -5016,13 +5016,12 @@ lpfc_els_rcv_rdp(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, if (RDP_NPORT_ID_SIZE != be32_to_cpu(rdp_req->nport_id_desc.length)) goto rjt_logerr; - rdp_context = kmalloc(sizeof(struct lpfc_rdp_context), GFP_KERNEL); + rdp_context = kzalloc(sizeof(struct lpfc_rdp_context), GFP_KERNEL); if (!rdp_context) { rjt_err = LSRJT_UNABLE_TPC; goto error; } - memset(rdp_context, 0, sizeof(struct lpfc_rdp_context)); cmd = &cmdiocb->iocb; rdp_context->ndlp = lpfc_nlp_get(ndlp); rdp_context->ox_id = cmd->unsli3.rcvsli3.ox_id; -- cgit v0.10.2 From b034573c7eb39aa58cd4a08e487869fea6d4ad2d Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 16 Dec 2015 18:12:08 -0500 Subject: lpfc: Update version to 11.0.0.10 for upstream patch set Update version to 11.0.0.10 for upstream patch set Signed-off-by: Dick Kennedy Signed-off-by: James Smart Reviewed-by: Hannes Reinicke Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index ea53aa6..4dc2256 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h @@ -18,7 +18,7 @@ * included with this package. * *******************************************************************/ -#define LPFC_DRIVER_VERSION "11.0.0.0." +#define LPFC_DRIVER_VERSION "11.0.0.10." #define LPFC_DRIVER_NAME "lpfc" /* Used for SLI 2/3 */ -- cgit v0.10.2 From 32c5844abb302e3fb1637ba6afe3d8132c64e57f Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Wed, 16 Dec 2015 17:53:51 -0500 Subject: scsi_debug: Increase the reported optimal transfer length The OPTIMAL TRANSFER LENGTH reported by scsi_debug is 64 blocks which translates to 32KB with the default logical block size. That's much lower than what real storage devices typically report (256KB to 1MB). Bump the optimal transfer length to 1024 blocks. Acked-by: Douglas Gilbert Reviewed-by: Ewan Milne Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 1bea1ad..237b691 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -129,7 +129,7 @@ static const char *scsi_debug_version_date = "20141022"; #define DEF_NO_LUN_0 0 #define DEF_NUM_PARTS 0 #define DEF_OPTS 0 -#define DEF_OPT_BLKS 64 +#define DEF_OPT_BLKS 1024 #define DEF_PHYSBLK_EXP 0 #define DEF_PTYPE 0 #define DEF_REMOVABLE false @@ -4139,7 +4139,7 @@ MODULE_PARM_DESC(no_lun_0, "no LU number 0 (def=0 -> have lun 0)"); MODULE_PARM_DESC(no_uld, "stop ULD (e.g. sd driver) attaching (def=0))"); MODULE_PARM_DESC(num_parts, "number of partitions(def=0)"); MODULE_PARM_DESC(num_tgts, "number of targets per host to simulate(def=1)"); -MODULE_PARM_DESC(opt_blks, "optimal transfer length in block (def=64)"); +MODULE_PARM_DESC(opt_blks, "optimal transfer length in blocks (def=1024)"); MODULE_PARM_DESC(opts, "1->noise, 2->medium_err, 4->timeout, 8->recovered_err... (def=0)"); MODULE_PARM_DESC(physblk_exp, "physical block exponent (def=0)"); MODULE_PARM_DESC(ptype, "SCSI peripheral type(def=0[disk])"); -- cgit v0.10.2 From a8036dfba94d2ddf70cc9d7e9c627b179f957299 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Sun, 6 Dec 2015 22:19:40 +0000 Subject: cciss: print max outstanding commands as a hex value The max outstanding commands is being printed with a 0x prefix to suggest it is a hex value, when in fact the integer decimal %d format specifier is being used and this is a bit confusing. Use %x instead to match the proceeding 0x prefix. Signed-off-by: Colin Ian King Signed-off-by: Martin K. Petersen diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 0422c47..2758982 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -3854,7 +3854,7 @@ static void print_cfg_table(ctlr_info_t *h) readl(&(tb->HostWrite.CoalIntDelay))); dev_dbg(&h->pdev->dev, " Coalesce Interrupt Count = 0x%x\n", readl(&(tb->HostWrite.CoalIntCount))); - dev_dbg(&h->pdev->dev, " Max outstanding commands = 0x%d\n", + dev_dbg(&h->pdev->dev, " Max outstanding commands = 0x%x\n", readl(&(tb->CmdsOutMax))); dev_dbg(&h->pdev->dev, " Bus Types = 0x%x\n", readl(&(tb->BusTypes))); -- cgit v0.10.2 From 2708f2957ce70037d3eab8a45523d4445404ecb4 Mon Sep 17 00:00:00 2001 From: Don Brace Date: Tue, 22 Dec 2015 10:36:36 -0600 Subject: hpsa: fix path_info_show Left off some changes from Rasmus Villemoes where he changed snprintf to scnprintf. Suggested-by: Rasmus Villemoes Reviewed-by: Justin Lindley Reviewed-by: Kevin Barnett Reviewed-by: Scott Teel Reviewed-by: Rasmus Villemoes Reviewed-by: Hannes Reinecke Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 6a8f958..9ad546e 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -795,7 +795,7 @@ static ssize_t path_info_show(struct device *dev, if (hdev->external || hdev->devtype == TYPE_RAID || is_logical_device(hdev)) { - output_len += snprintf(buf + output_len, + output_len += scnprintf(buf + output_len, PAGE_SIZE - output_len, "%s\n", active); continue; @@ -809,28 +809,28 @@ static ssize_t path_info_show(struct device *dev, if (phys_connector[1] < '0') phys_connector[1] = '0'; if (hdev->phys_connector[i] > 0) - output_len += snprintf(buf + output_len, + output_len += scnprintf(buf + output_len, PAGE_SIZE - output_len, "PORT: %.2s ", phys_connector); if (hdev->devtype == TYPE_DISK && hdev->expose_device) { if (box == 0 || box == 0xFF) { - output_len += snprintf(buf + output_len, + output_len += scnprintf(buf + output_len, PAGE_SIZE - output_len, "BAY: %hhu %s\n", bay, active); } else { - output_len += snprintf(buf + output_len, + output_len += scnprintf(buf + output_len, PAGE_SIZE - output_len, "BOX: %hhu BAY: %hhu %s\n", box, bay, active); } } else if (box != 0 && box != 0xFF) { - output_len += snprintf(buf + output_len, + output_len += scnprintf(buf + output_len, PAGE_SIZE - output_len, "BOX: %hhu %s\n", box, active); } else - output_len += snprintf(buf + output_len, + output_len += scnprintf(buf + output_len, PAGE_SIZE - output_len, "%s\n", active); } -- cgit v0.10.2 From 09371d623c9c3dc6ed7f53ec8ab01d25f0c6c697 Mon Sep 17 00:00:00 2001 From: Don Brace Date: Tue, 22 Dec 2015 10:36:42 -0600 Subject: hpsa: Change SAS transport devices to bus 0. SAS transport places devices on bus 0 but driver was setting the bus to 3. Reviewed-by: Justin Lindley Reviewed-by: Kevin Barnett Reviewed-by: Scott Teel Reviewed-by: Matthew R. Ochs Reviewed-by: Hannes Reinecke Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h index ae5beda..fdd39fc 100644 --- a/drivers/scsi/hpsa.h +++ b/drivers/scsi/hpsa.h @@ -400,7 +400,7 @@ struct offline_device_entry { #define HPSA_PHYSICAL_DEVICE_BUS 0 #define HPSA_RAID_VOLUME_BUS 1 #define HPSA_EXTERNAL_RAID_VOLUME_BUS 2 -#define HPSA_HBA_BUS 3 +#define HPSA_HBA_BUS 0 /* Send the command to the hardware -- cgit v0.10.2 From cca8f13b4fdaf3583e103ae7f96fda948839b265 Mon Sep 17 00:00:00 2001 From: Don Brace Date: Tue, 22 Dec 2015 10:36:48 -0600 Subject: hpsa: Add box and bay information for enclosure devices Adding a new method to display enclosure device information. Reviewed-by: Justin Lindley Reviewed-by: Kevin Barnett Reviewed-by: Scott Teel Reviewed-by: Hannes Reinecke Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 9ad546e..17a3976 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -750,7 +750,6 @@ static ssize_t host_show_hp_ssd_smart_path_enabled(struct device *dev, } #define MAX_PATHS 8 - static ssize_t path_info_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -792,9 +791,7 @@ static ssize_t path_info_show(struct device *dev, hdev->bus, hdev->target, hdev->lun, scsi_device_type(hdev->devtype)); - if (hdev->external || - hdev->devtype == TYPE_RAID || - is_logical_device(hdev)) { + if (hdev->devtype == TYPE_RAID || is_logical_device(hdev)) { output_len += scnprintf(buf + output_len, PAGE_SIZE - output_len, "%s\n", active); @@ -808,8 +805,7 @@ static ssize_t path_info_show(struct device *dev, phys_connector[0] = '0'; if (phys_connector[1] < '0') phys_connector[1] = '0'; - if (hdev->phys_connector[i] > 0) - output_len += scnprintf(buf + output_len, + output_len += scnprintf(buf + output_len, PAGE_SIZE - output_len, "PORT: %.2s ", phys_connector); @@ -3191,6 +3187,87 @@ out: return rc; } +/* + * get enclosure information + * struct ReportExtendedLUNdata *rlep - Used for BMIC drive number + * struct hpsa_scsi_dev_t *encl_dev - device entry for enclosure + * Uses id_physical_device to determine the box_index. + */ +static void hpsa_get_enclosure_info(struct ctlr_info *h, + unsigned char *scsi3addr, + struct ReportExtendedLUNdata *rlep, int rle_index, + struct hpsa_scsi_dev_t *encl_dev) +{ + int rc = -1; + struct CommandList *c = NULL; + struct ErrorInfo *ei = NULL; + struct bmic_sense_storage_box_params *bssbp = NULL; + struct bmic_identify_physical_device *id_phys = NULL; + struct ext_report_lun_entry *rle = &rlep->LUN[rle_index]; + u16 bmic_device_index = 0; + + bmic_device_index = GET_BMIC_DRIVE_NUMBER(&rle->lunid[0]); + + if (bmic_device_index == 0xFF00) + goto out; + + bssbp = kzalloc(sizeof(*bssbp), GFP_KERNEL); + if (!bssbp) + goto out; + + id_phys = kzalloc(sizeof(*id_phys), GFP_KERNEL); + if (!id_phys) + goto out; + + rc = hpsa_bmic_id_physical_device(h, scsi3addr, bmic_device_index, + id_phys, sizeof(*id_phys)); + if (rc) { + dev_warn(&h->pdev->dev, "%s: id_phys failed %d bdi[0x%x]\n", + __func__, encl_dev->external, bmic_device_index); + goto out; + } + + c = cmd_alloc(h); + + rc = fill_cmd(c, BMIC_SENSE_STORAGE_BOX_PARAMS, h, bssbp, + sizeof(*bssbp), 0, RAID_CTLR_LUNID, TYPE_CMD); + + if (rc) + goto out; + + if (id_phys->phys_connector[1] == 'E') + c->Request.CDB[5] = id_phys->box_index; + else + c->Request.CDB[5] = 0; + + rc = hpsa_scsi_do_simple_cmd_with_retry(h, c, PCI_DMA_FROMDEVICE, + NO_TIMEOUT); + if (rc) + goto out; + + ei = c->err_info; + if (ei->CommandStatus != 0 && ei->CommandStatus != CMD_DATA_UNDERRUN) { + rc = -1; + goto out; + } + + encl_dev->box[id_phys->active_path_number] = bssbp->phys_box_on_port; + memcpy(&encl_dev->phys_connector[id_phys->active_path_number], + bssbp->phys_connector, sizeof(bssbp->phys_connector)); + + rc = IO_OK; +out: + kfree(bssbp); + kfree(id_phys); + + if (c) + cmd_free(h, c); + + if (rc != IO_OK) + hpsa_show_dev_msg(KERN_INFO, h, encl_dev, + "Error, could not get enclosure information\n"); +} + static u64 hpsa_get_sas_address_from_report_physical(struct ctlr_info *h, unsigned char *scsi3addr) { @@ -4032,7 +4109,8 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h) /* skip masked non-disk devices */ if (MASKED_DEVICE(lunaddrbytes) && physical_device && - (physdev_list->LUN[phys_dev_index].device_flags & 0x01)) + (physdev_list->LUN[phys_dev_index].device_type != 0x06) && + (physdev_list->LUN[phys_dev_index].device_flags & 0x01)) continue; /* Get device type, vendor, model, device id */ @@ -4116,7 +4194,12 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h) break; case TYPE_TAPE: case TYPE_MEDIUM_CHANGER: + ncurrent++; + break; case TYPE_ENCLOSURE: + hpsa_get_enclosure_info(h, lunaddrbytes, + physdev_list, phys_dev_index, + this_device); ncurrent++; break; case TYPE_RAID: @@ -6629,6 +6712,16 @@ static int fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h, c->Request.CDB[7] = (size >> 16) & 0xFF; c->Request.CDB[8] = (size >> 8) & 0XFF; break; + case BMIC_SENSE_STORAGE_BOX_PARAMS: + c->Request.CDBLen = 10; + c->Request.type_attr_dir = + TYPE_ATTR_DIR(cmd_type, ATTR_SIMPLE, XFER_READ); + c->Request.Timeout = 0; + c->Request.CDB[0] = BMIC_READ; + c->Request.CDB[6] = BMIC_SENSE_STORAGE_BOX_PARAMS; + c->Request.CDB[7] = (size >> 16) & 0xFF; + c->Request.CDB[8] = (size >> 8) & 0XFF; + break; case BMIC_IDENTIFY_CONTROLLER: c->Request.CDBLen = 10; c->Request.type_attr_dir = diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h index d92ef0d..6a919ad 100644 --- a/drivers/scsi/hpsa_cmd.h +++ b/drivers/scsi/hpsa_cmd.h @@ -291,6 +291,7 @@ struct SenseSubsystem_info { #define BMIC_SENSE_DIAG_OPTIONS 0xF5 #define HPSA_DIAG_OPTS_DISABLE_RLD_CACHING 0x40000000 #define BMIC_SENSE_SUBSYSTEM_INFORMATION 0x66 +#define BMIC_SENSE_STORAGE_BOX_PARAMS 0x65 /* Command List Structure */ union SCSI3Addr { @@ -842,5 +843,17 @@ struct bmic_sense_subsystem_info { u8 pad[332]; }; +struct bmic_sense_storage_box_params { + u8 reserved[36]; + u8 inquiry_valid; + u8 reserved_1[68]; + u8 phys_box_on_port; + u8 reserved_2[22]; + u16 connection_info; + u8 reserver_3[84]; + u8 phys_connector[2]; + u8 reserved_4[296]; +}; + #pragma pack() #endif /* HPSA_CMD_H */ -- cgit v0.10.2 From 5f985d88bac34e7f3b4403118eab072902a0b392 Mon Sep 17 00:00:00 2001 From: Tomas Henzl Date: Wed, 23 Dec 2015 14:21:47 +0100 Subject: mpt3sas: A correction in unmap_resources It might happen that we try to free an already freed pointer. Reported-by: Maurizio Lombardi Signed-off-by: Tomas Henzl Acked-by: Chaitra P B Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index 11393eb..83658ac 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -2020,8 +2020,10 @@ mpt3sas_base_unmap_resources(struct MPT3SAS_ADAPTER *ioc) _base_free_irq(ioc); _base_disable_msix(ioc); - if (ioc->msix96_vector) + if (ioc->msix96_vector) { kfree(ioc->replyPostRegisterIndex); + ioc->replyPostRegisterIndex = NULL; + } if (ioc->chip_phys) { iounmap(ioc->chip); -- cgit v0.10.2 From c56f5f1de3a6ab8ec985edbc358e1fd8d4e36a65 Mon Sep 17 00:00:00 2001 From: Wilfried Weissmann Date: Sun, 27 Dec 2015 20:21:19 +0100 Subject: mvsas: Add SGPIO support to Marvell 94xx Add SGPIO support to Marvell 94xx. Signed-off-by: Wilfried Weissmann Reviewed-by: James Bottomley Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/mvsas/mv_94xx.c b/drivers/scsi/mvsas/mv_94xx.c index 9270d15..f6fc4a7 100644 --- a/drivers/scsi/mvsas/mv_94xx.c +++ b/drivers/scsi/mvsas/mv_94xx.c @@ -330,6 +330,51 @@ static void mvs_94xx_phy_enable(struct mvs_info *mvi, u32 phy_id) mvs_write_port_vsr_data(mvi, phy_id, tmp & 0xfd7fffff); } +static void mvs_94xx_sgpio_init(struct mvs_info *mvi) +{ + void __iomem *regs = mvi->regs_ex - 0x10200; + u32 tmp; + + tmp = mr32(MVS_HST_CHIP_CONFIG); + tmp |= 0x100; + mw32(MVS_HST_CHIP_CONFIG, tmp); + + mw32(MVS_SGPIO_CTRL + MVS_SGPIO_HOST_OFFSET * mvi->id, + MVS_SGPIO_CTRL_SDOUT_AUTO << MVS_SGPIO_CTRL_SDOUT_SHIFT); + + mw32(MVS_SGPIO_CFG1 + MVS_SGPIO_HOST_OFFSET * mvi->id, + 8 << MVS_SGPIO_CFG1_LOWA_SHIFT | + 8 << MVS_SGPIO_CFG1_HIA_SHIFT | + 4 << MVS_SGPIO_CFG1_LOWB_SHIFT | + 4 << MVS_SGPIO_CFG1_HIB_SHIFT | + 2 << MVS_SGPIO_CFG1_MAXACTON_SHIFT | + 1 << MVS_SGPIO_CFG1_FORCEACTOFF_SHIFT + ); + + mw32(MVS_SGPIO_CFG2 + MVS_SGPIO_HOST_OFFSET * mvi->id, + (300000 / 100) << MVS_SGPIO_CFG2_CLK_SHIFT | /* 100kHz clock */ + 66 << MVS_SGPIO_CFG2_BLINK_SHIFT /* (66 * 0,121 Hz?)*/ + ); + + mw32(MVS_SGPIO_CFG0 + MVS_SGPIO_HOST_OFFSET * mvi->id, + MVS_SGPIO_CFG0_ENABLE | + MVS_SGPIO_CFG0_BLINKA | + MVS_SGPIO_CFG0_BLINKB | + /* 3*4 data bits / PDU */ + (12 - 1) << MVS_SGPIO_CFG0_AUT_BITLEN_SHIFT + ); + + mw32(MVS_SGPIO_DCTRL + MVS_SGPIO_HOST_OFFSET * mvi->id, + DEFAULT_SGPIO_BITS); + + mw32(MVS_SGPIO_DSRC + MVS_SGPIO_HOST_OFFSET * mvi->id, + ((mvi->id * 4) + 3) << (8 * 3) | + ((mvi->id * 4) + 2) << (8 * 2) | + ((mvi->id * 4) + 1) << (8 * 1) | + ((mvi->id * 4) + 0) << (8 * 0)); + +} + static int mvs_94xx_init(struct mvs_info *mvi) { void __iomem *regs = mvi->regs; @@ -533,6 +578,8 @@ static int mvs_94xx_init(struct mvs_info *mvi) /* Enable SRS interrupt */ mw32(MVS_INT_MASK_SRS_0, 0xFFFF); + mvs_94xx_sgpio_init(mvi); + return 0; } @@ -1005,6 +1052,92 @@ static void mvs_94xx_tune_interrupt(struct mvs_info *mvi, u32 time) } +static int mvs_94xx_gpio_write(struct mvs_prv_info *mvs_prv, + u8 reg_type, u8 reg_index, + u8 reg_count, u8 *write_data) +{ + int i; + + switch (reg_type) { + + case SAS_GPIO_REG_TX_GP: + if (reg_index == 0) + return -EINVAL; + + if (reg_count > 1) + return -EINVAL; + + if (reg_count == 0) + return 0; + + /* maximum supported bits = hosts * 4 drives * 3 bits */ + for (i = 0; i < mvs_prv->n_host * 4 * 3; i++) { + + /* select host */ + struct mvs_info *mvi = mvs_prv->mvi[i/(4*3)]; + + void __iomem *regs = mvi->regs_ex - 0x10200; + + int drive = (i/3) & (4-1); /* drive number on host */ + u32 block = mr32(MVS_SGPIO_DCTRL + + MVS_SGPIO_HOST_OFFSET * mvi->id); + + + /* + * if bit is set then create a mask with the first + * bit of the drive set in the mask ... + */ + u32 bit = (write_data[i/8] & (1 << (i&(8-1)))) ? + 1<<(24-drive*8) : 0; + + /* + * ... and then shift it to the right position based + * on the led type (activity/id/fail) + */ + switch (i%3) { + case 0: /* activity */ + block &= ~((0x7 << MVS_SGPIO_DCTRL_ACT_SHIFT) + << (24-drive*8)); + /* hardwire activity bit to SOF */ + block |= LED_BLINKA_SOF << ( + MVS_SGPIO_DCTRL_ACT_SHIFT + + (24-drive*8)); + break; + case 1: /* id */ + block &= ~((0x3 << MVS_SGPIO_DCTRL_LOC_SHIFT) + << (24-drive*8)); + block |= bit << MVS_SGPIO_DCTRL_LOC_SHIFT; + break; + case 2: /* fail */ + block &= ~((0x7 << MVS_SGPIO_DCTRL_ERR_SHIFT) + << (24-drive*8)); + block |= bit << MVS_SGPIO_DCTRL_ERR_SHIFT; + break; + } + + mw32(MVS_SGPIO_DCTRL + MVS_SGPIO_HOST_OFFSET * mvi->id, + block); + + } + + return reg_count; + + case SAS_GPIO_REG_TX: + if (reg_index + reg_count > mvs_prv->n_host) + return -EINVAL; + + for (i = 0; i < reg_count; i++) { + struct mvs_info *mvi = mvs_prv->mvi[i+reg_index]; + void __iomem *regs = mvi->regs_ex - 0x10200; + + mw32(MVS_SGPIO_DCTRL + MVS_SGPIO_HOST_OFFSET * mvi->id, + be32_to_cpu(((u32 *) write_data)[i])); + } + return reg_count; + } + return -ENOSYS; +} + const struct mvs_dispatch mvs_94xx_dispatch = { "mv94xx", mvs_94xx_init, @@ -1057,5 +1190,6 @@ const struct mvs_dispatch mvs_94xx_dispatch = { mvs_94xx_fix_dma, mvs_94xx_tune_interrupt, mvs_94xx_non_spec_ncq_error, + mvs_94xx_gpio_write, }; diff --git a/drivers/scsi/mvsas/mv_94xx.h b/drivers/scsi/mvsas/mv_94xx.h index 14e1974..5789608 100644 --- a/drivers/scsi/mvsas/mv_94xx.h +++ b/drivers/scsi/mvsas/mv_94xx.h @@ -38,6 +38,10 @@ enum VANIR_REVISION_ID { VANIR_C2_REV = 0xC2, }; +enum host_registers { + MVS_HST_CHIP_CONFIG = 0x10104, /* chip configuration */ +}; + enum hw_registers { MVS_GBL_CTL = 0x04, /* global control */ MVS_GBL_INT_STAT = 0x00, /* global irq status */ @@ -239,6 +243,73 @@ struct mvs_prd { __le32 im_len; } __attribute__ ((packed)); +enum sgpio_registers { + MVS_SGPIO_HOST_OFFSET = 0x100, /* offset between hosts */ + + MVS_SGPIO_CFG0 = 0xc200, + MVS_SGPIO_CFG0_ENABLE = (1 << 0), /* enable pins */ + MVS_SGPIO_CFG0_BLINKB = (1 << 1), /* blink generators */ + MVS_SGPIO_CFG0_BLINKA = (1 << 2), + MVS_SGPIO_CFG0_INVSCLK = (1 << 3), /* invert signal? */ + MVS_SGPIO_CFG0_INVSLOAD = (1 << 4), + MVS_SGPIO_CFG0_INVSDOUT = (1 << 5), + MVS_SGPIO_CFG0_SLOAD_FALLEDGE = (1 << 6), /* rise/fall edge? */ + MVS_SGPIO_CFG0_SDOUT_FALLEDGE = (1 << 7), + MVS_SGPIO_CFG0_SDIN_RISEEDGE = (1 << 8), + MVS_SGPIO_CFG0_MAN_BITLEN_SHIFT = 18, /* bits/frame manual mode */ + MVS_SGPIO_CFG0_AUT_BITLEN_SHIFT = 24, /* bits/frame auto mode */ + + MVS_SGPIO_CFG1 = 0xc204, /* blink timing register */ + MVS_SGPIO_CFG1_LOWA_SHIFT = 0, /* A off time */ + MVS_SGPIO_CFG1_HIA_SHIFT = 4, /* A on time */ + MVS_SGPIO_CFG1_LOWB_SHIFT = 8, /* B off time */ + MVS_SGPIO_CFG1_HIB_SHIFT = 12, /* B on time */ + MVS_SGPIO_CFG1_MAXACTON_SHIFT = 16, /* max activity on time */ + + /* force activity off time */ + MVS_SGPIO_CFG1_FORCEACTOFF_SHIFT = 20, + /* stretch activity on time */ + MVS_SGPIO_CFG1_STRCHACTON_SHIFT = 24, + /* stretch activiity off time */ + MVS_SGPIO_CFG1_STRCHACTOFF_SHIFT = 28, + + + MVS_SGPIO_CFG2 = 0xc208, /* clock speed register */ + MVS_SGPIO_CFG2_CLK_SHIFT = 0, + MVS_SGPIO_CFG2_BLINK_SHIFT = 20, + + MVS_SGPIO_CTRL = 0xc20c, /* SDOUT/SDIN mode control */ + MVS_SGPIO_CTRL_SDOUT_AUTO = 2, + MVS_SGPIO_CTRL_SDOUT_SHIFT = 2, + + MVS_SGPIO_DSRC = 0xc220, /* map ODn bits to drives */ + + MVS_SGPIO_DCTRL = 0xc238, + MVS_SGPIO_DCTRL_ERR_SHIFT = 0, + MVS_SGPIO_DCTRL_LOC_SHIFT = 3, + MVS_SGPIO_DCTRL_ACT_SHIFT = 5, +}; + +enum sgpio_led_status { + LED_OFF = 0, + LED_ON = 1, + LED_BLINKA = 2, + LED_BLINKA_INV = 3, + LED_BLINKA_SOF = 4, + LED_BLINKA_EOF = 5, + LED_BLINKB = 6, + LED_BLINKB_INV = 7, +}; + +#define DEFAULT_SGPIO_BITS ((LED_BLINKA_SOF << \ + MVS_SGPIO_DCTRL_ACT_SHIFT) << (8 * 3) | \ + (LED_BLINKA_SOF << \ + MVS_SGPIO_DCTRL_ACT_SHIFT) << (8 * 2) | \ + (LED_BLINKA_SOF << \ + MVS_SGPIO_DCTRL_ACT_SHIFT) << (8 * 1) | \ + (LED_BLINKA_SOF << \ + MVS_SGPIO_DCTRL_ACT_SHIFT) << (8 * 0)) + /* * these registers are accessed through port vendor * specific address/data registers diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c index 90fdf0e..6110ef3 100644 --- a/drivers/scsi/mvsas/mv_init.c +++ b/drivers/scsi/mvsas/mv_init.c @@ -84,6 +84,8 @@ static struct sas_domain_function_template mvs_transport_ops = { .lldd_port_formed = mvs_port_formed, .lldd_port_deformed = mvs_port_deformed, + .lldd_write_gpio = mvs_gpio_write, + }; static void mvs_phy_init(struct mvs_info *mvi, int phy_id) diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c index e712fe7..83cd3ea 100644 --- a/drivers/scsi/mvsas/mv_sas.c +++ b/drivers/scsi/mvsas/mv_sas.c @@ -2105,3 +2105,16 @@ int mvs_int_rx(struct mvs_info *mvi, bool self_clear) return 0; } +int mvs_gpio_write(struct sas_ha_struct *sha, u8 reg_type, u8 reg_index, + u8 reg_count, u8 *write_data) +{ + struct mvs_prv_info *mvs_prv = sha->lldd_ha; + struct mvs_info *mvi = mvs_prv->mvi[0]; + + if (MVS_CHIP_DISP->gpio_write) { + return MVS_CHIP_DISP->gpio_write(mvs_prv, reg_type, + reg_index, reg_count, write_data); + } + + return -ENOSYS; +} diff --git a/drivers/scsi/mvsas/mv_sas.h b/drivers/scsi/mvsas/mv_sas.h index dc409c0..f9afd4c 100644 --- a/drivers/scsi/mvsas/mv_sas.h +++ b/drivers/scsi/mvsas/mv_sas.h @@ -103,6 +103,7 @@ enum dev_reset { }; struct mvs_info; +struct mvs_prv_info; struct mvs_dispatch { char *name; @@ -172,6 +173,8 @@ struct mvs_dispatch { int buf_len, int from, void *prd); void (*tune_interrupt)(struct mvs_info *mvi, u32 time); void (*non_spec_ncq_error)(struct mvs_info *mvi); + int (*gpio_write)(struct mvs_prv_info *mvs_prv, u8 reg_type, + u8 reg_index, u8 reg_count, u8 *write_data); }; @@ -476,5 +479,7 @@ void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events); void mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st); int mvs_int_rx(struct mvs_info *mvi, bool self_clear); struct mvs_device *mvs_find_dev_by_reg_set(struct mvs_info *mvi, u8 reg_set); +int mvs_gpio_write(struct sas_ha_struct *, u8 reg_type, u8 reg_index, + u8 reg_count, u8 *write_data); #endif -- cgit v0.10.2 From 83d1e8b9b51b06d79653293d0bf34ff2c61abe46 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Wed, 23 Dec 2015 13:15:48 -0800 Subject: storvsc: Fix a bug in the layout of the hv_fc_wwn_packet The hv_fc_wwn_packet is exchanged over vmbus. Make the definition in Linux match the Windows definition. Signed-off-by: K. Y. Srinivasan Reviewed-by: Johannes Thumshirn Reviewed-by: Long Li Reviewed-by: Hannes Reinecke Tested-by: Alex Ng Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index c41f674..00bb4bd 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -92,9 +92,8 @@ enum vstor_packet_operation { */ struct hv_fc_wwn_packet { - bool primary_active; - u8 reserved1; - u8 reserved2; + u8 primary_active; + u8 reserved1[3]; u8 primary_port_wwn[8]; u8 primary_node_wwn[8]; u8 secondary_port_wwn[8]; -- cgit v0.10.2 From dac582417bc449b1f7f572d3f1dd9d23eec15cc9 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Wed, 23 Dec 2015 13:15:49 -0800 Subject: storvsc: Properly support Fibre Channel devices For FC devices managed by this driver, atttach the appropriate transport template. This will allow us to create the appropriate sysfs files for these devices. With this we can publish the wwn for both the port and the node. Signed-off-by: K. Y. Srinivasan Reviewed-by: Long Li Tested-by: Alex Ng Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 00bb4bd..cfbb289 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -41,6 +41,7 @@ #include #include #include +#include /* * All wire protocol details (storage protocol between the guest and the host) @@ -397,6 +398,9 @@ static int storvsc_timeout = 180; static int msft_blist_flags = BLIST_TRY_VPD_PAGES; +#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) +static struct scsi_transport_template *fc_transport_template; +#endif static void storvsc_on_channel_callback(void *context); @@ -456,6 +460,11 @@ struct storvsc_device { /* Used for vsc/vsp channel reset process */ struct storvsc_cmd_request init_request; struct storvsc_cmd_request reset_request; + /* + * Currently active port and node names for FC devices. + */ + u64 node_name; + u64 port_name; }; struct hv_host_device { @@ -695,7 +704,26 @@ static void handle_multichannel_storage(struct hv_device *device, int max_chns) vmbus_are_subchannels_present(device->channel); } -static int storvsc_channel_init(struct hv_device *device) +static void cache_wwn(struct storvsc_device *stor_device, + struct vstor_packet *vstor_packet) +{ + /* + * Cache the currently active port and node ww names. + */ + if (vstor_packet->wwn_packet.primary_active) { + stor_device->node_name = + wwn_to_u64(vstor_packet->wwn_packet.primary_node_wwn); + stor_device->port_name = + wwn_to_u64(vstor_packet->wwn_packet.primary_port_wwn); + } else { + stor_device->node_name = + wwn_to_u64(vstor_packet->wwn_packet.secondary_node_wwn); + stor_device->port_name = + wwn_to_u64(vstor_packet->wwn_packet.secondary_port_wwn); + } +} + +static int storvsc_channel_init(struct hv_device *device, bool is_fc) { struct storvsc_device *stor_device; struct storvsc_cmd_request *request; @@ -727,19 +755,15 @@ static int storvsc_channel_init(struct hv_device *device) VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret != 0) - goto cleanup; + return ret; t = wait_for_completion_timeout(&request->wait_event, 5*HZ); - if (t == 0) { - ret = -ETIMEDOUT; - goto cleanup; - } + if (t == 0) + return -ETIMEDOUT; if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || - vstor_packet->status != 0) { - ret = -EINVAL; - goto cleanup; - } + vstor_packet->status != 0) + return -EINVAL; for (i = 0; i < ARRAY_SIZE(vmstor_protocols); i++) { @@ -764,18 +788,14 @@ static int storvsc_channel_init(struct hv_device *device) VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret != 0) - goto cleanup; + return ret; t = wait_for_completion_timeout(&request->wait_event, 5*HZ); - if (t == 0) { - ret = -ETIMEDOUT; - goto cleanup; - } + if (t == 0) + return -ETIMEDOUT; - if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO) { - ret = -EINVAL; - goto cleanup; - } + if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO) + return -EINVAL; if (vstor_packet->status == 0) { vmstor_proto_version = @@ -791,10 +811,8 @@ static int storvsc_channel_init(struct hv_device *device) } } - if (vstor_packet->status != 0) { - ret = -EINVAL; - goto cleanup; - } + if (vstor_packet->status != 0) + return -EINVAL; memset(vstor_packet, 0, sizeof(struct vstor_packet)); @@ -809,19 +827,15 @@ static int storvsc_channel_init(struct hv_device *device) VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret != 0) - goto cleanup; + return ret; t = wait_for_completion_timeout(&request->wait_event, 5*HZ); - if (t == 0) { - ret = -ETIMEDOUT; - goto cleanup; - } + if (t == 0) + return -ETIMEDOUT; if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || - vstor_packet->status != 0) { - ret = -EINVAL; - goto cleanup; - } + vstor_packet->status != 0) + return -EINVAL; /* * Check to see if multi-channel support is there. @@ -837,6 +851,38 @@ static int storvsc_channel_init(struct hv_device *device) stor_device->max_transfer_bytes = vstor_packet->storage_channel_properties.max_transfer_bytes; + if (!is_fc) + goto done; + + memset(vstor_packet, 0, sizeof(struct vstor_packet)); + vstor_packet->operation = VSTOR_OPERATION_FCHBA_DATA; + vstor_packet->flags = REQUEST_COMPLETION_FLAG; + + ret = vmbus_sendpacket(device->channel, vstor_packet, + (sizeof(struct vstor_packet) - + vmscsi_size_delta), + (unsigned long)request, + VM_PKT_DATA_INBAND, + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + + if (ret != 0) + return ret; + + t = wait_for_completion_timeout(&request->wait_event, 5*HZ); + if (t == 0) + return -ETIMEDOUT; + + if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || + vstor_packet->status != 0) + return -EINVAL; + + /* + * Cache the currently active port and node ww names. + */ + cache_wwn(stor_device, vstor_packet); + +done: + memset(vstor_packet, 0, sizeof(struct vstor_packet)); vstor_packet->operation = VSTOR_OPERATION_END_INITIALIZATION; vstor_packet->flags = REQUEST_COMPLETION_FLAG; @@ -849,25 +895,19 @@ static int storvsc_channel_init(struct hv_device *device) VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret != 0) - goto cleanup; + return ret; t = wait_for_completion_timeout(&request->wait_event, 5*HZ); - if (t == 0) { - ret = -ETIMEDOUT; - goto cleanup; - } + if (t == 0) + return -ETIMEDOUT; if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || - vstor_packet->status != 0) { - ret = -EINVAL; - goto cleanup; - } + vstor_packet->status != 0) + return -EINVAL; if (process_sub_channels) handle_multichannel_storage(device, max_chns); - -cleanup: return ret; } @@ -1076,6 +1116,14 @@ static void storvsc_on_receive(struct hv_device *device, schedule_work(&work->work); break; + case VSTOR_OPERATION_FCHBA_DATA: + stor_device = get_in_stor_device(device); + cache_wwn(stor_device, vstor_packet); +#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) + fc_host_node_name(stor_device->host) = stor_device->node_name; + fc_host_port_name(stor_device->host) = stor_device->port_name; +#endif + break; default: break; } @@ -1131,7 +1179,8 @@ static void storvsc_on_channel_callback(void *context) return; } -static int storvsc_connect_to_vsp(struct hv_device *device, u32 ring_size) +static int storvsc_connect_to_vsp(struct hv_device *device, u32 ring_size, + bool is_fc) { struct vmstorage_channel_properties props; int ret; @@ -1148,7 +1197,7 @@ static int storvsc_connect_to_vsp(struct hv_device *device, u32 ring_size) if (ret != 0) return ret; - ret = storvsc_channel_init(device); + ret = storvsc_channel_init(device, is_fc); return ret; } @@ -1573,6 +1622,7 @@ static int storvsc_probe(struct hv_device *device, struct Scsi_Host *host; struct hv_host_device *host_dev; bool dev_is_ide = ((dev_id->driver_data == IDE_GUID) ? true : false); + bool is_fc = ((dev_id->driver_data == SFC_GUID) ? true : false); int target = 0; struct storvsc_device *stor_device; int max_luns_per_target; @@ -1630,7 +1680,7 @@ static int storvsc_probe(struct hv_device *device, hv_set_drvdata(device, stor_device); stor_device->port_number = host->host_no; - ret = storvsc_connect_to_vsp(device, storvsc_ringbuffer_size); + ret = storvsc_connect_to_vsp(device, storvsc_ringbuffer_size, is_fc); if (ret) goto err_out1; @@ -1642,6 +1692,9 @@ static int storvsc_probe(struct hv_device *device, host->max_lun = STORVSC_FC_MAX_LUNS_PER_TARGET; host->max_id = STORVSC_FC_MAX_TARGETS; host->max_channel = STORVSC_FC_MAX_CHANNELS - 1; +#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) + host->transportt = fc_transport_template; +#endif break; case SCSI_GUID: @@ -1681,6 +1734,12 @@ static int storvsc_probe(struct hv_device *device, goto err_out2; } } +#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) + if (host->transportt == fc_transport_template) { + fc_host_node_name(host) = stor_device->node_name; + fc_host_port_name(host) = stor_device->port_name; + } +#endif return 0; err_out2: @@ -1706,6 +1765,10 @@ static int storvsc_remove(struct hv_device *dev) struct storvsc_device *stor_device = hv_get_drvdata(dev); struct Scsi_Host *host = stor_device->host; +#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) + if (host->transportt == fc_transport_template) + fc_remove_host(host); +#endif scsi_remove_host(host); storvsc_dev_remove(dev); scsi_host_put(host); @@ -1720,8 +1783,16 @@ static struct hv_driver storvsc_drv = { .remove = storvsc_remove, }; +#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) +static struct fc_function_template fc_transport_functions = { + .show_host_node_name = 1, + .show_host_port_name = 1, +}; +#endif + static int __init storvsc_drv_init(void) { + int ret; /* * Divide the ring buffer data size (which is 1 page less @@ -1736,12 +1807,28 @@ static int __init storvsc_drv_init(void) vmscsi_size_delta, sizeof(u64))); - return vmbus_driver_register(&storvsc_drv); +#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) + fc_transport_template = fc_attach_transport(&fc_transport_functions); + if (!fc_transport_template) + return -ENODEV; +#endif + + ret = vmbus_driver_register(&storvsc_drv); + +#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) + if (ret) + fc_release_transport(fc_transport_template); +#endif + + return ret; } static void __exit storvsc_drv_exit(void) { vmbus_driver_unregister(&storvsc_drv); +#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) + fc_release_transport(fc_transport_template); +#endif } MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 59635018f9b7ae8b3e304d7a5da6f628b5a1dcf6 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Wed, 23 Dec 2015 13:15:50 -0800 Subject: storvsc: Refactor the code in storvsc_channel_init() The function storvsc_channel_init() repeatedly interacts with the host to extract various channel properties. Refactor this code to eliminate code repetition. Signed-off-by: K. Y. Srinivasan Reviewed-by: Long Li Reviewed-by: Johannes Thumshirn Reviewed-by: Hannes Reinecke Tested-by: Alex Ng Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index cfbb289..811f276 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -723,29 +723,17 @@ static void cache_wwn(struct storvsc_device *stor_device, } } -static int storvsc_channel_init(struct hv_device *device, bool is_fc) + +static int storvsc_execute_vstor_op(struct hv_device *device, + struct storvsc_cmd_request *request, + bool status_check) { - struct storvsc_device *stor_device; - struct storvsc_cmd_request *request; struct vstor_packet *vstor_packet; - int ret, t, i; - int max_chns; - bool process_sub_channels = false; - - stor_device = get_out_stor_device(device); - if (!stor_device) - return -ENODEV; + int ret, t; - request = &stor_device->init_request; vstor_packet = &request->vstor_packet; - /* - * Now, initiate the vsc/vsp initialization protocol on the open - * channel - */ - memset(request, 0, sizeof(struct storvsc_cmd_request)); init_completion(&request->wait_event); - vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION; vstor_packet->flags = REQUEST_COMPLETION_FLAG; ret = vmbus_sendpacket(device->channel, vstor_packet, @@ -761,17 +749,50 @@ static int storvsc_channel_init(struct hv_device *device, bool is_fc) if (t == 0) return -ETIMEDOUT; + if (!status_check) + return ret; + if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || vstor_packet->status != 0) return -EINVAL; + return ret; +} + +static int storvsc_channel_init(struct hv_device *device, bool is_fc) +{ + struct storvsc_device *stor_device; + struct storvsc_cmd_request *request; + struct vstor_packet *vstor_packet; + int ret, i; + int max_chns; + bool process_sub_channels = false; + + stor_device = get_out_stor_device(device); + if (!stor_device) + return -ENODEV; + + request = &stor_device->init_request; + vstor_packet = &request->vstor_packet; + + /* + * Now, initiate the vsc/vsp initialization protocol on the open + * channel + */ + memset(request, 0, sizeof(struct storvsc_cmd_request)); + vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION; + ret = storvsc_execute_vstor_op(device, request, true); + if (ret) + return ret; + /* + * Query host supported protocol version. + */ for (i = 0; i < ARRAY_SIZE(vmstor_protocols); i++) { /* reuse the packet for version range supported */ memset(vstor_packet, 0, sizeof(struct vstor_packet)); vstor_packet->operation = VSTOR_OPERATION_QUERY_PROTOCOL_VERSION; - vstor_packet->flags = REQUEST_COMPLETION_FLAG; vstor_packet->version.major_minor = vmstor_protocols[i].protocol_version; @@ -780,20 +801,10 @@ static int storvsc_channel_init(struct hv_device *device, bool is_fc) * The revision number is only used in Windows; set it to 0. */ vstor_packet->version.revision = 0; - - ret = vmbus_sendpacket(device->channel, vstor_packet, - (sizeof(struct vstor_packet) - - vmscsi_size_delta), - (unsigned long)request, - VM_PKT_DATA_INBAND, - VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + ret = storvsc_execute_vstor_op(device, request, false); if (ret != 0) return ret; - t = wait_for_completion_timeout(&request->wait_event, 5*HZ); - if (t == 0) - return -ETIMEDOUT; - if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO) return -EINVAL; @@ -817,26 +828,10 @@ static int storvsc_channel_init(struct hv_device *device, bool is_fc) memset(vstor_packet, 0, sizeof(struct vstor_packet)); vstor_packet->operation = VSTOR_OPERATION_QUERY_PROPERTIES; - vstor_packet->flags = REQUEST_COMPLETION_FLAG; - - ret = vmbus_sendpacket(device->channel, vstor_packet, - (sizeof(struct vstor_packet) - - vmscsi_size_delta), - (unsigned long)request, - VM_PKT_DATA_INBAND, - VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); - + ret = storvsc_execute_vstor_op(device, request, true); if (ret != 0) return ret; - t = wait_for_completion_timeout(&request->wait_event, 5*HZ); - if (t == 0) - return -ETIMEDOUT; - - if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || - vstor_packet->status != 0) - return -EINVAL; - /* * Check to see if multi-channel support is there. * Hosts that implement protocol version of 5.1 and above @@ -854,28 +849,15 @@ static int storvsc_channel_init(struct hv_device *device, bool is_fc) if (!is_fc) goto done; + /* + * For FC devices retrieve FC HBA data. + */ memset(vstor_packet, 0, sizeof(struct vstor_packet)); vstor_packet->operation = VSTOR_OPERATION_FCHBA_DATA; - vstor_packet->flags = REQUEST_COMPLETION_FLAG; - - ret = vmbus_sendpacket(device->channel, vstor_packet, - (sizeof(struct vstor_packet) - - vmscsi_size_delta), - (unsigned long)request, - VM_PKT_DATA_INBAND, - VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); - + ret = storvsc_execute_vstor_op(device, request, true); if (ret != 0) return ret; - t = wait_for_completion_timeout(&request->wait_event, 5*HZ); - if (t == 0) - return -ETIMEDOUT; - - if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || - vstor_packet->status != 0) - return -EINVAL; - /* * Cache the currently active port and node ww names. */ @@ -885,26 +867,10 @@ done: memset(vstor_packet, 0, sizeof(struct vstor_packet)); vstor_packet->operation = VSTOR_OPERATION_END_INITIALIZATION; - vstor_packet->flags = REQUEST_COMPLETION_FLAG; - - ret = vmbus_sendpacket(device->channel, vstor_packet, - (sizeof(struct vstor_packet) - - vmscsi_size_delta), - (unsigned long)request, - VM_PKT_DATA_INBAND, - VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); - + ret = storvsc_execute_vstor_op(device, request, true); if (ret != 0) return ret; - t = wait_for_completion_timeout(&request->wait_event, 5*HZ); - if (t == 0) - return -ETIMEDOUT; - - if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || - vstor_packet->status != 0) - return -EINVAL; - if (process_sub_channels) handle_multichannel_storage(device, max_chns); -- cgit v0.10.2 From 03996f2064a5c5b7c1bd942794d622179acf2d61 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Wed, 23 Dec 2015 13:15:51 -0800 Subject: storvsc: Tighten up the interrupt path On the interrupt path, we repeatedly establish the pointer to the storvsc_device. While the compiler does inline get_in_stor_device() (and other static functions) in the call chain in the interrupt path, the compiler is repeatedly inlining the call to get_in_stor_device() each time it is invoked. The return value of get_in_stor_device() can be cached in the interrupt path since there is higher level serialization in place to ensure correct handling when the module unload races with the processing of an incoming message from the host. Optimize this code path by caching the pointer to storvsc_device and passing it as an argument. Signed-off-by: K. Y. Srinivasan Reviewed-by: Long Li Reviewed-by: Johannes Thumshirn Reviewed-by: Hannes Reinecke Tested-by: Alex Ng Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 811f276..41c115c 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -945,19 +945,16 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb, } -static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request) +static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request, + struct storvsc_device *stor_dev) { struct scsi_cmnd *scmnd = cmd_request->cmd; - struct hv_host_device *host_dev = shost_priv(scmnd->device->host); struct scsi_sense_hdr sense_hdr; struct vmscsi_request *vm_srb; struct Scsi_Host *host; - struct storvsc_device *stor_dev; - struct hv_device *dev = host_dev->dev; u32 payload_sz = cmd_request->payload_sz; void *payload = cmd_request->payload; - stor_dev = get_in_stor_device(dev); host = stor_dev->host; vm_srb = &cmd_request->vstor_packet.vm_srb; @@ -987,14 +984,13 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request) kfree(payload); } -static void storvsc_on_io_completion(struct hv_device *device, +static void storvsc_on_io_completion(struct storvsc_device *stor_device, struct vstor_packet *vstor_packet, struct storvsc_cmd_request *request) { - struct storvsc_device *stor_device; struct vstor_packet *stor_pkt; + struct hv_device *device = stor_device->device; - stor_device = hv_get_drvdata(device); stor_pkt = &request->vstor_packet; /* @@ -1049,7 +1045,7 @@ static void storvsc_on_io_completion(struct hv_device *device, stor_pkt->vm_srb.data_transfer_length = vstor_packet->vm_srb.data_transfer_length; - storvsc_command_completion(request); + storvsc_command_completion(request, stor_device); if (atomic_dec_and_test(&stor_device->num_outstanding_req) && stor_device->drain_notify) @@ -1058,21 +1054,19 @@ static void storvsc_on_io_completion(struct hv_device *device, } -static void storvsc_on_receive(struct hv_device *device, +static void storvsc_on_receive(struct storvsc_device *stor_device, struct vstor_packet *vstor_packet, struct storvsc_cmd_request *request) { struct storvsc_scan_work *work; - struct storvsc_device *stor_device; switch (vstor_packet->operation) { case VSTOR_OPERATION_COMPLETE_IO: - storvsc_on_io_completion(device, vstor_packet, request); + storvsc_on_io_completion(stor_device, vstor_packet, request); break; case VSTOR_OPERATION_REMOVE_DEVICE: case VSTOR_OPERATION_ENUMERATE_BUS: - stor_device = get_in_stor_device(device); work = kmalloc(sizeof(struct storvsc_scan_work), GFP_ATOMIC); if (!work) return; @@ -1083,7 +1077,6 @@ static void storvsc_on_receive(struct hv_device *device, break; case VSTOR_OPERATION_FCHBA_DATA: - stor_device = get_in_stor_device(device); cache_wwn(stor_device, vstor_packet); #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) fc_host_node_name(stor_device->host) = stor_device->node_name; @@ -1133,7 +1126,7 @@ static void storvsc_on_channel_callback(void *context) vmscsi_size_delta)); complete(&request->wait_event); } else { - storvsc_on_receive(device, + storvsc_on_receive(stor_device, (struct vstor_packet *)packet, request); } -- cgit v0.10.2 From a9be294ecb3b9dc82b15625631b153f871181d16 Mon Sep 17 00:00:00 2001 From: Manoj Kumar Date: Mon, 14 Dec 2015 14:55:09 -0600 Subject: cxlflash: Fix to escalate LINK_RESET also on port 1 The original fix to escalate a 'login timed out' error to a LINK_RESET was only made for one of the two ports on the card. This fix resolves the same issue for the second port (port 1). Signed-off-by: Manoj N. Kumar Acked-by: Matthew R. Ochs Reviewed-by: Uma Krishnan Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c index 1e5bf0c..09fe252 100644 --- a/drivers/scsi/cxlflash/main.c +++ b/drivers/scsi/cxlflash/main.c @@ -1108,7 +1108,7 @@ static const struct asyc_intr_info ainfo[] = { {SISL_ASTATUS_FC1_OTHER, "other error", 1, CLR_FC_ERROR | LINK_RESET}, {SISL_ASTATUS_FC1_LOGO, "target initiated LOGO", 1, 0}, {SISL_ASTATUS_FC1_CRC_T, "CRC threshold exceeded", 1, LINK_RESET}, - {SISL_ASTATUS_FC1_LOGI_R, "login timed out, retrying", 1, 0}, + {SISL_ASTATUS_FC1_LOGI_R, "login timed out, retrying", 1, LINK_RESET}, {SISL_ASTATUS_FC1_LOGI_F, "login failed", 1, CLR_FC_ERROR}, {SISL_ASTATUS_FC1_LOGI_S, "login succeeded", 1, SCAN_HOST}, {SISL_ASTATUS_FC1_LINK_DN, "link down", 1, 0}, -- cgit v0.10.2 From d5e26bb1d812ba74f29b6bcbc88c3dbfb3eed824 Mon Sep 17 00:00:00 2001 From: "Matthew R. Ochs" Date: Mon, 14 Dec 2015 14:55:44 -0600 Subject: cxlflash: Fix to avoid virtual LUN failover failure Applications which use virtual LUN's that are backed by a physical LUN over both adapter ports may experience an I/O failure in the event of a link loss (e.g. cable pull). Virtual LUNs may be accessed through one or both ports of the adapter. This access is encoded in the translation entries that comprise the virtual LUN and used by the AFU for load-balancing I/O and handling failover scenarios. In a link loss scenario, even though the AFU is able to maintain connectivity to the LUN, it is up to the application to retry the failed I/O. When applications are unaware of the virtual LUN's underlying topology, they are unable to make a sound decision of when to retry an I/O and therefore are forced to make their reaction to a failed I/O absolute. The result is either a failure to retry I/O or increased latency for scenarios where a retry is pointless. To remedy this scenario, provide feedback back to the application on virtual LUN creation as to which ports the LUN may be accessed. LUN's spanning both ports are candidates for a retry in a presence of an I/O failure. Signed-off-by: Matthew R. Ochs Acked-by: Manoj Kumar Reviewed-by: Uma Krishnan Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/cxlflash/vlun.c b/drivers/scsi/cxlflash/vlun.c index a53f583..50f8e93 100644 --- a/drivers/scsi/cxlflash/vlun.c +++ b/drivers/scsi/cxlflash/vlun.c @@ -1008,6 +1008,8 @@ int cxlflash_disk_virtual_open(struct scsi_device *sdev, void *arg) virt->last_lba = last_lba; virt->rsrc_handle = rsrc_handle; + if (lli->port_sel == BOTH_PORTS) + virt->hdr.return_flags |= DK_CXLFLASH_ALL_PORTS_ACTIVE; out: if (likely(ctxi)) put_context(ctxi); diff --git a/include/uapi/scsi/cxlflash_ioctl.h b/include/uapi/scsi/cxlflash_ioctl.h index 831351b..2302f3c 100644 --- a/include/uapi/scsi/cxlflash_ioctl.h +++ b/include/uapi/scsi/cxlflash_ioctl.h @@ -31,6 +31,16 @@ struct dk_cxlflash_hdr { }; /* + * Return flag definitions available to all ioctls + * + * Similar to the input flags, these are grown from the bottom-up with the + * intention that ioctl-specific return flag definitions would grow from the + * top-down, allowing the two sets to co-exist. While not required/enforced + * at this time, this provides future flexibility. + */ +#define DK_CXLFLASH_ALL_PORTS_ACTIVE 0x0000000000000001ULL + +/* * Notes: * ----- * The 'context_id' field of all ioctl structures contains the context -- cgit v0.10.2 From 85599218914dadad3347eaa4337e71f09f39e78f Mon Sep 17 00:00:00 2001 From: Uma Krishnan Date: Mon, 14 Dec 2015 15:06:33 -0600 Subject: cxlflash: Removed driver date print Having a date for the driver requires it to be updated quite often. Removing the date which is not necessary. Also made use of the existing symbol to print the driver name. Signed-off-by: Uma Krishnan Reviewed-by: Andrew Donnellan Acked-by: Matthew R. Ochs Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c index 09fe252..35a3202 100644 --- a/drivers/scsi/cxlflash/main.c +++ b/drivers/scsi/cxlflash/main.c @@ -2585,8 +2585,7 @@ static struct pci_driver cxlflash_driver = { */ static int __init init_cxlflash(void) { - pr_info("%s: IBM Power CXL Flash Adapter: %s\n", - __func__, CXLFLASH_DRIVER_DATE); + pr_info("%s: %s\n", __func__, CXLFLASH_ADAPTER_NAME); cxlflash_list_init(); diff --git a/drivers/scsi/cxlflash/main.h b/drivers/scsi/cxlflash/main.h index 6032456..7e2d0e1 100644 --- a/drivers/scsi/cxlflash/main.h +++ b/drivers/scsi/cxlflash/main.h @@ -22,7 +22,6 @@ #define CXLFLASH_NAME "cxlflash" #define CXLFLASH_ADAPTER_NAME "IBM POWER CXL Flash Adapter" -#define CXLFLASH_DRIVER_DATE "(August 13, 2015)" #define PCI_DEVICE_ID_IBM_CORSA 0x04F0 #define CXLFLASH_SUBS_DEV_ID 0x04F0 -- cgit v0.10.2 From ee91e332a6e6e9b939f60f6e1bd72fb2def5290d Mon Sep 17 00:00:00 2001 From: Manoj Kumar Date: Mon, 14 Dec 2015 15:07:02 -0600 Subject: cxlflash: Fix to resolve cmd leak after host reset After a few iterations of resetting the card, either during EEH recovery, or a host_reset the following is seen in the logs. cxlflash 0008:00: cxlflash_queuecommand: could not get a free command At every reset of the card, the commands that are outstanding are being leaked. No effort is being made to reap these commands. A few more resets later, the above error message floods the logs and the card is rendered totally unusable as no free commands are available. Iterated through the 'cmd' queue and printed out the 'free' counter and found that on each reset certain commands were in-use and stayed in-use through subsequent resets. To resolve this issue, when the card is reset, reap all the commands that are active/outstanding. Signed-off-by: Manoj N. Kumar Acked-by: Matthew R. Ochs Reviewed-by: Andrew Donnellan Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c index 35a3202..ac39856 100644 --- a/drivers/scsi/cxlflash/main.c +++ b/drivers/scsi/cxlflash/main.c @@ -632,15 +632,30 @@ static void free_mem(struct cxlflash_cfg *cfg) * @cfg: Internal structure associated with the host. * * Safe to call with AFU in a partially allocated/initialized state. + * + * Cleans up all state associated with the command queue, and unmaps + * the MMIO space. + * + * - complete() will take care of commands we initiated (they'll be checked + * in as part of the cleanup that occurs after the completion) + * + * - cmd_checkin() will take care of entries that we did not initiate and that + * have not (and will not) complete because they are sitting on a [now stale] + * hardware queue */ static void stop_afu(struct cxlflash_cfg *cfg) { int i; struct afu *afu = cfg->afu; + struct afu_cmd *cmd; if (likely(afu)) { - for (i = 0; i < CXLFLASH_NUM_CMDS; i++) - complete(&afu->cmd[i].cevent); + for (i = 0; i < CXLFLASH_NUM_CMDS; i++) { + cmd = &afu->cmd[i]; + complete(&cmd->cevent); + if (!atomic_read(&cmd->free)) + cmd_checkin(cmd); + } if (likely(afu->afu_map)) { cxl_psa_unmap((void __iomem *)afu->afu_map); -- cgit v0.10.2 From b45cdbaf9f7f0486847c52f60747fb108724652a Mon Sep 17 00:00:00 2001 From: Manoj Kumar Date: Mon, 14 Dec 2015 15:07:23 -0600 Subject: cxlflash: Resolve oops in wait_port_offline If an async error interrupt is generated, and the error requires the FC link to be reset, it cannot be performed in the interrupt context. So a work element is scheduled to complete the link reset in a process context. If either an EEH event or an escalation occurs in between when the interrupt is generated and the scheduled work is started, the MMIO space may no longer be available. This will cause an oops in the worker thread. [ 606.806583] NIP kthread_data+0x28/0x40 [ 606.806633] LR wq_worker_sleeping+0x30/0x100 [ 606.806694] Call Trace: [ 606.806721] 0x50 (unreliable) [ 606.806796] wq_worker_sleeping+0x30/0x100 [ 606.806884] __schedule+0x69c/0x8a0 [ 606.806959] schedule+0x44/0xc0 [ 606.807034] do_exit+0x770/0xb90 [ 606.807109] die+0x300/0x460 [ 606.807185] bad_page_fault+0xd8/0x150 [ 606.807259] handle_page_fault+0x2c/0x30 [ 606.807338] wait_port_offline.constprop.12+0x60/0x130 [cxlflash] To prevent the problem space area from being unmapped, when there is pending work, a mapcount (using the kref mechanism) is held. The mapcount is released only when the work is completed. The last reference release is tied to the unmapping service. Signed-off-by: Manoj N. Kumar Acked-by: Matthew R. Ochs Reviewed-by: Uma Krishnan Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/cxlflash/common.h b/drivers/scsi/cxlflash/common.h index c11cd19..5ada926 100644 --- a/drivers/scsi/cxlflash/common.h +++ b/drivers/scsi/cxlflash/common.h @@ -165,6 +165,8 @@ struct afu { struct sisl_host_map __iomem *host_map; /* MC host map */ struct sisl_ctrl_map __iomem *ctrl_map; /* MC control map */ + struct kref mapcount; + ctx_hndl_t ctx_hndl; /* master's context handle */ u64 *hrrq_start; u64 *hrrq_end; diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c index ac39856..30542ca 100644 --- a/drivers/scsi/cxlflash/main.c +++ b/drivers/scsi/cxlflash/main.c @@ -368,6 +368,7 @@ out: no_room: afu->read_room = true; + kref_get(&cfg->afu->mapcount); schedule_work(&cfg->work_q); rc = SCSI_MLQUEUE_HOST_BUSY; goto out; @@ -473,6 +474,16 @@ out: return rc; } +static void afu_unmap(struct kref *ref) +{ + struct afu *afu = container_of(ref, struct afu, mapcount); + + if (likely(afu->afu_map)) { + cxl_psa_unmap((void __iomem *)afu->afu_map); + afu->afu_map = NULL; + } +} + /** * cxlflash_driver_info() - information handler for this host driver * @host: SCSI host associated with device. @@ -503,6 +514,7 @@ static int cxlflash_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scp) ulong lock_flags; short lflag = 0; int rc = 0; + int kref_got = 0; dev_dbg_ratelimited(dev, "%s: (scp=%p) %d/%d/%d/%llu " "cdb=(%08X-%08X-%08X-%08X)\n", @@ -547,6 +559,9 @@ static int cxlflash_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scp) goto out; } + kref_get(&cfg->afu->mapcount); + kref_got = 1; + cmd->rcb.ctx_id = afu->ctx_hndl; cmd->rcb.port_sel = port_sel; cmd->rcb.lun_id = lun_to_lunid(scp->device->lun); @@ -587,6 +602,8 @@ static int cxlflash_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scp) } out: + if (kref_got) + kref_put(&afu->mapcount, afu_unmap); pr_devel("%s: returning rc=%d\n", __func__, rc); return rc; } @@ -661,6 +678,7 @@ static void stop_afu(struct cxlflash_cfg *cfg) cxl_psa_unmap((void __iomem *)afu->afu_map); afu->afu_map = NULL; } + kref_put(&afu->mapcount, afu_unmap); } } @@ -746,8 +764,8 @@ static void cxlflash_remove(struct pci_dev *pdev) scsi_remove_host(cfg->host); /* fall through */ case INIT_STATE_AFU: - term_afu(cfg); cancel_work_sync(&cfg->work_q); + term_afu(cfg); case INIT_STATE_PCI: pci_release_regions(cfg->dev); pci_disable_device(pdev); @@ -1331,6 +1349,7 @@ static irqreturn_t cxlflash_async_err_irq(int irq, void *data) __func__, port); cfg->lr_state = LINK_RESET_REQUIRED; cfg->lr_port = port; + kref_get(&cfg->afu->mapcount); schedule_work(&cfg->work_q); } @@ -1351,6 +1370,7 @@ static irqreturn_t cxlflash_async_err_irq(int irq, void *data) if (info->action & SCAN_HOST) { atomic_inc(&cfg->scan_host_needed); + kref_get(&cfg->afu->mapcount); schedule_work(&cfg->work_q); } } @@ -1746,6 +1766,7 @@ static int init_afu(struct cxlflash_cfg *cfg) rc = -ENOMEM; goto err1; } + kref_init(&afu->mapcount); /* No byte reverse on reading afu_version or string will be backwards */ reg = readq(&afu->afu_map->global.regs.afu_version); @@ -1780,8 +1801,7 @@ out: return rc; err2: - cxl_psa_unmap((void __iomem *)afu->afu_map); - afu->afu_map = NULL; + kref_put(&afu->mapcount, afu_unmap); err1: term_mc(cfg, UNDO_START); goto out; @@ -2354,6 +2374,7 @@ static void cxlflash_worker_thread(struct work_struct *work) if (atomic_dec_if_positive(&cfg->scan_host_needed) >= 0) scsi_scan_host(cfg->host); + kref_put(&afu->mapcount, afu_unmap); } /** -- cgit v0.10.2 From a2746fb16e41b7c8f02aa4d2605ecce97abbebbd Mon Sep 17 00:00:00 2001 From: Manoj Kumar Date: Mon, 14 Dec 2015 15:07:43 -0600 Subject: cxlflash: Enable device id for future IBM CXL adapter This drop enables a future card with a device id of 0x0600 to be recognized by the cxlflash driver. As per the design, the Accelerator Function Unit (AFU) for this new IBM CXL Flash Adapter retains the same host interface as the previous generation. For the early prototypes of the new card, the driver with this change behaves exactly as the driver prior to this behaved with the earlier generation card. Therefore, no card specific programming has been added. These card specific changes can be staged in later if needed. Signed-off-by: Manoj N. Kumar Acked-by: Matthew R. Ochs Reviewed-by: Andrew Donnellan Signed-off-by: Martin K. Petersen diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c index 30542ca..f6d90ce 100644 --- a/drivers/scsi/cxlflash/main.c +++ b/drivers/scsi/cxlflash/main.c @@ -2309,6 +2309,7 @@ static struct scsi_host_template driver_template = { * Device dependent values */ static struct dev_dependent_vals dev_corsa_vals = { CXLFLASH_MAX_SECTORS }; +static struct dev_dependent_vals dev_flash_gt_vals = { CXLFLASH_MAX_SECTORS }; /* * PCI device binding table @@ -2316,6 +2317,8 @@ static struct dev_dependent_vals dev_corsa_vals = { CXLFLASH_MAX_SECTORS }; static struct pci_device_id cxlflash_pci_table[] = { {PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CORSA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (kernel_ulong_t)&dev_corsa_vals}, + {PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_FLASH_GT, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, (kernel_ulong_t)&dev_flash_gt_vals}, {} }; diff --git a/drivers/scsi/cxlflash/main.h b/drivers/scsi/cxlflash/main.h index 7e2d0e1..0faed42 100644 --- a/drivers/scsi/cxlflash/main.h +++ b/drivers/scsi/cxlflash/main.h @@ -23,8 +23,8 @@ #define CXLFLASH_NAME "cxlflash" #define CXLFLASH_ADAPTER_NAME "IBM POWER CXL Flash Adapter" -#define PCI_DEVICE_ID_IBM_CORSA 0x04F0 -#define CXLFLASH_SUBS_DEV_ID 0x04F0 +#define PCI_DEVICE_ID_IBM_CORSA 0x04F0 +#define PCI_DEVICE_ID_IBM_FLASH_GT 0x0600 /* Since there is only one target, make it 0 */ #define CXLFLASH_TARGET 0 -- cgit v0.10.2