diff options
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/Kconfig | 9 | ||||
-rw-r--r-- | drivers/scsi/atari_dma_emul.c | 468 | ||||
-rw-r--r-- | drivers/scsi/atari_scsi.c | 27 | ||||
-rw-r--r-- | drivers/scsi/ch.c | 6 | ||||
-rw-r--r-- | drivers/scsi/dpt_i2o.c | 2 | ||||
-rw-r--r-- | drivers/scsi/esp_scsi.h | 3 | ||||
-rw-r--r-- | drivers/scsi/ide-scsi.c | 218 | ||||
-rw-r--r-- | drivers/scsi/osst.c | 3 | ||||
-rw-r--r-- | drivers/scsi/pcmcia/aha152x_stub.c | 58 | ||||
-rw-r--r-- | drivers/scsi/pcmcia/fdomain_stub.c | 37 | ||||
-rw-r--r-- | drivers/scsi/pcmcia/nsp_cs.c | 194 | ||||
-rw-r--r-- | drivers/scsi/pcmcia/qlogic_stub.c | 47 | ||||
-rw-r--r-- | drivers/scsi/pcmcia/sym53c500_cs.c | 46 | ||||
-rw-r--r-- | drivers/scsi/qlogicpti.c | 146 | ||||
-rw-r--r-- | drivers/scsi/qlogicpti.h | 2 | ||||
-rw-r--r-- | drivers/scsi/sg.c | 10 | ||||
-rw-r--r-- | drivers/scsi/st.c | 11 | ||||
-rw-r--r-- | drivers/scsi/sun_esp.c | 267 |
18 files changed, 500 insertions, 1054 deletions
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index d3b211af4e1c..403ecad48d4b 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -1640,6 +1640,7 @@ config ATARI_SCSI tristate "Atari native SCSI support" depends on ATARI && SCSI select SCSI_SPI_ATTRS + select NVRAM ---help--- If you have an Atari with built-in NCR5380 SCSI controller (TT, Falcon, ...) say Y to get it supported. Of course also, if you have @@ -1670,14 +1671,6 @@ config ATARI_SCSI_RESET_BOOT boot process fractionally longer but may assist recovery from errors that leave the devices with SCSI operations partway completed. -config TT_DMA_EMUL - bool "Hades SCSI DMA emulator" - depends on ATARI_SCSI && HADES - help - This option enables code which emulates the TT SCSI DMA chip on the - Hades. This increases the SCSI transfer rates at least ten times - compared to PIO transfers. - config MAC_SCSI bool "Macintosh NCR5380 SCSI" depends on MAC && SCSI=y diff --git a/drivers/scsi/atari_dma_emul.c b/drivers/scsi/atari_dma_emul.c deleted file mode 100644 index cdc710ea00fa..000000000000 --- a/drivers/scsi/atari_dma_emul.c +++ /dev/null @@ -1,468 +0,0 @@ -/* - * atari_dma_emul.c -- TT SCSI DMA emulator for the Hades. - * - * Copyright 1997 Wout Klaren <W.Klaren@inter.nl.net> - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - * - * This code was written using the Hades TOS source code as a - * reference. This source code can be found on the home page - * of Medusa Computer Systems. - * - * Version 0.1, 1997-09-24. - * - * This code should be considered experimental. It has only been - * tested on a Hades with a 68060. It might not work on a Hades - * with a 68040. Make backups of your hard drives before using - * this code. - */ - -#include <linux/compiler.h> -#include <asm/thread_info.h> -#include <asm/uaccess.h> - -#define hades_dma_ctrl (*(unsigned char *) 0xffff8717) -#define hades_psdm_reg (*(unsigned char *) 0xffff8741) - -#define TRANSFER_SIZE 16 - -struct m68040_frame { - unsigned long effaddr; /* effective address */ - unsigned short ssw; /* special status word */ - unsigned short wb3s; /* write back 3 status */ - unsigned short wb2s; /* write back 2 status */ - unsigned short wb1s; /* write back 1 status */ - unsigned long faddr; /* fault address */ - unsigned long wb3a; /* write back 3 address */ - unsigned long wb3d; /* write back 3 data */ - unsigned long wb2a; /* write back 2 address */ - unsigned long wb2d; /* write back 2 data */ - unsigned long wb1a; /* write back 1 address */ - unsigned long wb1dpd0; /* write back 1 data/push data 0*/ - unsigned long pd1; /* push data 1*/ - unsigned long pd2; /* push data 2*/ - unsigned long pd3; /* push data 3*/ -}; - -static void writeback (unsigned short wbs, unsigned long wba, - unsigned long wbd, void *old_buserr) -{ - mm_segment_t fs = get_fs(); - static void *save_buserr; - - __asm__ __volatile__ ("movec.l %%vbr,%%a0\n\t" - "move.l %0,8(%%a0)\n\t" - : - : "r" (&&bus_error) - : "a0" ); - - save_buserr = old_buserr; - - set_fs (MAKE_MM_SEG(wbs & WBTM_040)); - - switch (wbs & WBSIZ_040) { - case BA_SIZE_BYTE: - put_user (wbd & 0xff, (char *)wba); - break; - case BA_SIZE_WORD: - put_user (wbd & 0xffff, (short *)wba); - break; - case BA_SIZE_LONG: - put_user (wbd, (int *)wba); - break; - } - - set_fs (fs); - return; - -bus_error: - __asm__ __volatile__ ("cmp.l %0,2(%%sp)\n\t" - "bcs.s .jump_old\n\t" - "cmp.l %1,2(%%sp)\n\t" - "bls.s .restore_old\n" - ".jump_old:\n\t" - "move.l %2,-(%%sp)\n\t" - "rts\n" - ".restore_old:\n\t" - "move.l %%a0,-(%%sp)\n\t" - "movec.l %%vbr,%%a0\n\t" - "move.l %2,8(%%a0)\n\t" - "move.l (%%sp)+,%%a0\n\t" - "rte\n\t" - : - : "i" (writeback), "i" (&&bus_error), - "m" (save_buserr) ); -} - -/* - * static inline void set_restdata_reg(unsigned char *cur_addr) - * - * Set the rest data register if necessary. - */ - -static inline void set_restdata_reg(unsigned char *cur_addr) -{ - if (((long) cur_addr & ~3) != 0) - tt_scsi_dma.dma_restdata = - *((unsigned long *) ((long) cur_addr & ~3)); -} - -/* - * void hades_dma_emulator(int irq, void *dummy) - * - * This code emulates TT SCSI DMA on the Hades. - * - * Note the following: - * - * 1. When there is no byte available to read from the SCSI bus, or - * when a byte cannot yet bet written to the SCSI bus, a bus - * error occurs when reading or writing the pseudo DMA data - * register (hades_psdm_reg). We have to catch this bus error - * and try again to read or write the byte. If after several tries - * we still get a bus error, the interrupt handler is left. When - * the byte can be read or written, the interrupt handler is - * called again. - * - * 2. The SCSI interrupt must be disabled in this interrupt handler. - * - * 3. If we set the EOP signal, the SCSI controller still expects one - * byte to be read or written. Therefore the last byte is transferred - * separately, after setting the EOP signal. - * - * 4. When this function is left, the address pointer (start_addr) is - * converted to a physical address. Because it points one byte - * further than the last transferred byte, it can point outside the - * current page. If virt_to_phys() is called with this address we - * might get an access error. Therefore virt_to_phys() is called with - * start_addr - 1 if the count has reached zero. The result is - * increased with one. - */ - -static irqreturn_t hades_dma_emulator(int irq, void *dummy) -{ - unsigned long dma_base; - register unsigned long dma_cnt asm ("d3"); - static long save_buserr; - register unsigned long save_sp asm ("d4"); - register int tries asm ("d5"); - register unsigned char *start_addr asm ("a3"), *end_addr asm ("a4"); - register unsigned char *eff_addr; - register unsigned char *psdm_reg; - unsigned long rem; - - atari_disable_irq(IRQ_TT_MFP_SCSI); - - /* - * Read the dma address and count registers. - */ - - dma_base = SCSI_DMA_READ_P(dma_addr); - dma_cnt = SCSI_DMA_READ_P(dma_cnt); - - /* - * Check if DMA is still enabled. - */ - - if ((tt_scsi_dma.dma_ctrl & 2) == 0) - { - atari_enable_irq(IRQ_TT_MFP_SCSI); - return IRQ_HANDLED; - } - - if (dma_cnt == 0) - { - printk(KERN_NOTICE "DMA emulation: count is zero.\n"); - tt_scsi_dma.dma_ctrl &= 0xfd; /* DMA ready. */ - atari_enable_irq(IRQ_TT_MFP_SCSI); - return IRQ_HANDLED; - } - - /* - * Install new bus error routine. - */ - - __asm__ __volatile__ ("movec.l %%vbr,%%a0\n\t" - "move.l 8(%%a0),%0\n\t" - "move.l %1,8(%%a0)\n\t" - : "=&r" (save_buserr) - : "r" (&&scsi_bus_error) - : "a0" ); - - hades_dma_ctrl &= 0xfc; /* Bus error and EOP off. */ - - /* - * Save the stack pointer. - */ - - __asm__ __volatile__ ("move.l %%sp,%0\n\t" - : "=&r" (save_sp) ); - - tries = 100; /* Maximum number of bus errors. */ - start_addr = phys_to_virt(dma_base); - end_addr = start_addr + dma_cnt; - -scsi_loop: - dma_cnt--; - rem = dma_cnt & (TRANSFER_SIZE - 1); - dma_cnt &= ~(TRANSFER_SIZE - 1); - psdm_reg = &hades_psdm_reg; - - if (tt_scsi_dma.dma_ctrl & 1) /* Read or write? */ - { - /* - * SCSI write. Abort when count is zero. - */ - - switch (rem) - { - case 0: - while (dma_cnt > 0) - { - dma_cnt -= TRANSFER_SIZE; - - *psdm_reg = *start_addr++; - case 15: - *psdm_reg = *start_addr++; - case 14: - *psdm_reg = *start_addr++; - case 13: - *psdm_reg = *start_addr++; - case 12: - *psdm_reg = *start_addr++; - case 11: - *psdm_reg = *start_addr++; - case 10: - *psdm_reg = *start_addr++; - case 9: - *psdm_reg = *start_addr++; - case 8: - *psdm_reg = *start_addr++; - case 7: - *psdm_reg = *start_addr++; - case 6: - *psdm_reg = *start_addr++; - case 5: - *psdm_reg = *start_addr++; - case 4: - *psdm_reg = *start_addr++; - case 3: - *psdm_reg = *start_addr++; - case 2: - *psdm_reg = *start_addr++; - case 1: - *psdm_reg = *start_addr++; - } - } - - hades_dma_ctrl |= 1; /* Set EOP. */ - udelay(10); - *psdm_reg = *start_addr++; /* Dummy byte. */ - tt_scsi_dma.dma_ctrl &= 0xfd; /* DMA ready. */ - } - else - { - /* - * SCSI read. Abort when count is zero. - */ - - switch (rem) - { - case 0: - while (dma_cnt > 0) - { - dma_cnt -= TRANSFER_SIZE; - - *start_addr++ = *psdm_reg; - case 15: - *start_addr++ = *psdm_reg; - case 14: - *start_addr++ = *psdm_reg; - case 13: - *start_addr++ = *psdm_reg; - case 12: - *start_addr++ = *psdm_reg; - case 11: - *start_addr++ = *psdm_reg; - case 10: - *start_addr++ = *psdm_reg; - case 9: - *start_addr++ = *psdm_reg; - case 8: - *start_addr++ = *psdm_reg; - case 7: - *start_addr++ = *psdm_reg; - case 6: - *start_addr++ = *psdm_reg; - case 5: - *start_addr++ = *psdm_reg; - case 4: - *start_addr++ = *psdm_reg; - case 3: - *start_addr++ = *psdm_reg; - case 2: - *start_addr++ = *psdm_reg; - case 1: - *start_addr++ = *psdm_reg; - } - } - - hades_dma_ctrl |= 1; /* Set EOP. */ - udelay(10); - *start_addr++ = *psdm_reg; - tt_scsi_dma.dma_ctrl &= 0xfd; /* DMA ready. */ - - set_restdata_reg(start_addr); - } - - if (start_addr != end_addr) - printk(KERN_CRIT "DMA emulation: FATAL: Count is not zero at end of transfer.\n"); - - dma_cnt = end_addr - start_addr; - -scsi_end: - dma_base = (dma_cnt == 0) ? virt_to_phys(start_addr - 1) + 1 : - virt_to_phys(start_addr); - - SCSI_DMA_WRITE_P(dma_addr, dma_base); - SCSI_DMA_WRITE_P(dma_cnt, dma_cnt); - - /* - * Restore old bus error routine. - */ - - __asm__ __volatile__ ("movec.l %%vbr,%%a0\n\t" - "move.l %0,8(%%a0)\n\t" - : - : "r" (save_buserr) - : "a0" ); - - atari_enable_irq(IRQ_TT_MFP_SCSI); - - return IRQ_HANDLED; - -scsi_bus_error: - /* - * First check if the bus error is caused by our code. - * If not, call the original handler. - */ - - __asm__ __volatile__ ("cmp.l %0,2(%%sp)\n\t" - "bcs.s .old_vector\n\t" - "cmp.l %1,2(%%sp)\n\t" - "bls.s .scsi_buserr\n" - ".old_vector:\n\t" - "move.l %2,-(%%sp)\n\t" - "rts\n" - ".scsi_buserr:\n\t" - : - : "i" (&&scsi_loop), "i" (&&scsi_end), - "m" (save_buserr) ); - - if (CPU_IS_060) - { - /* - * Get effective address and restore the stack. - */ - - __asm__ __volatile__ ("move.l 8(%%sp),%0\n\t" - "move.l %1,%%sp\n\t" - : "=a&" (eff_addr) - : "r" (save_sp) ); - } - else - { - register struct m68040_frame *frame; - - __asm__ __volatile__ ("lea 8(%%sp),%0\n\t" - : "=a&" (frame) ); - - if (tt_scsi_dma.dma_ctrl & 1) - { - /* - * Bus error while writing. - */ - - if (frame->wb3s & WBV_040) - { - if (frame->wb3a == (long) &hades_psdm_reg) - start_addr--; - else - writeback(frame->wb3s, frame->wb3a, - frame->wb3d, &&scsi_bus_error); - } - - if (frame->wb2s & WBV_040) - { - if (frame->wb2a == (long) &hades_psdm_reg) - start_addr--; - else - writeback(frame->wb2s, frame->wb2a, - frame->wb2d, &&scsi_bus_error); - } - - if (frame->wb1s & WBV_040) - { - if (frame->wb1a == (long) &hades_psdm_reg) - start_addr--; - } - } - else - { - /* - * Bus error while reading. - */ - - if (frame->wb3s & WBV_040) - writeback(frame->wb3s, frame->wb3a, - frame->wb3d, &&scsi_bus_error); - } - - eff_addr = (unsigned char *) frame->faddr; - - __asm__ __volatile__ ("move.l %0,%%sp\n\t" - : - : "r" (save_sp) ); - } - - dma_cnt = end_addr - start_addr; - - if (eff_addr == &hades_psdm_reg) - { - /* - * Bus error occurred while reading the pseudo - * DMA register. Time out. - */ - - tries--; - - if (tries <= 0) - { - if ((tt_scsi_dma.dma_ctrl & 1) == 0) /* Read or write? */ - set_restdata_reg(start_addr); - - if (dma_cnt <= 1) - printk(KERN_CRIT "DMA emulation: Fatal " - "error while %s the last byte.\n", - (tt_scsi_dma.dma_ctrl & 1) - ? "writing" : "reading"); - - goto scsi_end; - } - else - goto scsi_loop; - } - else - { - /* - * Bus error during pseudo DMA transfer. - * Terminate the DMA transfer. - */ - - hades_dma_ctrl |= 3; /* Set EOP and bus error. */ - if ((tt_scsi_dma.dma_ctrl & 1) == 0) /* Read or write? */ - set_restdata_reg(start_addr); - goto scsi_end; - } -} diff --git a/drivers/scsi/atari_scsi.c b/drivers/scsi/atari_scsi.c index f5732d8f67fe..21fe07f9df87 100644 --- a/drivers/scsi/atari_scsi.c +++ b/drivers/scsi/atari_scsi.c @@ -249,10 +249,6 @@ static int setup_hostid = -1; module_param(setup_hostid, int, 0); -#if defined(CONFIG_TT_DMA_EMUL) -#include "atari_dma_emul.c" -#endif - #if defined(REAL_DMA) static int scsi_dma_is_ignored_buserr(unsigned char dma_stat) @@ -695,21 +691,8 @@ int atari_scsi_detect(struct scsi_host_template *host) #ifdef REAL_DMA tt_scsi_dma.dma_ctrl = 0; atari_dma_residual = 0; -#ifdef CONFIG_TT_DMA_EMUL - if (MACH_IS_HADES) { - if (request_irq(IRQ_AUTO_2, hades_dma_emulator, - IRQ_TYPE_PRIO, "Hades DMA emulator", - hades_dma_emulator)) { - printk(KERN_ERR "atari_scsi_detect: cannot allocate irq %d, aborting (MACH_IS_HADES)",IRQ_AUTO_2); - free_irq(IRQ_TT_MFP_SCSI, instance); - scsi_unregister(atari_scsi_host); - atari_stram_free(atari_dma_buffer); - atari_dma_buffer = 0; - return 0; - } - } -#endif - if (MACH_IS_MEDUSA || MACH_IS_HADES) { + + if (MACH_IS_MEDUSA) { /* While the read overruns (described by Drew Eckhardt in * NCR5380.c) never happened on TTs, they do in fact on the Medusa * (This was the cause why SCSI didn't work right for so long @@ -1007,11 +990,7 @@ static unsigned long atari_dma_xfer_len(unsigned long wanted_len, Scsi_Cmnd *cmd, int write_flag) { unsigned long possible_len, limit; -#ifndef CONFIG_TT_DMA_EMUL - if (MACH_IS_HADES) - /* Hades has no SCSI DMA at all :-( Always force use of PIO */ - return 0; -#endif + if (IS_A_TT()) /* TT SCSI DMA can transfer arbitrary #bytes */ return wanted_len; diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c index 3c257fe0893e..88ecf94ad979 100644 --- a/drivers/scsi/ch.c +++ b/drivers/scsi/ch.c @@ -914,9 +914,9 @@ static int ch_probe(struct device *dev) ch->minor = minor; sprintf(ch->name,"ch%d",ch->minor); - class_dev = device_create_drvdata(ch_sysfs_class, dev, - MKDEV(SCSI_CHANGER_MAJOR, ch->minor), - ch, "s%s", ch->name); + class_dev = device_create(ch_sysfs_class, dev, + MKDEV(SCSI_CHANGER_MAJOR, ch->minor), ch, + "s%s", ch->name); if (IS_ERR(class_dev)) { printk(KERN_WARNING "ch%d: device_create failed\n", ch->minor); diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c index 1fe0901e8119..8aba4fdfb522 100644 --- a/drivers/scsi/dpt_i2o.c +++ b/drivers/scsi/dpt_i2o.c @@ -271,7 +271,7 @@ rebuild_sys_tab: pHba->initialized = TRUE; pHba->state &= ~DPTI_STATE_RESET; if (adpt_sysfs_class) { - struct device *dev = device_create_drvdata(adpt_sysfs_class, + struct device *dev = device_create(adpt_sysfs_class, NULL, MKDEV(DPTI_I2O_MAJOR, pHba->unit), NULL, "dpti%d", pHba->unit); if (IS_ERR(dev)) { diff --git a/drivers/scsi/esp_scsi.h b/drivers/scsi/esp_scsi.h index bb43a1388188..28e22acf87ea 100644 --- a/drivers/scsi/esp_scsi.h +++ b/drivers/scsi/esp_scsi.h @@ -521,7 +521,8 @@ struct esp { struct completion *eh_reset; - struct sbus_dma *dma; + void *dma; + int dmarev; }; /* A front-end driver for the ESP chip should do the following in diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 81c16cba5417..740bad435995 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -40,7 +40,6 @@ #include <linux/ioport.h> #include <linux/blkdev.h> #include <linux/errno.h> -#include <linux/hdreg.h> #include <linux/slab.h> #include <linux/ide.h> #include <linux/scatterlist.h> @@ -83,7 +82,6 @@ typedef struct ide_scsi_obj { struct gendisk *disk; struct Scsi_Host *host; - struct ide_atapi_pc *pc; /* Current packet command */ unsigned long transform; /* SCSI cmd translation layer */ unsigned long log; /* log flags */ } idescsi_scsi_t; @@ -131,50 +129,6 @@ static inline idescsi_scsi_t *drive_to_idescsi(ide_drive_t *ide_drive) return scsihost_to_idescsi(ide_drive->driver_data); } -/* - * PIO data transfer routine using the scatter gather table. - */ -static void ide_scsi_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, - unsigned int bcount, int write) -{ - ide_hwif_t *hwif = drive->hwif; - const struct ide_tp_ops *tp_ops = hwif->tp_ops; - xfer_func_t *xf = write ? tp_ops->output_data : tp_ops->input_data; - char *buf; - int count; - - while (bcount) { - count = min(pc->sg->length - pc->b_count, bcount); - if (PageHighMem(sg_page(pc->sg))) { - unsigned long flags; - - local_irq_save(flags); - buf = kmap_atomic(sg_page(pc->sg), KM_IRQ0) + - pc->sg->offset; - xf(drive, NULL, buf + pc->b_count, count); - kunmap_atomic(buf - pc->sg->offset, KM_IRQ0); - local_irq_restore(flags); - } else { - buf = sg_virt(pc->sg); - xf(drive, NULL, buf + pc->b_count, count); - } - bcount -= count; pc->b_count += count; - if (pc->b_count == pc->sg->length) { - if (!--pc->sg_cnt) - break; - pc->sg = sg_next(pc->sg); - pc->b_count = 0; - } - } - - if (bcount) { - printk(KERN_ERR "%s: scatter gather table too small, %s\n", - drive->name, write ? "padding with zeros" - : "discarding data"); - ide_pad_transfer(drive, write, bcount); - } -} - static void ide_scsi_hex_dump(u8 *data, int len) { print_hex_dump(KERN_CONT, "", DUMP_PREFIX_NONE, 16, 1, data, len, 0); @@ -182,10 +136,10 @@ static void ide_scsi_hex_dump(u8 *data, int len) static int idescsi_end_request(ide_drive_t *, int, int); -static void ide_scsi_callback(ide_drive_t *drive) +static void ide_scsi_callback(ide_drive_t *drive, int dsc) { idescsi_scsi_t *scsi = drive_to_idescsi(drive); - struct ide_atapi_pc *pc = scsi->pc; + struct ide_atapi_pc *pc = drive->pc; if (pc->flags & PC_FLAG_TIMEDOUT) debug_log("%s: got timed out packet %lu at %lu\n", __func__, @@ -244,9 +198,9 @@ idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err) { ide_hwif_t *hwif = drive->hwif; - if (hwif->tp_ops->read_status(hwif) & (BUSY_STAT | DRQ_STAT)) + if (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ)) /* force an abort */ - hwif->tp_ops->exec_command(hwif, WIN_IDLEIMMEDIATE); + hwif->tp_ops->exec_command(hwif, ATA_CMD_IDLEIMMEDIATE); rq->errors++; @@ -312,49 +266,10 @@ static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs) spin_unlock_irqrestore(host->host_lock, flags); kfree(pc); blk_put_request(rq); - scsi->pc = NULL; + drive->pc = NULL; return 0; } -static inline unsigned long get_timeout(struct ide_atapi_pc *pc) -{ - return max_t(unsigned long, WAIT_CMD, pc->timeout - jiffies); -} - -static int idescsi_expiry(ide_drive_t *drive) -{ - idescsi_scsi_t *scsi = drive_to_idescsi(drive); - struct ide_atapi_pc *pc = scsi->pc; - - debug_log("%s called for %lu at %lu\n", __func__, - pc->scsi_cmd->serial_number, jiffies); - - pc->flags |= PC_FLAG_TIMEDOUT; - - return 0; /* we do not want the ide subsystem to retry */ -} - -/* - * Our interrupt handler. - */ -static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) -{ - idescsi_scsi_t *scsi = drive_to_idescsi(drive); - struct ide_atapi_pc *pc = scsi->pc; - - return ide_pc_intr(drive, pc, idescsi_pc_intr, get_timeout(pc), - idescsi_expiry, NULL, NULL, NULL, - ide_scsi_io_buffers); -} - -static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive) -{ - idescsi_scsi_t *scsi = drive_to_idescsi(drive); - - return ide_transfer_pc(drive, scsi->pc, idescsi_pc_intr, - get_timeout(scsi->pc), idescsi_expiry); -} - static inline int idescsi_set_direction(struct ide_atapi_pc *pc) { switch (pc->c[0]) { @@ -397,13 +312,10 @@ static int idescsi_map_sg(ide_drive_t *drive, struct ide_atapi_pc *pc) static ide_startstop_t idescsi_issue_pc(ide_drive_t *drive, struct ide_atapi_pc *pc) { - idescsi_scsi_t *scsi = drive_to_idescsi(drive); - /* Set the current packet command */ - scsi->pc = pc; + drive->pc = pc; - return ide_issue_pc(drive, pc, idescsi_transfer_pc, - get_timeout(pc), idescsi_expiry); + return ide_issue_pc(drive, ide_scsi_get_timeout(pc), ide_scsi_expiry); } /* @@ -419,7 +331,8 @@ static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *r if (blk_sense_request(rq) || blk_special_request(rq)) { struct ide_atapi_pc *pc = (struct ide_atapi_pc *)rq->special; - if (drive->using_dma && !idescsi_map_sg(drive, pc)) + if ((drive->dev_flags & IDE_DFLAG_USING_DMA) && + idescsi_map_sg(drive, pc) == 0) pc->flags |= PC_FLAG_DMA_OK; return idescsi_issue_pc(drive, pc); @@ -430,21 +343,41 @@ static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *r } #ifdef CONFIG_IDE_PROC_FS -static void idescsi_add_settings(ide_drive_t *drive) -{ - idescsi_scsi_t *scsi = drive_to_idescsi(drive); - -/* - * drive setting name read/write data type min max mul_factor div_factor data pointer set function - */ - ide_add_setting(drive, "bios_cyl", SETTING_RW, TYPE_INT, 0, 1023, 1, 1, &drive->bios_cyl, NULL); - ide_add_setting(drive, "bios_head", SETTING_RW, TYPE_BYTE, 0, 255, 1, 1, &drive->bios_head, NULL); - ide_add_setting(drive, "bios_sect", SETTING_RW, TYPE_BYTE, 0, 63, 1, 1, &drive->bios_sect, NULL); - ide_add_setting(drive, "transform", SETTING_RW, TYPE_INT, 0, 3, 1, 1, &scsi->transform, NULL); - ide_add_setting(drive, "log", SETTING_RW, TYPE_INT, 0, 1, 1, 1, &scsi->log, NULL); -} -#else -static inline void idescsi_add_settings(ide_drive_t *drive) { ; } +#define ide_scsi_devset_get(name, field) \ +static int get_##name(ide_drive_t *drive) \ +{ \ + idescsi_scsi_t *scsi = drive_to_idescsi(drive); \ + return scsi->field; \ +} + +#define ide_scsi_devset_set(name, field) \ +static int set_##name(ide_drive_t *drive, int arg) \ +{ \ + idescsi_scsi_t *scsi = drive_to_idescsi(drive); \ + scsi->field = arg; \ + return 0; \ +} + +#define ide_scsi_devset_rw_field(_name, _field) \ +ide_scsi_devset_get(_name, _field); \ +ide_scsi_devset_set(_name, _field); \ +IDE_DEVSET(_name, DS_SYNC, get_##_name, set_##_name); + +ide_devset_rw_field(bios_cyl, bios_cyl); +ide_devset_rw_field(bios_head, bios_head); +ide_devset_rw_field(bios_sect, bios_sect); + +ide_scsi_devset_rw_field(transform, transform); +ide_scsi_devset_rw_field(log, log); + +static const struct ide_proc_devset idescsi_settings[] = { + IDE_PROC_DEVSET(bios_cyl, 0, 1023), + IDE_PROC_DEVSET(bios_head, 0, 255), + IDE_PROC_DEVSET(bios_sect, 0, 63), + IDE_PROC_DEVSET(log, 0, 1), + IDE_PROC_DEVSET(transform, 0, 3), + { 0 }, +}; #endif /* @@ -452,16 +385,16 @@ static inline void idescsi_add_settings(ide_drive_t *drive) { ; } */ static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi) { - if (drive->id && (drive->id->config & 0x0060) == 0x20) - set_bit(IDE_AFLAG_DRQ_INTERRUPT, &drive->atapi_flags); clear_bit(IDESCSI_SG_TRANSFORM, &scsi->transform); #if IDESCSI_DEBUG_LOG set_bit(IDESCSI_LOG_CMD, &scsi->log); #endif /* IDESCSI_DEBUG_LOG */ - drive->pc_callback = ide_scsi_callback; + drive->pc_callback = ide_scsi_callback; + drive->pc_update_buffers = NULL; + drive->pc_io_buffers = ide_io_buffers; - idescsi_add_settings(drive); + ide_proc_register_driver(drive, scsi->driver); } static void ide_scsi_remove(ide_drive_t *drive) @@ -481,7 +414,7 @@ static void ide_scsi_remove(ide_drive_t *drive) ide_scsi_put(scsi); - drive->scsi = 0; + drive->dev_flags &= ~IDE_DFLAG_SCSI; } static int ide_scsi_probe(ide_drive_t *); @@ -502,13 +435,12 @@ static ide_driver_t idescsi_driver = { .probe = ide_scsi_probe, .remove = ide_scsi_remove, .version = IDESCSI_VERSION, - .media = ide_scsi, - .supports_dsc_overlap = 0, .do_request = idescsi_do_request, .end_request = idescsi_end_request, .error = idescsi_atapi_error, #ifdef CONFIG_IDE_PROC_FS .proc = idescsi_proc, + .settings = idescsi_settings, #endif }; @@ -647,6 +579,8 @@ static int idescsi_eh_abort (struct scsi_cmnd *cmd) int busy; int ret = FAILED; + struct ide_atapi_pc *pc; + /* In idescsi_eh_abort we try to gently pry our command from the ide subsystem */ if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) @@ -667,26 +601,27 @@ static int idescsi_eh_abort (struct scsi_cmnd *cmd) spin_lock_irq(&ide_lock); /* If there is no pc running we're done (our interrupt took care of it) */ - if (!scsi->pc) { + pc = drive->pc; + if (pc == NULL) { ret = SUCCESS; goto ide_unlock; } /* It's somewhere in flight. Does ide subsystem agree? */ - if (scsi->pc->scsi_cmd->serial_number == cmd->serial_number && !busy && - elv_queue_empty(drive->queue) && HWGROUP(drive)->rq != scsi->pc->rq) { + if (pc->scsi_cmd->serial_number == cmd->serial_number && !busy && + elv_queue_empty(drive->queue) && HWGROUP(drive)->rq != pc->rq) { /* * FIXME - not sure this condition can ever occur */ printk (KERN_ERR "ide-scsi: cmd aborted!\n"); - if (blk_sense_request(scsi->pc->rq)) - kfree(scsi->pc->buf); + if (blk_sense_request(pc->rq)) + kfree(pc->buf); /* we need to call blk_put_request twice. */ - blk_put_request(scsi->pc->rq); - blk_put_request(scsi->pc->rq); - kfree(scsi->pc); - scsi->pc = NULL; + blk_put_request(pc->rq); + blk_put_request(pc->rq); + kfree(pc); + drive->pc = NULL; ret = SUCCESS; } @@ -708,6 +643,8 @@ static int idescsi_eh_reset (struct scsi_cmnd *cmd) int ready = 0; int ret = SUCCESS; + struct ide_atapi_pc *pc; + /* In idescsi_eh_reset we forcefully remove the command from the ide subsystem and reset the device. */ if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) @@ -722,7 +659,9 @@ static int idescsi_eh_reset (struct scsi_cmnd *cmd) spin_lock_irq(cmd->device->host->host_lock); spin_lock(&ide_lock); - if (!scsi->pc || (req = scsi->pc->rq) != HWGROUP(drive)->rq || !HWGROUP(drive)->handler) { + pc = drive->pc; + + if (pc == NULL || (req = pc->rq) != HWGROUP(drive)->rq || !HWGROUP(drive)->handler) { printk (KERN_WARNING "ide-scsi: No active request in idescsi_eh_reset\n"); spin_unlock(&ide_lock); spin_unlock_irq(cmd->device->host->host_lock); @@ -733,9 +672,9 @@ static int idescsi_eh_reset (struct scsi_cmnd *cmd) if (__blk_end_request(req, -EIO, 0)) BUG(); if (blk_sense_request(req)) - kfree(scsi->pc->buf); - kfree(scsi->pc); - scsi->pc = NULL; + kfree(pc->buf); + kfree(pc); + drive->pc = NULL; blk_put_request(req); /* now nuke the drive queue */ @@ -811,6 +750,7 @@ static int ide_scsi_probe(ide_drive_t *drive) struct gendisk *g; static int warned; int err = -ENOMEM; + u16 last_lun; if (!warned && drive->media == ide_cdrom) { printk(KERN_WARNING "ide-scsi is deprecated for cd burning! Use ide-cd and give dev=/dev/hdX as device\n"); @@ -821,12 +761,11 @@ static int ide_scsi_probe(ide_drive_t *drive) return -ENODEV; if (!strstr("ide-scsi", drive->driver_req) || - !drive->present || drive->media == ide_disk || !(host = scsi_host_alloc(&idescsi_template,sizeof(idescsi_scsi_t)))) return -ENODEV; - drive->scsi = 1; + drive->dev_flags |= IDE_DFLAG_SCSI; g = alloc_disk(1 << PARTN_BITS); if (!g) @@ -836,12 +775,12 @@ static int ide_scsi_probe(ide_drive_t *drive) host->max_id = 1; - if (drive->id->last_lun) - debug_log("%s: id->last_lun=%u\n", drive->name, - drive->id->last_lun); + last_lun = drive->id[ATA_ID_LAST_LUN]; + if (last_lun) + debug_log("%s: last_lun=%u\n", drive->name, last_lun); - if ((drive->id->last_lun & 0x7) != 7) - host->max_lun = (drive->id->last_lun & 0x7) + 1; + if ((last_lun & 7) != 7) + host->max_lun = (last_lun & 7) + 1; else host->max_lun = 1; @@ -852,7 +791,6 @@ static int ide_scsi_probe(ide_drive_t *drive) idescsi->host = host; idescsi->disk = g; g->private_data = &idescsi->driver; - ide_proc_register_driver(drive, &idescsi_driver); err = 0; idescsi_setup(drive, idescsi); g->fops = &idescsi_ops; @@ -868,7 +806,7 @@ static int ide_scsi_probe(ide_drive_t *drive) put_disk(g); out_host_put: - drive->scsi = 0; + drive->dev_flags &= ~IDE_DFLAG_SCSI; scsi_host_put(host); return err; } diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c index 1c79f9794f4e..0ea78d9a37db 100644 --- a/drivers/scsi/osst.c +++ b/drivers/scsi/osst.c @@ -5708,7 +5708,8 @@ static int osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * S struct device *osst_member; int err; - osst_member = device_create_drvdata(osst_sysfs_class, device, dev, STp, "%s", name); + osst_member = device_create(osst_sysfs_class, device, dev, STp, + "%s", name); if (IS_ERR(osst_member)) { printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name); return PTR_ERR(osst_member); diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c index 2dd0dc9a9aed..165ff884f48e 100644 --- a/drivers/scsi/pcmcia/aha152x_stub.c +++ b/drivers/scsi/pcmcia/aha152x_stub.c @@ -140,44 +140,41 @@ static void aha152x_detach(struct pcmcia_device *link) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) +static int aha152x_config_check(struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cfg, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) +{ + /* For New Media T&J, look for a SCSI window */ + if (cfg->io.win[0].len >= 0x20) + p_dev->io.BasePort1 = cfg->io.win[0].base; + else if ((cfg->io.nwin > 1) && + (cfg->io.win[1].len >= 0x20)) + p_dev->io.BasePort1 = cfg->io.win[1].base; + if ((cfg->io.nwin > 0) && + (p_dev->io.BasePort1 < 0xffff)) { + if (!pcmcia_request_io(p_dev, &p_dev->io)) + return 0; + } + return -EINVAL; +} + static int aha152x_config_cs(struct pcmcia_device *link) { scsi_info_t *info = link->priv; struct aha152x_setup s; - tuple_t tuple; - cisparse_t parse; - int i, last_ret, last_fn; - u_char tuple_data[64]; + int last_ret, last_fn; struct Scsi_Host *host; - + DEBUG(0, "aha152x_config(0x%p)\n", link); - tuple.TupleData = tuple_data; - tuple.TupleDataMax = 64; - tuple.TupleOffset = 0; - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - tuple.Attributes = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - while (1) { - if (pcmcia_get_tuple_data(link, &tuple) != 0 || - pcmcia_parse_tuple(link, &tuple, &parse) != 0) - goto next_entry; - /* For New Media T&J, look for a SCSI window */ - if (parse.cftable_entry.io.win[0].len >= 0x20) - link->io.BasePort1 = parse.cftable_entry.io.win[0].base; - else if ((parse.cftable_entry.io.nwin > 1) && - (parse.cftable_entry.io.win[1].len >= 0x20)) - link->io.BasePort1 = parse.cftable_entry.io.win[1].base; - if ((parse.cftable_entry.io.nwin > 0) && - (link->io.BasePort1 < 0xffff)) { - link->conf.ConfigIndex = parse.cftable_entry.index; - i = pcmcia_request_io(link, &link->io); - if (i == CS_SUCCESS) break; - } - next_entry: - CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); + last_ret = pcmcia_loop_config(link, aha152x_config_check, NULL); + if (last_ret) { + cs_error(link, RequestIO, last_ret); + goto failed; } - + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); @@ -208,6 +205,7 @@ static int aha152x_config_cs(struct pcmcia_device *link) cs_failed: cs_error(link, last_fn, last_ret); +failed: aha152x_release_cs(link); return -ENODEV; } diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c index d8b99351b053..06254f46a0dd 100644 --- a/drivers/scsi/pcmcia/fdomain_stub.c +++ b/drivers/scsi/pcmcia/fdomain_stub.c @@ -123,34 +123,30 @@ static void fdomain_detach(struct pcmcia_device *link) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) +static int fdomain_config_check(struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cfg, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) +{ + p_dev->io.BasePort1 = cfg->io.win[0].base; + return pcmcia_request_io(p_dev, &p_dev->io); +} + + static int fdomain_config(struct pcmcia_device *link) { scsi_info_t *info = link->priv; - tuple_t tuple; - cisparse_t parse; - int i, last_ret, last_fn; - u_char tuple_data[64]; + int last_ret, last_fn; char str[22]; struct Scsi_Host *host; DEBUG(0, "fdomain_config(0x%p)\n", link); - tuple.TupleData = tuple_data; - tuple.TupleDataMax = 64; - tuple.TupleOffset = 0; - - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - while (1) { - if (pcmcia_get_tuple_data(link, &tuple) != 0 || - pcmcia_parse_tuple(link, &tuple, &parse) != 0) - goto next_entry; - link->conf.ConfigIndex = parse.cftable_entry.index; - link->io.BasePort1 = parse.cftable_entry.io.win[0].base; - i = pcmcia_request_io(link, &link->io); - if (i == CS_SUCCESS) break; - next_entry: - CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); + last_ret = pcmcia_loop_config(link, fdomain_config_check, NULL); + if (last_ret) { + cs_error(link, RequestIO, last_ret); + goto failed; } CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); @@ -181,6 +177,7 @@ static int fdomain_config(struct pcmcia_device *link) cs_failed: cs_error(link, last_fn, last_ret); +failed: fdomain_release(link); return -ENODEV; } /* fdomain_config */ diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index 24e6cb8396e3..11a61ea8d5d9 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c @@ -1606,133 +1606,129 @@ static void nsp_cs_detach(struct pcmcia_device *link) is received, to configure the PCMCIA socket, and to make the ethernet device available to the system. ======================================================================*/ -#define CS_CHECK(fn, ret) \ -do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -/*====================================================================*/ -static int nsp_cs_config(struct pcmcia_device *link) -{ - int ret; - scsi_info_t *info = link->priv; - tuple_t tuple; - cisparse_t parse; - int last_ret, last_fn; - unsigned char tuple_data[64]; - config_info_t conf; - win_req_t req; - memreq_t map; - cistpl_cftable_entry_t dflt = { 0 }; - struct Scsi_Host *host; - nsp_hw_data *data = &nsp_data_base; - - nsp_dbg(NSP_DEBUG_INIT, "in"); - - tuple.Attributes = 0; - tuple.TupleData = tuple_data; - tuple.TupleDataMax = sizeof(tuple_data); - tuple.TupleOffset = 0; - - /* Look up the current Vcc */ - CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf)); - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - while (1) { - cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); +struct nsp_cs_configdata { + nsp_hw_data *data; + win_req_t req; +}; - if (pcmcia_get_tuple_data(link, &tuple) != 0 || - pcmcia_parse_tuple(link, &tuple, &parse) != 0) - goto next_entry; +static int nsp_cs_config_check(struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cfg, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) +{ + struct nsp_cs_configdata *cfg_mem = priv_data; - if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { dflt = *cfg; } - if (cfg->index == 0) { goto next_entry; } - link->conf.ConfigIndex = cfg->index; + if (cfg->index == 0) + return -ENODEV; - /* Does this card need audio output? */ - if (cfg->flags & CISTPL_CFTABLE_AUDIO) { - link->conf.Attributes |= CONF_ENABLE_SPKR; - link->conf.Status = CCSR_AUDIO_ENA; - } + /* Does this card need audio output? */ + if (cfg->flags & CISTPL_CFTABLE_AUDIO) { + p_dev->conf.Attributes |= CONF_ENABLE_SPKR; + p_dev->conf.Status = CCSR_AUDIO_ENA; + } - /* Use power settings for Vcc and Vpp if present */ - /* Note that the CIS values need to be rescaled */ - if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) { - if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000) { - goto next_entry; - } - } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) { - if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM]/10000) { - goto next_entry; - } + /* Use power settings for Vcc and Vpp if present */ + /* Note that the CIS values need to be rescaled */ + if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) { + if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000) + return -ENODEV; + else if (dflt->vcc.present & (1<<CISTPL_POWER_VNOM)) { + if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM]/10000) + return -ENODEV; } if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) { - link->conf.Vpp = + p_dev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; - } else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) { - link->conf.Vpp = - dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; + } else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM)) { + p_dev->conf.Vpp = + dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000; } /* Do we need to allocate an interrupt? */ - if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) { - link->conf.Attributes |= CONF_ENABLE_IRQ; - } + if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) + p_dev->conf.Attributes |= CONF_ENABLE_IRQ; /* IO window settings */ - link->io.NumPorts1 = link->io.NumPorts2 = 0; - if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { - cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; + p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; + if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { + cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; if (!(io->flags & CISTPL_IO_8BIT)) - link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; if (!(io->flags & CISTPL_IO_16BIT)) - link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; - link->io.BasePort1 = io->win[0].base; - link->io.NumPorts1 = io->win[0].len; + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; + p_dev->io.BasePort1 = io->win[0].base; + p_dev->io.NumPorts1 = io->win[0].len; if (io->nwin > 1) { - link->io.Attributes2 = link->io.Attributes1; - link->io.BasePort2 = io->win[1].base; - link->io.NumPorts2 = io->win[1].len; + p_dev->io.Attributes2 = p_dev->io.Attributes1; + p_dev->io.BasePort2 = io->win[1].base; + p_dev->io.NumPorts2 = io->win[1].len; } /* This reserves IO space but doesn't actually enable it */ - if (pcmcia_request_io(link, &link->io) != 0) + if (pcmcia_request_io(p_dev, &p_dev->io) != 0) goto next_entry; } - if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) { - cistpl_mem_t *mem = - (cfg->mem.nwin) ? &cfg->mem : &dflt.mem; - req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM; - req.Attributes |= WIN_ENABLE; - req.Base = mem->win[0].host_addr; - req.Size = mem->win[0].len; - if (req.Size < 0x1000) { - req.Size = 0x1000; - } - req.AccessSpeed = 0; - if (pcmcia_request_window(&link, &req, &link->win) != 0) + if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) { + memreq_t map; + cistpl_mem_t *mem = + (cfg->mem.nwin) ? &cfg->mem : &dflt->mem; + cfg_mem->req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM; + cfg_mem->req.Attributes |= WIN_ENABLE; + cfg_mem->req.Base = mem->win[0].host_addr; + cfg_mem->req.Size = mem->win[0].len; + if (cfg_mem->req.Size < 0x1000) + cfg_mem->req.Size = 0x1000; + cfg_mem->req.AccessSpeed = 0; + if (pcmcia_request_window(&p_dev, &cfg_mem->req, &p_dev->win) != 0) goto next_entry; map.Page = 0; map.CardOffset = mem->win[0].card_addr; - if (pcmcia_map_mem_page(link->win, &map) != 0) + if (pcmcia_map_mem_page(p_dev->win, &map) != 0) goto next_entry; - data->MmioAddress = (unsigned long)ioremap_nocache(req.Base, req.Size); - data->MmioLength = req.Size; + cfg_mem->data->MmioAddress = (unsigned long) ioremap_nocache(cfg_mem->req.Base, cfg_mem->req.Size); + cfg_mem->data->MmioLength = cfg_mem->req.Size; } /* If we got this far, we're cool! */ - break; - - next_entry: - nsp_dbg(NSP_DEBUG_INIT, "next"); - pcmcia_disable_device(link); - CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); + return 0; } +next_entry: + nsp_dbg(NSP_DEBUG_INIT, "next"); + pcmcia_disable_device(p_dev); + return -ENODEV; +} + +static int nsp_cs_config(struct pcmcia_device *link) +{ + int ret; + scsi_info_t *info = link->priv; + struct nsp_cs_configdata *cfg_mem; + struct Scsi_Host *host; + nsp_hw_data *data = &nsp_data_base; + + nsp_dbg(NSP_DEBUG_INIT, "in"); + + cfg_mem = kzalloc(sizeof(cfg_mem), GFP_KERNEL); + if (!cfg_mem) + return -ENOMEM; + cfg_mem->data = data; + + ret = pcmcia_loop_config(link, nsp_cs_config_check, cfg_mem); + goto cs_failed; + if (link->conf.Attributes & CONF_ENABLE_IRQ) { - CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); + if (pcmcia_request_irq(link, &link->irq)) + goto cs_failed; } - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); + + ret = pcmcia_request_configuration(link, &link->conf); + if (ret) + goto cs_failed; if (free_ports) { if (link->io.BasePort1) { @@ -1790,20 +1786,20 @@ static int nsp_cs_config(struct pcmcia_device *link) printk(" & 0x%04x-0x%04x", link->io.BasePort2, link->io.BasePort2+link->io.NumPorts2-1); if (link->win) - printk(", mem 0x%06lx-0x%06lx", req.Base, - req.Base+req.Size-1); + printk(", mem 0x%06lx-0x%06lx", cfg_mem->req.Base, + cfg_mem->req.Base+cfg_mem->req.Size-1); printk("\n"); + kfree(cfg_mem); return 0; cs_failed: nsp_dbg(NSP_DEBUG_INIT, "config fail"); - cs_error(link, last_fn, last_ret); nsp_cs_release(link); + kfree(cfg_mem); return -ENODEV; } /* nsp_cs_config */ -#undef CS_CHECK /*====================================================================== diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c index 67c5a58d17df..20c3e5e6d88a 100644 --- a/drivers/scsi/pcmcia/qlogic_stub.c +++ b/drivers/scsi/pcmcia/qlogic_stub.c @@ -195,39 +195,33 @@ static void qlogic_detach(struct pcmcia_device *link) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) +static int qlogic_config_check(struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cfg, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) +{ + p_dev->io.BasePort1 = cfg->io.win[0].base; + p_dev->io.NumPorts1 = cfg->io.win[0].len; + + if (p_dev->io.BasePort1 == 0) + return -ENODEV; + + return pcmcia_request_io(p_dev, &p_dev->io); +} + static int qlogic_config(struct pcmcia_device * link) { scsi_info_t *info = link->priv; - tuple_t tuple; - cisparse_t parse; - int i, last_ret, last_fn; - unsigned short tuple_data[32]; + int last_ret, last_fn; struct Scsi_Host *host; DEBUG(0, "qlogic_config(0x%p)\n", link); - info->manf_id = link->manf_id; - - tuple.TupleData = (cisdata_t *) tuple_data; - tuple.TupleDataMax = 64; - tuple.TupleOffset = 0; - - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - while (1) { - if (pcmcia_get_tuple_data(link, &tuple) != 0 || - pcmcia_parse_tuple(link, &tuple, &parse) != 0) - goto next_entry; - link->conf.ConfigIndex = parse.cftable_entry.index; - link->io.BasePort1 = parse.cftable_entry.io.win[0].base; - link->io.NumPorts1 = parse.cftable_entry.io.win[0].len; - if (link->io.BasePort1 != 0) { - i = pcmcia_request_io(link, &link->io); - if (i == CS_SUCCESS) - break; - } - next_entry: - CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); + last_ret = pcmcia_loop_config(link, qlogic_config_check, NULL); + if (last_ret) { + cs_error(link, RequestIO, last_ret); + goto failed; } CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); @@ -262,6 +256,7 @@ static int qlogic_config(struct pcmcia_device * link) cs_failed: cs_error(link, last_fn, last_ret); pcmcia_disable_device(link); +failed: return -ENODEV; } /* qlogic_config */ diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c index 0be232b58ffb..b330c11a1752 100644 --- a/drivers/scsi/pcmcia/sym53c500_cs.c +++ b/drivers/scsi/pcmcia/sym53c500_cs.c @@ -700,15 +700,27 @@ static struct scsi_host_template sym53c500_driver_template = { #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) +static int SYM53C500_config_check(struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cfg, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) +{ + p_dev->io.BasePort1 = cfg->io.win[0].base; + p_dev->io.NumPorts1 = cfg->io.win[0].len; + + if (p_dev->io.BasePort1 == 0) + return -ENODEV; + + return pcmcia_request_io(p_dev, &p_dev->io); +} + static int SYM53C500_config(struct pcmcia_device *link) { struct scsi_info_t *info = link->priv; - tuple_t tuple; - cisparse_t parse; - int i, last_ret, last_fn; + int last_ret, last_fn; int irq_level, port_base; - unsigned short tuple_data[32]; struct Scsi_Host *host; struct scsi_host_template *tpnt = &sym53c500_driver_template; struct sym53c500_data *data; @@ -717,27 +729,10 @@ SYM53C500_config(struct pcmcia_device *link) info->manf_id = link->manf_id; - tuple.TupleData = (cisdata_t *)tuple_data; - tuple.TupleDataMax = 64; - tuple.TupleOffset = 0; - - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - while (1) { - if (pcmcia_get_tuple_data(link, &tuple) != 0 || - pcmcia_parse_tuple(link, &tuple, &parse) != 0) - goto next_entry; - link->conf.ConfigIndex = parse.cftable_entry.index; - link->io.BasePort1 = parse.cftable_entry.io.win[0].base; - link->io.NumPorts1 = parse.cftable_entry.io.win[0].len; - - if (link->io.BasePort1 != 0) { - i = pcmcia_request_io(link, &link->io); - if (i == CS_SUCCESS) - break; - } -next_entry: - CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); + last_ret = pcmcia_loop_config(link, SYM53C500_config_check, NULL); + if (last_ret) { + cs_error(link, RequestIO, last_ret); + goto failed; } CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); @@ -831,6 +826,7 @@ err_release: cs_failed: cs_error(link, last_fn, last_ret); +failed: SYM53C500_release(link); return -ENODEV; } /* SYM53C500_config */ diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c index 905350896725..69d6ad862b60 100644 --- a/drivers/scsi/qlogicpti.c +++ b/drivers/scsi/qlogicpti.c @@ -1,6 +1,6 @@ /* qlogicpti.c: Performance Technologies QlogicISP sbus card driver. * - * Copyright (C) 1996, 2006 David S. Miller (davem@davemloft.net) + * Copyright (C) 1996, 2006, 2008 David S. Miller (davem@davemloft.net) * * A lot of this driver was directly stolen from Erik H. Moe's PCI * Qlogic ISP driver. Mucho kudos to him for this code. @@ -25,12 +25,14 @@ #include <linux/interrupt.h> #include <linux/module.h> #include <linux/jiffies.h> +#include <linux/dma-mapping.h> +#include <linux/of.h> +#include <linux/of_device.h> #include <asm/byteorder.h> #include "qlogicpti.h" -#include <asm/sbus.h> #include <asm/dma.h> #include <asm/system.h> #include <asm/ptrace.h> @@ -157,7 +159,7 @@ static inline void set_sbus_cfg1(struct qlogicpti *qpti) * is a nop and the chip ends up using the smallest burst * size. -DaveM */ - if (sbus_can_burst64(qpti->sdev) && (bursts & DMA_BURST64)) { + if (sbus_can_burst64() && (bursts & DMA_BURST64)) { val = (SBUS_CFG1_BENAB | SBUS_CFG1_B64); } else #endif @@ -684,19 +686,19 @@ static void __devexit qpti_chain_del(struct qlogicpti *qpti) static int __devinit qpti_map_regs(struct qlogicpti *qpti) { - struct sbus_dev *sdev = qpti->sdev; + struct of_device *op = qpti->op; - qpti->qregs = sbus_ioremap(&sdev->resource[0], 0, - sdev->reg_addrs[0].reg_size, - "PTI Qlogic/ISP"); + qpti->qregs = of_ioremap(&op->resource[0], 0, + resource_size(&op->resource[0]), + "PTI Qlogic/ISP"); if (!qpti->qregs) { printk("PTI: Qlogic/ISP registers are unmappable\n"); return -1; } if (qpti->is_pti) { - qpti->sreg = sbus_ioremap(&sdev->resource[0], (16 * 4096), - sizeof(unsigned char), - "PTI Qlogic/ISP statreg"); + qpti->sreg = of_ioremap(&op->resource[0], (16 * 4096), + sizeof(unsigned char), + "PTI Qlogic/ISP statreg"); if (!qpti->sreg) { printk("PTI: Qlogic/ISP status register is unmappable\n"); return -1; @@ -707,9 +709,9 @@ static int __devinit qpti_map_regs(struct qlogicpti *qpti) static int __devinit qpti_register_irq(struct qlogicpti *qpti) { - struct sbus_dev *sdev = qpti->sdev; + struct of_device *op = qpti->op; - qpti->qhost->irq = qpti->irq = sdev->irqs[0]; + qpti->qhost->irq = qpti->irq = op->irqs[0]; /* We used to try various overly-clever things to * reduce the interrupt processing overhead on @@ -732,17 +734,19 @@ fail: static void __devinit qpti_get_scsi_id(struct qlogicpti *qpti) { - qpti->scsi_id = prom_getintdefault(qpti->prom_node, - "initiator-id", - -1); + struct of_device *op = qpti->op; + struct device_node *dp; + + dp = op->node; + + qpti->scsi_id = of_getintprop_default(dp, "initiator-id", -1); if (qpti->scsi_id == -1) - qpti->scsi_id = prom_getintdefault(qpti->prom_node, - "scsi-initiator-id", - -1); + qpti->scsi_id = of_getintprop_default(dp, "scsi-initiator-id", + -1); if (qpti->scsi_id == -1) qpti->scsi_id = - prom_getintdefault(qpti->sdev->bus->prom_node, - "scsi-initiator-id", 7); + of_getintprop_default(dp->parent, + "scsi-initiator-id", 7); qpti->qhost->this_id = qpti->scsi_id; qpti->qhost->max_sectors = 64; @@ -751,12 +755,11 @@ static void __devinit qpti_get_scsi_id(struct qlogicpti *qpti) static void qpti_get_bursts(struct qlogicpti *qpti) { - struct sbus_dev *sdev = qpti->sdev; + struct of_device *op = qpti->op; u8 bursts, bmask; - bursts = prom_getintdefault(qpti->prom_node, "burst-sizes", 0xff); - bmask = prom_getintdefault(sdev->bus->prom_node, - "burst-sizes", 0xff); + bursts = of_getintprop_default(op->node, "burst-sizes", 0xff); + bmask = of_getintprop_default(op->node->parent, "burst-sizes", 0xff); if (bmask != 0xff) bursts &= bmask; if (bursts == 0xff || @@ -785,25 +788,25 @@ static void qpti_get_clock(struct qlogicpti *qpti) */ static int __devinit qpti_map_queues(struct qlogicpti *qpti) { - struct sbus_dev *sdev = qpti->sdev; + struct of_device *op = qpti->op; #define QSIZE(entries) (((entries) + 1) * QUEUE_ENTRY_LEN) - qpti->res_cpu = sbus_alloc_consistent(sdev, - QSIZE(RES_QUEUE_LEN), - &qpti->res_dvma); + qpti->res_cpu = dma_alloc_coherent(&op->dev, + QSIZE(RES_QUEUE_LEN), + &qpti->res_dvma, GFP_ATOMIC); if (qpti->res_cpu == NULL || qpti->res_dvma == 0) { printk("QPTI: Cannot map response queue.\n"); return -1; } - qpti->req_cpu = sbus_alloc_consistent(sdev, - QSIZE(QLOGICPTI_REQ_QUEUE_LEN), - &qpti->req_dvma); + qpti->req_cpu = dma_alloc_coherent(&op->dev, + QSIZE(QLOGICPTI_REQ_QUEUE_LEN), + &qpti->req_dvma, GFP_ATOMIC); if (qpti->req_cpu == NULL || qpti->req_dvma == 0) { - sbus_free_consistent(sdev, QSIZE(RES_QUEUE_LEN), - qpti->res_cpu, qpti->res_dvma); + dma_free_coherent(&op->dev, QSIZE(RES_QUEUE_LEN), + qpti->res_cpu, qpti->res_dvma); printk("QPTI: Cannot map request queue.\n"); return -1; } @@ -875,8 +878,9 @@ static inline int load_cmd(struct scsi_cmnd *Cmnd, struct Command_Entry *cmd, int sg_count; sg = scsi_sglist(Cmnd); - sg_count = sbus_map_sg(qpti->sdev, sg, scsi_sg_count(Cmnd), - Cmnd->sc_data_direction); + sg_count = dma_map_sg(&qpti->op->dev, sg, + scsi_sg_count(Cmnd), + Cmnd->sc_data_direction); ds = cmd->dataseg; cmd->segment_cnt = sg_count; @@ -1152,9 +1156,9 @@ static struct scsi_cmnd *qlogicpti_intr_handler(struct qlogicpti *qpti) Cmnd->result = DID_ERROR << 16; if (scsi_bufflen(Cmnd)) - sbus_unmap_sg(qpti->sdev, - scsi_sglist(Cmnd), scsi_sg_count(Cmnd), - Cmnd->sc_data_direction); + dma_unmap_sg(&qpti->op->dev, + scsi_sglist(Cmnd), scsi_sg_count(Cmnd), + Cmnd->sc_data_direction); qpti->cmd_count[Cmnd->device->id]--; sbus_writew(out_ptr, qpti->qregs + MBOX5); @@ -1268,34 +1272,32 @@ static struct scsi_host_template qpti_template = { .use_clustering = ENABLE_CLUSTERING, }; -static int __devinit qpti_sbus_probe(struct of_device *dev, const struct of_device_id *match) +static int __devinit qpti_sbus_probe(struct of_device *op, const struct of_device_id *match) { - static int nqptis; - struct sbus_dev *sdev = to_sbus_device(&dev->dev); - struct device_node *dp = dev->node; struct scsi_host_template *tpnt = match->data; + struct device_node *dp = op->node; struct Scsi_Host *host; struct qlogicpti *qpti; + static int nqptis; const char *fcode; /* Sometimes Antares cards come up not completely * setup, and we get a report of a zero IRQ. */ - if (sdev->irqs[0] == 0) + if (op->irqs[0] == 0) return -ENODEV; host = scsi_host_alloc(tpnt, sizeof(struct qlogicpti)); if (!host) return -ENOMEM; - qpti = (struct qlogicpti *) host->hostdata; + qpti = shost_priv(host); host->max_id = MAX_TARGETS; qpti->qhost = host; - qpti->sdev = sdev; + qpti->op = op; qpti->qpti_id = nqptis; - qpti->prom_node = sdev->prom_node; - strcpy(qpti->prom_name, sdev->ofdev.node->name); + strcpy(qpti->prom_name, op->node->name); qpti->is_pti = strcmp(qpti->prom_name, "QLGC,isp"); if (qpti_map_regs(qpti) < 0) @@ -1341,12 +1343,12 @@ static int __devinit qpti_sbus_probe(struct of_device *dev, const struct of_devi (qpti->ultra ? "Ultra" : "Fast"), (qpti->differential ? "differential" : "single ended")); - if (scsi_add_host(host, &dev->dev)) { + if (scsi_add_host(host, &op->dev)) { printk("qlogicpti%d: Failed scsi_add_host\n", qpti->qpti_id); goto fail_unmap_queues; } - dev_set_drvdata(&sdev->ofdev.dev, qpti); + dev_set_drvdata(&op->dev, qpti); qpti_chain_add(qpti); @@ -1357,19 +1359,20 @@ static int __devinit qpti_sbus_probe(struct of_device *dev, const struct of_devi fail_unmap_queues: #define QSIZE(entries) (((entries) + 1) * QUEUE_ENTRY_LEN) - sbus_free_consistent(qpti->sdev, - QSIZE(RES_QUEUE_LEN), - qpti->res_cpu, qpti->res_dvma); - sbus_free_consistent(qpti->sdev, - QSIZE(QLOGICPTI_REQ_QUEUE_LEN), - qpti->req_cpu, qpti->req_dvma); + dma_free_coherent(&op->dev, + QSIZE(RES_QUEUE_LEN), + qpti->res_cpu, qpti->res_dvma); + dma_free_coherent(&op->dev, + QSIZE(QLOGICPTI_REQ_QUEUE_LEN), + qpti->req_cpu, qpti->req_dvma); #undef QSIZE fail_unmap_regs: - sbus_iounmap(qpti->qregs, - qpti->sdev->reg_addrs[0].reg_size); + of_iounmap(&op->resource[0], qpti->qregs, + resource_size(&op->resource[0])); if (qpti->is_pti) - sbus_iounmap(qpti->sreg, sizeof(unsigned char)); + of_iounmap(&op->resource[0], qpti->sreg, + sizeof(unsigned char)); fail_free_irq: free_irq(qpti->irq, qpti); @@ -1380,9 +1383,9 @@ fail_unlink: return -ENODEV; } -static int __devexit qpti_sbus_remove(struct of_device *dev) +static int __devexit qpti_sbus_remove(struct of_device *op) { - struct qlogicpti *qpti = dev_get_drvdata(&dev->dev); + struct qlogicpti *qpti = dev_get_drvdata(&op->dev); qpti_chain_del(qpti); @@ -1395,24 +1398,25 @@ static int __devexit qpti_sbus_remove(struct of_device *dev) free_irq(qpti->irq, qpti); #define QSIZE(entries) (((entries) + 1) * QUEUE_ENTRY_LEN) - sbus_free_consistent(qpti->sdev, - QSIZE(RES_QUEUE_LEN), - qpti->res_cpu, qpti->res_dvma); - sbus_free_consistent(qpti->sdev, - QSIZE(QLOGICPTI_REQ_QUEUE_LEN), - qpti->req_cpu, qpti->req_dvma); + dma_free_coherent(&op->dev, + QSIZE(RES_QUEUE_LEN), + qpti->res_cpu, qpti->res_dvma); + dma_free_coherent(&op->dev, + QSIZE(QLOGICPTI_REQ_QUEUE_LEN), + qpti->req_cpu, qpti->req_dvma); #undef QSIZE - sbus_iounmap(qpti->qregs, qpti->sdev->reg_addrs[0].reg_size); + of_iounmap(&op->resource[0], qpti->qregs, + resource_size(&op->resource[0])); if (qpti->is_pti) - sbus_iounmap(qpti->sreg, sizeof(unsigned char)); + of_iounmap(&op->resource[0], qpti->sreg, sizeof(unsigned char)); scsi_host_put(qpti->qhost); return 0; } -static struct of_device_id qpti_match[] = { +static const struct of_device_id qpti_match[] = { { .name = "ptisp", .data = &qpti_template, @@ -1442,7 +1446,7 @@ static struct of_platform_driver qpti_sbus_driver = { static int __init qpti_init(void) { - return of_register_driver(&qpti_sbus_driver, &sbus_bus_type); + return of_register_driver(&qpti_sbus_driver, &of_bus_type); } static void __exit qpti_exit(void) @@ -1453,7 +1457,7 @@ static void __exit qpti_exit(void) MODULE_DESCRIPTION("QlogicISP SBUS driver"); MODULE_AUTHOR("David S. Miller (davem@davemloft.net)"); MODULE_LICENSE("GPL"); -MODULE_VERSION("2.0"); +MODULE_VERSION("2.1"); module_init(qpti_init); module_exit(qpti_exit); diff --git a/drivers/scsi/qlogicpti.h b/drivers/scsi/qlogicpti.h index ef6da2df584b..9c053bbaa877 100644 --- a/drivers/scsi/qlogicpti.h +++ b/drivers/scsi/qlogicpti.h @@ -342,7 +342,7 @@ struct qlogicpti { u_int req_in_ptr; /* index of next request slot */ u_int res_out_ptr; /* index of next result slot */ long send_marker; /* must we send a marker? */ - struct sbus_dev *sdev; + struct of_device *op; unsigned long __pad; int cmd_count[MAX_TARGETS]; diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index ba9b9bbd4e73..93bd59a1ed79 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -1450,12 +1450,10 @@ sg_add(struct device *cl_dev, struct class_interface *cl_intf) if (sg_sysfs_valid) { struct device *sg_class_member; - sg_class_member = device_create_drvdata(sg_sysfs_class, - cl_dev->parent, - MKDEV(SCSI_GENERIC_MAJOR, - sdp->index), - sdp, - "%s", disk->disk_name); + sg_class_member = device_create(sg_sysfs_class, cl_dev->parent, + MKDEV(SCSI_GENERIC_MAJOR, + sdp->index), + sdp, "%s", disk->disk_name); if (IS_ERR(sg_class_member)) { printk(KERN_ERR "sg_add: " "device_create failed\n"); diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index c2bb53e3d941..5c28d08f18f4 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -4428,13 +4428,10 @@ static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode) snprintf(name, 10, "%s%s%s", rew ? "n" : "", STp->disk->disk_name, st_formats[i]); st_class_member = - device_create_drvdata(st_sysfs_class, - &STp->device->sdev_gendev, - MKDEV(SCSI_TAPE_MAJOR, - TAPE_MINOR(dev_num, - mode, rew)), - &STp->modes[mode], - "%s", name); + device_create(st_sysfs_class, &STp->device->sdev_gendev, + MKDEV(SCSI_TAPE_MAJOR, + TAPE_MINOR(dev_num, mode, rew)), + &STp->modes[mode], "%s", name); if (IS_ERR(st_class_member)) { printk(KERN_WARNING "st%d: device_create failed\n", dev_num); diff --git a/drivers/scsi/sun_esp.c b/drivers/scsi/sun_esp.c index f9cf70151366..3d73aad4bc82 100644 --- a/drivers/scsi/sun_esp.c +++ b/drivers/scsi/sun_esp.c @@ -1,6 +1,6 @@ /* sun_esp.c: ESP front-end for Sparc SBUS systems. * - * Copyright (C) 2007 David S. Miller (davem@davemloft.net) + * Copyright (C) 2007, 2008 David S. Miller (davem@davemloft.net) */ #include <linux/kernel.h> @@ -9,60 +9,70 @@ #include <linux/module.h> #include <linux/mm.h> #include <linux/init.h> +#include <linux/dma-mapping.h> +#include <linux/of.h> +#include <linux/of_device.h> #include <asm/irq.h> #include <asm/io.h> #include <asm/dma.h> -#include <asm/sbus.h> - #include <scsi/scsi_host.h> #include "esp_scsi.h" #define DRV_MODULE_NAME "sun_esp" #define PFX DRV_MODULE_NAME ": " -#define DRV_VERSION "1.000" -#define DRV_MODULE_RELDATE "April 19, 2007" +#define DRV_VERSION "1.100" +#define DRV_MODULE_RELDATE "August 27, 2008" #define dma_read32(REG) \ sbus_readl(esp->dma_regs + (REG)) #define dma_write32(VAL, REG) \ sbus_writel((VAL), esp->dma_regs + (REG)) -static int __devinit esp_sbus_find_dma(struct esp *esp, struct sbus_dev *dma_sdev) -{ - struct sbus_dev *sdev = esp->dev; - struct sbus_dma *dma; +/* DVMA chip revisions */ +enum dvma_rev { + dvmarev0, + dvmaesc1, + dvmarev1, + dvmarev2, + dvmarev3, + dvmarevplus, + dvmahme +}; - if (dma_sdev != NULL) { - for_each_dvma(dma) { - if (dma->sdev == dma_sdev) - break; - } - } else { - for_each_dvma(dma) { - if (dma->sdev == NULL) - break; +static int __devinit esp_sbus_setup_dma(struct esp *esp, + struct of_device *dma_of) +{ + esp->dma = dma_of; - /* If bus + slot are the same and it has the - * correct OBP name, it's ours. - */ - if (sdev->bus == dma->sdev->bus && - sdev->slot == dma->sdev->slot && - (!strcmp(dma->sdev->prom_name, "dma") || - !strcmp(dma->sdev->prom_name, "espdma"))) - break; - } - } + esp->dma_regs = of_ioremap(&dma_of->resource[0], 0, + resource_size(&dma_of->resource[0]), + "espdma"); + if (!esp->dma_regs) + return -ENOMEM; - if (dma == NULL) { - printk(KERN_ERR PFX "[%s] Cannot find dma.\n", - sdev->ofdev.node->full_name); - return -ENODEV; + switch (dma_read32(DMA_CSR) & DMA_DEVICE_ID) { + case DMA_VERS0: + esp->dmarev = dvmarev0; + break; + case DMA_ESCV1: + esp->dmarev = dvmaesc1; + break; + case DMA_VERS1: + esp->dmarev = dvmarev1; + break; + case DMA_VERS2: + esp->dmarev = dvmarev2; + break; + case DMA_VERHME: + esp->dmarev = dvmahme; + break; + case DMA_VERSPLUS: + esp->dmarev = dvmarevplus; + break; } - esp->dma = dma; - esp->dma_regs = dma->regs; return 0; @@ -70,18 +80,18 @@ static int __devinit esp_sbus_find_dma(struct esp *esp, struct sbus_dev *dma_sde static int __devinit esp_sbus_map_regs(struct esp *esp, int hme) { - struct sbus_dev *sdev = esp->dev; + struct of_device *op = esp->dev; struct resource *res; /* On HME, two reg sets exist, first is DVMA, * second is ESP registers. */ if (hme) - res = &sdev->resource[1]; + res = &op->resource[1]; else - res = &sdev->resource[0]; + res = &op->resource[0]; - esp->regs = sbus_ioremap(res, 0, SBUS_ESP_REG_SIZE, "ESP"); + esp->regs = of_ioremap(res, 0, SBUS_ESP_REG_SIZE, "ESP"); if (!esp->regs) return -ENOMEM; @@ -90,10 +100,11 @@ static int __devinit esp_sbus_map_regs(struct esp *esp, int hme) static int __devinit esp_sbus_map_command_block(struct esp *esp) { - struct sbus_dev *sdev = esp->dev; + struct of_device *op = esp->dev; - esp->command_block = sbus_alloc_consistent(sdev, 16, - &esp->command_block_dma); + esp->command_block = dma_alloc_coherent(&op->dev, 16, + &esp->command_block_dma, + GFP_ATOMIC); if (!esp->command_block) return -ENOMEM; return 0; @@ -102,17 +113,18 @@ static int __devinit esp_sbus_map_command_block(struct esp *esp) static int __devinit esp_sbus_register_irq(struct esp *esp) { struct Scsi_Host *host = esp->host; - struct sbus_dev *sdev = esp->dev; + struct of_device *op = esp->dev; - host->irq = sdev->irqs[0]; + host->irq = op->irqs[0]; return request_irq(host->irq, scsi_esp_intr, IRQF_SHARED, "ESP", esp); } -static void __devinit esp_get_scsi_id(struct esp *esp) +static void __devinit esp_get_scsi_id(struct esp *esp, struct of_device *espdma) { - struct sbus_dev *sdev = esp->dev; - struct device_node *dp = sdev->ofdev.node; + struct of_device *op = esp->dev; + struct device_node *dp; + dp = op->node; esp->scsi_id = of_getintprop_default(dp, "initiator-id", 0xff); if (esp->scsi_id != 0xff) goto done; @@ -121,13 +133,7 @@ static void __devinit esp_get_scsi_id(struct esp *esp) if (esp->scsi_id != 0xff) goto done; - if (!sdev->bus) { - /* SUN4 */ - esp->scsi_id = 7; - goto done; - } - - esp->scsi_id = of_getintprop_default(sdev->bus->ofdev.node, + esp->scsi_id = of_getintprop_default(espdma->node, "scsi-initiator-id", 7); done: @@ -137,9 +143,10 @@ done: static void __devinit esp_get_differential(struct esp *esp) { - struct sbus_dev *sdev = esp->dev; - struct device_node *dp = sdev->ofdev.node; + struct of_device *op = esp->dev; + struct device_node *dp; + dp = op->node; if (of_find_property(dp, "differential", NULL)) esp->flags |= ESP_FLAG_DIFFERENTIAL; else @@ -148,43 +155,36 @@ static void __devinit esp_get_differential(struct esp *esp) static void __devinit esp_get_clock_params(struct esp *esp) { - struct sbus_dev *sdev = esp->dev; - struct device_node *dp = sdev->ofdev.node; - struct device_node *bus_dp; + struct of_device *op = esp->dev; + struct device_node *bus_dp, *dp; int fmhz; - bus_dp = NULL; - if (sdev != NULL && sdev->bus != NULL) - bus_dp = sdev->bus->ofdev.node; + dp = op->node; + bus_dp = dp->parent; fmhz = of_getintprop_default(dp, "clock-frequency", 0); if (fmhz == 0) - fmhz = (!bus_dp) ? 0 : - of_getintprop_default(bus_dp, "clock-frequency", 0); + fmhz = of_getintprop_default(bus_dp, "clock-frequency", 0); esp->cfreq = fmhz; } -static void __devinit esp_get_bursts(struct esp *esp, struct sbus_dev *dma) +static void __devinit esp_get_bursts(struct esp *esp, struct of_device *dma_of) { - struct sbus_dev *sdev = esp->dev; - struct device_node *dp = sdev->ofdev.node; - u8 bursts; + struct device_node *dma_dp = dma_of->node; + struct of_device *op = esp->dev; + struct device_node *dp; + u8 bursts, val; + dp = op->node; bursts = of_getintprop_default(dp, "burst-sizes", 0xff); - if (dma) { - struct device_node *dma_dp = dma->ofdev.node; - u8 val = of_getintprop_default(dma_dp, "burst-sizes", 0xff); - if (val != 0xff) - bursts &= val; - } + val = of_getintprop_default(dma_dp, "burst-sizes", 0xff); + if (val != 0xff) + bursts &= val; - if (sdev->bus) { - u8 val = of_getintprop_default(sdev->bus->ofdev.node, - "burst-sizes", 0xff); - if (val != 0xff) - bursts &= val; - } + val = of_getintprop_default(dma_dp->parent, "burst-sizes", 0xff); + if (val != 0xff) + bursts &= val; if (bursts == 0xff || (bursts & DMA_BURST16) == 0 || @@ -194,9 +194,9 @@ static void __devinit esp_get_bursts(struct esp *esp, struct sbus_dev *dma) esp->bursts = bursts; } -static void __devinit esp_sbus_get_props(struct esp *esp, struct sbus_dev *espdma) +static void __devinit esp_sbus_get_props(struct esp *esp, struct of_device *espdma) { - esp_get_scsi_id(esp); + esp_get_scsi_id(esp, espdma); esp_get_differential(esp); esp_get_clock_params(esp); esp_get_bursts(esp, espdma); @@ -215,25 +215,33 @@ static u8 sbus_esp_read8(struct esp *esp, unsigned long reg) static dma_addr_t sbus_esp_map_single(struct esp *esp, void *buf, size_t sz, int dir) { - return sbus_map_single(esp->dev, buf, sz, dir); + struct of_device *op = esp->dev; + + return dma_map_single(&op->dev, buf, sz, dir); } static int sbus_esp_map_sg(struct esp *esp, struct scatterlist *sg, int num_sg, int dir) { - return sbus_map_sg(esp->dev, sg, num_sg, dir); + struct of_device *op = esp->dev; + + return dma_map_sg(&op->dev, sg, num_sg, dir); } static void sbus_esp_unmap_single(struct esp *esp, dma_addr_t addr, size_t sz, int dir) { - sbus_unmap_single(esp->dev, addr, sz, dir); + struct of_device *op = esp->dev; + + dma_unmap_single(&op->dev, addr, sz, dir); } static void sbus_esp_unmap_sg(struct esp *esp, struct scatterlist *sg, int num_sg, int dir) { - sbus_unmap_sg(esp->dev, sg, num_sg, dir); + struct of_device *op = esp->dev; + + dma_unmap_sg(&op->dev, sg, num_sg, dir); } static int sbus_esp_irq_pending(struct esp *esp) @@ -247,24 +255,26 @@ static void sbus_esp_reset_dma(struct esp *esp) { int can_do_burst16, can_do_burst32, can_do_burst64; int can_do_sbus64, lim; + struct of_device *op; u32 val; can_do_burst16 = (esp->bursts & DMA_BURST16) != 0; can_do_burst32 = (esp->bursts & DMA_BURST32) != 0; can_do_burst64 = 0; can_do_sbus64 = 0; - if (sbus_can_dma_64bit(esp->dev)) + op = esp->dev; + if (sbus_can_dma_64bit()) can_do_sbus64 = 1; - if (sbus_can_burst64(esp->sdev)) + if (sbus_can_burst64()) can_do_burst64 = (esp->bursts & DMA_BURST64) != 0; /* Put the DVMA into a known state. */ - if (esp->dma->revision != dvmahme) { + if (esp->dmarev != dvmahme) { val = dma_read32(DMA_CSR); dma_write32(val | DMA_RST_SCSI, DMA_CSR); dma_write32(val & ~DMA_RST_SCSI, DMA_CSR); } - switch (esp->dma->revision) { + switch (esp->dmarev) { case dvmahme: dma_write32(DMA_RESET_FAS366, DMA_CSR); dma_write32(DMA_RST_SCSI, DMA_CSR); @@ -282,7 +292,7 @@ static void sbus_esp_reset_dma(struct esp *esp) if (can_do_sbus64) { esp->prev_hme_dmacsr |= DMA_SCSI_SBUS64; - sbus_set_sbus64(esp->dev, esp->bursts); + sbus_set_sbus64(&op->dev, esp->bursts); } lim = 1000; @@ -346,14 +356,14 @@ static void sbus_esp_dma_drain(struct esp *esp) u32 csr; int lim; - if (esp->dma->revision == dvmahme) + if (esp->dmarev == dvmahme) return; csr = dma_read32(DMA_CSR); if (!(csr & DMA_FIFO_ISDRAIN)) return; - if (esp->dma->revision != dvmarev3 && esp->dma->revision != dvmaesc1) + if (esp->dmarev != dvmarev3 && esp->dmarev != dvmaesc1) dma_write32(csr | DMA_FIFO_STDRAIN, DMA_CSR); lim = 1000; @@ -369,7 +379,7 @@ static void sbus_esp_dma_drain(struct esp *esp) static void sbus_esp_dma_invalidate(struct esp *esp) { - if (esp->dma->revision == dvmahme) { + if (esp->dmarev == dvmahme) { dma_write32(DMA_RST_SCSI, DMA_CSR); esp->prev_hme_dmacsr = ((esp->prev_hme_dmacsr | @@ -440,7 +450,7 @@ static void sbus_esp_send_dma_cmd(struct esp *esp, u32 addr, u32 esp_count, else csr &= ~DMA_ST_WRITE; dma_write32(csr, DMA_CSR); - if (esp->dma->revision == dvmaesc1) { + if (esp->dmarev == dvmaesc1) { u32 end = PAGE_ALIGN(addr + dma_count + 16U); dma_write32(end - addr, DMA_COUNT); } @@ -476,10 +486,8 @@ static const struct esp_driver_ops sbus_esp_ops = { .dma_error = sbus_esp_dma_error, }; -static int __devinit esp_sbus_probe_one(struct device *dev, - struct sbus_dev *esp_dev, - struct sbus_dev *espdma, - struct sbus_bus *sbus, +static int __devinit esp_sbus_probe_one(struct of_device *op, + struct of_device *espdma, int hme) { struct scsi_host_template *tpnt = &scsi_esp_template; @@ -497,13 +505,13 @@ static int __devinit esp_sbus_probe_one(struct device *dev, esp = shost_priv(host); esp->host = host; - esp->dev = esp_dev; + esp->dev = op; esp->ops = &sbus_esp_ops; if (hme) esp->flags |= ESP_FLAG_WIDE_CAPABLE; - err = esp_sbus_find_dma(esp, espdma); + err = esp_sbus_setup_dma(esp, espdma); if (err < 0) goto fail_unlink; @@ -525,15 +533,15 @@ static int __devinit esp_sbus_probe_one(struct device *dev, * come up with the reset bit set, so make sure that * is clear first. */ - if (esp->dma->revision == dvmaesc1) { + if (esp->dmarev == dvmaesc1) { u32 val = dma_read32(DMA_CSR); dma_write32(val & ~DMA_RST_SCSI, DMA_CSR); } - dev_set_drvdata(&esp_dev->ofdev.dev, esp); + dev_set_drvdata(&op->dev, esp); - err = scsi_esp_register(esp, dev); + err = scsi_esp_register(esp, &op->dev); if (err) goto fail_free_irq; @@ -542,41 +550,46 @@ static int __devinit esp_sbus_probe_one(struct device *dev, fail_free_irq: free_irq(host->irq, esp); fail_unmap_command_block: - sbus_free_consistent(esp->dev, 16, - esp->command_block, - esp->command_block_dma); + dma_free_coherent(&op->dev, 16, + esp->command_block, + esp->command_block_dma); fail_unmap_regs: - sbus_iounmap(esp->regs, SBUS_ESP_REG_SIZE); + of_iounmap(&op->resource[(hme ? 1 : 0)], esp->regs, SBUS_ESP_REG_SIZE); fail_unlink: scsi_host_put(host); fail: return err; } -static int __devinit esp_sbus_probe(struct of_device *dev, const struct of_device_id *match) +static int __devinit esp_sbus_probe(struct of_device *op, const struct of_device_id *match) { - struct sbus_dev *sdev = to_sbus_device(&dev->dev); - struct device_node *dp = dev->node; - struct sbus_dev *dma_sdev = NULL; + struct device_node *dma_node = NULL; + struct device_node *dp = op->node; + struct of_device *dma_of = NULL; int hme = 0; if (dp->parent && (!strcmp(dp->parent->name, "espdma") || !strcmp(dp->parent->name, "dma"))) - dma_sdev = sdev->parent; + dma_node = dp->parent; else if (!strcmp(dp->name, "SUNW,fas")) { - dma_sdev = sdev; + dma_node = op->node; hme = 1; } + if (dma_node) + dma_of = of_find_device_by_node(dma_node); + if (!dma_of) + return -ENODEV; - return esp_sbus_probe_one(&dev->dev, sdev, dma_sdev, - sdev->bus, hme); + return esp_sbus_probe_one(op, dma_of, hme); } -static int __devexit esp_sbus_remove(struct of_device *dev) +static int __devexit esp_sbus_remove(struct of_device *op) { - struct esp *esp = dev_get_drvdata(&dev->dev); + struct esp *esp = dev_get_drvdata(&op->dev); + struct of_device *dma_of = esp->dma; unsigned int irq = esp->host->irq; + bool is_hme; u32 val; scsi_esp_unregister(esp); @@ -586,17 +599,25 @@ static int __devexit esp_sbus_remove(struct of_device *dev) dma_write32(val & ~DMA_INT_ENAB, DMA_CSR); free_irq(irq, esp); - sbus_free_consistent(esp->dev, 16, - esp->command_block, - esp->command_block_dma); - sbus_iounmap(esp->regs, SBUS_ESP_REG_SIZE); + + is_hme = (esp->dmarev == dvmahme); + + dma_free_coherent(&op->dev, 16, + esp->command_block, + esp->command_block_dma); + of_iounmap(&op->resource[(is_hme ? 1 : 0)], esp->regs, + SBUS_ESP_REG_SIZE); + of_iounmap(&dma_of->resource[0], esp->dma_regs, + resource_size(&dma_of->resource[0])); scsi_host_put(esp->host); + dev_set_drvdata(&op->dev, NULL); + return 0; } -static struct of_device_id esp_match[] = { +static const struct of_device_id esp_match[] = { { .name = "SUNW,esp", }, @@ -619,7 +640,7 @@ static struct of_platform_driver esp_sbus_driver = { static int __init sunesp_init(void) { - return of_register_driver(&esp_sbus_driver, &sbus_bus_type); + return of_register_driver(&esp_sbus_driver, &of_bus_type); } static void __exit sunesp_exit(void) |