Commit 4478f040 authored by Martin Dalecki's avatar Martin Dalecki Committed by Linus Torvalds

[PATCH] 2.5.18 IDE 71

 - Rewritten Artop host chip driver by Vojtech Pavlik. His log entries are:

   Cleanup whitespace.

   Remove superfluous chip entries in chip table.  Remove global variables to
   allow more than one controller.  Remove other forgotten stuff.

   This is a new driver for the Artop (Acard) controllers. It's completely
   untested, as I have never seen the hardware. However, I suspect it is much
   less broken than the previous one ...

   UDMA33 controller cannot detect 80-wire cable.

 - Separate ioctl handling out from ide.c. It's big enough.

 - Move atapi_read and atapi_write to the new atapi module.  Fix the declaration
   of those functions. The data buffer did have the void * type!

 - Separate module handling code out from actual transfer handling code in to a
   new module called main.c. Slowly we are at the stage where the code indeed
   has to be organized logically and not just "sporadically" as was the case
   before.

 - Apply patch by Adam Richter for the ide-scsi.c attach method implementation.
   This particular driver is still broken due to generic SCSI layer issues.

 - Apply true modularization patch for qd65xx.c by Samuel Thibault. Here
   are his notes about it:

   Then, patch-modularize-2.[45] is a proposal for modularizing qd65xx.o. As a
   single module, one can choose to insmod it before being able to do some
   hdparm -p /dev/hd[a-d]. But one can't remove it while tuned, since selectproc
   may be needed.

   I am sorry I wasn't able to test it under 2.5 series, lacking a functionning
   kernel for my test computer, but it seemed to work perfectly under 2.4
   series, and patches are almost the same.

 - Move PCI device id's to where they belong. Patch by Vojtech Pavlik.

 - Don't use BH_Lock in ide-tape.c - somehow this driver scares me sometimes.
parent cd556cb5
...@@ -295,28 +295,13 @@ CONFIG_IDEDMA_IVB ...@@ -295,28 +295,13 @@ CONFIG_IDEDMA_IVB
It is normally safe to answer Y; however, the default is N. It is normally safe to answer Y; however, the default is N.
CONFIG_BLK_DEV_AEC62XX CONFIG_BLK_DEV_AEC62XX
This driver adds up to 4 more EIDE devices sharing a single This driver adds explicit support for Acard AEC62xx (Artop ATP8xx)
interrupt. This add-on card is a bootable PCI UDMA controller. In IDE controllers. This allows the kernel to change PIO, DMA and UDMA
order to get this card to initialize correctly in some cases, you speeds and to configure the chip to optimum performance.
should say Y here, and preferably also to "Use DMA by default when
available".
The ATP850U/UF is an UltraDMA 33 chipset base.
The ATP860 is an UltraDMA 66 chipset base.
The ATP860M(acintosh) version is an UltraDMA 66 chipset base.
The ATP865 is an ATA100/133 chipset.
Please read the comments at the top of <file:drivers/ide/aec62xx.c>.
If you say Y here, then say Y to "Use DMA by default when available"
as well.
CONFIG_AEC62XX_TUNING
Please read the comments at the top of <file:drivers/ide/aec62xx.c>.
If unsure, say N.
CONFIG_AEC6280_BURST CONFIG_AEC6280_BURST
Use burst mode for DMA transfers. Higher speed, but causes more load Use burst mode for DMA transfers. This helps to achieve higher
on the bus. transfer rates, but causes more load on the PCI bus.
If unsure, say N. If unsure, say N.
......
...@@ -40,9 +40,8 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then ...@@ -40,9 +40,8 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then
int ' Default queue depth' CONFIG_BLK_DEV_IDE_TCQ_DEPTH 32 int ' Default queue depth' CONFIG_BLK_DEV_IDE_TCQ_DEPTH 32
fi fi
dep_bool ' Good-Bad DMA Model-Firmware (EXPERIMENTAL)' CONFIG_IDEDMA_NEW_DRIVE_LISTINGS $CONFIG_EXPERIMENTAL dep_bool ' Good-Bad DMA Model-Firmware (EXPERIMENTAL)' CONFIG_IDEDMA_NEW_DRIVE_LISTINGS $CONFIG_EXPERIMENTAL
dep_bool ' AEC62XX chip set support' CONFIG_BLK_DEV_AEC62XX $CONFIG_BLK_DEV_IDEDMA_PCI dep_bool ' Acard (Artop) chipset support' CONFIG_BLK_DEV_AEC62XX $CONFIG_BLK_DEV_IDEDMA_PCI
dep_mbool ' AEC62XX Tuning support' CONFIG_AEC62XX_TUNING $CONFIG_BLK_DEV_AEC62XX dep_mbool ' ATP865 burst mode' CONFIG_AEC6280_BURST $CONFIG_BLK_DEV_AEC62XX
dep_mbool ' AEC6280 Burst mode' CONFIG_AEC6280_BURST $CONFIG_BLK_DEV_AEC62XX
dep_bool ' ALI M15x3 chipset support' CONFIG_BLK_DEV_ALI15X3 $CONFIG_BLK_DEV_IDEDMA_PCI dep_bool ' ALI M15x3 chipset support' CONFIG_BLK_DEV_ALI15X3 $CONFIG_BLK_DEV_IDEDMA_PCI
dep_mbool ' ALI M15x3 WDC support (DANGEROUS)' CONFIG_WDC_ALI15X3 $CONFIG_BLK_DEV_ALI15X3 $CONFIG_EXPERIMENTAL dep_mbool ' ALI M15x3 WDC support (DANGEROUS)' CONFIG_WDC_ALI15X3 $CONFIG_BLK_DEV_ALI15X3 $CONFIG_EXPERIMENTAL
dep_bool ' AMD and nVidia chipset support' CONFIG_BLK_DEV_AMD74XX $CONFIG_BLK_DEV_IDEDMA_PCI dep_bool ' AMD and nVidia chipset support' CONFIG_BLK_DEV_AMD74XX $CONFIG_BLK_DEV_IDEDMA_PCI
...@@ -122,7 +121,7 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then ...@@ -122,7 +121,7 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then
if [ "$CONFIG_BLK_DEV_IDEDISK" = "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then if [ "$CONFIG_BLK_DEV_IDEDISK" = "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then
bool ' PROMISE DC4030 support (EXPERIMENTAL)' CONFIG_BLK_DEV_PDC4030 bool ' PROMISE DC4030 support (EXPERIMENTAL)' CONFIG_BLK_DEV_PDC4030
fi fi
bool ' QDI QD65xx support' CONFIG_BLK_DEV_QD65XX dep_tristate ' QDI QD65xx support' CONFIG_BLK_DEV_QD65XX $CONFIG_BLK_DEV_IDE
bool ' UMC-8672 support' CONFIG_BLK_DEV_UMC8672 bool ' UMC-8672 support' CONFIG_BLK_DEV_UMC8672
fi fi
if [ "$CONFIG_BLK_DEV_IDEDMA_PCI" = "y" -o \ if [ "$CONFIG_BLK_DEV_IDEDMA_PCI" = "y" -o \
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
O_TARGET := idedriver.o O_TARGET := idedriver.o
export-objs := ide-taskfile.o ide.o ide-features.o ide-probe.o quirks.o pcidma.o tcq.o \ export-objs := ide-taskfile.o main.o ide.o ide-features.o ide-probe.o quirks.o pcidma.o tcq.o \
atapi.o ataraid.o atapi.o ataraid.o
obj-y := obj-y :=
...@@ -27,6 +27,7 @@ obj-$(CONFIG_BLK_DEV_IDETAPE) += ide-tape.o ...@@ -27,6 +27,7 @@ obj-$(CONFIG_BLK_DEV_IDETAPE) += ide-tape.o
obj-$(CONFIG_BLK_DEV_IDEFLOPPY) += ide-floppy.o obj-$(CONFIG_BLK_DEV_IDEFLOPPY) += ide-floppy.o
obj-$(CONFIG_BLK_DEV_IT8172) += it8172.o obj-$(CONFIG_BLK_DEV_IT8172) += it8172.o
obj-$(CONFIG_BLK_DEV_QD65XX) += qd65xx.o
ide-obj-$(CONFIG_BLK_DEV_AEC62XX) += aec62xx.o ide-obj-$(CONFIG_BLK_DEV_AEC62XX) += aec62xx.o
ide-obj-$(CONFIG_BLK_DEV_ALI14XX) += ali14xx.o ide-obj-$(CONFIG_BLK_DEV_ALI14XX) += ali14xx.o
...@@ -58,7 +59,6 @@ ide-obj-$(CONFIG_BLK_DEV_SVWKS) += serverworks.o ...@@ -58,7 +59,6 @@ ide-obj-$(CONFIG_BLK_DEV_SVWKS) += serverworks.o
ide-obj-$(CONFIG_BLK_DEV_PDC202XX) += pdc202xx.o ide-obj-$(CONFIG_BLK_DEV_PDC202XX) += pdc202xx.o
ide-obj-$(CONFIG_BLK_DEV_PDC4030) += pdc4030.o ide-obj-$(CONFIG_BLK_DEV_PDC4030) += pdc4030.o
ide-obj-$(CONFIG_BLK_DEV_PIIX) += piix.o ide-obj-$(CONFIG_BLK_DEV_PIIX) += piix.o
ide-obj-$(CONFIG_BLK_DEV_QD65XX) += qd65xx.o
ide-obj-$(CONFIG_BLK_DEV_IDE_RAPIDE) += rapide.o ide-obj-$(CONFIG_BLK_DEV_IDE_RAPIDE) += rapide.o
ide-obj-$(CONFIG_BLK_DEV_RZ1000) += rz1000.o ide-obj-$(CONFIG_BLK_DEV_RZ1000) += rz1000.o
ide-obj-$(CONFIG_BLK_DEV_SIS5513) += sis5513.o ide-obj-$(CONFIG_BLK_DEV_SIS5513) += sis5513.o
...@@ -74,6 +74,7 @@ obj-$(CONFIG_BLK_DEV_ATARAID) += ataraid.o ...@@ -74,6 +74,7 @@ obj-$(CONFIG_BLK_DEV_ATARAID) += ataraid.o
obj-$(CONFIG_BLK_DEV_ATARAID_PDC) += pdcraid.o obj-$(CONFIG_BLK_DEV_ATARAID_PDC) += pdcraid.o
obj-$(CONFIG_BLK_DEV_ATARAID_HPT) += hptraid.o obj-$(CONFIG_BLK_DEV_ATARAID_HPT) += hptraid.o
ide-mod-objs := ide-taskfile.o ide.o ide-probe.o ide-geometry.o ide-features.o ata-timing.o atapi.o $(ide-obj-y) ide-mod-objs := ide-taskfile.o main.o ide.o ide-probe.o ide-geometry.o ide-features.o \
ioctl.o atapi.o ata-timing.o$(ide-obj-y)
include $(TOPDIR)/Rules.make include $(TOPDIR)/Rules.make
This diff is collapsed.
...@@ -37,6 +37,21 @@ ...@@ -37,6 +37,21 @@
#include <asm/bitops.h> #include <asm/bitops.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
/*
* Initializes a packet command. Used by tape and floppy driver.
*/
void atapi_init_pc(struct atapi_packet_command *pc)
{
memset(pc->c, 0, 12);
pc->retries = 0;
pc->flags = 0;
pc->request_transfer = 0;
pc->buffer = pc->pc_buffer;
pc->buffer_size = IDEFLOPPY_PC_BUFFER_SIZE;
pc->b_data = NULL;
pc->bio = NULL;
}
/* /*
* Too bad. The drive wants to send us data which we are not ready to accept. * Too bad. The drive wants to send us data which we are not ready to accept.
* Just throw it away. * Just throw it away.
...@@ -54,22 +69,57 @@ void atapi_write_zeros(struct ata_device *drive, unsigned int bcount) ...@@ -54,22 +69,57 @@ void atapi_write_zeros(struct ata_device *drive, unsigned int bcount)
} }
/* /*
* Initializes a packet command. Used by tape and floppy driver. * The following routines are mainly used by the ATAPI drivers.
*
* These routines will round up any request for an odd number of bytes, so if
* an odd n is specified, be sure that there's at least one extra byte
* allocated for the buffer.
*/ */
void atapi_init_pc(struct atapi_packet_command *pc) void atapi_read(struct ata_device *drive, u8 *buf, unsigned int n)
{ {
memset(pc->c, 0, 12); if (drive->channel->atapi_read) {
pc->retries = 0; drive->channel->atapi_read(drive, buf, n);
pc->flags = 0; return;
pc->request_transfer = 0; }
pc->buffer = pc->pc_buffer;
pc->buffer_size = IDEFLOPPY_PC_BUFFER_SIZE; ++n;
pc->b_data = NULL; #if defined(CONFIG_ATARI) || defined(CONFIG_Q40)
pc->bio = NULL; if (MACH_IS_ATARI || MACH_IS_Q40) {
/* Atari has a byte-swapped IDE interface */
insw_swapw(IDE_DATA_REG, buf, n / 2);
return;
}
#endif
ata_read(drive, buf, n / 4);
if ((n & 0x03) >= 2)
insw(IDE_DATA_REG, buf + (n & ~0x03), 1);
}
void atapi_write(struct ata_device *drive, u8 *buf, unsigned int n)
{
if (drive->channel->atapi_write) {
drive->channel->atapi_write(drive, buf, n);
return;
}
++n;
#if defined(CONFIG_ATARI) || defined(CONFIG_Q40)
if (MACH_IS_ATARI || MACH_IS_Q40) {
/* Atari has a byte-swapped IDE interface */
outsw_swapw(IDE_DATA_REG, buf, n / 2);
return;
}
#endif
ata_write(drive, buf, n / 4);
if ((n & 0x03) >= 2)
outsw(IDE_DATA_REG, buf + (n & ~0x03), 1);
} }
EXPORT_SYMBOL(atapi_discard_data); EXPORT_SYMBOL(atapi_discard_data);
EXPORT_SYMBOL(atapi_write_zeros); EXPORT_SYMBOL(atapi_write_zeros);
EXPORT_SYMBOL(atapi_init_pc); EXPORT_SYMBOL(atapi_init_pc);
EXPORT_SYMBOL(atapi_read);
EXPORT_SYMBOL(atapi_write);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -314,6 +314,7 @@ ...@@ -314,6 +314,7 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include <linux/atapi.h>
#include "ide-cd.h" #include "ide-cd.h"
/**************************************************************************** /****************************************************************************
...@@ -2988,7 +2989,7 @@ static void ide_cdrom_attach(struct ata_device *drive) ...@@ -2988,7 +2989,7 @@ static void ide_cdrom_attach(struct ata_device *drive)
channel = drive->channel; channel = drive->channel;
unit = drive - channel->drives; unit = drive - channel->drives;
ide_revalidate_disk(mk_kdev(channel->major, unit << PARTN_BITS)); ata_revalidate(mk_kdev(channel->major, unit << PARTN_BITS));
} }
MODULE_PARM(ignore, "s"); MODULE_PARM(ignore, "s");
......
...@@ -361,8 +361,8 @@ static int idedisk_open (struct inode *inode, struct file *filp, struct ata_devi ...@@ -361,8 +361,8 @@ static int idedisk_open (struct inode *inode, struct file *filp, struct ata_devi
/* /*
* Ignore the return code from door_lock, since the open() has * Ignore the return code from door_lock, since the open() has
* already succeeded, and the door_lock is irrelevant at this * already succeeded once, and the door_lock is irrelevant at this
* point. * time.
*/ */
if (drive->doorlocking && ide_raw_taskfile(drive, &args)) if (drive->doorlocking && ide_raw_taskfile(drive, &args))
...@@ -1196,7 +1196,7 @@ static void idedisk_attach(struct ata_device *drive) ...@@ -1196,7 +1196,7 @@ static void idedisk_attach(struct ata_device *drive)
channel = drive->channel; channel = drive->channel;
unit = drive - channel->drives; unit = drive - channel->drives;
ide_revalidate_disk(mk_kdev(channel->major, unit << PARTN_BITS)); ata_revalidate(mk_kdev(channel->major, unit << PARTN_BITS));
} }
static void __exit idedisk_exit(void) static void __exit idedisk_exit(void)
......
...@@ -2036,7 +2036,7 @@ static void idefloppy_attach(struct ata_device *drive) ...@@ -2036,7 +2036,7 @@ static void idefloppy_attach(struct ata_device *drive)
channel = drive->channel; channel = drive->channel;
unit = drive - channel->drives; unit = drive - channel->drives;
ide_revalidate_disk(mk_kdev(channel->major, unit << PARTN_BITS)); ata_revalidate(mk_kdev(channel->major, unit << PARTN_BITS));
} }
MODULE_DESCRIPTION("ATAPI FLOPPY Driver"); MODULE_DESCRIPTION("ATAPI FLOPPY Driver");
......
...@@ -27,10 +27,6 @@ ...@@ -27,10 +27,6 @@
#include "pcihost.h" #include "pcihost.h"
/* Missing PCI device IDs: */
#define PCI_VENDOR_ID_HINT 0x3388
#define PCI_DEVICE_ID_HINT 0x8013
/* /*
* This is the list of registered PCI chipset driver data structures. * This is the list of registered PCI chipset driver data structures.
*/ */
...@@ -756,7 +752,7 @@ static struct ata_pci_device chipsets[] __initdata = { ...@@ -756,7 +752,7 @@ static struct ata_pci_device chipsets[] __initdata = {
}, },
{ {
vendor: PCI_VENDOR_ID_HINT, vendor: PCI_VENDOR_ID_HINT,
device: PCI_DEVICE_ID_HINT, device: PCI_DEVICE_ID_HINT_VXPROII_IDE,
bootable: ON_BOARD bootable: ON_BOARD
}, },
{ {
......
/* /**** vi:set ts=8 sts=8 sw=8:************************************************
* linux/drivers/ide/ide-pnp.c
* *
* This file provides autodetection for ISA PnP IDE interfaces. * This file provides autodetection for ISA PnP IDE interfaces.
* It was tested with "ESS ES1868 Plug and Play AudioDrive" IDE interface. * It was tested with "ESS ES1868 Plug and Play AudioDrive" IDE interface.
...@@ -33,19 +32,27 @@ ...@@ -33,19 +32,27 @@
#define DEV_NAME(dev) (dev->bus->name ? dev->bus->name : "ISA PnP") #define DEV_NAME(dev) (dev->bus->name ? dev->bus->name : "ISA PnP")
#define GENERIC_HD_DATA 0 enum {
#define GENERIC_HD_ERROR 1 GENERIC_HD_DATA,
#define GENERIC_HD_NSECTOR 2 GENERIC_HD_ERROR,
#define GENERIC_HD_SECTOR 3 GENERIC_HD_NSECTOR,
#define GENERIC_HD_LCYL 4 GENERIC_HD_SECTOR,
#define GENERIC_HD_HCYL 5 GENERIC_HD_LCYL,
#define GENERIC_HD_SELECT 6 GENERIC_HD_HCYL,
#define GENERIC_HD_STATUS 7 GENERIC_HD_SELECT,
GENERIC_HD_STATUS
};
static int generic_ide_offsets[IDE_NR_PORTS] __initdata = { static int generic_ide_offsets[IDE_NR_PORTS] __initdata = {
GENERIC_HD_DATA, GENERIC_HD_ERROR, GENERIC_HD_NSECTOR, GENERIC_HD_DATA,
GENERIC_HD_SECTOR, GENERIC_HD_LCYL, GENERIC_HD_HCYL, GENERIC_HD_ERROR,
GENERIC_HD_SELECT, GENERIC_HD_STATUS, -1, -1 GENERIC_HD_NSECTOR,
GENERIC_HD_SECTOR,
GENERIC_HD_LCYL,
GENERIC_HD_HCYL,
GENERIC_HD_SELECT,
GENERIC_HD_STATUS,
-1, -1
}; };
/* ISA PnP device table entry */ /* ISA PnP device table entry */
...@@ -83,11 +90,13 @@ static int __init pnpide_generic_init(struct pci_dev *dev, int enable) ...@@ -83,11 +90,13 @@ static int __init pnpide_generic_init(struct pci_dev *dev, int enable)
} }
/* Add your devices here :)) */ /* Add your devices here :)) */
struct pnp_dev_t idepnp_devices[] __initdata = { static struct pnp_dev_t pnp_devices[] __initdata = {
/* Generic ESDI/IDE/ATA compatible hard disk controller */ /* Generic ESDI/IDE/ATA compatible hard disk controller */
{ ISAPNP_ANY_ID, ISAPNP_ANY_ID, {
ISAPNP_ANY_ID, ISAPNP_ANY_ID,
ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0x0600), ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0x0600),
pnpide_generic_init }, pnpide_generic_init
},
{ 0 } { 0 }
}; };
...@@ -125,7 +134,7 @@ void __init pnpide_init(int enable) ...@@ -125,7 +134,7 @@ void __init pnpide_init(int enable)
return; return;
} }
#endif #endif
for (dev_type = idepnp_devices; dev_type->vendor; dev_type++) { for (dev_type = pnp_devices; dev_type->vendor; dev_type++) {
while ((dev = isapnp_find_dev(NULL, dev_type->vendor, while ((dev = isapnp_find_dev(NULL, dev_type->vendor,
dev_type->device, dev))) { dev_type->device, dev))) {
......
...@@ -2806,9 +2806,14 @@ static idetape_stage_t *__idetape_kmalloc_stage (idetape_tape_t *tape, int full, ...@@ -2806,9 +2806,14 @@ static idetape_stage_t *__idetape_kmalloc_stage (idetape_tape_t *tape, int full,
if (clear) if (clear)
memset(bio_data(bio), 0, PAGE_SIZE); memset(bio_data(bio), 0, PAGE_SIZE);
bio->bi_size = PAGE_SIZE; bio->bi_size = PAGE_SIZE;
if(bv->bv_len == full) bv->bv_len = bio->bi_size; if(bv->bv_len == full)
set_bit (BH_Lock, &bio->bi_flags); bv->bv_len = bio->bi_size;
#if 0
/* FIXME: What what this supposed to achieve? */
set_bit (BH_Lock, &bio->bi_flags);
#endif
while (--pages) { while (--pages) {
if ((bio->bi_io_vec[pages].bv_page = alloc_page(GFP_KERNEL)) == NULL) if ((bio->bi_io_vec[pages].bv_page = alloc_page(GFP_KERNEL)) == NULL)
goto abort; goto abort;
...@@ -2837,7 +2842,11 @@ static idetape_stage_t *__idetape_kmalloc_stage (idetape_tape_t *tape, int full, ...@@ -2837,7 +2842,11 @@ static idetape_stage_t *__idetape_kmalloc_stage (idetape_tape_t *tape, int full,
//bio->bi_io_vec[0].bv_offset = b_data; //bio->bi_io_vec[0].bv_offset = b_data;
bio->bi_size = PAGE_SIZE; bio->bi_size = PAGE_SIZE;
atomic_set(&bio->bi_cnt, full ? bio->bi_size : 0); atomic_set(&bio->bi_cnt, full ? bio->bi_size : 0);
#if 0
/* FIXME: What what this supposed to achieve? */
set_bit (BH_Lock, &bio->bi_flags); set_bit (BH_Lock, &bio->bi_flags);
#endif
prev_bio->bi_next = bio; prev_bio->bi_next = bio;
} }
bio->bi_size -= tape->excess_bh_size; bio->bi_size -= tape->excess_bh_size;
...@@ -6153,7 +6162,7 @@ static void idetape_attach(struct ata_device *drive) ...@@ -6153,7 +6162,7 @@ static void idetape_attach(struct ata_device *drive)
channel = drive->channel; channel = drive->channel;
unit = drive - channel->drives; unit = drive - channel->drives;
ide_revalidate_disk(mk_kdev(channel->major, unit << PARTN_BITS)); ata_revalidate(mk_kdev(channel->major, unit << PARTN_BITS));
} }
MODULE_DESCRIPTION("ATAPI Streaming TAPE Driver"); MODULE_DESCRIPTION("ATAPI Streaming TAPE Driver");
......
...@@ -160,53 +160,6 @@ void ata_write(struct ata_device *drive, void *buffer, unsigned int wcount) ...@@ -160,53 +160,6 @@ void ata_write(struct ata_device *drive, void *buffer, unsigned int wcount)
} }
} }
/*
* The following routines are mainly used by the ATAPI drivers.
*
* These routines will round up any request for an odd number of bytes,
* so if an odd bytecount is specified, be sure that there's at least one
* extra byte allocated for the buffer.
*/
void atapi_read(struct ata_device *drive, void *buffer, unsigned int bytecount)
{
if (drive->channel->atapi_read) {
drive->channel->atapi_read(drive, buffer, bytecount);
return;
}
++bytecount;
#if defined(CONFIG_ATARI) || defined(CONFIG_Q40)
if (MACH_IS_ATARI || MACH_IS_Q40) {
/* Atari has a byte-swapped IDE interface */
insw_swapw(IDE_DATA_REG, buffer, bytecount / 2);
return;
}
#endif
ata_read(drive, buffer, bytecount / 4);
if ((bytecount & 0x03) >= 2)
insw(IDE_DATA_REG, ((byte *)buffer) + (bytecount & ~0x03), 1);
}
void atapi_write(struct ata_device *drive, void *buffer, unsigned int bytecount)
{
if (drive->channel->atapi_write) {
drive->channel->atapi_write(drive, buffer, bytecount);
return;
}
++bytecount;
#if defined(CONFIG_ATARI) || defined(CONFIG_Q40)
if (MACH_IS_ATARI || MACH_IS_Q40) {
/* Atari has a byte-swapped IDE interface */
outsw_swapw(IDE_DATA_REG, buffer, bytecount / 2);
return;
}
#endif
ata_write(drive, buffer, bytecount / 4);
if ((bytecount & 0x03) >= 2)
outsw(IDE_DATA_REG, ((byte *)buffer) + (bytecount & ~0x03), 1);
}
/* /*
* Needed for PCI irq sharing * Needed for PCI irq sharing
*/ */
...@@ -1032,8 +985,6 @@ int ide_cmd_ioctl(struct ata_device *drive, unsigned long arg) ...@@ -1032,8 +985,6 @@ int ide_cmd_ioctl(struct ata_device *drive, unsigned long arg)
EXPORT_SYMBOL(drive_is_ready); EXPORT_SYMBOL(drive_is_ready);
EXPORT_SYMBOL(ata_read); EXPORT_SYMBOL(ata_read);
EXPORT_SYMBOL(ata_write); EXPORT_SYMBOL(ata_write);
EXPORT_SYMBOL(atapi_read);
EXPORT_SYMBOL(atapi_write);
EXPORT_SYMBOL(ata_taskfile); EXPORT_SYMBOL(ata_taskfile);
EXPORT_SYMBOL(recal_intr); EXPORT_SYMBOL(recal_intr);
EXPORT_SYMBOL(task_no_data_intr); EXPORT_SYMBOL(task_no_data_intr);
......
This diff is collapsed.
/**** vi:set ts=8 sts=8 sw=8:************************************************
*
* Copyright (C) 2002 Marcin Dalecki <martin@dalecki.de>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
/*
* Generic ioctl handling for all ATA/ATAPI device drivers.
*/
#include <linux/types.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/errno.h>
#include <linux/blkpg.h>
#include <linux/pci.h>
#include <linux/cdrom.h>
#include <linux/device.h>
#include <linux/ide.h>
#include <asm/uaccess.h>
#include "ioctl.h"
/*
* NOTE: Due to ridiculous coding habbits in the hdparm utility we have to
* always return unsigned long in case we are returning simple values.
*/
int ata_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
unsigned int major, minor;
struct ata_device *drive;
struct request rq;
kdev_t dev;
dev = inode->i_rdev;
major = major(dev);
minor = minor(dev);
if ((drive = get_info_ptr(inode->i_rdev)) == NULL)
return -ENODEV;
/* Contrary to popular beleve we disallow even the reading of the ioctl
* values for users which don't have permission too. We do this becouse
* such information could be used by an attacker to deply a simple-user
* attack, which triggers bugs present only on a particular
* configuration.
*/
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
ide_init_drive_cmd(&rq);
switch (cmd) {
case HDIO_GET_32BIT: {
unsigned long val = drive->channel->io_32bit;
if (put_user(val, (unsigned long *) arg))
return -EFAULT;
return 0;
}
case HDIO_SET_32BIT:
if (arg < 0 || arg > 1)
return -EINVAL;
if (drive->channel->no_io_32bit)
return -EIO;
if (ide_spin_wait_hwgroup(drive))
return -EBUSY;
drive->channel->io_32bit = arg;
spin_unlock_irq(drive->channel->lock);
return 0;
case HDIO_SET_PIO_MODE:
if (arg < 0 || arg > 255)
return -EINVAL;
if (!drive->channel->tuneproc)
return -ENOSYS;
/* FIXME: we can see that tuneproc whould do the
* locking!.
*/
if (ide_spin_wait_hwgroup(drive))
return -EBUSY;
drive->channel->tuneproc(drive, (u8) arg);
spin_unlock_irq(drive->channel->lock);
return 0;
case HDIO_GET_UNMASKINTR: {
unsigned long val = drive->channel->unmask;
if (put_user(val, (unsigned long *) arg))
return -EFAULT;
return 0;
}
case HDIO_SET_UNMASKINTR:
if (arg < 0 || arg > 1)
return -EINVAL;
if (drive->channel->no_unmask)
return -EIO;
if (ide_spin_wait_hwgroup(drive))
return -EBUSY;
drive->channel->unmask = arg;
spin_unlock_irq(drive->channel->lock);
return 0;
case HDIO_GET_DMA: {
unsigned long val = drive->using_dma;
if (put_user(val, (unsigned long *) arg))
return -EFAULT;
return 0;
}
case HDIO_SET_DMA:
if (arg < 0 || arg > 1)
return -EINVAL;
if (!drive->driver)
return -EPERM;
if (!drive->id || !(drive->id->capability & 1) || !drive->channel->XXX_udma)
return -EPERM;
if (ide_spin_wait_hwgroup(drive))
return -EBUSY;
udma_enable(drive, arg, 1);
spin_unlock_irq(drive->channel->lock);
return 0;
case HDIO_GETGEO: {
struct hd_geometry *loc = (struct hd_geometry *) arg;
unsigned short bios_cyl = drive->bios_cyl; /* truncate */
if (!loc || (drive->type != ATA_DISK && drive->type != ATA_FLOPPY))
return -EINVAL;
if (put_user(drive->bios_head, (byte *) &loc->heads))
return -EFAULT;
if (put_user(drive->bios_sect, (byte *) &loc->sectors))
return -EFAULT;
if (put_user(bios_cyl, (unsigned short *) &loc->cylinders))
return -EFAULT;
if (put_user((unsigned)drive->part[minor(inode->i_rdev)&PARTN_MASK].start_sect,
(unsigned long *) &loc->start))
return -EFAULT;
return 0;
}
case HDIO_GETGEO_BIG_RAW: {
struct hd_big_geometry *loc = (struct hd_big_geometry *) arg;
if (!loc || (drive->type != ATA_DISK && drive->type != ATA_FLOPPY))
return -EINVAL;
if (put_user(drive->head, (u8 *) &loc->heads))
return -EFAULT;
if (put_user(drive->sect, (u8 *) &loc->sectors))
return -EFAULT;
if (put_user(drive->cyl, (unsigned int *) &loc->cylinders))
return -EFAULT;
if (put_user((unsigned)drive->part[minor(inode->i_rdev)&PARTN_MASK].start_sect,
(unsigned long *) &loc->start))
return -EFAULT;
return 0;
}
case BLKRRPART: /* Re-read partition tables */
return ata_revalidate(inode->i_rdev);
case HDIO_GET_IDENTITY:
if (minor(inode->i_rdev) & PARTN_MASK)
return -EINVAL;
if (drive->id == NULL)
return -ENOMSG;
if (copy_to_user((char *)arg, (char *)drive->id, sizeof(*drive->id)))
return -EFAULT;
return 0;
case HDIO_GET_NICE:
return put_user(drive->dsc_overlap << IDE_NICE_DSC_OVERLAP |
drive->atapi_overlap << IDE_NICE_ATAPI_OVERLAP,
(long *) arg);
case HDIO_DRIVE_CMD:
if (!capable(CAP_SYS_RAWIO))
return -EACCES;
return ide_cmd_ioctl(drive, arg);
case HDIO_SET_NICE:
if (arg != (arg & ((1 << IDE_NICE_DSC_OVERLAP))))
return -EPERM;
drive->dsc_overlap = (arg >> IDE_NICE_DSC_OVERLAP) & 1;
/* Only CD-ROM's and tapes support DSC overlap. */
if (drive->dsc_overlap && !(drive->type == ATA_ROM || drive->type == ATA_TAPE)) {
drive->dsc_overlap = 0;
return -EPERM;
}
return 0;
case BLKGETSIZE:
case BLKGETSIZE64:
case BLKROSET:
case BLKROGET:
case BLKFLSBUF:
case BLKSSZGET:
case BLKPG:
case BLKELVGET:
case BLKELVSET:
case BLKBSZGET:
case BLKBSZSET:
return blk_ioctl(inode->i_bdev, cmd, arg);
/*
* uniform packet command handling
*/
case CDROMEJECT:
case CDROMCLOSETRAY:
return block_ioctl(inode->i_bdev, cmd, arg);
case HDIO_GET_BUSSTATE:
if (put_user(drive->channel->bus_state, (long *)arg))
return -EFAULT;
return 0;
case HDIO_SET_BUSSTATE:
if (drive->channel->busproc)
drive->channel->busproc(drive, (int)arg);
return 0;
/* Now check whatever this particular ioctl has a device type
* specific implementation.
*/
default:
if (ata_ops(drive) && ata_ops(drive)->ioctl)
return ata_ops(drive)->ioctl(drive, inode, file, cmd, arg);
return -EINVAL;
}
}
/**** vi:set ts=8 sts=8 sw=8:************************************************
*
* Copyright (C) 2002 Marcin Dalecki <martin@dalecki.de>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
extern int ata_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
This diff is collapsed.
This diff is collapsed.
...@@ -564,8 +564,12 @@ media_bay_step(int i) ...@@ -564,8 +564,12 @@ media_bay_step(int i)
bay->timer = 0; bay->timer = 0;
bay->state = mb_up; bay->state = mb_up;
if (bay->cd_index < 0) { if (bay->cd_index < 0) {
hw_regs_t hw;
pmu_suspend(); pmu_suspend();
bay->cd_index = ide_register(bay->cd_base, 0, bay->cd_irq); ide_init_hwif_ports(&hw, (ide_ioreg_t) bay->cd_base, (ide_ioreg_t) 0, NULL);
hw.irq = bay->cd_irq;
bay->cd_index = ide_register_hw(&hw, NULL);
pmu_resume(); pmu_resume();
} }
if (bay->cd_index == -1) { if (bay->cd_index == -1) {
......
...@@ -234,12 +234,17 @@ static void hexdump(u8 *x, int len) ...@@ -234,12 +234,17 @@ static void hexdump(u8 *x, int len)
printk("]\n"); printk("]\n");
} }
static inline idescsi_scsi_t *idescsi_private(struct Scsi_Host *host)
{
return (idescsi_scsi_t*) &host[1];
}
static int idescsi_end_request(struct ata_device *drive, struct request *rq, int uptodate) static int idescsi_end_request(struct ata_device *drive, struct request *rq, int uptodate)
{ {
idescsi_scsi_t *scsi = drive->driver_data; struct Scsi_Host *host = drive->driver_data;
idescsi_scsi_t *scsi = idescsi_private(host);
struct atapi_packet_command *pc = (struct atapi_packet_command *) rq->special; struct atapi_packet_command *pc = (struct atapi_packet_command *) rq->special;
int log = test_bit(IDESCSI_LOG_CMD, &scsi->log); int log = test_bit(IDESCSI_LOG_CMD, &scsi->log);
struct Scsi_Host *host;
u8 *scsi_buf; u8 *scsi_buf;
unsigned long flags; unsigned long flags;
...@@ -289,20 +294,21 @@ static inline unsigned long get_timeout(struct atapi_packet_command *pc) ...@@ -289,20 +294,21 @@ static inline unsigned long get_timeout(struct atapi_packet_command *pc)
*/ */
static ide_startstop_t idescsi_pc_intr(struct ata_device *drive, struct request *rq) static ide_startstop_t idescsi_pc_intr(struct ata_device *drive, struct request *rq)
{ {
idescsi_scsi_t *scsi = drive->driver_data; struct Scsi_Host *host = drive->driver_data;
idescsi_scsi_t *scsi = idescsi_private(host);
byte status, ireason; byte status, ireason;
int bcount; int bcount;
struct atapi_packet_command *pc = scsi->pc; struct atapi_packet_command *pc=scsi->pc;
unsigned int temp; unsigned int temp;
#if IDESCSI_DEBUG_LOG #if IDESCSI_DEBUG_LOG
printk (KERN_INFO "ide-scsi: Reached idescsi_pc_intr interrupt handler\n"); printk (KERN_INFO "ide-scsi: Reached idescsi_pc_intr interrupt handler\n");
#endif #endif /* IDESCSI_DEBUG_LOG */
if (test_and_clear_bit(PC_DMA_IN_PROGRESS, &pc->flags)) { if (test_and_clear_bit (PC_DMA_IN_PROGRESS, &pc->flags)) {
#if IDESCSI_DEBUG_LOG #if IDESCSI_DEBUG_LOG
printk ("ide-scsi: %s: DMA complete\n", drive->name); printk ("ide-scsi: %s: DMA complete\n", drive->name);
#endif #endif /* IDESCSI_DEBUG_LOG */
pc->actually_transferred=pc->request_transfer; pc->actually_transferred=pc->request_transfer;
udma_stop(drive); udma_stop(drive);
} }
...@@ -372,7 +378,8 @@ static ide_startstop_t idescsi_pc_intr(struct ata_device *drive, struct request ...@@ -372,7 +378,8 @@ static ide_startstop_t idescsi_pc_intr(struct ata_device *drive, struct request
static ide_startstop_t idescsi_transfer_pc(struct ata_device *drive, struct request *rq) static ide_startstop_t idescsi_transfer_pc(struct ata_device *drive, struct request *rq)
{ {
idescsi_scsi_t *scsi = drive->driver_data; struct Scsi_Host *host = drive->driver_data;
idescsi_scsi_t *scsi = idescsi_private(host);
struct atapi_packet_command *pc = scsi->pc; struct atapi_packet_command *pc = scsi->pc;
byte ireason; byte ireason;
ide_startstop_t startstop; ide_startstop_t startstop;
...@@ -397,7 +404,8 @@ static ide_startstop_t idescsi_transfer_pc(struct ata_device *drive, struct requ ...@@ -397,7 +404,8 @@ static ide_startstop_t idescsi_transfer_pc(struct ata_device *drive, struct requ
static ide_startstop_t idescsi_issue_pc(struct ata_device *drive, struct request *rq, static ide_startstop_t idescsi_issue_pc(struct ata_device *drive, struct request *rq,
struct atapi_packet_command *pc) struct atapi_packet_command *pc)
{ {
idescsi_scsi_t *scsi = drive->driver_data; struct Scsi_Host *host = drive->driver_data;
idescsi_scsi_t *scsi = idescsi_private(host);
int bcount; int bcount;
int dma_ok = 0; int dma_ok = 0;
...@@ -463,36 +471,14 @@ static void idescsi_ide_release(struct inode *inode, struct file *filp, struct a ...@@ -463,36 +471,14 @@ static void idescsi_ide_release(struct inode *inode, struct file *filp, struct a
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
} }
static struct ata_device *idescsi_drives[MAX_HWIFS * MAX_DRIVES]; static int idescsi_cleanup (struct ata_device *drive)
static int idescsi_initialized = 0;
/*
* Driver initialization.
*/
static void idescsi_setup(struct ata_device *drive, idescsi_scsi_t *scsi, int id)
{ {
idescsi_drives[id] = drive; struct Scsi_Host *host = drive->driver_data;
drive->driver_data = scsi;
drive->ready_stat = 0;
memset (scsi, 0, sizeof (idescsi_scsi_t));
scsi->drive = drive;
if (drive->id && (drive->id->config & 0x0060) == 0x20)
set_bit (IDESCSI_DRQ_INTERRUPT, &scsi->flags);
set_bit(IDESCSI_TRANSFORM, &scsi->transform);
clear_bit(IDESCSI_SG_TRANSFORM, &scsi->transform);
#if IDESCSI_DEBUG_LOG
set_bit(IDESCSI_LOG_CMD, &scsi->log);
#endif
}
static int idescsi_cleanup(struct ata_device *drive) if (ide_unregister_subdriver (drive)) {
{
idescsi_scsi_t *scsi = drive->driver_data;
if (ide_unregister_subdriver (drive))
return 1; return 1;
drive->driver_data = NULL; }
kfree (scsi); scsi_unregister(host);
return 0; return 0;
} }
...@@ -522,73 +508,9 @@ static struct ata_operations idescsi_driver = { ...@@ -522,73 +508,9 @@ static struct ata_operations idescsi_driver = {
capacity: NULL, capacity: NULL,
}; };
static void idescsi_attach(struct ata_device *drive)
{
idescsi_scsi_t *scsi;
int i, id;
char *req;
struct ata_channel *channel;
int unit;
if (idescsi_initialized)
return;
idescsi_initialized = 1;
for (i = 0; i < MAX_HWIFS * MAX_DRIVES; i++)
idescsi_drives[i] = NULL;
req = drive->driver_req;
if (req[0] != '\0' && strcmp(req, "ide-scsi"))
return;
if ((scsi = (idescsi_scsi_t *) kmalloc (sizeof (idescsi_scsi_t), GFP_KERNEL)) == NULL) {
printk(KERN_ERR "ide-scsi: %s: Can't allocate a scsi structure\n", drive->name);
return;
}
if (ide_register_subdriver (drive, &idescsi_driver)) {
printk(KERN_ERR "ide-scsi: %s: Failed to register the driver with ide.c\n", drive->name);
kfree (scsi);
return;
}
for (id = 0; id < MAX_HWIFS * MAX_DRIVES && idescsi_drives[id]; id++);
idescsi_setup (drive, scsi, id);
channel = drive->channel;
unit = drive - channel->drives;
ide_revalidate_disk(mk_kdev(channel->major, unit << PARTN_BITS));
}
int idescsi_detect (Scsi_Host_Template *host_template) int idescsi_detect (Scsi_Host_Template *host_template)
{ {
struct Scsi_Host *host; return register_ata_driver(&idescsi_driver);
int id;
int last_lun = 0;
host_template->proc_name = "ide-scsi";
host = scsi_register(host_template, 0);
if(host == NULL)
return 0;
for (id = 0; id < MAX_HWIFS * MAX_DRIVES && idescsi_drives[id]; id++)
last_lun = max(last_lun, idescsi_drives[id]->last_lun);
host->max_id = id;
host->max_lun = last_lun + 1;
host->can_queue = host->cmd_per_lun * id;
return 1;
}
int idescsi_release (struct Scsi_Host *host)
{
struct ata_device *drive;
int id;
for (id = 0; id < MAX_HWIFS * MAX_DRIVES; id++) {
drive = idescsi_drives[id];
if (drive) {
MOD_DEC_USE_COUNT;
}
}
return 0;
} }
const char *idescsi_info (struct Scsi_Host *host) const char *idescsi_info (struct Scsi_Host *host)
...@@ -598,8 +520,7 @@ const char *idescsi_info (struct Scsi_Host *host) ...@@ -598,8 +520,7 @@ const char *idescsi_info (struct Scsi_Host *host)
int idescsi_ioctl (Scsi_Device *dev, int cmd, void *arg) int idescsi_ioctl (Scsi_Device *dev, int cmd, void *arg)
{ {
struct ata_device *drive = idescsi_drives[dev->id]; idescsi_scsi_t *scsi = idescsi_private(dev->host);
idescsi_scsi_t *scsi = drive->driver_data;
if (cmd == SG_SET_TRANSFORM) { if (cmd == SG_SET_TRANSFORM) {
if (arg) if (arg)
...@@ -693,7 +614,8 @@ static inline struct bio *idescsi_dma_bio(struct ata_device *drive, struct atapi ...@@ -693,7 +614,8 @@ static inline struct bio *idescsi_dma_bio(struct ata_device *drive, struct atapi
static inline int should_transform(struct ata_device *drive, Scsi_Cmnd *cmd) static inline int should_transform(struct ata_device *drive, Scsi_Cmnd *cmd)
{ {
idescsi_scsi_t *scsi = drive->driver_data; struct Scsi_Host *host = drive->driver_data;
idescsi_scsi_t *scsi = idescsi_private(host);
if (major(cmd->request.rq_dev) == SCSI_GENERIC_MAJOR) if (major(cmd->request.rq_dev) == SCSI_GENERIC_MAJOR)
return test_bit(IDESCSI_SG_TRANSFORM, &scsi->transform); return test_bit(IDESCSI_SG_TRANSFORM, &scsi->transform);
...@@ -702,16 +624,11 @@ static inline int should_transform(struct ata_device *drive, Scsi_Cmnd *cmd) ...@@ -702,16 +624,11 @@ static inline int should_transform(struct ata_device *drive, Scsi_Cmnd *cmd)
int idescsi_queue (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) int idescsi_queue (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
{ {
struct ata_device *drive = idescsi_drives[cmd->target]; idescsi_scsi_t *scsi = idescsi_private(cmd->host);
idescsi_scsi_t *scsi; struct ata_device *drive = scsi->drive;
struct request *rq = NULL; struct request *rq = NULL;
struct atapi_packet_command *pc = NULL; struct atapi_packet_command *pc = NULL;
if (!drive) {
printk (KERN_ERR "ide-scsi: drive id %d not present\n", cmd->target);
goto abort;
}
scsi = drive->driver_data;
pc = kmalloc(sizeof(*pc), GFP_ATOMIC); pc = kmalloc(sizeof(*pc), GFP_ATOMIC);
rq = kmalloc(sizeof(*rq), GFP_ATOMIC); rq = kmalloc(sizeof(*rq), GFP_ATOMIC);
if (rq == NULL || pc == NULL) { if (rq == NULL || pc == NULL) {
...@@ -774,7 +691,8 @@ int idescsi_device_reset (Scsi_Cmnd *cmd) ...@@ -774,7 +691,8 @@ int idescsi_device_reset (Scsi_Cmnd *cmd)
int idescsi_bios (Disk *disk, kdev_t dev, int *parm) int idescsi_bios (Disk *disk, kdev_t dev, int *parm)
{ {
struct ata_device *drive = idescsi_drives[disk->device->id]; idescsi_scsi_t *scsi = idescsi_private(disk->device->host);
struct ata_device *drive = scsi->drive;
if (drive->bios_cyl && drive->bios_head && drive->bios_sect) { if (drive->bios_cyl && drive->bios_head && drive->bios_sect) {
parm[0] = drive->bios_head; parm[0] = drive->bios_head;
...@@ -788,7 +706,10 @@ static Scsi_Host_Template idescsi_template = { ...@@ -788,7 +706,10 @@ static Scsi_Host_Template idescsi_template = {
module: THIS_MODULE, module: THIS_MODULE,
name: "idescsi", name: "idescsi",
detect: idescsi_detect, detect: idescsi_detect,
release: idescsi_release, release: NULL, /* unregister_ata_driver is always
called before scsi_unregister_host,
there never controllers left to
release by that point. */
info: idescsi_info, info: idescsi_info,
ioctl: idescsi_ioctl, ioctl: idescsi_ioctl,
queuecommand: idescsi_queue, queuecommand: idescsi_queue,
...@@ -801,33 +722,65 @@ static Scsi_Host_Template idescsi_template = { ...@@ -801,33 +722,65 @@ static Scsi_Host_Template idescsi_template = {
cmd_per_lun: 5, cmd_per_lun: 5,
use_clustering: DISABLE_CLUSTERING, use_clustering: DISABLE_CLUSTERING,
emulated: 1, emulated: 1,
proc_name: "ide-scsi",
}; };
/*
static int __init idescsi_init(void) * Driver initialization.
*/
static void idescsi_attach(struct ata_device *drive)
{ {
int ret; idescsi_scsi_t *scsi;
ret = ata_driver_module(&idescsi_driver); struct Scsi_Host *host;
scsi_register_host(&idescsi_template);
return 0;
}
static void __exit exit_idescsi_module(void)
{
scsi_unregister_host(&idescsi_template);
#if 0 if (drive->type == ATA_DISK)
/* FIXME: what about this cleanup stuff here? This all should be done return;
* on close time perhaps? */
host = scsi_register(&idescsi_template, sizeof(idescsi_scsi_t));
if (idescsi_cleanup (drive)) { if(host == NULL) {
printk ("%s: exit_idescsi_module() called while still busy\n", drive->name); printk (KERN_ERR
"ide-scsi: %s: Can't allocate a scsi host structure\n",
drive->name);
return;
} }
host->max_lun = drive->last_lun + 1;
if (ide_register_subdriver (drive, &idescsi_driver)) {
printk (KERN_ERR "ide-scsi: %s: Failed to register the driver with ide.c\n", drive->name);
scsi_unregister(host);
return;
}
drive->driver_data = host;
drive->ready_stat = 0;
scsi = idescsi_private(host);
memset (scsi, 0, sizeof (idescsi_scsi_t));
scsi->drive = drive;
if (drive->id && (drive->id->config & 0x0060) == 0x20)
set_bit (IDESCSI_DRQ_INTERRUPT, &scsi->flags);
set_bit(IDESCSI_TRANSFORM, &scsi->transform);
clear_bit(IDESCSI_SG_TRANSFORM, &scsi->transform);
#if IDESCSI_DEBUG_LOG
set_bit(IDESCSI_LOG_CMD, &scsi->log);
#endif #endif
}
static int __init init_idescsi_module(void)
{
return scsi_register_host(&idescsi_template);
}
static void __exit exit_idescsi_module(void)
{
unregister_ata_driver(&idescsi_driver); unregister_ata_driver(&idescsi_driver);
scsi_unregister_host(&idescsi_template);
} }
module_init(idescsi_init); module_init(init_idescsi_module);
module_exit(exit_idescsi_module); module_exit(exit_idescsi_module);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -58,8 +58,11 @@ struct atapi_packet_command { ...@@ -58,8 +58,11 @@ struct atapi_packet_command {
} s; } s;
}; };
extern void atapi_init_pc(struct atapi_packet_command *pc);
extern void atapi_discard_data(struct ata_device *drive, unsigned int bcount); extern void atapi_discard_data(struct ata_device *, unsigned int);
extern void atapi_write_zeros(struct ata_device *drive, unsigned int bcount); extern void atapi_write_zeros(struct ata_device *, unsigned int);
extern void atapi_read(struct ata_device *, u8 *, unsigned int);
extern void atapi_write(struct ata_device *, u8 *, unsigned int);
extern void atapi_init_pc(struct atapi_packet_command *pc);
...@@ -742,9 +742,6 @@ struct ata_taskfile { ...@@ -742,9 +742,6 @@ struct ata_taskfile {
extern void ata_read(struct ata_device *, void *, unsigned int); extern void ata_read(struct ata_device *, void *, unsigned int);
extern void ata_write(struct ata_device *, void *, unsigned int); extern void ata_write(struct ata_device *, void *, unsigned int);
extern void atapi_read(struct ata_device *, void *, unsigned int);
extern void atapi_write(struct ata_device *, void *, unsigned int);
extern ide_startstop_t ata_taskfile(struct ata_device *, extern ide_startstop_t ata_taskfile(struct ata_device *,
struct ata_taskfile *, struct request *); struct ata_taskfile *, struct request *);
...@@ -811,7 +808,8 @@ extern int idescsi_init (void); ...@@ -811,7 +808,8 @@ extern int idescsi_init (void);
extern int ide_register_subdriver(struct ata_device *, struct ata_operations *); extern int ide_register_subdriver(struct ata_device *, struct ata_operations *);
extern int ide_unregister_subdriver(struct ata_device *drive); extern int ide_unregister_subdriver(struct ata_device *drive);
extern int ide_revalidate_disk(kdev_t i_rdev); extern int ata_revalidate(kdev_t i_rdev);
extern void ide_driver_module(void);
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
# define ON_BOARD 0 # define ON_BOARD 0
......
...@@ -1787,3 +1787,7 @@ ...@@ -1787,3 +1787,7 @@
#define PCI_DEVICE_ID_MICROGATE_USC 0x0010 #define PCI_DEVICE_ID_MICROGATE_USC 0x0010
#define PCI_DEVICE_ID_MICROGATE_SCC 0x0020 #define PCI_DEVICE_ID_MICROGATE_SCC 0x0020
#define PCI_DEVICE_ID_MICROGATE_SCA 0x0030 #define PCI_DEVICE_ID_MICROGATE_SCA 0x0030
#define PCI_VENDOR_ID_HINT 0x3388
#define PCI_DEVICE_ID_HINT_VXPROII_IDE 0x8013
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment