Commit 6ba988bc authored by Anton Altaparmakov's avatar Anton Altaparmakov

Merge cantab.net:/usr/src/bklinux-2.5 into cantab.net:/usr/src/tng

parents 5d7264e1 3150c862
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/spinlock.h>
#include <asm/hwrpb.h> #include <asm/hwrpb.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -1103,66 +1104,7 @@ static int SMC37c669_xlate_drq( ...@@ -1103,66 +1104,7 @@ static int SMC37c669_xlate_drq(
unsigned int drq unsigned int drq
); );
#if 0 static spinlock_t smc_lock __cacheline_aligned = SPIN_LOCK_UNLOCKED;
/*
** External Data Declarations
*/
extern struct LOCK spl_atomic;
/*
** External Function Prototype Declarations
*/
/* From kernel_alpha.mar */
extern spinlock(
struct LOCK *spl
);
extern spinunlock(
struct LOCK *spl
);
/* From filesys.c */
int allocinode(
char *name,
int can_create,
struct INODE **ipp
);
extern int null_procedure( void );
int smcc669_init( void );
int smcc669_open( struct FILE *fp, char *info, char *next, char *mode );
int smcc669_read( struct FILE *fp, int size, int number, unsigned char *buf );
int smcc669_write( struct FILE *fp, int size, int number, unsigned char *buf );
int smcc669_close( struct FILE *fp );
struct DDB smc_ddb = {
"smc", /* how this routine wants to be called */
smcc669_read, /* read routine */
smcc669_write, /* write routine */
smcc669_open, /* open routine */
smcc669_close, /* close routine */
null_procedure, /* name expansion routine */
null_procedure, /* delete routine */
null_procedure, /* create routine */
null_procedure, /* setmode */
null_procedure, /* validation routine */
0, /* class specific use */
1, /* allows information */
0, /* must be stacked */
0, /* is a flash update driver */
0, /* is a block device */
0, /* not seekable */
0, /* is an Ethernet device */
0, /* is a filesystem driver */
};
#endif
#define spinlock(x)
#define spinunlock(x)
/* /*
**++ **++
...@@ -2042,10 +1984,10 @@ static void __init SMC37c669_config_mode( ...@@ -2042,10 +1984,10 @@ static void __init SMC37c669_config_mode(
** mode. Therefore, a spinlock is placed around the two writes to ** mode. Therefore, a spinlock is placed around the two writes to
** guarantee that they complete uninterrupted. ** guarantee that they complete uninterrupted.
*/ */
spinlock( &spl_atomic ); spin_lock(&smc_lock);
wb( &SMC37c669->index_port, SMC37c669_CONFIG_ON_KEY ); wb( &SMC37c669->index_port, SMC37c669_CONFIG_ON_KEY );
wb( &SMC37c669->index_port, SMC37c669_CONFIG_ON_KEY ); wb( &SMC37c669->index_port, SMC37c669_CONFIG_ON_KEY );
spinunlock( &spl_atomic ); spin_unlock(&smc_lock);
} }
else { else {
wb( &SMC37c669->index_port, SMC37c669_CONFIG_OFF_KEY ); wb( &SMC37c669->index_port, SMC37c669_CONFIG_OFF_KEY );
......
...@@ -791,7 +791,7 @@ static int e100_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct ...@@ -791,7 +791,7 @@ static int e100_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct
if(!atapi) { if(!atapi) {
/* set the irq handler which will finish the request when DMA is done */ /* set the irq handler which will finish the request when DMA is done */
ide_set_handler(drive, &etrax_dma_intr, WAIT_CMD, NULL); ata_set_handler(drive, &etrax_dma_intr, WAIT_CMD, NULL);
/* issue cmd to drive */ /* issue cmd to drive */
OUT_BYTE(WIN_READDMA, IDE_COMMAND_REG); OUT_BYTE(WIN_READDMA, IDE_COMMAND_REG);
...@@ -802,10 +802,10 @@ static int e100_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct ...@@ -802,10 +802,10 @@ static int e100_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct
*R_DMA_CH3_CMD = IO_STATE(R_DMA_CH3_CMD, cmd, start); *R_DMA_CH3_CMD = IO_STATE(R_DMA_CH3_CMD, cmd, start);
/* initiate a multi word dma read using DMA handshaking */ /* initiate a multi word dma read using DMA handshaking */
*R_ATA_TRANSFER_CNT = *R_ATA_TRANSFER_CNT =
IO_FIELD(R_ATA_TRANSFER_CNT, count, ata_tot_size >> 1); IO_FIELD(R_ATA_TRANSFER_CNT, count, ata_tot_size >> 1);
*R_ATA_CTRL_DATA = *R_ATA_CTRL_DATA =
IO_FIELD(R_ATA_CTRL_DATA, data, IDE_DATA_REG) | IO_FIELD(R_ATA_CTRL_DATA, data, IDE_DATA_REG) |
IO_STATE(R_ATA_CTRL_DATA, rw, read) | IO_STATE(R_ATA_CTRL_DATA, rw, read) |
...@@ -831,7 +831,7 @@ static int e100_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct ...@@ -831,7 +831,7 @@ static int e100_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct
if(!atapi) { if(!atapi) {
/* set the irq handler which will finish the request when DMA is done */ /* set the irq handler which will finish the request when DMA is done */
ide_set_handler(drive, &etrax_dma_intr, WAIT_CMD, NULL); ata_set_handler(drive, &etrax_dma_intr, WAIT_CMD, NULL);
/* issue cmd to drive */ /* issue cmd to drive */
OUT_BYTE(WIN_WRITEDMA, IDE_COMMAND_REG); OUT_BYTE(WIN_WRITEDMA, IDE_COMMAND_REG);
......
...@@ -217,7 +217,7 @@ EXPORT_SYMBOL(__global_cli); ...@@ -217,7 +217,7 @@ EXPORT_SYMBOL(__global_cli);
EXPORT_SYMBOL(__global_sti); EXPORT_SYMBOL(__global_sti);
EXPORT_SYMBOL(__global_save_flags); EXPORT_SYMBOL(__global_save_flags);
EXPORT_SYMBOL(__global_restore_flags); EXPORT_SYMBOL(__global_restore_flags);
#ifdef SPINLOCK_DEBUG #ifdef CONFIG_DEBUG_SPINLOCK
EXPORT_SYMBOL(_raw_spin_lock); EXPORT_SYMBOL(_raw_spin_lock);
EXPORT_SYMBOL(_raw_spin_unlock); EXPORT_SYMBOL(_raw_spin_unlock);
EXPORT_SYMBOL(_raw_spin_trylock); EXPORT_SYMBOL(_raw_spin_trylock);
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#include <asm/system.h> #include <asm/system.h>
#include <asm/io.h> #include <asm/io.h>
#ifdef SPINLOCK_DEBUG #ifdef CONFIG_DEBUG_SPINLOCK
#undef INIT_STUCK #undef INIT_STUCK
#define INIT_STUCK 200000000 /*0xffffffff*/ #define INIT_STUCK 200000000 /*0xffffffff*/
......
...@@ -408,16 +408,6 @@ CONFIG_BLK_DEV_PIIX ...@@ -408,16 +408,6 @@ CONFIG_BLK_DEV_PIIX
the kernel to change PIO, DMA and UDMA speeds and to configure the kernel to change PIO, DMA and UDMA speeds and to configure
the chip to optimum performance. the chip to optimum performance.
CONFIG_BLK_DEV_PIIX_TRY133
The ICH2, ICH2-M, ICH3, ICH3-M, ICH3-S, ICH-4 and CICH chips can
support UDMA133 in hardware, even though the specifications of
the chips say otherwise. By enabling this option, you allow the
driver to enable the UDMA133 mode on these chips. Note that if
it doesn't work, your data gets lost, you're on your own, don't
expect any help.
Say N here, unless you really know what are you doing.
CONFIG_BLK_DEV_PDC202XX CONFIG_BLK_DEV_PDC202XX
Promise Ultra33 or PDC20246 Promise Ultra33 or PDC20246
Promise Ultra66 or PDC20262 Promise Ultra66 or PDC20262
......
...@@ -52,9 +52,6 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then ...@@ -52,9 +52,6 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then
dep_mbool ' HPT34X AUTODMA support (EXPERMENTAL)' CONFIG_HPT34X_AUTODMA $CONFIG_BLK_DEV_HPT34X $CONFIG_EXPERIMENTAL dep_mbool ' HPT34X AUTODMA support (EXPERMENTAL)' CONFIG_HPT34X_AUTODMA $CONFIG_BLK_DEV_HPT34X $CONFIG_EXPERIMENTAL
dep_bool ' HPT366 chipset support' CONFIG_BLK_DEV_HPT366 $CONFIG_BLK_DEV_IDEDMA_PCI dep_bool ' HPT366 chipset support' CONFIG_BLK_DEV_HPT366 $CONFIG_BLK_DEV_IDEDMA_PCI
dep_bool ' Intel and Efar (SMsC) chipset support' CONFIG_BLK_DEV_PIIX $CONFIG_BLK_DEV_IDEDMA_PCI dep_bool ' Intel and Efar (SMsC) chipset support' CONFIG_BLK_DEV_PIIX $CONFIG_BLK_DEV_IDEDMA_PCI
if [ "$CONFIG_BLK_DEV_PIIX" = "y" ]; then
dep_bool ' Allow undocumented UDMA133 on ICH chips (EXPERIMENTAL)' CONFIG_BLK_DEV_PIIX_TRY133 $CONFIG_EXPERIMENTAL
fi
if [ "$CONFIG_MIPS_ITE8172" = "y" -o "$CONFIG_MIPS_IVR" = "y" ]; then if [ "$CONFIG_MIPS_ITE8172" = "y" -o "$CONFIG_MIPS_IVR" = "y" ]; then
dep_mbool ' IT8172 IDE support' CONFIG_BLK_DEV_IT8172 $CONFIG_BLK_DEV_IDEDMA_PCI dep_mbool ' IT8172 IDE support' CONFIG_BLK_DEV_IT8172 $CONFIG_BLK_DEV_IDEDMA_PCI
dep_mbool ' IT8172 IDE Tuning support' CONFIG_IT8172_TUNING $CONFIG_BLK_DEV_IT8172 $CONFIG_IDEDMA_PCI_AUTO dep_mbool ' IT8172 IDE Tuning support' CONFIG_IT8172_TUNING $CONFIG_BLK_DEV_IT8172 $CONFIG_IDEDMA_PCI_AUTO
......
/* /*
* *
* $Id: aec62xx.c,v 1.0 2002/05/24 14:37:19 vojtech Exp $ * aec62xx.c, v1.2 2002/05/24
* *
* Copyright (c) 2002 Vojtech Pavlik * Copyright (c) 2002 Vojtech Pavlik
* *
...@@ -60,7 +60,9 @@ ...@@ -60,7 +60,9 @@
#define AEC_PLLCLK_ATA133 0x10 #define AEC_PLLCLK_ATA133 0x10
#define AEC_CABLEPINS_INPUT 0x10 #define AEC_CABLEPINS_INPUT 0x10
static unsigned char aec_cyc2udma[17] = { 0, 0, 7, 6, 5, 4, 4, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1 }; static unsigned char aec_cyc2udma[9] = { 5, 5, 5, 4, 3, 2, 2, 1, 1 };
static unsigned char aec_cyc2act[16] = { 1, 1, 2, 3, 4, 5, 6, 0, 0, 7, 7, 7, 7, 7, 7, 7 };
static unsigned char aec_cyc2rec[16] = { 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 12, 13, 14 };
/* /*
* aec_set_speed_old() writes timing values to * aec_set_speed_old() writes timing values to
...@@ -71,8 +73,10 @@ static void aec_set_speed_old(struct pci_dev *dev, unsigned char dn, struct ata_ ...@@ -71,8 +73,10 @@ static void aec_set_speed_old(struct pci_dev *dev, unsigned char dn, struct ata_
{ {
unsigned char t; unsigned char t;
pci_write_config_byte(dev, AEC_DRIVE_TIMING + (dn << 1), FIT(timing->active, 0, 15)); pci_write_config_byte(dev, AEC_DRIVE_TIMING + (dn << 1),
pci_write_config_byte(dev, AEC_DRIVE_TIMING + (dn << 1) + 1, FIT(timing->recover, 0, 15)); aec_cyc2act[FIT(timing->active, 0, 15)]);
pci_write_config_byte(dev, AEC_DRIVE_TIMING + (dn << 1) + 1,
aec_cyc2rec[FIT(timing->recover, 0, 15)]);
pci_read_config_byte(dev, AEC_UDMA_OLD, &t); pci_read_config_byte(dev, AEC_UDMA_OLD, &t);
t &= ~(3 << (dn << 1)); t &= ~(3 << (dn << 1));
...@@ -91,12 +95,19 @@ static void aec_set_speed_new(struct pci_dev *dev, unsigned char dn, struct ata_ ...@@ -91,12 +95,19 @@ static void aec_set_speed_new(struct pci_dev *dev, unsigned char dn, struct ata_
unsigned char t; unsigned char t;
pci_write_config_byte(dev, AEC_DRIVE_TIMING + dn, pci_write_config_byte(dev, AEC_DRIVE_TIMING + dn,
(FIT(timing->active, 0, 15) << 4) | FIT(timing->recover, 0, 15)); (aec_cyc2act[FIT(timing->active, 0, 15)] << 4)
| aec_cyc2rec[FIT(timing->recover, 0, 15)]);
pci_read_config_byte(dev, AEC_UDMA_NEW + (dn >> 1), &t); pci_read_config_byte(dev, AEC_UDMA_NEW + (dn >> 1), &t);
t &= ~(0xf << ((dn & 1) << 2)); t &= ~(0xf << ((dn & 1) << 2));
if (timing->udma) if (timing->udma) {
t |= aec_cyc2udma[FIT(timing->udma, 2, 16)] << ((dn & 1) << 2); if (timing->udma >= 2)
t |= aec_cyc2udma[FIT(timing->udma, 2, 8)] << ((dn & 1) << 2);
if (timing->mode == XFER_UDMA_5)
t |= 6;
if (timing->mode == XFER_UDMA_6)
t |= 7;
}
pci_write_config_byte(dev, AEC_UDMA_NEW + (dn >> 1), t); pci_write_config_byte(dev, AEC_UDMA_NEW + (dn >> 1), t);
} }
...@@ -120,9 +131,10 @@ static int aec_set_drive(struct ata_device *drive, unsigned char speed) ...@@ -120,9 +131,10 @@ static int aec_set_drive(struct ata_device *drive, unsigned char speed)
drive->dn >> 1, drive->dn & 1); drive->dn >> 1, drive->dn & 1);
T = 1000000000 / system_bus_speed; T = 1000000000 / system_bus_speed;
UT = T / (aec_old ? 1 : 4); UT = T / (aec_old ? 1 : 2);
ata_timing_compute(drive, speed, &t, T, UT); ata_timing_compute(drive, speed, &t, T, UT);
ata_timing_merge_8bit(&t);
if (aec_old) if (aec_old)
aec_set_speed_old(drive->channel->pci_dev, drive->dn, &t); aec_set_speed_old(drive->channel->pci_dev, drive->dn, &t);
......
...@@ -136,6 +136,20 @@ short ata_timing_mode(struct ata_device *drive, int map) ...@@ -136,6 +136,20 @@ short ata_timing_mode(struct ata_device *drive, int map)
(drive->id->tPIO == 0) ? XFER_PIO_0 : XFER_PIO_SLOW; (drive->id->tPIO == 0) ? XFER_PIO_0 : XFER_PIO_SLOW;
} }
/*
* Just get a pointer to the struct describing the timing values used commonly
* for a particular mode.
*/
struct ata_timing* ata_timing_data(short speed)
{
struct ata_timing *t;
for (t = ata_timing; t->mode != speed; t++)
if (t->mode < 0)
return NULL;
return t;
}
/* /*
* This is just unit conversion. * This is just unit conversion.
*/ */
...@@ -179,17 +193,15 @@ void ata_timing_merge(struct ata_timing *a, struct ata_timing *b, ...@@ -179,17 +193,15 @@ void ata_timing_merge(struct ata_timing *a, struct ata_timing *b,
} }
/* /*
* Just get a pointer to the struct describing the timing values used commonly * Not all controllers can do separate timing for 8-bit command transfers
* for a particular mode. * and 16-bit data transfers.
*/ */
struct ata_timing* ata_timing_data(short speed)
{
struct ata_timing *t;
for (t = ata_timing; t->mode != speed; t++) void ata_timing_merge_8bit(struct ata_timing *t)
if (t->mode < 0) {
return NULL; t->active = max(t->active, t->act8b);
return t; t->recover = max(t->recover, t->rec8b);
t->cycle = max(t->cycle, t->cyc8b);
} }
int ata_timing_compute(struct ata_device *drive, short speed, struct ata_timing *t, int ata_timing_compute(struct ata_device *drive, short speed, struct ata_timing *t,
...@@ -204,6 +216,8 @@ int ata_timing_compute(struct ata_device *drive, short speed, struct ata_timing ...@@ -204,6 +216,8 @@ int ata_timing_compute(struct ata_device *drive, short speed, struct ata_timing
if (!(s = ata_timing_data(speed))) if (!(s = ata_timing_data(speed)))
return -EINVAL; return -EINVAL;
memcpy(t, s, sizeof(struct ata_timing));
/* If the drive is an EIDE drive, it can tell us it needs extended /* If the drive is an EIDE drive, it can tell us it needs extended
* PIO/MWDMA cycle timing. * PIO/MWDMA cycle timing.
*/ */
...@@ -229,7 +243,7 @@ int ata_timing_compute(struct ata_device *drive, short speed, struct ata_timing ...@@ -229,7 +243,7 @@ int ata_timing_compute(struct ata_device *drive, short speed, struct ata_timing
/* Convert the timing to bus clock counts. /* Convert the timing to bus clock counts.
*/ */
ata_timing_quantize(s, t, T, UT); ata_timing_quantize(t, t, T, UT);
/* Even in DMA/UDMA modes we still use PIO access for IDENTIFY, /* Even in DMA/UDMA modes we still use PIO access for IDENTIFY,
* S.M.A.R.T and some other commands. We have to ensure that the DMA * S.M.A.R.T and some other commands. We have to ensure that the DMA
......
...@@ -69,7 +69,7 @@ extern struct ata_timing ata_timing[]; ...@@ -69,7 +69,7 @@ extern struct ata_timing ata_timing[];
#define XFER_EPIO 0x01 #define XFER_EPIO 0x01
#define XFER_PIO 0x00 #define XFER_PIO 0x00
/* External interface to host chips chanell timing setup. /* External interface to host chips channel timing setup.
* *
* It's a bit elaborate due to the legacy we have to bear. * It's a bit elaborate due to the legacy we have to bear.
*/ */
...@@ -79,6 +79,7 @@ extern void ata_timing_quantize(struct ata_timing *t, struct ata_timing *q, ...@@ -79,6 +79,7 @@ extern void ata_timing_quantize(struct ata_timing *t, struct ata_timing *q,
int T, int UT); int T, int UT);
extern void ata_timing_merge(struct ata_timing *a, struct ata_timing *b, extern void ata_timing_merge(struct ata_timing *a, struct ata_timing *b,
struct ata_timing *m, unsigned int what); struct ata_timing *m, unsigned int what);
void ata_timing_merge_8bit(struct ata_timing *t);
extern struct ata_timing* ata_timing_data(short speed); extern struct ata_timing* ata_timing_data(short speed);
extern int ata_timing_compute(struct ata_device *drive, extern int ata_timing_compute(struct ata_device *drive,
short speed, struct ata_timing *t, int T, int UT); short speed, struct ata_timing *t, int T, int UT);
......
...@@ -266,11 +266,10 @@ static int hpt34x_udma_init(struct ata_device *drive, struct request *rq) ...@@ -266,11 +266,10 @@ static int hpt34x_udma_init(struct ata_device *drive, struct request *rq)
outb(inb(dma_base+2)|6, dma_base+2); /* clear INTR & ERROR flags */ outb(inb(dma_base+2)|6, dma_base+2); /* clear INTR & ERROR flags */
drive->waiting_for_dma = 1; drive->waiting_for_dma = 1;
if (drive->type != ATA_DISK) if (drive->type == ATA_DISK) {
return 0; ata_set_handler(drive, ide_dma_intr, WAIT_CMD, NULL); /* issue cmd to drive */
OUT_BYTE((cmd == 0x09) ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
ide_set_handler(drive, ide_dma_intr, WAIT_CMD, NULL); /* issue cmd to drive */ }
OUT_BYTE((cmd == 0x09) ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
return 0; return 0;
} }
......
...@@ -281,7 +281,7 @@ static int ide_build_sglist(struct ata_device *drive, struct request *rq) ...@@ -281,7 +281,7 @@ static int ide_build_sglist(struct ata_device *drive, struct request *rq)
struct scatterlist *sg = ch->sg_table; struct scatterlist *sg = ch->sg_table;
int nents; int nents;
if (rq->flags & REQ_SPECIAL) { if ((rq->flags & REQ_SPECIAL) && (drive->type == ATA_DISK)) {
struct ata_taskfile *args = rq->special; struct ata_taskfile *args = rq->special;
if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE) if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE)
...@@ -521,7 +521,7 @@ icside_dma_common(struct ata_device *drive, struct request *rq, ...@@ -521,7 +521,7 @@ icside_dma_common(struct ata_device *drive, struct request *rq,
static int icside_dma_init(struct ata_device *drive, struct request *rq) static int icside_dma_init(struct ata_device *drive, struct request *rq)
{ {
struct ata_channel *ch = drive->channel; struct ata_channel *ch = drive->channel;
unsigned int cmd; u8 int cmd;
if (icside_dma_common(drive, rq, DMA_MODE_WRITE)) if (icside_dma_common(drive, rq, DMA_MODE_WRITE))
return 1; return 1;
...@@ -529,7 +529,7 @@ static int icside_dma_init(struct ata_device *drive, struct request *rq) ...@@ -529,7 +529,7 @@ static int icside_dma_init(struct ata_device *drive, struct request *rq)
if (drive->type != ATA_DISK) if (drive->type != ATA_DISK)
return 0; return 0;
ide_set_handler(drive, icside_dmaintr, WAIT_CMD, NULL); ata_set_handler(drive, icside_dmaintr, WAIT_CMD, NULL);
if ((rq->flags & REQ_SPECIAL) && drive->addressing == 1) { if ((rq->flags & REQ_SPECIAL) && drive->addressing == 1) {
struct ata_taskfile *args = rq->special; struct ata_taskfile *args = rq->special;
...@@ -542,6 +542,7 @@ static int icside_dma_init(struct ata_device *drive, struct request *rq) ...@@ -542,6 +542,7 @@ static int icside_dma_init(struct ata_device *drive, struct request *rq)
OUT_BYTE(cmd, IDE_COMMAND_REG); OUT_BYTE(cmd, IDE_COMMAND_REG);
enable_dma(ch->hw.dma); enable_dma(ch->hw.dma);
return 0; return 0;
} }
......
...@@ -728,6 +728,8 @@ static ide_startstop_t cdrom_start_packet_command(struct ata_device *drive, ...@@ -728,6 +728,8 @@ static ide_startstop_t cdrom_start_packet_command(struct ata_device *drive,
int xferlen, int xferlen,
ata_handler_t handler) ata_handler_t handler)
{ {
unsigned long flags;
struct ata_channel *ch = drive->channel;
ide_startstop_t startstop; ide_startstop_t startstop;
struct cdrom_info *info = drive->driver_data; struct cdrom_info *info = drive->driver_data;
...@@ -735,6 +737,8 @@ static ide_startstop_t cdrom_start_packet_command(struct ata_device *drive, ...@@ -735,6 +737,8 @@ static ide_startstop_t cdrom_start_packet_command(struct ata_device *drive,
if (ide_wait_stat(&startstop, drive, rq, 0, BUSY_STAT, WAIT_READY)) if (ide_wait_stat(&startstop, drive, rq, 0, BUSY_STAT, WAIT_READY))
return startstop; return startstop;
spin_lock_irqsave(ch->lock, flags);
if (info->dma) { if (info->dma) {
if (info->cmd == READ || info->cmd == WRITE) if (info->cmd == READ || info->cmd == WRITE)
info->dma = !udma_init(drive, rq); info->dma = !udma_init(drive, rq);
...@@ -754,11 +758,18 @@ static ide_startstop_t cdrom_start_packet_command(struct ata_device *drive, ...@@ -754,11 +758,18 @@ static ide_startstop_t cdrom_start_packet_command(struct ata_device *drive,
udma_start(drive, rq); udma_start(drive, rq);
if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) { if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {
ide_set_handler(drive, handler, WAIT_CMD, cdrom_timer_expiry); ata_set_handler(drive, handler, WAIT_CMD, cdrom_timer_expiry);
OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */ OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */
spin_unlock_irqrestore(ch->lock, flags);
return ide_started; return ide_started;
} else { } else {
OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */ OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */
spin_unlock_irqrestore(ch->lock, flags);
/* FIXME: Woah we have to ungrab the lock before the IRQ
* handler gets called.
*/
return handler(drive, rq); return handler(drive, rq);
} }
} }
...@@ -773,6 +784,8 @@ static ide_startstop_t cdrom_transfer_packet_command(struct ata_device *drive, ...@@ -773,6 +784,8 @@ static ide_startstop_t cdrom_transfer_packet_command(struct ata_device *drive,
unsigned char *cmd, unsigned long timeout, unsigned char *cmd, unsigned long timeout,
ata_handler_t handler) ata_handler_t handler)
{ {
unsigned long flags;
struct ata_channel *ch = drive->channel;
ide_startstop_t startstop; ide_startstop_t startstop;
if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) { if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {
...@@ -789,11 +802,11 @@ static ide_startstop_t cdrom_transfer_packet_command(struct ata_device *drive, ...@@ -789,11 +802,11 @@ static ide_startstop_t cdrom_transfer_packet_command(struct ata_device *drive,
return startstop; return startstop;
} }
/* Arm the interrupt handler. */ /* Arm the interrupt handler and send the command to the device. */
ide_set_handler(drive, handler, timeout, cdrom_timer_expiry); spin_lock_irqsave(ch->lock, flags);
ata_set_handler(drive, handler, timeout, cdrom_timer_expiry);
/* Send the command to the device. */
atapi_write(drive, cmd, CDROM_PACKET_SIZE); atapi_write(drive, cmd, CDROM_PACKET_SIZE);
spin_unlock_irqrestore(ch->lock, flags);
return ide_started; return ide_started;
} }
...@@ -893,6 +906,8 @@ int cdrom_read_check_ireason(struct ata_device *drive, struct request *rq, int l ...@@ -893,6 +906,8 @@ int cdrom_read_check_ireason(struct ata_device *drive, struct request *rq, int l
*/ */
static ide_startstop_t cdrom_read_intr(struct ata_device *drive, struct request *rq) static ide_startstop_t cdrom_read_intr(struct ata_device *drive, struct request *rq)
{ {
unsigned long flags;
struct ata_channel *ch = drive->channel;
int stat; int stat;
int ireason, len, sectors_to_transfer, nskip; int ireason, len, sectors_to_transfer, nskip;
struct cdrom_info *info = drive->driver_data; struct cdrom_info *info = drive->driver_data;
...@@ -1007,7 +1022,9 @@ static ide_startstop_t cdrom_read_intr(struct ata_device *drive, struct request ...@@ -1007,7 +1022,9 @@ static ide_startstop_t cdrom_read_intr(struct ata_device *drive, struct request
} }
/* Done moving data! Wait for another interrupt. */ /* Done moving data! Wait for another interrupt. */
ide_set_handler(drive, cdrom_read_intr, WAIT_CMD, NULL); spin_lock_irqsave(ch->lock, flags);
ata_set_handler(drive, cdrom_read_intr, WAIT_CMD, NULL);
spin_unlock_irqrestore(ch->lock, flags);
return ide_started; return ide_started;
} }
...@@ -1234,6 +1251,8 @@ static ide_startstop_t cdrom_start_read(struct ata_device *drive, struct request ...@@ -1234,6 +1251,8 @@ static ide_startstop_t cdrom_start_read(struct ata_device *drive, struct request
/* Interrupt routine for packet command completion. */ /* Interrupt routine for packet command completion. */
static ide_startstop_t cdrom_pc_intr(struct ata_device *drive, struct request *rq) static ide_startstop_t cdrom_pc_intr(struct ata_device *drive, struct request *rq)
{ {
unsigned long flags;
struct ata_channel *ch = drive->channel;
int ireason, len, stat, thislen; int ireason, len, stat, thislen;
/* FIXME --mdcki */ /* FIXME --mdcki */
...@@ -1326,7 +1345,9 @@ static ide_startstop_t cdrom_pc_intr(struct ata_device *drive, struct request *r ...@@ -1326,7 +1345,9 @@ static ide_startstop_t cdrom_pc_intr(struct ata_device *drive, struct request *r
} }
/* Now we wait for another interrupt. */ /* Now we wait for another interrupt. */
ide_set_handler(drive, cdrom_pc_intr, WAIT_CMD, cdrom_timer_expiry); spin_lock_irqsave(ch->lock, flags);
ata_set_handler(drive, cdrom_pc_intr, WAIT_CMD, cdrom_timer_expiry);
spin_unlock_irqrestore(ch->lock, flags);
return ide_started; return ide_started;
} }
...@@ -1469,6 +1490,8 @@ static inline int cdrom_write_check_ireason(struct ata_device *drive, struct req ...@@ -1469,6 +1490,8 @@ static inline int cdrom_write_check_ireason(struct ata_device *drive, struct req
static ide_startstop_t cdrom_write_intr(struct ata_device *drive, struct request *rq) static ide_startstop_t cdrom_write_intr(struct ata_device *drive, struct request *rq)
{ {
unsigned long flags;
struct ata_channel *ch = drive->channel;
int stat, ireason, len, sectors_to_transfer, uptodate; int stat, ireason, len, sectors_to_transfer, uptodate;
struct cdrom_info *info = drive->driver_data; struct cdrom_info *info = drive->driver_data;
int dma_error = 0, dma = info->dma; int dma_error = 0, dma = info->dma;
...@@ -1559,7 +1582,9 @@ static ide_startstop_t cdrom_write_intr(struct ata_device *drive, struct request ...@@ -1559,7 +1582,9 @@ static ide_startstop_t cdrom_write_intr(struct ata_device *drive, struct request
} }
/* re-arm handler */ /* re-arm handler */
ide_set_handler(drive, cdrom_write_intr, 5 * WAIT_CMD, NULL); spin_lock_irqsave(ch->lock, flags);
ata_set_handler(drive, cdrom_write_intr, 5 * WAIT_CMD, NULL);
spin_unlock_irqrestore(ch->lock, flags);
return ide_started; return ide_started;
} }
......
...@@ -95,8 +95,9 @@ static int lba_capacity_is_ok(struct hd_driveid *id) ...@@ -95,8 +95,9 @@ static int lba_capacity_is_ok(struct hd_driveid *id)
*/ */
static ide_startstop_t task_in_intr(struct ata_device *drive, struct request *rq) static ide_startstop_t task_in_intr(struct ata_device *drive, struct request *rq)
{ {
char *buf = NULL;
unsigned long flags; unsigned long flags;
struct ata_channel *ch = drive->channel;
char *buf = NULL;
if (!ata_status(drive, DATA_READY, BAD_R_STAT)) { if (!ata_status(drive, DATA_READY, BAD_R_STAT)) {
if (drive->status & (ERR_STAT|DRQ_STAT)) if (drive->status & (ERR_STAT|DRQ_STAT))
...@@ -106,7 +107,14 @@ static ide_startstop_t task_in_intr(struct ata_device *drive, struct request *rq ...@@ -106,7 +107,14 @@ static ide_startstop_t task_in_intr(struct ata_device *drive, struct request *rq
#if 0 #if 0
printk("task_in_intr to Soon wait for next interrupt\n"); printk("task_in_intr to Soon wait for next interrupt\n");
#endif #endif
ide_set_handler(drive, task_in_intr, WAIT_CMD, NULL);
/* FIXME: this locking should encompass the above register
* file access too.
*/
spin_lock_irqsave(ch->lock, flags);
ata_set_handler(drive, task_in_intr, WAIT_CMD, NULL);
spin_unlock_irqrestore(ch->lock, flags);
return ide_started; return ide_started;
} }
...@@ -132,8 +140,14 @@ static ide_startstop_t task_in_intr(struct ata_device *drive, struct request *rq ...@@ -132,8 +140,14 @@ static ide_startstop_t task_in_intr(struct ata_device *drive, struct request *rq
return ide_stopped; return ide_stopped;
} }
/* FIXME: this locking should encompass the above register
* file access too.
*/
spin_lock_irqsave(ch->lock, flags);
/* still data left to transfer */ /* still data left to transfer */
ide_set_handler(drive, task_in_intr, WAIT_CMD, NULL); ata_set_handler(drive, task_in_intr, WAIT_CMD, NULL);
spin_unlock_irqrestore(ch->lock, flags);
return ide_started; return ide_started;
} }
...@@ -143,8 +157,9 @@ static ide_startstop_t task_in_intr(struct ata_device *drive, struct request *rq ...@@ -143,8 +157,9 @@ static ide_startstop_t task_in_intr(struct ata_device *drive, struct request *rq
*/ */
static ide_startstop_t task_out_intr(struct ata_device *drive, struct request *rq) static ide_startstop_t task_out_intr(struct ata_device *drive, struct request *rq)
{ {
char *buf = NULL;
unsigned long flags; unsigned long flags;
struct ata_channel *ch = drive->channel;
char *buf = NULL;
if (!ata_status(drive, DRIVE_READY, drive->bad_wstat)) if (!ata_status(drive, DRIVE_READY, drive->bad_wstat))
return ata_error(drive, rq, __FUNCTION__); return ata_error(drive, rq, __FUNCTION__);
...@@ -165,7 +180,13 @@ static ide_startstop_t task_out_intr(struct ata_device *drive, struct request *r ...@@ -165,7 +180,13 @@ static ide_startstop_t task_out_intr(struct ata_device *drive, struct request *r
rq->current_nr_sectors--; rq->current_nr_sectors--;
} }
ide_set_handler(drive, task_out_intr, WAIT_CMD, NULL); /* FIXME: this locking should encompass the above register
* file access too.
*/
spin_lock_irqsave(ch->lock, flags);
ata_set_handler(drive, task_out_intr, WAIT_CMD, NULL);
spin_unlock_irqrestore(ch->lock, flags);
return ide_started; return ide_started;
} }
...@@ -175,16 +196,25 @@ static ide_startstop_t task_out_intr(struct ata_device *drive, struct request *r ...@@ -175,16 +196,25 @@ static ide_startstop_t task_out_intr(struct ata_device *drive, struct request *r
*/ */
static ide_startstop_t task_mulin_intr(struct ata_device *drive, struct request *rq) static ide_startstop_t task_mulin_intr(struct ata_device *drive, struct request *rq)
{ {
char *buf = NULL;
unsigned int msect, nsect;
unsigned long flags; unsigned long flags;
struct ata_channel *ch = drive->channel;
char *buf = NULL;
unsigned int msect;
unsigned int nsect;
if (!ata_status(drive, DATA_READY, BAD_R_STAT)) { if (!ata_status(drive, DATA_READY, BAD_R_STAT)) {
if (drive->status & (ERR_STAT|DRQ_STAT)) if (drive->status & (ERR_STAT|DRQ_STAT))
return ata_error(drive, rq, __FUNCTION__); return ata_error(drive, rq, __FUNCTION__);
/* FIXME: this locking should encompass the above register
* file access too.
*/
spin_lock_irqsave(ch->lock, flags);
/* no data yet, so wait for another interrupt */ /* no data yet, so wait for another interrupt */
ide_set_handler(drive, task_mulin_intr, WAIT_CMD, NULL); ata_set_handler(drive, task_mulin_intr, WAIT_CMD, NULL);
spin_unlock_irqrestore(ch->lock, flags);
return ide_started; return ide_started;
} }
...@@ -213,17 +243,24 @@ static ide_startstop_t task_mulin_intr(struct ata_device *drive, struct request ...@@ -213,17 +243,24 @@ static ide_startstop_t task_mulin_intr(struct ata_device *drive, struct request
} }
} while (msect); } while (msect);
/* FIXME: this locking should encompass the above register
* file access too.
*/
spin_lock_irqsave(ch->lock, flags);
/* /*
* more data left * more data left
*/ */
ide_set_handler(drive, task_mulin_intr, WAIT_CMD, NULL); ata_set_handler(drive, task_mulin_intr, WAIT_CMD, NULL);
spin_unlock_irqrestore(ch->lock, flags);
return ide_started; return ide_started;
} }
static ide_startstop_t task_mulout_intr(struct ata_device *drive, struct request *rq) static ide_startstop_t task_mulout_intr(struct ata_device *drive, struct request *rq)
{ {
unsigned long flags;
struct ata_channel *ch = drive->channel;
int ok; int ok;
int mcount = drive->mult_count; int mcount = drive->mult_count;
ide_startstop_t startstop; ide_startstop_t startstop;
...@@ -255,8 +292,15 @@ static ide_startstop_t task_mulout_intr(struct ata_device *drive, struct request ...@@ -255,8 +292,15 @@ static ide_startstop_t task_mulout_intr(struct ata_device *drive, struct request
if (!ok) { if (!ok) {
/* no data yet, so wait for another interrupt */ /* no data yet, so wait for another interrupt */
if (!drive->channel->handler) if (!ch->handler) {
ide_set_handler(drive, task_mulout_intr, WAIT_CMD, NULL); /* FIXME: this locking should encompass the above register
* file access too.
*/
spin_lock_irqsave(ch->lock, flags);
ata_set_handler(drive, task_mulout_intr, WAIT_CMD, NULL);
spin_unlock_irqrestore(ch->lock, flags);
}
return ide_started; return ide_started;
} }
...@@ -298,8 +342,15 @@ static ide_startstop_t task_mulout_intr(struct ata_device *drive, struct request ...@@ -298,8 +342,15 @@ static ide_startstop_t task_mulout_intr(struct ata_device *drive, struct request
} while (mcount); } while (mcount);
rq->errors = 0; rq->errors = 0;
if (!drive->channel->handler) if (!ch->handler) {
ide_set_handler(drive, task_mulout_intr, WAIT_CMD, NULL); /* FIXME: this locking should encompass the above register
* file access too.
*/
spin_lock_irqsave(ch->lock, flags);
ata_set_handler(drive, task_mulout_intr, WAIT_CMD, NULL);
spin_unlock_irqrestore(ch->lock, flags);
}
return ide_started; return ide_started;
} }
......
...@@ -821,6 +821,8 @@ static void idefloppy_retry_pc(struct ata_device *drive) ...@@ -821,6 +821,8 @@ static void idefloppy_retry_pc(struct ata_device *drive)
*/ */
static ide_startstop_t idefloppy_pc_intr(struct ata_device *drive, struct request *rq) static ide_startstop_t idefloppy_pc_intr(struct ata_device *drive, struct request *rq)
{ {
unsigned long flags;
struct ata_channel *ch = drive->channel;
idefloppy_floppy_t *floppy = drive->driver_data; idefloppy_floppy_t *floppy = drive->driver_data;
idefloppy_status_reg_t status; idefloppy_status_reg_t status;
idefloppy_bcount_reg_t bcount; idefloppy_bcount_reg_t bcount;
...@@ -833,7 +835,7 @@ static ide_startstop_t idefloppy_pc_intr(struct ata_device *drive, struct reques ...@@ -833,7 +835,7 @@ static ide_startstop_t idefloppy_pc_intr(struct ata_device *drive, struct reques
#endif #endif
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
if (test_bit (PC_DMA_IN_PROGRESS, &pc->flags)) { if (test_bit(PC_DMA_IN_PROGRESS, &pc->flags)) {
if (udma_stop(drive)) { if (udma_stop(drive)) {
set_bit (PC_DMA_ERROR, &pc->flags); set_bit (PC_DMA_ERROR, &pc->flags);
} else { } else {
...@@ -883,15 +885,24 @@ static ide_startstop_t idefloppy_pc_intr(struct ata_device *drive, struct reques ...@@ -883,15 +885,24 @@ static ide_startstop_t idefloppy_pc_intr(struct ata_device *drive, struct reques
return ide_stopped; return ide_stopped;
} }
#endif #endif
/* FIXME: this locking should encompass the above register
* file access too.
*/
spin_lock_irqsave(ch->lock, flags);
bcount.b.high=IN_BYTE (IDE_BCOUNTH_REG); /* Get the number of bytes to transfer */ bcount.b.high=IN_BYTE (IDE_BCOUNTH_REG); /* Get the number of bytes to transfer */
bcount.b.low=IN_BYTE (IDE_BCOUNTL_REG); /* on this interrupt */ bcount.b.low=IN_BYTE (IDE_BCOUNTL_REG); /* on this interrupt */
ireason.all=IN_BYTE (IDE_IREASON_REG); ireason.all=IN_BYTE (IDE_IREASON_REG);
if (ireason.b.cod) { if (ireason.b.cod) {
spin_unlock_irqrestore(ch->lock, flags);
printk (KERN_ERR "ide-floppy: CoD != 0 in idefloppy_pc_intr\n"); printk (KERN_ERR "ide-floppy: CoD != 0 in idefloppy_pc_intr\n");
return ide_stopped; return ide_stopped;
} }
if (ireason.b.io == test_bit(PC_WRITING, &pc->flags)) { /* Hopefully, we will never get here */ if (ireason.b.io == test_bit(PC_WRITING, &pc->flags)) { /* Hopefully, we will never get here */
spin_unlock_irqrestore(ch->lock, flags);
printk (KERN_ERR "ide-floppy: We wanted to %s, ", ireason.b.io ? "Write":"Read"); printk (KERN_ERR "ide-floppy: We wanted to %s, ", ireason.b.io ? "Write":"Read");
printk (KERN_ERR "but the floppy wants us to %s !\n",ireason.b.io ? "Read":"Write"); printk (KERN_ERR "but the floppy wants us to %s !\n",ireason.b.io ? "Read":"Write");
return ide_stopped; return ide_stopped;
...@@ -901,8 +912,11 @@ static ide_startstop_t idefloppy_pc_intr(struct ata_device *drive, struct reques ...@@ -901,8 +912,11 @@ static ide_startstop_t idefloppy_pc_intr(struct ata_device *drive, struct reques
if ( temp > pc->request_transfer) { if ( temp > pc->request_transfer) {
if (temp > pc->buffer_size) { if (temp > pc->buffer_size) {
printk (KERN_ERR "ide-floppy: The floppy wants to send us more data than expected - discarding data\n"); printk (KERN_ERR "ide-floppy: The floppy wants to send us more data than expected - discarding data\n");
atapi_discard_data (drive,bcount.all); atapi_discard_data (drive,bcount.all);
ide_set_handler(drive, idefloppy_pc_intr,IDEFLOPPY_WAIT_CMD, NULL); ata_set_handler(drive, idefloppy_pc_intr,IDEFLOPPY_WAIT_CMD, NULL);
spin_unlock_irqrestore(ch->lock, flags);
return ide_started; return ide_started;
} }
#if IDEFLOPPY_DEBUG_LOG #if IDEFLOPPY_DEBUG_LOG
...@@ -924,7 +938,8 @@ static ide_startstop_t idefloppy_pc_intr(struct ata_device *drive, struct reques ...@@ -924,7 +938,8 @@ static ide_startstop_t idefloppy_pc_intr(struct ata_device *drive, struct reques
pc->actually_transferred+=bcount.all; /* Update the current position */ pc->actually_transferred+=bcount.all; /* Update the current position */
pc->current_position+=bcount.all; pc->current_position+=bcount.all;
ide_set_handler(drive, idefloppy_pc_intr,IDEFLOPPY_WAIT_CMD, NULL); /* And set the interrupt handler again */ ata_set_handler(drive, idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); /* And set the interrupt handler again */
spin_unlock_irqrestore(ch->lock, flags);
return ide_started; return ide_started;
} }
...@@ -936,6 +951,8 @@ static ide_startstop_t idefloppy_pc_intr(struct ata_device *drive, struct reques ...@@ -936,6 +951,8 @@ static ide_startstop_t idefloppy_pc_intr(struct ata_device *drive, struct reques
*/ */
static ide_startstop_t idefloppy_transfer_pc(struct ata_device *drive, struct request *rq) static ide_startstop_t idefloppy_transfer_pc(struct ata_device *drive, struct request *rq)
{ {
unsigned long flags;
struct ata_channel *ch = drive->channel;
ide_startstop_t startstop; ide_startstop_t startstop;
idefloppy_floppy_t *floppy = drive->driver_data; idefloppy_floppy_t *floppy = drive->driver_data;
idefloppy_ireason_reg_t ireason; idefloppy_ireason_reg_t ireason;
...@@ -944,14 +961,23 @@ static ide_startstop_t idefloppy_transfer_pc(struct ata_device *drive, struct re ...@@ -944,14 +961,23 @@ static ide_startstop_t idefloppy_transfer_pc(struct ata_device *drive, struct re
printk (KERN_ERR "ide-floppy: Strange, packet command initiated yet DRQ isn't asserted\n"); printk (KERN_ERR "ide-floppy: Strange, packet command initiated yet DRQ isn't asserted\n");
return startstop; return startstop;
} }
/* FIXME: this locking should encompass the above register
* file access too.
*/
spin_lock_irqsave(ch->lock, flags);
ireason.all=IN_BYTE (IDE_IREASON_REG); ireason.all=IN_BYTE (IDE_IREASON_REG);
if (!ireason.b.cod || ireason.b.io) { if (!ireason.b.cod || ireason.b.io) {
spin_unlock_irqrestore(ch->lock, flags);
printk (KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while issuing a packet command\n"); printk (KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while issuing a packet command\n");
return ide_stopped; return ide_stopped;
} }
ide_set_handler (drive, idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); /* Set the interrupt routine */ ata_set_handler (drive, idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); /* Set the interrupt routine */
atapi_write(drive, floppy->pc->c, 12); /* Send the actual packet */ atapi_write(drive, floppy->pc->c, 12); /* Send the actual packet */
spin_unlock_irqrestore(ch->lock, flags);
return ide_started; return ide_started;
} }
...@@ -979,6 +1005,8 @@ static int idefloppy_transfer_pc2(struct ata_device *drive, struct request *__rq ...@@ -979,6 +1005,8 @@ static int idefloppy_transfer_pc2(struct ata_device *drive, struct request *__rq
static ide_startstop_t idefloppy_transfer_pc1(struct ata_device *drive, struct request *rq) static ide_startstop_t idefloppy_transfer_pc1(struct ata_device *drive, struct request *rq)
{ {
unsigned long flags;
struct ata_channel *ch = drive->channel;
idefloppy_floppy_t *floppy = drive->driver_data; idefloppy_floppy_t *floppy = drive->driver_data;
ide_startstop_t startstop; ide_startstop_t startstop;
idefloppy_ireason_reg_t ireason; idefloppy_ireason_reg_t ireason;
...@@ -987,22 +1015,32 @@ static ide_startstop_t idefloppy_transfer_pc1(struct ata_device *drive, struct r ...@@ -987,22 +1015,32 @@ static ide_startstop_t idefloppy_transfer_pc1(struct ata_device *drive, struct r
printk (KERN_ERR "ide-floppy: Strange, packet command initiated yet DRQ isn't asserted\n"); printk (KERN_ERR "ide-floppy: Strange, packet command initiated yet DRQ isn't asserted\n");
return startstop; return startstop;
} }
/* FIXME: this locking should encompass the above register
* file access too.
*/
spin_lock_irqsave(ch->lock, flags);
ireason.all=IN_BYTE (IDE_IREASON_REG); ireason.all=IN_BYTE (IDE_IREASON_REG);
if (!ireason.b.cod || ireason.b.io) { if (!ireason.b.cod || ireason.b.io) {
spin_unlock_irqrestore(ch->lock, flags);
printk (KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while issuing a packet command\n"); printk (KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while issuing a packet command\n");
return ide_stopped; return ide_stopped;
} }
/* /*
* The following delay solves a problem with ATAPI Zip 100 drives where the * The following delay solves a problem with ATAPI Zip 100 drives where
* Busy flag was apparently being deasserted before the unit was ready to * the Busy flag was apparently being deasserted before the unit was
* receive data. This was happening on a 1200 MHz Athlon system. 10/26/01 * ready to receive data. This was happening on a 1200 MHz Athlon
* 25msec is too short, 40 and 50msec work well. idefloppy_pc_intr will * system. 10/26/01 25msec is too short, 40 and 50msec work well.
* not be actually used until after the packet is moved in about 50 msec. * idefloppy_pc_intr will not be actually used until after the packet
* is moved in about 50 msec.
*/ */
ide_set_handler(drive, ata_set_handler(drive,
idefloppy_pc_intr, /* service routine for packet command */ idefloppy_pc_intr, /* service routine for packet command */
floppy->ticks, /* wait this long before "failing" */ floppy->ticks, /* wait this long before "failing" */
idefloppy_transfer_pc2); /* fail == transfer_pc2 */ idefloppy_transfer_pc2); /* fail == transfer_pc2 */
spin_unlock_irqrestore(ch->lock, flags);
return ide_started; return ide_started;
} }
...@@ -1047,7 +1085,7 @@ static ide_startstop_t idefloppy_issue_pc(struct ata_device *drive, struct reque ...@@ -1047,7 +1085,7 @@ static ide_startstop_t idefloppy_issue_pc(struct ata_device *drive, struct reque
} }
#if IDEFLOPPY_DEBUG_LOG #if IDEFLOPPY_DEBUG_LOG
printk (KERN_INFO "Retry number - %d\n",pc->retries); printk (KERN_INFO "Retry number - %d\n",pc->retries);
#endif /* IDEFLOPPY_DEBUG_LOG */ #endif
pc->retries++; pc->retries++;
pc->actually_transferred=0; /* We haven't transferred any data yet */ pc->actually_transferred=0; /* We haven't transferred any data yet */
...@@ -1082,9 +1120,19 @@ static ide_startstop_t idefloppy_issue_pc(struct ata_device *drive, struct reque ...@@ -1082,9 +1120,19 @@ static ide_startstop_t idefloppy_issue_pc(struct ata_device *drive, struct reque
pkt_xfer_routine = &idefloppy_transfer_pc; /* immediate */ pkt_xfer_routine = &idefloppy_transfer_pc; /* immediate */
} }
if (test_bit (IDEFLOPPY_DRQ_INTERRUPT, &floppy->flags)) { if (test_bit(IDEFLOPPY_DRQ_INTERRUPT, &floppy->flags)) {
ide_set_handler(drive, pkt_xfer_routine, IDEFLOPPY_WAIT_CMD, NULL); unsigned long flags;
struct ata_channel *ch = drive->channel;
/* FIXME: this locking should encompass the above register
* file access too.
*/
spin_lock_irqsave(ch->lock, flags);
ata_set_handler(drive, pkt_xfer_routine, IDEFLOPPY_WAIT_CMD, NULL);
OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* Issue the packet command */ OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* Issue the packet command */
spin_unlock_irqrestore(ch->lock, flags);
return ide_started; return ide_started;
} else { } else {
OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG);
...@@ -1750,8 +1798,6 @@ static void idefloppy_release(struct inode *inode, struct file *filp, struct ata ...@@ -1750,8 +1798,6 @@ static void idefloppy_release(struct inode *inode, struct file *filp, struct ata
if (!drive->usage) { if (!drive->usage) {
idefloppy_floppy_t *floppy = drive->driver_data; idefloppy_floppy_t *floppy = drive->driver_data;
invalidate_bdev (inode->i_bdev, 0);
/* IOMEGA Clik! drives do not support lock/unlock commands */ /* IOMEGA Clik! drives do not support lock/unlock commands */
if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags)) { if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags)) {
idefloppy_create_prevent_cmd (&pc, 0); idefloppy_create_prevent_cmd (&pc, 0);
......
/* /*
* linux/drivers/ide/ide-pmac.c Version ?.?? Mar. 18, 2000
*
* Support for IDE interfaces on PowerMacs. * Support for IDE interfaces on PowerMacs.
* These IDE interfaces are memory-mapped and have a DBDMA channel * These IDE interfaces are memory-mapped and have a DBDMA channel
* for doing DMA. * for doing DMA.
...@@ -1436,7 +1434,8 @@ static int pmac_udma_init(struct ata_device *drive, struct request *rq) ...@@ -1436,7 +1434,8 @@ static int pmac_udma_init(struct ata_device *drive, struct request *rq)
drive->waiting_for_dma = 1; drive->waiting_for_dma = 1;
if (drive->type != ATA_DISK) if (drive->type != ATA_DISK)
return 0; return 0;
ide_set_handler(drive, ide_dma_intr, WAIT_CMD, NULL);
ata_set_handler(drive, ide_dma_intr, WAIT_CMD, NULL);
if ((rq->flags & REQ_SPECIAL) && if ((rq->flags & REQ_SPECIAL) &&
(drive->addressing == 1)) { (drive->addressing == 1)) {
struct ata_taskfile *args = rq->special; struct ata_taskfile *args = rq->special;
......
...@@ -892,7 +892,7 @@ typedef struct { ...@@ -892,7 +892,7 @@ typedef struct {
struct bio *bio; struct bio *bio;
char *b_data; char *b_data;
int b_count; int b_count;
/* /*
* Pipeline parameters. * Pipeline parameters.
* *
...@@ -1864,6 +1864,7 @@ static int idetape_end_request(struct ata_device *drive, struct request *rq, int ...@@ -1864,6 +1864,7 @@ static int idetape_end_request(struct ata_device *drive, struct request *rq, int
idetape_increase_max_pipeline_stages (drive); idetape_increase_max_pipeline_stages (drive);
} }
} }
blkdev_dequeue_request(rq); blkdev_dequeue_request(rq);
drive->rq = NULL; drive->rq = NULL;
end_that_request_last(rq); end_that_request_last(rq);
...@@ -1977,6 +1978,8 @@ static void idetape_postpone_request(struct ata_device *drive, struct request *r ...@@ -1977,6 +1978,8 @@ static void idetape_postpone_request(struct ata_device *drive, struct request *r
*/ */
static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request *rq) static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request *rq)
{ {
unsigned long flags;
struct ata_channel *ch = drive->channel;
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
idetape_status_reg_t status; idetape_status_reg_t status;
idetape_bcount_reg_t bcount; idetape_bcount_reg_t bcount;
...@@ -2080,15 +2083,24 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request ...@@ -2080,15 +2083,24 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request
return ide_stopped; return ide_stopped;
} }
#endif #endif
/* FIXME: this locking should encompass the above register
* file access too.
*/
spin_lock_irqsave(ch->lock, flags);
bcount.b.high = IN_BYTE (IDE_BCOUNTH_REG); /* Get the number of bytes to transfer */ bcount.b.high = IN_BYTE (IDE_BCOUNTH_REG); /* Get the number of bytes to transfer */
bcount.b.low = IN_BYTE (IDE_BCOUNTL_REG); /* on this interrupt */ bcount.b.low = IN_BYTE (IDE_BCOUNTL_REG); /* on this interrupt */
ireason.all = IN_BYTE (IDE_IREASON_REG); ireason.all = IN_BYTE (IDE_IREASON_REG);
if (ireason.b.cod) { if (ireason.b.cod) {
spin_unlock_irqrestore(ch->lock, flags);
printk (KERN_ERR "ide-tape: CoD != 0 in idetape_pc_intr\n"); printk (KERN_ERR "ide-tape: CoD != 0 in idetape_pc_intr\n");
return ide_stopped; return ide_stopped;
} }
if (ireason.b.io == test_bit (PC_WRITING, &pc->flags)) { /* Hopefully, we will never get here */ if (ireason.b.io == test_bit (PC_WRITING, &pc->flags)) { /* Hopefully, we will never get here */
spin_unlock_irqrestore(ch->lock, flags);
printk (KERN_ERR "ide-tape: We wanted to %s, ", ireason.b.io ? "Write":"Read"); printk (KERN_ERR "ide-tape: We wanted to %s, ", ireason.b.io ? "Write":"Read");
printk (KERN_ERR "ide-tape: but the tape wants us to %s !\n",ireason.b.io ? "Read":"Write"); printk (KERN_ERR "ide-tape: but the tape wants us to %s !\n",ireason.b.io ? "Read":"Write");
return ide_stopped; return ide_stopped;
...@@ -2099,7 +2111,9 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request ...@@ -2099,7 +2111,9 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request
if (temp > pc->buffer_size) { if (temp > pc->buffer_size) {
printk (KERN_ERR "ide-tape: The tape wants to send us more data than expected - discarding data\n"); printk (KERN_ERR "ide-tape: The tape wants to send us more data than expected - discarding data\n");
atapi_discard_data (drive, bcount.all); atapi_discard_data (drive, bcount.all);
ide_set_handler(drive, idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); ata_set_handler(drive, idetape_pc_intr, IDETAPE_WAIT_CMD, NULL);
spin_unlock_irqrestore(ch->lock, flags);
return ide_started; return ide_started;
} }
#if IDETAPE_DEBUG_LOG #if IDETAPE_DEBUG_LOG
...@@ -2125,7 +2139,9 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request ...@@ -2125,7 +2139,9 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request
if (tape->debug_level >= 2) if (tape->debug_level >= 2)
printk(KERN_INFO "ide-tape: [cmd %x] transferred %d bytes on that interrupt\n", pc->c[0], bcount.all); printk(KERN_INFO "ide-tape: [cmd %x] transferred %d bytes on that interrupt\n", pc->c[0], bcount.all);
#endif #endif
ide_set_handler(drive, idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); /* And set the interrupt handler again */ ata_set_handler(drive, idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); /* And set the interrupt handler again */
spin_unlock_irqrestore(ch->lock, flags);
return ide_started; return ide_started;
} }
...@@ -2173,6 +2189,8 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request ...@@ -2173,6 +2189,8 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request
*/ */
static ide_startstop_t idetape_transfer_pc(struct ata_device *drive, struct request *rq) static ide_startstop_t idetape_transfer_pc(struct ata_device *drive, struct request *rq)
{ {
unsigned long flags;
struct ata_channel *ch = drive->channel;
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
struct atapi_packet_command *pc = tape->pc; struct atapi_packet_command *pc = tape->pc;
idetape_ireason_reg_t ireason; idetape_ireason_reg_t ireason;
...@@ -2183,6 +2201,12 @@ static ide_startstop_t idetape_transfer_pc(struct ata_device *drive, struct requ ...@@ -2183,6 +2201,12 @@ static ide_startstop_t idetape_transfer_pc(struct ata_device *drive, struct requ
printk (KERN_ERR "ide-tape: Strange, packet command initiated yet DRQ isn't asserted\n"); printk (KERN_ERR "ide-tape: Strange, packet command initiated yet DRQ isn't asserted\n");
return startstop; return startstop;
} }
/* FIXME: this locking should encompass the above register
* file access too.
*/
spin_lock_irqsave(ch->lock, flags);
ireason.all = IN_BYTE (IDE_IREASON_REG); ireason.all = IN_BYTE (IDE_IREASON_REG);
while (retries-- && (!ireason.b.cod || ireason.b.io)) { while (retries-- && (!ireason.b.cod || ireason.b.io)) {
printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while issuing a packet command, retrying\n"); printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while issuing a packet command, retrying\n");
...@@ -2196,11 +2220,14 @@ static ide_startstop_t idetape_transfer_pc(struct ata_device *drive, struct requ ...@@ -2196,11 +2220,14 @@ static ide_startstop_t idetape_transfer_pc(struct ata_device *drive, struct requ
} }
if (!ireason.b.cod || ireason.b.io) { if (!ireason.b.cod || ireason.b.io) {
printk (KERN_ERR "ide-tape: (IO,CoD) != (0,1) while issuing a packet command\n"); printk (KERN_ERR "ide-tape: (IO,CoD) != (0,1) while issuing a packet command\n");
spin_unlock_irqrestore(ch->lock, flags);
return ide_stopped; return ide_stopped;
} }
tape->cmd_start_time = jiffies; tape->cmd_start_time = jiffies;
ide_set_handler(drive, idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); /* Set the interrupt routine */ ata_set_handler(drive, idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); /* Set the interrupt routine */
atapi_write(drive,pc->c,12); /* Send the actual packet */ atapi_write(drive,pc->c,12); /* Send the actual packet */
spin_unlock_irqrestore(ch->lock, flags);
return ide_started; return ide_started;
} }
...@@ -2274,8 +2301,18 @@ static ide_startstop_t idetape_issue_packet_command(struct ata_device *drive, ...@@ -2274,8 +2301,18 @@ static ide_startstop_t idetape_issue_packet_command(struct ata_device *drive,
} }
#endif #endif
if (test_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags)) { if (test_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags)) {
ide_set_handler(drive, idetape_transfer_pc, IDETAPE_WAIT_CMD, NULL); unsigned long flags;
struct ata_channel *ch = drive->channel;
/* FIXME: this locking should encompass the above register
* file access too.
*/
spin_lock_irqsave(ch->lock, flags);
ata_set_handler(drive, idetape_transfer_pc, IDETAPE_WAIT_CMD, NULL);
OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG); OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG);
spin_unlock_irqrestore(ch->lock, flags);
return ide_started; return ide_started;
} else { } else {
OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG); OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG);
...@@ -3326,7 +3363,7 @@ static int __idetape_discard_read_pipeline(struct ata_device *drive) ...@@ -3326,7 +3363,7 @@ static int __idetape_discard_read_pipeline(struct ata_device *drive)
tape->merge_stage = NULL; tape->merge_stage = NULL;
} }
tape->chrdev_direction = idetape_direction_none; tape->chrdev_direction = idetape_direction_none;
if (tape->first_stage == NULL) if (tape->first_stage == NULL)
return 0; return 0;
...@@ -3723,10 +3760,10 @@ static int idetape_add_chrdev_write_request(struct ata_device *drive, int blocks ...@@ -3723,10 +3760,10 @@ static int idetape_add_chrdev_write_request(struct ata_device *drive, int blocks
#if IDETAPE_DEBUG_LOG #if IDETAPE_DEBUG_LOG
if (tape->debug_level >= 3) if (tape->debug_level >= 3)
printk (KERN_INFO "ide-tape: Reached idetape_add_chrdev_write_request\n"); printk (KERN_INFO "ide-tape: Reached idetape_add_chrdev_write_request\n");
#endif /* IDETAPE_DEBUG_LOG */ #endif
/* /*
* Attempt to allocate a new stage. * Attempt to allocate a new stage.
* Pay special attention to possible race conditions. * Pay special attention to possible race conditions.
*/ */
while ((new_stage = idetape_kmalloc_stage (tape)) == NULL) { while ((new_stage = idetape_kmalloc_stage (tape)) == NULL) {
......
...@@ -199,13 +199,21 @@ ide_startstop_t ata_taskfile(struct ata_device *drive, ...@@ -199,13 +199,21 @@ ide_startstop_t ata_taskfile(struct ata_device *drive,
IDE_SELECT_REG); IDE_SELECT_REG);
if (ar->handler) { if (ar->handler) {
unsigned long flags;
struct ata_channel *ch = drive->channel;
/* This is apparently supposed to reset the wait timeout for /* This is apparently supposed to reset the wait timeout for
* the interrupt to accur. * the interrupt to accur.
*/ */
ide_set_handler(drive, ar->handler, WAIT_CMD, NULL); /* FIXME: this locking should encompass the above register
* file access too.
*/
spin_lock_irqsave(ch->lock, flags);
ata_set_handler(drive, ar->handler, WAIT_CMD, NULL);
OUT_BYTE(ar->cmd, IDE_COMMAND_REG); OUT_BYTE(ar->cmd, IDE_COMMAND_REG);
spin_unlock_irqrestore(ch->lock, flags);
/* FIXME: Warning check for race between handler and prehandler /* FIXME: Warning check for race between handler and prehandler
* for writing first block of data. however since we are well * for writing first block of data. however since we are well
...@@ -373,8 +381,12 @@ ide_startstop_t ata_special_intr(struct ata_device *drive, struct ...@@ -373,8 +381,12 @@ ide_startstop_t ata_special_intr(struct ata_device *drive, struct
struct ata_taskfile *ar = rq->special; struct ata_taskfile *ar = rq->special;
ide_startstop_t ret = ide_stopped; ide_startstop_t ret = ide_stopped;
unsigned long flags;
ide__sti(); /* local CPU only */ ide__sti(); /* local CPU only */
spin_lock_irqsave(drive->channel->lock, flags);
if (rq->buffer && ar->taskfile.sector_number) { if (rq->buffer && ar->taskfile.sector_number) {
if (!ata_status(drive, 0, DRQ_STAT) && ar->taskfile.sector_number) { if (!ata_status(drive, 0, DRQ_STAT) && ar->taskfile.sector_number) {
int retries = 10; int retries = 10;
...@@ -409,6 +421,8 @@ ide_startstop_t ata_special_intr(struct ata_device *drive, struct ...@@ -409,6 +421,8 @@ ide_startstop_t ata_special_intr(struct ata_device *drive, struct
drive->rq = NULL; drive->rq = NULL;
end_that_request_last(rq); end_that_request_last(rq);
spin_unlock_irqrestore(drive->channel->lock, flags);
return ret; return ret;
} }
......
...@@ -160,25 +160,25 @@ int ide_end_request(struct ata_device *drive, struct request *rq, int uptodate) ...@@ -160,25 +160,25 @@ int ide_end_request(struct ata_device *drive, struct request *rq, int uptodate)
* at the appropriate code to handle the next interrupt, and a * at the appropriate code to handle the next interrupt, and a
* timer is started to prevent us from waiting forever in case * timer is started to prevent us from waiting forever in case
* something goes wrong (see the ide_timer_expiry() handler later on). * something goes wrong (see the ide_timer_expiry() handler later on).
*
* Channel lock should be held.
*/ */
void ide_set_handler(struct ata_device *drive, ata_handler_t handler, void ata_set_handler(struct ata_device *drive, ata_handler_t handler,
unsigned long timeout, ata_expiry_t expiry) unsigned long timeout, ata_expiry_t expiry)
{ {
unsigned long flags;
struct ata_channel *ch = drive->channel; struct ata_channel *ch = drive->channel;
spin_lock_irqsave(ch->lock, flags); if (ch->handler)
printk("%s: %s: handler not null; old=%p, new=%p, from %p\n",
drive->name, __FUNCTION__, ch->handler, handler, __builtin_return_address(0));
if (ch->handler != NULL) {
printk("%s: ide_set_handler: handler not null; old=%p, new=%p, from %p\n",
drive->name, ch->handler, handler, __builtin_return_address(0));
}
ch->handler = handler; ch->handler = handler;
ch->expiry = expiry; ch->expiry = expiry;
ch->timer.expires = jiffies + timeout; ch->timer.expires = jiffies + timeout;
add_timer(&ch->timer); add_timer(&ch->timer);
spin_unlock_irqrestore(ch->lock, flags);
} }
static void check_crc_errors(struct ata_device *drive) static void check_crc_errors(struct ata_device *drive)
...@@ -256,26 +256,30 @@ static ide_startstop_t do_reset1(struct ata_device *, int); /* needed below */ ...@@ -256,26 +256,30 @@ static ide_startstop_t do_reset1(struct ata_device *, int); /* needed below */
*/ */
static ide_startstop_t atapi_reset_pollfunc(struct ata_device *drive, struct request *__rq) static ide_startstop_t atapi_reset_pollfunc(struct ata_device *drive, struct request *__rq)
{ {
unsigned long flags;
struct ata_channel *ch = drive->channel; struct ata_channel *ch = drive->channel;
int ret = ide_stopped;
ata_select(drive, 10); ata_select(drive, 10);
if (ata_status(drive, 0, BUSY_STAT)) if (!ata_status(drive, 0, BUSY_STAT)) {
printk("%s: ATAPI reset complete\n", drive->name);
else {
if (time_before(jiffies, ch->poll_timeout)) { if (time_before(jiffies, ch->poll_timeout)) {
ide_set_handler (drive, atapi_reset_pollfunc, HZ/20, NULL); spin_lock_irqsave(ch->lock, flags);
ata_set_handler(drive, atapi_reset_pollfunc, HZ/20, NULL);
spin_unlock_irqrestore(ch->lock, flags);
ret = ide_started; /* continue polling */
} else {
ch->poll_timeout = 0; /* end of polling */
printk("%s: ATAPI reset timed out, status=0x%02x\n", drive->name, drive->status);
return ide_started; /* continue polling */ ret = do_reset1(drive, 1); /* do it the old fashioned way */
} }
ch->poll_timeout = 0; /* end of polling */ } else {
printk("%s: ATAPI reset timed out, status=0x%02x\n", drive->name, drive->status); printk("%s: ATAPI reset complete\n", drive->name);
ch->poll_timeout = 0; /* done polling */
return do_reset1(drive, 1); /* do it the old fashioned way */
} }
ch->poll_timeout = 0; /* done polling */
return ide_stopped; return ret;
} }
/* /*
...@@ -289,12 +293,16 @@ static ide_startstop_t reset_pollfunc(struct ata_device *drive, struct request * ...@@ -289,12 +293,16 @@ static ide_startstop_t reset_pollfunc(struct ata_device *drive, struct request *
if (!ata_status(drive, 0, BUSY_STAT)) { if (!ata_status(drive, 0, BUSY_STAT)) {
if (time_before(jiffies, ch->poll_timeout)) { if (time_before(jiffies, ch->poll_timeout)) {
ide_set_handler(drive, reset_pollfunc, HZ/20, NULL); unsigned long flags;
spin_lock_irqsave(ch->lock, flags);
ata_set_handler(drive, reset_pollfunc, HZ/20, NULL);
spin_unlock_irqrestore(ch->lock, flags);
return ide_started; /* continue polling */ return ide_started; /* continue polling */
} }
printk("%s: reset timed out, status=0x%02x\n", ch->name, drive->status); printk("%s: reset timed out, status=0x%02x\n", ch->name, drive->status);
drive->failures++; ++drive->failures;
} else { } else {
u8 stat; u8 stat;
...@@ -303,11 +311,11 @@ static ide_startstop_t reset_pollfunc(struct ata_device *drive, struct request * ...@@ -303,11 +311,11 @@ static ide_startstop_t reset_pollfunc(struct ata_device *drive, struct request *
printk("success\n"); printk("success\n");
drive->failures = 0; drive->failures = 0;
} else { } else {
char *msg; const char *msg = "";
#if FANCY_STATUS_DUMPS #if FANCY_STATUS_DUMPS
u8 val; u8 val;
static char *messages[5] = { static const char *messages[5] = {
" passed", " passed",
" formatter device", " formatter device",
" sector buffer", " sector buffer",
...@@ -319,13 +327,11 @@ static ide_startstop_t reset_pollfunc(struct ata_device *drive, struct request * ...@@ -319,13 +327,11 @@ static ide_startstop_t reset_pollfunc(struct ata_device *drive, struct request *
val = stat & 0x7f; val = stat & 0x7f;
if (val >= 1 && val <= 5) if (val >= 1 && val <= 5)
msg = messages[val -1]; msg = messages[val -1];
else
msg = "";
if (stat & 0x80) if (stat & 0x80)
printk("; slave:"); printk("; slave:");
#endif #endif
printk("%s error [%02x]\n", msg, stat); printk(KERN_ERR "%s error [%02x]\n", msg, stat);
drive->failures++; ++drive->failures;
} }
} }
ch->poll_timeout = 0; /* done polling */ ch->poll_timeout = 0; /* done polling */
...@@ -347,6 +353,8 @@ static ide_startstop_t reset_pollfunc(struct ata_device *drive, struct request * ...@@ -347,6 +353,8 @@ static ide_startstop_t reset_pollfunc(struct ata_device *drive, struct request *
* Equally poor, though, is the fact that this may a very long time to * Equally poor, though, is the fact that this may a very long time to
* complete, (up to 30 seconds worst case). So, instead of busy-waiting here * complete, (up to 30 seconds worst case). So, instead of busy-waiting here
* for it, we set a timer to poll at 50ms intervals. * for it, we set a timer to poll at 50ms intervals.
*
* Channel lock should be held.
*/ */
static ide_startstop_t do_reset1(struct ata_device *drive, int do_not_try_atapi) static ide_startstop_t do_reset1(struct ata_device *drive, int do_not_try_atapi)
...@@ -364,7 +372,7 @@ static ide_startstop_t do_reset1(struct ata_device *drive, int do_not_try_atapi) ...@@ -364,7 +372,7 @@ static ide_startstop_t do_reset1(struct ata_device *drive, int do_not_try_atapi)
ata_select(drive, 20); ata_select(drive, 20);
OUT_BYTE(WIN_SRST, IDE_COMMAND_REG); OUT_BYTE(WIN_SRST, IDE_COMMAND_REG);
ch->poll_timeout = jiffies + WAIT_WORSTCASE; ch->poll_timeout = jiffies + WAIT_WORSTCASE;
ide_set_handler(drive, atapi_reset_pollfunc, HZ/20, NULL); ata_set_handler(drive, atapi_reset_pollfunc, HZ/20, NULL);
__restore_flags(flags); /* local CPU only */ __restore_flags(flags); /* local CPU only */
return ide_started; return ide_started;
...@@ -377,7 +385,7 @@ static ide_startstop_t do_reset1(struct ata_device *drive, int do_not_try_atapi) ...@@ -377,7 +385,7 @@ static ide_startstop_t do_reset1(struct ata_device *drive, int do_not_try_atapi)
for (unit = 0; unit < MAX_DRIVES; ++unit) for (unit = 0; unit < MAX_DRIVES; ++unit)
check_crc_errors(&ch->drives[unit]); check_crc_errors(&ch->drives[unit]);
__restore_flags (flags); /* local CPU only */ __restore_flags(flags); /* local CPU only */
return ide_started; return ide_started;
} }
...@@ -546,6 +554,8 @@ static int do_recalibrate(struct ata_device *drive) ...@@ -546,6 +554,8 @@ static int do_recalibrate(struct ata_device *drive)
/* /*
* Take action based on the error returned by the drive. * Take action based on the error returned by the drive.
*
* FIXME: Channel lock should be held.
*/ */
ide_startstop_t ata_error(struct ata_device *drive, struct request *rq, const char *msg) ide_startstop_t ata_error(struct ata_device *drive, struct request *rq, const char *msg)
{ {
...@@ -613,6 +623,8 @@ ide_startstop_t ata_error(struct ata_device *drive, struct request *rq, const ch ...@@ -613,6 +623,8 @@ ide_startstop_t ata_error(struct ata_device *drive, struct request *rq, const ch
* That could be done by busy-waiting for the first jiffy or two, and then * That could be done by busy-waiting for the first jiffy or two, and then
* setting a timer to wake up at half second intervals thereafter, until * setting a timer to wake up at half second intervals thereafter, until
* timeout is achieved, before timing out. * timeout is achieved, before timing out.
*
* FIXME: Channel lock should be held.
*/ */
int ide_wait_stat(ide_startstop_t *startstop, int ide_wait_stat(ide_startstop_t *startstop,
struct ata_device *drive, struct request *rq, struct ata_device *drive, struct request *rq,
...@@ -709,7 +721,8 @@ static ide_startstop_t start_request(struct ata_device *drive, struct request *r ...@@ -709,7 +721,8 @@ static ide_startstop_t start_request(struct ata_device *drive, struct request *r
/* This issues a special drive command. /* This issues a special drive command.
*/ */
if (rq->flags & REQ_SPECIAL) if (rq->flags & REQ_SPECIAL)
return ata_taskfile(drive, rq->special, NULL); if (drive->type == ATA_DISK)
return ata_taskfile(drive, rq->special, NULL);
/* The normal way of execution is to pass and execute the request /* The normal way of execution is to pass and execute the request
* handler down to the device type driver. * handler down to the device type driver.
...@@ -744,6 +757,7 @@ ide_startstop_t restart_request(struct ata_device *drive) ...@@ -744,6 +757,7 @@ ide_startstop_t restart_request(struct ata_device *drive)
{ {
struct ata_channel *ch = drive->channel; struct ata_channel *ch = drive->channel;
unsigned long flags; unsigned long flags;
int ret;
spin_lock_irqsave(ch->lock, flags); spin_lock_irqsave(ch->lock, flags);
...@@ -752,7 +766,12 @@ ide_startstop_t restart_request(struct ata_device *drive) ...@@ -752,7 +766,12 @@ ide_startstop_t restart_request(struct ata_device *drive)
spin_unlock_irqrestore(ch->lock, flags); spin_unlock_irqrestore(ch->lock, flags);
return start_request(drive, drive->rq); /* FIXME make start_request do the unlock itself and
* push this locking further down. */
ret = start_request(drive, drive->rq);
return ret;
} }
/* /*
...@@ -844,14 +863,16 @@ static struct ata_device *choose_urgent_device(struct ata_channel *channel) ...@@ -844,14 +863,16 @@ static struct ata_device *choose_urgent_device(struct ata_channel *channel)
sleep = jiffies + WAIT_MIN_SLEEP; sleep = jiffies + WAIT_MIN_SLEEP;
#if 1 #if 1
if (timer_pending(&channel->timer)) if (timer_pending(&channel->timer))
printk(KERN_ERR "ide_set_handler: timer already active\n"); printk(KERN_ERR "%s: timer already active\n", __FUNCTION__);
#endif #endif
set_bit(IDE_SLEEP, channel->active); set_bit(IDE_SLEEP, channel->active);
mod_timer(&channel->timer, sleep); mod_timer(&channel->timer, sleep);
/* we purposely leave hwgroup busy while sleeping */ /* we purposely leave hwgroup busy while sleeping */
} else { } else {
/* FIXME: use queue plugging instead of active to
* block upper layers from stomping on us */
/* Ugly, but how can we sleep for the lock otherwise? */ /* Ugly, but how can we sleep for the lock otherwise? */
ide_release_lock(&irq_lock);/* for atari only */ ide_release_lock(&ide_irq_lock);/* for atari only */
clear_bit(IDE_BUSY, channel->active); clear_bit(IDE_BUSY, channel->active);
} }
...@@ -918,11 +939,10 @@ static void queue_commands(struct ata_device *drive) ...@@ -918,11 +939,10 @@ static void queue_commands(struct ata_device *drive)
drive->rq = rq; drive->rq = rq;
/* FIXME: push this locaing further down */
spin_unlock(drive->channel->lock); spin_unlock(drive->channel->lock);
ide__sti(); /* allow other IRQs while we start this request */ ide__sti(); /* allow other IRQs while we start this request */
startstop = start_request(drive, rq); startstop = start_request(drive, rq);
spin_lock_irq(drive->channel->lock); spin_lock_irq(drive->channel->lock);
/* command started, we are busy */ /* command started, we are busy */
...@@ -948,7 +968,7 @@ static void queue_commands(struct ata_device *drive) ...@@ -948,7 +968,7 @@ static void queue_commands(struct ata_device *drive)
*/ */
static void do_request(struct ata_channel *channel) static void do_request(struct ata_channel *channel)
{ {
ide_get_lock(&irq_lock, ata_irq_request, hwgroup);/* for atari only: POSSIBLY BROKEN HERE(?) */ ide_get_lock(&ide_irq_lock, ata_irq_request, channel);/* for atari only: POSSIBLY BROKEN HERE(?) */
// __cli(); /* necessary paranoia: ensure IRQs are masked on local CPU */ // __cli(); /* necessary paranoia: ensure IRQs are masked on local CPU */
while (!test_and_set_bit(IDE_BUSY, channel->active)) { while (!test_and_set_bit(IDE_BUSY, channel->active)) {
...@@ -1142,7 +1162,7 @@ void ide_timer_expiry(unsigned long data) ...@@ -1142,7 +1162,7 @@ void ide_timer_expiry(unsigned long data)
* *
* In reality, this is a non-issue. The new command is not sent unless the * In reality, this is a non-issue. The new command is not sent unless the
* drive is ready to accept one, in which case we know the drive is not * drive is ready to accept one, in which case we know the drive is not
* trying to interrupt us. And ide_set_handler() is always invoked before * trying to interrupt us. And ata_set_handler() is always invoked before
* completing the issuance of any new drive command, so we will not be * completing the issuance of any new drive command, so we will not be
* accidentally invoked as a result of any valid command completion interrupt. * accidentally invoked as a result of any valid command completion interrupt.
* *
...@@ -1416,7 +1436,7 @@ EXPORT_SYMBOL(drive_is_flashcard); ...@@ -1416,7 +1436,7 @@ EXPORT_SYMBOL(drive_is_flashcard);
EXPORT_SYMBOL(ide_timer_expiry); EXPORT_SYMBOL(ide_timer_expiry);
EXPORT_SYMBOL(do_ide_request); EXPORT_SYMBOL(do_ide_request);
EXPORT_SYMBOL(ide_set_handler); EXPORT_SYMBOL(ata_set_handler);
EXPORT_SYMBOL(ata_dump); EXPORT_SYMBOL(ata_dump);
EXPORT_SYMBOL(ata_error); EXPORT_SYMBOL(ata_error);
......
...@@ -47,15 +47,15 @@ static int do_cmd_ioctl(struct ata_device *drive, unsigned long arg) ...@@ -47,15 +47,15 @@ static int do_cmd_ioctl(struct ata_device *drive, unsigned long arg)
u8 *argbuf = vals; u8 *argbuf = vals;
int argsize = 4; int argsize = 4;
struct ata_taskfile args; struct ata_taskfile args;
struct request rq; struct request req;
/* Second phase. /* Second phase.
*/ */
if (copy_from_user(vals, (void *)arg, 4)) if (copy_from_user(vals, (void *)arg, 4))
return -EFAULT; return -EFAULT;
memset(&rq, 0, sizeof(rq)); memset(&req, 0, sizeof(req));
rq.flags = REQ_SPECIAL; req.flags = REQ_SPECIAL;
memset(&args, 0, sizeof(args)); memset(&args, 0, sizeof(args));
...@@ -85,9 +85,9 @@ static int do_cmd_ioctl(struct ata_device *drive, unsigned long arg) ...@@ -85,9 +85,9 @@ static int do_cmd_ioctl(struct ata_device *drive, unsigned long arg)
*/ */
args.handler = ata_special_intr; args.handler = ata_special_intr;
rq.buffer = argbuf + 4; req.buffer = argbuf + 4;
rq.special = &args; req.special = &args;
err = ide_do_drive_cmd(drive, &rq, ide_wait); err = ide_do_drive_cmd(drive, &req, ide_wait);
argbuf[0] = drive->status; argbuf[0] = drive->status;
argbuf[1] = args.taskfile.feature; argbuf[1] = args.taskfile.feature;
......
...@@ -114,12 +114,12 @@ spinlock_t ide_lock __cacheline_aligned = SPIN_LOCK_UNLOCKED; ...@@ -114,12 +114,12 @@ spinlock_t ide_lock __cacheline_aligned = SPIN_LOCK_UNLOCKED;
static int ide_scan_direction; /* THIS was formerly 2.2.x pci=reverse */ static int ide_scan_direction; /* THIS was formerly 2.2.x pci=reverse */
#endif #endif
#if defined(__mc68000__) || defined(CONFIG_APUS) #ifdef ATA_ARCH_LOCK
/* /*
* This is used by the Atari code to obtain access to the IDE interrupt, * This is used by the Atari code to obtain access to the IDE interrupt,
* which is shared between several drivers. * which is shared between several drivers.
*/ */
static int irq_lock; int ide_irq_lock;
#endif #endif
int noautodma = 0; int noautodma = 0;
...@@ -679,8 +679,8 @@ static int __init stridx (const char *s, char c) ...@@ -679,8 +679,8 @@ static int __init stridx (const char *s, char c)
*/ */
static int __init match_parm (char *s, const char *keywords[], int vals[], int max_vals) static int __init match_parm (char *s, const char *keywords[], int vals[], int max_vals)
{ {
static const char *decimal = "0123456789"; static const char decimal[] = "0123456789";
static const char *hex = "0123456789abcdef"; static const char hex[] = "0123456789abcdef";
int i, n; int i, n;
if (*s++ == '=') { if (*s++ == '=') {
...@@ -1449,7 +1449,7 @@ static int __init ata_module_init(void) ...@@ -1449,7 +1449,7 @@ static int __init ata_module_init(void)
#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
# if defined(__mc68000__) || defined(CONFIG_APUS) # if defined(__mc68000__) || defined(CONFIG_APUS)
if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) { if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) {
// ide_get_lock(&irq_lock, NULL, NULL);/* for atari only */ ide_get_lock(&ide_irq_lock, NULL, NULL);/* for atari only */
disable_irq(ide_hwifs[0].irq); /* disable_irq_nosync ?? */ disable_irq(ide_hwifs[0].irq); /* disable_irq_nosync ?? */
// disable_irq_nosync(ide_hwifs[0].irq); // disable_irq_nosync(ide_hwifs[0].irq);
} }
...@@ -1460,7 +1460,7 @@ static int __init ata_module_init(void) ...@@ -1460,7 +1460,7 @@ static int __init ata_module_init(void)
# if defined(__mc68000__) || defined(CONFIG_APUS) # if defined(__mc68000__) || defined(CONFIG_APUS)
if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) { if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) {
enable_irq(ide_hwifs[0].irq); enable_irq(ide_hwifs[0].irq);
ide_release_lock(&irq_lock);/* for atari only */ ide_release_lock(&ide_irq_lock);/* for atari only */
} }
# endif # endif
#endif #endif
......
...@@ -64,7 +64,7 @@ static int build_sglist(struct ata_device *drive, struct request *rq) ...@@ -64,7 +64,7 @@ static int build_sglist(struct ata_device *drive, struct request *rq)
struct scatterlist *sg = ch->sg_table; struct scatterlist *sg = ch->sg_table;
int nents = 0; int nents = 0;
if (rq->flags & REQ_SPECIAL) { if ((rq->flags & REQ_SPECIAL) && (drive->type == ATA_DISK)) {
struct ata_taskfile *args = rq->special; struct ata_taskfile *args = rq->special;
#if 1 #if 1
unsigned char *virt_addr = rq->buffer; unsigned char *virt_addr = rq->buffer;
...@@ -388,7 +388,11 @@ int udma_new_table(struct ata_device *drive, struct request *rq) ...@@ -388,7 +388,11 @@ int udma_new_table(struct ata_device *drive, struct request *rq)
return count; return count;
} }
/* Teardown mappings after DMA has completed. */ /*
* Teardown mappings after DMA has completed.
*
* Channel lock should be held.
*/
void udma_destroy_table(struct ata_channel *ch) void udma_destroy_table(struct ata_channel *ch)
{ {
pci_unmap_sg(ch->pci_dev, ch->sg_table, ch->sg_nents, ch->sg_dma_direction); pci_unmap_sg(ch->pci_dev, ch->sg_table, ch->sg_nents, ch->sg_dma_direction);
...@@ -398,8 +402,9 @@ void udma_destroy_table(struct ata_channel *ch) ...@@ -398,8 +402,9 @@ void udma_destroy_table(struct ata_channel *ch)
* Prepare the channel for a DMA startfer. Please note that only the broken * Prepare the channel for a DMA startfer. Please note that only the broken
* Pacific Digital host chip needs the reques to be passed there to decide * Pacific Digital host chip needs the reques to be passed there to decide
* about addressing modes. * about addressing modes.
*
* Channel lock should be held.
*/ */
int udma_pci_start(struct ata_device *drive, struct request *rq) int udma_pci_start(struct ata_device *drive, struct request *rq)
{ {
struct ata_channel *ch = drive->channel; struct ata_channel *ch = drive->channel;
...@@ -414,6 +419,9 @@ int udma_pci_start(struct ata_device *drive, struct request *rq) ...@@ -414,6 +419,9 @@ int udma_pci_start(struct ata_device *drive, struct request *rq)
return 0; return 0;
} }
/*
* Channel lock should be held.
*/
int udma_pci_stop(struct ata_device *drive) int udma_pci_stop(struct ata_device *drive)
{ {
struct ata_channel *ch = drive->channel; struct ata_channel *ch = drive->channel;
...@@ -431,6 +439,8 @@ int udma_pci_stop(struct ata_device *drive) ...@@ -431,6 +439,8 @@ int udma_pci_stop(struct ata_device *drive)
/* /*
* FIXME: This should be attached to a channel as we can see now! * FIXME: This should be attached to a channel as we can see now!
*
* Channel lock should be held.
*/ */
int udma_pci_irq_status(struct ata_device *drive) int udma_pci_irq_status(struct ata_device *drive)
{ {
...@@ -517,6 +527,8 @@ void ata_init_dma(struct ata_channel *ch, unsigned long dma_base) ...@@ -517,6 +527,8 @@ void ata_init_dma(struct ata_channel *ch, unsigned long dma_base)
* *
* It's exported only for host chips which use it for fallback or (too) late * It's exported only for host chips which use it for fallback or (too) late
* capability checking. * capability checking.
*
* Channel lock should be held.
*/ */
int udma_pci_init(struct ata_device *drive, struct request *rq) int udma_pci_init(struct ata_device *drive, struct request *rq)
{ {
...@@ -534,7 +546,7 @@ int udma_pci_init(struct ata_device *drive, struct request *rq) ...@@ -534,7 +546,7 @@ int udma_pci_init(struct ata_device *drive, struct request *rq)
else else
cmd = 0x00; cmd = 0x00;
ide_set_handler(drive, ide_dma_intr, WAIT_CMD, dma_timer_expiry); ata_set_handler(drive, ide_dma_intr, WAIT_CMD, dma_timer_expiry);
if (drive->addressing) if (drive->addressing)
outb(cmd ? WIN_READDMA_EXT : WIN_WRITEDMA_EXT, IDE_COMMAND_REG); outb(cmd ? WIN_READDMA_EXT : WIN_WRITEDMA_EXT, IDE_COMMAND_REG);
else else
......
...@@ -428,7 +428,16 @@ static ide_startstop_t promise_read_intr(struct ata_device *drive, struct reques ...@@ -428,7 +428,16 @@ static ide_startstop_t promise_read_intr(struct ata_device *drive, struct reques
if (drive->status & DRQ_STAT) if (drive->status & DRQ_STAT)
goto read_again; goto read_again;
if (drive->status & BUSY_STAT) { if (drive->status & BUSY_STAT) {
ide_set_handler(drive, promise_read_intr, WAIT_CMD, NULL); unsigned long flags;
struct ata_channel *ch = drive->channel;
/* FIXME: this locking should encompass the above register
* file access too.
*/
spin_lock_irqsave(ch->lock, flags);
ata_set_handler(drive, promise_read_intr, WAIT_CMD, NULL);
spin_unlock_irqrestore(ch->lock, flags);
#ifdef DEBUG_READ #ifdef DEBUG_READ
printk(KERN_DEBUG "%s: promise_read: waiting for" printk(KERN_DEBUG "%s: promise_read: waiting for"
"interrupt\n", drive->name); "interrupt\n", drive->name);
...@@ -456,7 +465,17 @@ static ide_startstop_t promise_complete_pollfunc(struct ata_device *drive, struc ...@@ -456,7 +465,17 @@ static ide_startstop_t promise_complete_pollfunc(struct ata_device *drive, struc
if (!ata_status(drive, 0, BUSY_STAT)) { if (!ata_status(drive, 0, BUSY_STAT)) {
if (time_before(jiffies, ch->poll_timeout)) { if (time_before(jiffies, ch->poll_timeout)) {
ide_set_handler(drive, promise_complete_pollfunc, HZ/100, NULL); unsigned long flags;
struct ata_channel *ch = drive->channel;
/* FIXME: this locking should encompass the above
* register file access too.
*/
spin_lock_irqsave(ch->lock, flags);
ata_set_handler(drive, promise_complete_pollfunc, HZ/100, NULL);
spin_unlock_irqrestore(ch->lock, flags);
return ide_started; /* continue polling... */ return ide_started; /* continue polling... */
} }
ch->poll_timeout = 0; ch->poll_timeout = 0;
...@@ -531,16 +550,22 @@ int promise_multwrite(struct ata_device *drive, struct request *rq, unsigned int ...@@ -531,16 +550,22 @@ int promise_multwrite(struct ata_device *drive, struct request *rq, unsigned int
*/ */
static ide_startstop_t promise_write_pollfunc(struct ata_device *drive, struct request *rq) static ide_startstop_t promise_write_pollfunc(struct ata_device *drive, struct request *rq)
{ {
unsigned long flags;
struct ata_channel *ch = drive->channel; struct ata_channel *ch = drive->channel;
spin_lock_irqsave(ch->lock, flags);
if (inb(IDE_NSECTOR_REG) != 0) { if (inb(IDE_NSECTOR_REG) != 0) {
if (time_before(jiffies, ch->poll_timeout)) { if (time_before(jiffies, ch->poll_timeout)) {
ide_set_handler(drive, promise_write_pollfunc, HZ/100, NULL); ata_set_handler(drive, promise_write_pollfunc, HZ/100, NULL);
spin_unlock_irqrestore(ch->lock, flags);
return ide_started; /* continue polling... */ return ide_started; /* continue polling... */
} }
ch->poll_timeout = 0; ch->poll_timeout = 0;
printk(KERN_ERR "%s: write timed out!\n", drive->name); printk(KERN_ERR "%s: write timed out!\n", drive->name);
ata_status(drive, 0, 0); ata_status(drive, 0, 0);
spin_unlock_irqrestore(ch->lock, flags);
return ata_error(drive, rq, "write timeout"); return ata_error(drive, rq, "write timeout");
} }
...@@ -549,11 +574,12 @@ static ide_startstop_t promise_write_pollfunc(struct ata_device *drive, struct r ...@@ -549,11 +574,12 @@ static ide_startstop_t promise_write_pollfunc(struct ata_device *drive, struct r
*/ */
promise_multwrite(drive, rq, 4); promise_multwrite(drive, rq, 4);
ch->poll_timeout = jiffies + WAIT_WORSTCASE; ch->poll_timeout = jiffies + WAIT_WORSTCASE;
ide_set_handler(drive, promise_complete_pollfunc, HZ/100, NULL); ata_set_handler(drive, promise_complete_pollfunc, HZ/100, NULL);
#ifdef DEBUG_WRITE #ifdef DEBUG_WRITE
printk(KERN_DEBUG "%s: Done last 4 sectors - status = %02x\n", printk(KERN_DEBUG "%s: Done last 4 sectors - status = %02x\n",
drive->name, drive->status); drive->name, drive->status);
#endif #endif
spin_unlock_irqrestore(ch->lock, flags);
return ide_started; return ide_started;
} }
...@@ -566,6 +592,7 @@ static ide_startstop_t promise_write_pollfunc(struct ata_device *drive, struct r ...@@ -566,6 +592,7 @@ static ide_startstop_t promise_write_pollfunc(struct ata_device *drive, struct r
*/ */
static ide_startstop_t promise_do_write(struct ata_device *drive, struct request *rq) static ide_startstop_t promise_do_write(struct ata_device *drive, struct request *rq)
{ {
unsigned long flags;
struct ata_channel *ch = drive->channel; struct ata_channel *ch = drive->channel;
#ifdef DEBUG_WRITE #ifdef DEBUG_WRITE
...@@ -573,26 +600,38 @@ static ide_startstop_t promise_do_write(struct ata_device *drive, struct request ...@@ -573,26 +600,38 @@ static ide_startstop_t promise_do_write(struct ata_device *drive, struct request
"buffer=%p\n", drive->name, rq->sector, "buffer=%p\n", drive->name, rq->sector,
rq->sector + rq->nr_sectors - 1, rq->buffer); rq->sector + rq->nr_sectors - 1, rq->buffer);
#endif #endif
/* FIXME: this locking should encompass the above register
* file access too.
*/
spin_lock_irqsave(ch->lock, flags);
/* /*
* If there are more than 4 sectors to transfer, do n-4 then go into * If there are more than 4 sectors to transfer, do n-4 then go into
* the polling strategy as defined above. * the polling strategy as defined above.
*/ */
if (rq->nr_sectors > 4) { if (rq->nr_sectors > 4) {
if (promise_multwrite(drive, rq, rq->nr_sectors - 4)) if (promise_multwrite(drive, rq, rq->nr_sectors - 4)) {
spin_unlock_irqrestore(ch->lock, flags);
return ide_stopped; return ide_stopped;
}
ch->poll_timeout = jiffies + WAIT_WORSTCASE; ch->poll_timeout = jiffies + WAIT_WORSTCASE;
ide_set_handler(drive, promise_write_pollfunc, HZ/100, NULL); ata_set_handler(drive, promise_write_pollfunc, HZ/100, NULL);
spin_unlock_irqrestore(ch->lock, flags);
return ide_started; return ide_started;
} else { } else {
/* /*
* There are 4 or fewer sectors to transfer, do them all in one go * There are 4 or fewer sectors to transfer, do them all in one go
* and wait for NOT BUSY. * and wait for NOT BUSY.
*/ */
if (promise_multwrite(drive, rq, rq->nr_sectors)) if (promise_multwrite(drive, rq, rq->nr_sectors)) {
spin_unlock_irqrestore(ch->lock, flags);
return ide_stopped; return ide_stopped;
}
ch->poll_timeout = jiffies + WAIT_WORSTCASE; ch->poll_timeout = jiffies + WAIT_WORSTCASE;
ide_set_handler(drive, promise_complete_pollfunc, HZ/100, NULL); ata_set_handler(drive, promise_complete_pollfunc, HZ/100, NULL);
spin_unlock_irqrestore(ch->lock, flags);
#ifdef DEBUG_WRITE #ifdef DEBUG_WRITE
printk(KERN_DEBUG "%s: promise_write: <= 4 sectors, " printk(KERN_DEBUG "%s: promise_write: <= 4 sectors, "
"status = %02x\n", drive->name, drive->status); "status = %02x\n", drive->name, drive->status);
...@@ -629,16 +668,19 @@ ide_startstop_t do_pdc4030_io(struct ata_device *drive, struct ata_taskfile *arg ...@@ -629,16 +668,19 @@ ide_startstop_t do_pdc4030_io(struct ata_device *drive, struct ata_taskfile *arg
switch (rq_data_dir(rq)) { switch (rq_data_dir(rq)) {
case READ: case READ:
/*
* The card's behaviour is odd at this point. If the data is /*
* available, DRQ will be true, and no interrupt will be * The card's behaviour is odd at this point. If the data is
* generated by the card. If this is the case, we need to call the * available, DRQ will be true, and no interrupt will be
* "interrupt" handler (promise_read_intr) directly. Otherwise, if * generated by the card. If this is the case, we need to call
* an interrupt is going to occur, bit0 of the SELECT register will * the "interrupt" handler (promise_read_intr) directly.
* be high, so we can set the handler the just return and be interrupted. * Otherwise, if an interrupt is going to occur, bit0 of the
* If neither of these is the case, we wait for up to 50ms (badly I'm * SELECT register will be high, so we can set the handler the
* afraid!) until one of them is. * just return and be interrupted. If neither of these is the
*/ * case, we wait for up to 50ms (badly I'm afraid!) until one
* of them is.
*/
timeout = jiffies + HZ/20; /* 50ms wait */ timeout = jiffies + HZ/20; /* 50ms wait */
do { do {
if (!ata_status(drive, 0, DRQ_STAT)) { if (!ata_status(drive, 0, DRQ_STAT)) {
...@@ -646,11 +688,21 @@ ide_startstop_t do_pdc4030_io(struct ata_device *drive, struct ata_taskfile *arg ...@@ -646,11 +688,21 @@ ide_startstop_t do_pdc4030_io(struct ata_device *drive, struct ata_taskfile *arg
return promise_read_intr(drive, rq); return promise_read_intr(drive, rq);
} }
if (inb(IDE_SELECT_REG) & 0x01) { if (inb(IDE_SELECT_REG) & 0x01) {
unsigned long flags;
struct ata_channel *ch = drive->channel;
/* FIXME: this locking should encompass the above register
* file access too.
*/
spin_lock_irqsave(ch->lock, flags);
#ifdef DEBUG_READ #ifdef DEBUG_READ
printk(KERN_DEBUG "%s: read: waiting for " printk(KERN_DEBUG "%s: read: waiting for "
"interrupt\n", drive->name); "interrupt\n", drive->name);
#endif #endif
ide_set_handler(drive, promise_read_intr, WAIT_CMD, NULL); ata_set_handler(drive, promise_read_intr, WAIT_CMD, NULL);
spin_unlock_irqrestore(ch->lock, flags);
return ide_started; return ide_started;
} }
udelay(1); udelay(1);
......
...@@ -72,11 +72,6 @@ ...@@ -72,11 +72,6 @@
#define PIIX_CHECK_REV 0x40 /* May be a buggy revision of PIIX */ #define PIIX_CHECK_REV 0x40 /* May be a buggy revision of PIIX */
#define PIIX_NODMA 0x80 /* Don't do DMA with this chip */ #define PIIX_NODMA 0x80 /* Don't do DMA with this chip */
#ifdef CONFIG_BLK_DEV_PIIX_TRY133 /* I think even the older ICHs should be able to do UDMA133 */
#undef PIIX_UDMA_100
#define PIIX_UDMA_100 PIIX_UDMA_133
#endif
/* /*
* Intel IDE chips * Intel IDE chips
*/ */
...@@ -104,7 +99,6 @@ static struct piix_ide_chip { ...@@ -104,7 +99,6 @@ static struct piix_ide_chip {
static struct piix_ide_chip *piix_config; static struct piix_ide_chip *piix_config;
static unsigned char piix_enabled; static unsigned char piix_enabled;
static unsigned int piix_80w;
static char *piix_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" }; static char *piix_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" };
......
...@@ -432,8 +432,8 @@ static unsigned int __init svwks_init_chipset(struct pci_dev *dev) ...@@ -432,8 +432,8 @@ static unsigned int __init svwks_init_chipset(struct pci_dev *dev)
return 0; return 0;
} }
/* On Dell PowerEdge servers with a CSB5, the top two bits of the subsystem /* On Dell PowerEdge servers with a CSB5/CSB6, the top two bits
* device ID indicate presence of an 80-pin cable. * of the subsystem device ID indicate presence of an 80-pin cable.
* Bit 15 clear = secondary IDE channel does not have 80-pin cable. * Bit 15 clear = secondary IDE channel does not have 80-pin cable.
* Bit 15 set = secondary IDE channel has 80-pin cable. * Bit 15 set = secondary IDE channel has 80-pin cable.
* Bit 14 clear = primary IDE channel does not have 80-pin cable. * Bit 14 clear = primary IDE channel does not have 80-pin cable.
...@@ -444,7 +444,8 @@ static unsigned int __init ata66_svwks_dell(struct ata_channel *hwif) ...@@ -444,7 +444,8 @@ static unsigned int __init ata66_svwks_dell(struct ata_channel *hwif)
struct pci_dev *dev = hwif->pci_dev; struct pci_dev *dev = hwif->pci_dev;
if (dev->subsystem_vendor == PCI_VENDOR_ID_DELL && if (dev->subsystem_vendor == PCI_VENDOR_ID_DELL &&
dev->vendor == PCI_VENDOR_ID_SERVERWORKS && dev->vendor == PCI_VENDOR_ID_SERVERWORKS &&
dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE) (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE ||
dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE))
return ((1 << (hwif->unit + 14)) & return ((1 << (hwif->unit + 14)) &
dev->subsystem_device) ? 1 : 0; dev->subsystem_device) ? 1 : 0;
return 0; return 0;
......
...@@ -58,11 +58,18 @@ static ide_startstop_t service(struct ata_device *drive, struct request *rq); ...@@ -58,11 +58,18 @@ static ide_startstop_t service(struct ata_device *drive, struct request *rq);
static ide_startstop_t tcq_nop_handler(struct ata_device *drive, struct request *rq) static ide_startstop_t tcq_nop_handler(struct ata_device *drive, struct request *rq)
{ {
struct ata_taskfile *args = rq->special; struct ata_taskfile *args = rq->special;
unsigned long flags;
ide__sti(); ide__sti();
spin_lock_irqsave(drive->channel->lock, flags);
blkdev_dequeue_request(rq); blkdev_dequeue_request(rq);
drive->rq = NULL; drive->rq = NULL;
end_that_request_last(rq); end_that_request_last(rq);
spin_unlock_irqrestore(drive->channel->lock, flags);
kfree(args); kfree(args);
return ide_stopped; return ide_stopped;
...@@ -218,6 +225,8 @@ static ide_startstop_t udma_tcq_start(struct ata_device *drive, struct request * ...@@ -218,6 +225,8 @@ static ide_startstop_t udma_tcq_start(struct ata_device *drive, struct request *
* and it must have reported a need for service (status has SERVICE_STAT set) * and it must have reported a need for service (status has SERVICE_STAT set)
* *
* Also, nIEN must be set as not to need protection against ide_dmaq_intr * Also, nIEN must be set as not to need protection against ide_dmaq_intr
*
* Channel lock should be held.
*/ */
static ide_startstop_t service(struct ata_device *drive, struct request *rq) static ide_startstop_t service(struct ata_device *drive, struct request *rq)
{ {
...@@ -503,6 +512,8 @@ static int tcq_wait_dataphase(struct ata_device *drive) ...@@ -503,6 +512,8 @@ static int tcq_wait_dataphase(struct ata_device *drive)
/* /*
* Invoked from a SERVICE interrupt, command etc already known. Just need to * Invoked from a SERVICE interrupt, command etc already known. Just need to
* start the dma engine for this tag. * start the dma engine for this tag.
*
* Channel lock should be held.
*/ */
static ide_startstop_t udma_tcq_start(struct ata_device *drive, struct request *rq) static ide_startstop_t udma_tcq_start(struct ata_device *drive, struct request *rq)
{ {
...@@ -527,6 +538,8 @@ static ide_startstop_t udma_tcq_start(struct ata_device *drive, struct request * ...@@ -527,6 +538,8 @@ static ide_startstop_t udma_tcq_start(struct ata_device *drive, struct request *
/* /*
* Start a queued command from scratch. * Start a queued command from scratch.
*
* Channel lock should be held.
*/ */
ide_startstop_t udma_tcq_taskfile(struct ata_device *drive, struct request *rq) ide_startstop_t udma_tcq_taskfile(struct ata_device *drive, struct request *rq)
{ {
......
...@@ -223,15 +223,15 @@ static int trm290_udma_init(struct ata_device *drive, struct request *rq) ...@@ -223,15 +223,15 @@ static int trm290_udma_init(struct ata_device *drive, struct request *rq)
} }
trm290_prepare_drive(drive, 1); /* select DMA xfer */ trm290_prepare_drive(drive, 1); /* select DMA xfer */
outl(ch->dmatable_dma|reading|writing, ch->dma_base); outl(ch->dmatable_dma|reading|writing, ch->dma_base);
drive->waiting_for_dma = 1; drive->waiting_for_dma = 1;
outw((count * 2) - 1, ch->dma_base+2); /* start DMA */ outw((count * 2) - 1, ch->dma_base+2); /* start DMA */
if (drive->type != ATA_DISK) if (drive->type == ATA_DISK) {
return 0; ata_set_handler(drive, ide_dma_intr, WAIT_CMD, NULL);
outb(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
ide_set_handler(drive, ide_dma_intr, WAIT_CMD, NULL); }
OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
return 0; return 0;
} }
......
...@@ -243,7 +243,7 @@ static int idescsi_end_request(struct ata_device *drive, struct request *rq, int ...@@ -243,7 +243,7 @@ static int idescsi_end_request(struct ata_device *drive, struct request *rq, int
u8 *scsi_buf; u8 *scsi_buf;
unsigned long flags; unsigned long flags;
if (!(rq->flags & REQ_SPECIAL)) { if (!(rq->flags & REQ_PC)) {
ide_end_request(drive, rq, uptodate); ide_end_request(drive, rq, uptodate);
return 0; return 0;
} }
...@@ -293,6 +293,8 @@ static inline unsigned long get_timeout(struct atapi_packet_command *pc) ...@@ -293,6 +293,8 @@ 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)
{ {
unsigned long flags;
struct ata_channel *ch = drive->channel;
struct Scsi_Host *host = drive->driver_data; struct Scsi_Host *host = drive->driver_data;
idescsi_scsi_t *scsi = idescsi_private(host); idescsi_scsi_t *scsi = idescsi_private(host);
u8 ireason; u8 ireason;
...@@ -333,6 +335,8 @@ static ide_startstop_t idescsi_pc_intr(struct ata_device *drive, struct request ...@@ -333,6 +335,8 @@ static ide_startstop_t idescsi_pc_intr(struct ata_device *drive, struct request
temp = pc->actually_transferred + bcount; temp = pc->actually_transferred + bcount;
if ( temp > pc->request_transfer) { if ( temp > pc->request_transfer) {
if (temp > pc->buffer_size) { if (temp > pc->buffer_size) {
unsigned long flags;
struct ata_channel *ch = drive->channel;
printk (KERN_ERR "ide-scsi: The scsi wants to send us more data than expected - discarding data\n"); printk (KERN_ERR "ide-scsi: The scsi wants to send us more data than expected - discarding data\n");
temp = pc->buffer_size - pc->actually_transferred; temp = pc->buffer_size - pc->actually_transferred;
if (temp) { if (temp) {
...@@ -346,7 +350,14 @@ static ide_startstop_t idescsi_pc_intr(struct ata_device *drive, struct request ...@@ -346,7 +350,14 @@ static ide_startstop_t idescsi_pc_intr(struct ata_device *drive, struct request
pc->actually_transferred += temp; pc->actually_transferred += temp;
pc->current_position += temp; pc->current_position += temp;
atapi_discard_data(drive,bcount - temp); atapi_discard_data(drive,bcount - temp);
ide_set_handler(drive, idescsi_pc_intr, get_timeout(pc), NULL); /* FIXME: this locking should encompass the above register
* file access too.
*/
spin_lock_irqsave(ch->lock, flags);
ata_set_handler(drive, idescsi_pc_intr, get_timeout(pc), NULL);
spin_unlock_irqrestore(ch->lock, flags);
return ide_started; return ide_started;
} }
#ifdef DEBUG #ifdef DEBUG
...@@ -370,12 +381,21 @@ static ide_startstop_t idescsi_pc_intr(struct ata_device *drive, struct request ...@@ -370,12 +381,21 @@ static ide_startstop_t idescsi_pc_intr(struct ata_device *drive, struct request
pc->actually_transferred+=bcount; /* Update the current position */ pc->actually_transferred+=bcount; /* Update the current position */
pc->current_position+=bcount; pc->current_position+=bcount;
ide_set_handler(drive, idescsi_pc_intr, get_timeout(pc), NULL); /* And set the interrupt handler again */ /* FIXME: this locking should encompass the above register
* file access too.
*/
spin_lock_irqsave(ch->lock, flags);
ata_set_handler(drive, idescsi_pc_intr, get_timeout(pc), NULL); /* And set the interrupt handler again */
spin_unlock_irqrestore(ch->lock, flags);
return ide_started; return ide_started;
} }
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)
{ {
unsigned long flags;
struct ata_channel *ch = drive->channel;
struct Scsi_Host *host = drive->driver_data; struct Scsi_Host *host = drive->driver_data;
idescsi_scsi_t *scsi = idescsi_private(host); idescsi_scsi_t *scsi = idescsi_private(host);
struct atapi_packet_command *pc = scsi->pc; struct atapi_packet_command *pc = scsi->pc;
...@@ -391,7 +411,15 @@ static ide_startstop_t idescsi_transfer_pc(struct ata_device *drive, struct requ ...@@ -391,7 +411,15 @@ static ide_startstop_t idescsi_transfer_pc(struct ata_device *drive, struct requ
printk (KERN_ERR "ide-scsi: (IO,CoD) != (0,1) while issuing a packet command\n"); printk (KERN_ERR "ide-scsi: (IO,CoD) != (0,1) while issuing a packet command\n");
return ide_stopped; return ide_stopped;
} }
ide_set_handler(drive, idescsi_pc_intr, get_timeout(pc), NULL); /* Set the interrupt routine */
/* FIXME: this locking should encompass the above register
* file access too.
*/
spin_lock_irqsave(ch->lock, flags);
ata_set_handler(drive, idescsi_pc_intr, get_timeout(pc), NULL); /* Set the interrupt routine */
spin_unlock_irqrestore(ch->lock, flags);
atapi_write(drive, scsi->pc->c, 12); /* Send the actual packet */ atapi_write(drive, scsi->pc->c, 12); /* Send the actual packet */
return ide_started; return ide_started;
} }
...@@ -425,8 +453,18 @@ static ide_startstop_t idescsi_issue_pc(struct ata_device *drive, struct request ...@@ -425,8 +453,18 @@ static ide_startstop_t idescsi_issue_pc(struct ata_device *drive, struct request
set_bit(PC_DMA_IN_PROGRESS, &pc->flags); set_bit(PC_DMA_IN_PROGRESS, &pc->flags);
udma_start(drive, rq); udma_start(drive, rq);
} }
if (test_bit (IDESCSI_DRQ_INTERRUPT, &scsi->flags)) { if (test_bit(IDESCSI_DRQ_INTERRUPT, &scsi->flags)) {
ide_set_handler(drive, idescsi_transfer_pc, get_timeout(pc), NULL); unsigned long flags;
struct ata_channel *ch = drive->channel;
/* FIXME: this locking should encompass the above register
* file access too.
*/
spin_lock_irqsave(ch->lock, flags);
ata_set_handler(drive, idescsi_transfer_pc, get_timeout(pc), NULL);
spin_unlock_irqrestore(ch->lock, flags);
OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* Issue the packet command */ OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* Issue the packet command */
return ide_started; return ide_started;
} else { } else {
...@@ -452,7 +490,7 @@ static ide_startstop_t idescsi_do_request(struct ata_device *drive, struct reque ...@@ -452,7 +490,7 @@ static ide_startstop_t idescsi_do_request(struct ata_device *drive, struct reque
rq->current_nr_sectors); rq->current_nr_sectors);
#endif #endif
if (rq->flags & REQ_SPECIAL) { if (rq->flags & REQ_PC) {
return idescsi_issue_pc(drive, rq, (struct atapi_packet_command *) rq->special); return idescsi_issue_pc(drive, rq, (struct atapi_packet_command *) rq->special);
} }
blk_dump_rq_flags(rq, "ide-scsi: unsup command"); blk_dump_rq_flags(rq, "ide-scsi: unsup command");
...@@ -667,7 +705,7 @@ static int idescsi_queue(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) ...@@ -667,7 +705,7 @@ static int idescsi_queue(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
} }
memset(rq, 0, sizeof(*rq)); memset(rq, 0, sizeof(*rq));
rq->flags = REQ_SPECIAL; rq->flags = REQ_PC;
rq->special = (char *) pc; rq->special = (char *) pc;
rq->bio = idescsi_dma_bio (drive, pc); rq->bio = idescsi_dma_bio (drive, pc);
spin_unlock_irq(cmd->host->host_lock); spin_unlock_irq(cmd->host->host_lock);
......
...@@ -254,8 +254,6 @@ ...@@ -254,8 +254,6 @@
* undef : traditional save_flags; cli; restore_flags; * undef : traditional save_flags; cli; restore_flags;
*/ */
//#define DEBUG_SPINLOCKS 2 /* Set to 0, 1 or 2 in include/linux/spinlock.h */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,30) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,30)
# include <linux/init.h> # include <linux/init.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,30) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,30)
...@@ -293,7 +291,7 @@ MODULE_DEVICE_TABLE(pci, tmscsim_pci_tbl); ...@@ -293,7 +291,7 @@ MODULE_DEVICE_TABLE(pci, tmscsim_pci_tbl);
# if USE_SPINLOCKS == 3 /* both */ # if USE_SPINLOCKS == 3 /* both */
# if defined (CONFIG_SMP) || DEBUG_SPINLOCKS > 0 # if defined (CONFIG_SMP)
# define DC390_LOCKA_INIT { spinlock_t __unlocked = SPIN_LOCK_UNLOCKED; pACB->lock = __unlocked; }; # define DC390_LOCKA_INIT { spinlock_t __unlocked = SPIN_LOCK_UNLOCKED; pACB->lock = __unlocked; };
# else # else
# define DC390_LOCKA_INIT # define DC390_LOCKA_INIT
...@@ -322,7 +320,7 @@ MODULE_DEVICE_TABLE(pci, tmscsim_pci_tbl); ...@@ -322,7 +320,7 @@ MODULE_DEVICE_TABLE(pci, tmscsim_pci_tbl);
# if USE_SPINLOCKS == 2 /* adapter specific locks */ # if USE_SPINLOCKS == 2 /* adapter specific locks */
# if defined (CONFIG_SMP) || DEBUG_SPINLOCKS > 0 # if defined (CONFIG_SMP)
# define DC390_LOCKA_INIT { spinlock_t __unlocked = SPIN_LOCK_UNLOCKED; pACB->lock = __unlocked; }; # define DC390_LOCKA_INIT { spinlock_t __unlocked = SPIN_LOCK_UNLOCKED; pACB->lock = __unlocked; };
# else # else
# define DC390_LOCKA_INIT # define DC390_LOCKA_INIT
......
/*
* SMP locks primitives for building ix86 locks
* (not yet used).
*
* Alan Cox, alan@cymru.net, 1995
*/
/*
* This would be much easier but far less clear and easy
* to borrow for other processors if it was just assembler.
*/
extern __inline__ void prim_spin_lock(struct spinlock *sp)
{
int processor=smp_processor_id();
/*
* Grab the lock bit
*/
while(lock_set_bit(0,&sp->lock))
{
/*
* Failed, but that's cos we own it!
*/
if(sp->cpu==processor)
{
sp->users++;
return 0;
}
/*
* Spin in the cache S state if possible
*/
while(sp->lock)
{
/*
* Wait for any invalidates to go off
*/
if(smp_invalidate_needed&(1<<processor))
while(lock_clear_bit(processor,&smp_invalidate_needed))
local_flush_tlb();
sp->spins++;
}
/*
* Someone wrote the line, we go 'I' and get
* the cache entry. Now try to regrab
*/
}
sp->users++;sp->cpu=processor;
return 1;
}
/*
* Release a spin lock
*/
extern __inline__ int prim_spin_unlock(struct spinlock *sp)
{
/* This is safe. The decrement is still guarded by the lock. A multilock would
not be safe this way */
if(!--sp->users)
{
lock_clear_bit(0,&sp->lock);sp->cpu= NO_PROC_ID;
return 1;
}
return 0;
}
/*
* Non blocking lock grab
*/
extern __inline__ int prim_spin_lock_nb(struct spinlock *sp)
{
if(lock_set_bit(0,&sp->lock))
return 0; /* Locked already */
sp->users++;
return 1; /* We got the lock */
}
/*
* These wrap the locking primitives up for usage
*/
extern __inline__ void spinlock(struct spinlock *sp)
{
if(sp->priority<current->lock_order)
panic("lock order violation: %s (%d)\n", sp->name, current->lock_order);
if(prim_spin_lock(sp))
{
/*
* We got a new lock. Update the priority chain
*/
sp->oldpri=current->lock_order;
current->lock_order=sp->priority;
}
}
extern __inline__ void spinunlock(struct spinlock *sp)
{
if(current->lock_order!=sp->priority)
panic("lock release order violation %s (%d)\n", sp->name, current->lock_order);
if(prim_spin_unlock(sp))
{
/*
* Update the debugging lock priority chain. We dumped
* our last right to the lock.
*/
current->lock_order=sp->oldpri;
}
}
extern __inline__ void spintestlock(struct spinlock *sp)
{
/*
* We do no sanity checks, it's legal to optimistically
* get a lower lock.
*/
prim_spin_lock_nb(sp);
}
extern __inline__ void spintestunlock(struct spinlock *sp)
{
/*
* A testlock doesn't update the lock chain so we
* must not update it on free
*/
prim_spin_unlock(sp);
}
/*
* SMP locks primitives for building ix86 locks
* (not yet used).
*
* Alan Cox, alan@redhat.com, 1995
*/
/*
* This would be much easier but far less clear and easy
* to borrow for other processors if it was just assembler.
*/
static __inline__ void prim_spin_lock(struct spinlock *sp)
{
int processor=smp_processor_id();
/*
* Grab the lock bit
*/
while(lock_set_bit(0,&sp->lock))
{
/*
* Failed, but that's cos we own it!
*/
if(sp->cpu==processor)
{
sp->users++;
return 0;
}
/*
* Spin in the cache S state if possible
*/
while(sp->lock)
{
/*
* Wait for any invalidates to go off
*/
if(smp_invalidate_needed&(1<<processor))
while(lock_clear_bit(processor,&smp_invalidate_needed))
local_flush_tlb();
sp->spins++;
}
/*
* Someone wrote the line, we go 'I' and get
* the cache entry. Now try to regrab
*/
}
sp->users++;sp->cpu=processor;
return 1;
}
/*
* Release a spin lock
*/
static __inline__ int prim_spin_unlock(struct spinlock *sp)
{
/* This is safe. The decrement is still guarded by the lock. A multilock would
not be safe this way */
if(!--sp->users)
{
sp->cpu= NO_PROC_ID;lock_clear_bit(0,&sp->lock);
return 1;
}
return 0;
}
/*
* Non blocking lock grab
*/
static __inline__ int prim_spin_lock_nb(struct spinlock *sp)
{
if(lock_set_bit(0,&sp->lock))
return 0; /* Locked already */
sp->users++;
return 1; /* We got the lock */
}
/*
* These wrap the locking primitives up for usage
*/
static __inline__ void spinlock(struct spinlock *sp)
{
if(sp->priority<current->lock_order)
panic("lock order violation: %s (%d)\n", sp->name, current->lock_order);
if(prim_spin_lock(sp))
{
/*
* We got a new lock. Update the priority chain
*/
sp->oldpri=current->lock_order;
current->lock_order=sp->priority;
}
}
static __inline__ void spinunlock(struct spinlock *sp)
{
int pri;
if(current->lock_order!=sp->priority)
panic("lock release order violation %s (%d)\n", sp->name, current->lock_order);
pri=sp->oldpri;
if(prim_spin_unlock(sp))
{
/*
* Update the debugging lock priority chain. We dumped
* our last right to the lock.
*/
current->lock_order=sp->pri;
}
}
static __inline__ void spintestlock(struct spinlock *sp)
{
/*
* We do no sanity checks, it's legal to optimistically
* get a lower lock.
*/
prim_spin_lock_nb(sp);
}
static __inline__ void spintestunlock(struct spinlock *sp)
{
/*
* A testlock doesn't update the lock chain so we
* must not update it on free
*/
prim_spin_unlock(sp);
}
...@@ -9,30 +9,20 @@ ...@@ -9,30 +9,20 @@
extern int printk(const char * fmt, ...) extern int printk(const char * fmt, ...)
__attribute__ ((format (printf, 1, 2))); __attribute__ ((format (printf, 1, 2)));
/* It seems that people are forgetting to
* initialize their spinlocks properly, tsk tsk.
* Remember to turn this off in 2.4. -ben
*/
#if defined(CONFIG_DEBUG_SPINLOCK)
#define SPINLOCK_DEBUG 1
#else
#define SPINLOCK_DEBUG 0
#endif
/* /*
* Your basic SMP spinlocks, allowing only a single CPU anywhere * Your basic SMP spinlocks, allowing only a single CPU anywhere
*/ */
typedef struct { typedef struct {
volatile unsigned int lock; volatile unsigned int lock;
#if SPINLOCK_DEBUG #ifdef CONFIG_DEBUG_SPINLOCK
unsigned magic; unsigned magic;
#endif #endif
} spinlock_t; } spinlock_t;
#define SPINLOCK_MAGIC 0xdead4ead #define SPINLOCK_MAGIC 0xdead4ead
#if SPINLOCK_DEBUG #ifdef CONFIG_DEBUG_SPINLOCK
#define SPINLOCK_MAGIC_INIT , SPINLOCK_MAGIC #define SPINLOCK_MAGIC_INIT , SPINLOCK_MAGIC
#else #else
#define SPINLOCK_MAGIC_INIT /* */ #define SPINLOCK_MAGIC_INIT /* */
...@@ -79,7 +69,7 @@ typedef struct { ...@@ -79,7 +69,7 @@ typedef struct {
static inline void _raw_spin_unlock(spinlock_t *lock) static inline void _raw_spin_unlock(spinlock_t *lock)
{ {
#if SPINLOCK_DEBUG #ifdef CONFIG_DEBUG_SPINLOCK
if (lock->magic != SPINLOCK_MAGIC) if (lock->magic != SPINLOCK_MAGIC)
BUG(); BUG();
if (!spin_is_locked(lock)) if (!spin_is_locked(lock))
...@@ -100,7 +90,7 @@ static inline void _raw_spin_unlock(spinlock_t *lock) ...@@ -100,7 +90,7 @@ static inline void _raw_spin_unlock(spinlock_t *lock)
static inline void _raw_spin_unlock(spinlock_t *lock) static inline void _raw_spin_unlock(spinlock_t *lock)
{ {
char oldval = 1; char oldval = 1;
#if SPINLOCK_DEBUG #ifdef CONFIG_DEBUG_SPINLOCK
if (lock->magic != SPINLOCK_MAGIC) if (lock->magic != SPINLOCK_MAGIC)
BUG(); BUG();
if (!spin_is_locked(lock)) if (!spin_is_locked(lock))
...@@ -125,7 +115,7 @@ static inline int _raw_spin_trylock(spinlock_t *lock) ...@@ -125,7 +115,7 @@ static inline int _raw_spin_trylock(spinlock_t *lock)
static inline void _raw_spin_lock(spinlock_t *lock) static inline void _raw_spin_lock(spinlock_t *lock)
{ {
#if SPINLOCK_DEBUG #ifdef CONFIG_DEBUG_SPINLOCK
__label__ here; __label__ here;
here: here:
if (lock->magic != SPINLOCK_MAGIC) { if (lock->magic != SPINLOCK_MAGIC) {
...@@ -151,14 +141,14 @@ printk("eip: %p\n", &&here); ...@@ -151,14 +141,14 @@ printk("eip: %p\n", &&here);
*/ */
typedef struct { typedef struct {
volatile unsigned int lock; volatile unsigned int lock;
#if SPINLOCK_DEBUG #ifdef CONFIG_DEBUG_SPINLOCK
unsigned magic; unsigned magic;
#endif #endif
} rwlock_t; } rwlock_t;
#define RWLOCK_MAGIC 0xdeaf1eed #define RWLOCK_MAGIC 0xdeaf1eed
#if SPINLOCK_DEBUG #ifdef CONFIG_DEBUG_SPINLOCK
#define RWLOCK_MAGIC_INIT , RWLOCK_MAGIC #define RWLOCK_MAGIC_INIT , RWLOCK_MAGIC
#else #else
#define RWLOCK_MAGIC_INIT /* */ #define RWLOCK_MAGIC_INIT /* */
...@@ -181,7 +171,7 @@ typedef struct { ...@@ -181,7 +171,7 @@ typedef struct {
static inline void _raw_read_lock(rwlock_t *rw) static inline void _raw_read_lock(rwlock_t *rw)
{ {
#if SPINLOCK_DEBUG #ifdef CONFIG_DEBUG_SPINLOCK
if (rw->magic != RWLOCK_MAGIC) if (rw->magic != RWLOCK_MAGIC)
BUG(); BUG();
#endif #endif
...@@ -190,7 +180,7 @@ static inline void _raw_read_lock(rwlock_t *rw) ...@@ -190,7 +180,7 @@ static inline void _raw_read_lock(rwlock_t *rw)
static inline void _raw_write_lock(rwlock_t *rw) static inline void _raw_write_lock(rwlock_t *rw)
{ {
#if SPINLOCK_DEBUG #ifdef CONFIG_DEBUG_SPINLOCK
if (rw->magic != RWLOCK_MAGIC) if (rw->magic != RWLOCK_MAGIC)
BUG(); BUG();
#endif #endif
......
...@@ -7,22 +7,20 @@ ...@@ -7,22 +7,20 @@
#include <asm/system.h> #include <asm/system.h>
#include <asm/processor.h> #include <asm/processor.h>
#undef SPINLOCK_DEBUG
/* /*
* Simple spin lock operations. * Simple spin lock operations.
*/ */
typedef struct { typedef struct {
volatile unsigned long lock; volatile unsigned long lock;
#ifdef SPINLOCK_DEBUG #ifdef CONFIG_DEBUG_SPINLOCK
volatile unsigned long owner_pc; volatile unsigned long owner_pc;
volatile unsigned long owner_cpu; volatile unsigned long owner_cpu;
#endif #endif
} spinlock_t; } spinlock_t;
#ifdef __KERNEL__ #ifdef __KERNEL__
#if SPINLOCK_DEBUG #if CONFIG_DEBUG_SPINLOCK
#define SPINLOCK_DEBUG_INIT , 0, 0 #define SPINLOCK_DEBUG_INIT , 0, 0
#else #else
#define SPINLOCK_DEBUG_INIT /* */ #define SPINLOCK_DEBUG_INIT /* */
...@@ -34,7 +32,7 @@ typedef struct { ...@@ -34,7 +32,7 @@ typedef struct {
#define spin_is_locked(x) ((x)->lock != 0) #define spin_is_locked(x) ((x)->lock != 0)
#define spin_unlock_wait(x) do { barrier(); } while(spin_is_locked(x)) #define spin_unlock_wait(x) do { barrier(); } while(spin_is_locked(x))
#ifndef SPINLOCK_DEBUG #ifndef CONFIG_DEBUG_SPINLOCK
static inline void _raw_spin_lock(spinlock_t *lock) static inline void _raw_spin_lock(spinlock_t *lock)
{ {
...@@ -88,12 +86,12 @@ extern unsigned long __spin_trylock(volatile unsigned long *lock); ...@@ -88,12 +86,12 @@ extern unsigned long __spin_trylock(volatile unsigned long *lock);
*/ */
typedef struct { typedef struct {
volatile unsigned long lock; volatile unsigned long lock;
#ifdef SPINLOCK_DEBUG #ifdef CONFIG_DEBUG_SPINLOCK
volatile unsigned long owner_pc; volatile unsigned long owner_pc;
#endif #endif
} rwlock_t; } rwlock_t;
#if SPINLOCK_DEBUG #if CONFIG_DEBUG_SPINLOCK
#define RWLOCK_DEBUG_INIT , 0 #define RWLOCK_DEBUG_INIT , 0
#else #else
#define RWLOCK_DEBUG_INIT /* */ #define RWLOCK_DEBUG_INIT /* */
...@@ -102,7 +100,7 @@ typedef struct { ...@@ -102,7 +100,7 @@ typedef struct {
#define RW_LOCK_UNLOCKED (rwlock_t) { 0 RWLOCK_DEBUG_INIT } #define RW_LOCK_UNLOCKED (rwlock_t) { 0 RWLOCK_DEBUG_INIT }
#define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while(0) #define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while(0)
#ifndef SPINLOCK_DEBUG #ifndef CONFIG_DEBUG_SPINLOCK
static __inline__ void _raw_read_lock(rwlock_t *rw) static __inline__ void _raw_read_lock(rwlock_t *rw)
{ {
......
/*
* SMP locks primitives for building ix86 locks
* (not yet used).
*
* Alan Cox, alan@redhat.com, 1995
*/
/*
* This would be much easier but far less clear and easy
* to borrow for other processors if it was just assembler.
*/
extern __inline__ void prim_spin_lock(struct spinlock *sp)
{
int processor=smp_processor_id();
/*
* Grab the lock bit
*/
while(lock_set_bit(0,&sp->lock))
{
/*
* Failed, but that's cos we own it!
*/
if(sp->cpu==processor)
{
sp->users++;
return 0;
}
/*
* Spin in the cache S state if possible
*/
while(sp->lock)
{
/*
* Wait for any invalidates to go off
*/
if(smp_invalidate_needed&(1<<processor))
while(lock_clear_bit(processor,&smp_invalidate_needed))
local_flush_tlb();
sp->spins++;
}
/*
* Someone wrote the line, we go 'I' and get
* the cache entry. Now try to regrab
*/
}
sp->users++;sp->cpu=processor;
return 1;
}
/*
* Release a spin lock
*/
extern __inline__ int prim_spin_unlock(struct spinlock *sp)
{
/* This is safe. The decrement is still guarded by the lock. A multilock would
not be safe this way */
if(!--sp->users)
{
sp->cpu= NO_PROC_ID;lock_clear_bit(0,&sp->lock);
return 1;
}
return 0;
}
/*
* Non blocking lock grab
*/
extern __inline__ int prim_spin_lock_nb(struct spinlock *sp)
{
if(lock_set_bit(0,&sp->lock))
return 0; /* Locked already */
sp->users++;
return 1; /* We got the lock */
}
/*
* These wrap the locking primitives up for usage
*/
extern __inline__ void spinlock(struct spinlock *sp)
{
if(sp->priority<current->lock_order)
panic("lock order violation: %s (%d)\n", sp->name, current->lock_order);
if(prim_spin_lock(sp))
{
/*
* We got a new lock. Update the priority chain
*/
sp->oldpri=current->lock_order;
current->lock_order=sp->priority;
}
}
extern __inline__ void spinunlock(struct spinlock *sp)
{
int pri;
if(current->lock_order!=sp->priority)
panic("lock release order violation %s (%d)\n", sp->name, current->lock_order);
pri=sp->oldpri;
if(prim_spin_unlock(sp))
{
/*
* Update the debugging lock priority chain. We dumped
* our last right to the lock.
*/
current->lock_order=sp->pri;
}
}
extern __inline__ void spintestlock(struct spinlock *sp)
{
/*
* We do no sanity checks, it's legal to optimistically
* get a lower lock.
*/
prim_spin_lock_nb(sp);
}
extern __inline__ void spintestunlock(struct spinlock *sp)
{
/*
* A testlock doesn't update the lock chain so we
* must not update it on free
*/
prim_spin_unlock(sp);
}
...@@ -9,30 +9,20 @@ ...@@ -9,30 +9,20 @@
extern int printk(const char * fmt, ...) extern int printk(const char * fmt, ...)
__attribute__ ((format (printf, 1, 2))); __attribute__ ((format (printf, 1, 2)));
/* It seems that people are forgetting to
* initialize their spinlocks properly, tsk tsk.
* Remember to turn this off in 2.4. -ben
*/
#if defined(CONFIG_DEBUG_SPINLOCK)
#define SPINLOCK_DEBUG 1
#else
#define SPINLOCK_DEBUG 0
#endif
/* /*
* Your basic SMP spinlocks, allowing only a single CPU anywhere * Your basic SMP spinlocks, allowing only a single CPU anywhere
*/ */
typedef struct { typedef struct {
volatile unsigned int lock; volatile unsigned int lock;
#if SPINLOCK_DEBUG #ifdef CONFIG_DEBUG_SPINLOCK
unsigned magic; unsigned magic;
#endif #endif
} spinlock_t; } spinlock_t;
#define SPINLOCK_MAGIC 0xdead4ead #define SPINLOCK_MAGIC 0xdead4ead
#if SPINLOCK_DEBUG #ifdef CONFIG_DEBUG_SPINLOCK
#define SPINLOCK_MAGIC_INIT , SPINLOCK_MAGIC #define SPINLOCK_MAGIC_INIT , SPINLOCK_MAGIC
#else #else
#define SPINLOCK_MAGIC_INIT /* */ #define SPINLOCK_MAGIC_INIT /* */
...@@ -82,7 +72,7 @@ static inline int _raw_spin_trylock(spinlock_t *lock) ...@@ -82,7 +72,7 @@ static inline int _raw_spin_trylock(spinlock_t *lock)
static inline void _raw_spin_lock(spinlock_t *lock) static inline void _raw_spin_lock(spinlock_t *lock)
{ {
#if SPINLOCK_DEBUG #ifdef CONFIG_DEBUG_SPINLOCK
__label__ here; __label__ here;
here: here:
if (lock->magic != SPINLOCK_MAGIC) { if (lock->magic != SPINLOCK_MAGIC) {
...@@ -97,7 +87,7 @@ printk("eip: %p\n", &&here); ...@@ -97,7 +87,7 @@ printk("eip: %p\n", &&here);
static inline void _raw_spin_unlock(spinlock_t *lock) static inline void _raw_spin_unlock(spinlock_t *lock)
{ {
#if SPINLOCK_DEBUG #ifdef CONFIG_DEBUG_SPINLOCK
if (lock->magic != SPINLOCK_MAGIC) if (lock->magic != SPINLOCK_MAGIC)
BUG(); BUG();
if (!spin_is_locked(lock)) if (!spin_is_locked(lock))
...@@ -120,14 +110,14 @@ static inline void _raw_spin_unlock(spinlock_t *lock) ...@@ -120,14 +110,14 @@ static inline void _raw_spin_unlock(spinlock_t *lock)
*/ */
typedef struct { typedef struct {
volatile unsigned int lock; volatile unsigned int lock;
#if SPINLOCK_DEBUG #ifdef CONFIG_DEBUG_SPINLOCK
unsigned magic; unsigned magic;
#endif #endif
} rwlock_t; } rwlock_t;
#define RWLOCK_MAGIC 0xdeaf1eed #define RWLOCK_MAGIC 0xdeaf1eed
#if SPINLOCK_DEBUG #ifdef CONFIG_DEBUG_SPINLOCK
#define RWLOCK_MAGIC_INIT , RWLOCK_MAGIC #define RWLOCK_MAGIC_INIT , RWLOCK_MAGIC
#else #else
#define RWLOCK_MAGIC_INIT /* */ #define RWLOCK_MAGIC_INIT /* */
...@@ -150,7 +140,7 @@ typedef struct { ...@@ -150,7 +140,7 @@ typedef struct {
extern inline void _raw_read_lock(rwlock_t *rw) extern inline void _raw_read_lock(rwlock_t *rw)
{ {
#if SPINLOCK_DEBUG #ifdef CONFIG_DEBUG_SPINLOCK
if (rw->magic != RWLOCK_MAGIC) if (rw->magic != RWLOCK_MAGIC)
BUG(); BUG();
#endif #endif
...@@ -159,7 +149,7 @@ extern inline void _raw_read_lock(rwlock_t *rw) ...@@ -159,7 +149,7 @@ extern inline void _raw_read_lock(rwlock_t *rw)
static inline void _raw_write_lock(rwlock_t *rw) static inline void _raw_write_lock(rwlock_t *rw)
{ {
#if SPINLOCK_DEBUG #ifdef CONFIG_DEBUG_SPINLOCK
if (rw->magic != RWLOCK_MAGIC) if (rw->magic != RWLOCK_MAGIC)
BUG(); BUG();
#endif #endif
......
...@@ -275,12 +275,8 @@ enum { ...@@ -275,12 +275,8 @@ enum {
#define ATM_ATMOPT_CLP 1 /* set CLP bit */ #define ATM_ATMOPT_CLP 1 /* set CLP bit */
typedef struct { unsigned long bits; } atm_vcc_flags_t;
struct atm_vcc { struct atm_vcc {
atm_vcc_flags_t flags; /* VCC flags (ATM_VF_*) */ unsigned long flags; /* VCC flags (ATM_VF_*) */
unsigned char family; /* address family; 0 if unused */ unsigned char family; /* address family; 0 if unused */
short vpi; /* VPI and VCI (types must be equal */ short vpi; /* VPI and VCI (types must be equal */
/* with sockaddr) */ /* with sockaddr) */
...@@ -330,10 +326,6 @@ struct atm_dev_addr { ...@@ -330,10 +326,6 @@ struct atm_dev_addr {
struct atm_dev_addr *next; /* next address */ struct atm_dev_addr *next; /* next address */
}; };
typedef struct { unsigned int bits; } atm_dev_flags_t;
struct atm_dev { struct atm_dev {
const struct atmdev_ops *ops; /* device operations; NULL if unused */ const struct atmdev_ops *ops; /* device operations; NULL if unused */
const struct atmphy_ops *phy; /* PHY operations, may be undefined */ const struct atmphy_ops *phy; /* PHY operations, may be undefined */
...@@ -344,7 +336,7 @@ struct atm_dev { ...@@ -344,7 +336,7 @@ struct atm_dev {
struct atm_vcc *last; /* last VCC (or undefined) */ struct atm_vcc *last; /* last VCC (or undefined) */
void *dev_data; /* per-device data */ void *dev_data; /* per-device data */
void *phy_data; /* private PHY date */ void *phy_data; /* private PHY date */
atm_dev_flags_t flags; /* device flags (ATM_DF_*) */ unsigned long flags; /* device flags (ATM_DF_*) */
struct atm_dev_addr *local; /* local ATM addresses */ struct atm_dev_addr *local; /* local ATM addresses */
unsigned char esi[ESI_LEN]; /* ESI ("MAC" addr) */ unsigned char esi[ESI_LEN]; /* ESI ("MAC" addr) */
struct atm_cirange ci_range; /* VPI/VCI range */ struct atm_cirange ci_range; /* VPI/VCI range */
...@@ -414,7 +406,7 @@ struct atm_skb_data { ...@@ -414,7 +406,7 @@ struct atm_skb_data {
#define ATM_SKB(skb) (((struct atm_skb_data *) (skb)->cb)) #define ATM_SKB(skb) (((struct atm_skb_data *) (skb)->cb))
struct atm_dev *atm_dev_register(const char *type,const struct atmdev_ops *ops, struct atm_dev *atm_dev_register(const char *type,const struct atmdev_ops *ops,
int number,atm_dev_flags_t *flags); /* number == -1: pick first available */ int number,unsigned long *flags); /* number == -1: pick first available */
struct atm_dev *atm_find_dev(int number); struct atm_dev *atm_find_dev(int number);
void atm_dev_deregister(struct atm_dev *dev); void atm_dev_deregister(struct atm_dev *dev);
void shutdown_atm_dev(struct atm_dev *dev); void shutdown_atm_dev(struct atm_dev *dev);
......
...@@ -213,6 +213,7 @@ void ide_setup_ports(hw_regs_t *hw, ...@@ -213,6 +213,7 @@ void ide_setup_ports(hw_regs_t *hw,
/* Currently only m68k, apus and m8xx need it */ /* Currently only m68k, apus and m8xx need it */
#ifdef ATA_ARCH_ACK_INTR #ifdef ATA_ARCH_ACK_INTR
extern int ide_irq_lock;
# define ide_ack_intr(hwif) (hwif->hw.ack_intr ? hwif->hw.ack_intr(hwif) : 1) # define ide_ack_intr(hwif) (hwif->hw.ack_intr ? hwif->hw.ack_intr(hwif) : 1)
#else #else
# define ide_ack_intr(hwif) (1) # define ide_ack_intr(hwif) (1)
...@@ -603,11 +604,7 @@ extern int noautodma; ...@@ -603,11 +604,7 @@ extern int noautodma;
extern int __ide_end_request(struct ata_device *, struct request *, int, unsigned int); extern int __ide_end_request(struct ata_device *, struct request *, int, unsigned int);
extern int ide_end_request(struct ata_device *drive, struct request *, int); extern int ide_end_request(struct ata_device *drive, struct request *, int);
/* extern void ata_set_handler(struct ata_device *drive, ata_handler_t handler,
* This is used on exit from the driver, to designate the next irq handler
* and also to start the safety timer.
*/
extern void ide_set_handler(struct ata_device *drive, ata_handler_t handler,
unsigned long timeout, ata_expiry_t expiry); unsigned long timeout, ata_expiry_t expiry);
extern u8 ata_dump(struct ata_device *, struct request *, const char *); extern u8 ata_dump(struct ata_device *, struct request *, const char *);
......
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
#define _NAMESPACE_H_ #define _NAMESPACE_H_
#ifdef __KERNEL__ #ifdef __KERNEL__
#include <linux/dcache.h>
#include <linux/sched.h>
struct namespace { struct namespace {
atomic_t count; atomic_t count;
struct vfsmount * root; struct vfsmount * root;
......
...@@ -1111,6 +1111,7 @@ ...@@ -1111,6 +1111,7 @@
#define PCI_DEVICE_ID_SERVERWORKS_CSB5 0x0201 #define PCI_DEVICE_ID_SERVERWORKS_CSB5 0x0201
#define PCI_DEVICE_ID_SERVERWORKS_OSB4IDE 0x0211 #define PCI_DEVICE_ID_SERVERWORKS_OSB4IDE 0x0211
#define PCI_DEVICE_ID_SERVERWORKS_CSB5IDE 0x0212 #define PCI_DEVICE_ID_SERVERWORKS_CSB5IDE 0x0212
#define PCI_DEVICE_ID_SERVERWORKS_CSB6IDE 0x0213
#define PCI_DEVICE_ID_SERVERWORKS_OSB4USB 0x0220 #define PCI_DEVICE_ID_SERVERWORKS_OSB4USB 0x0220
#define PCI_DEVICE_ID_SERVERWORKS_CSB5USB PCI_DEVICE_ID_SERVERWORKS_OSB4USB #define PCI_DEVICE_ID_SERVERWORKS_CSB5USB PCI_DEVICE_ID_SERVERWORKS_OSB4USB
#define PCI_DEVICE_ID_SERVERWORKS_CSB5ISA 0x0230 #define PCI_DEVICE_ID_SERVERWORKS_CSB5ISA 0x0230
......
...@@ -64,13 +64,9 @@ ...@@ -64,13 +64,9 @@
#elif !defined(spin_lock_init) /* !SMP and spin_lock_init not previously #elif !defined(spin_lock_init) /* !SMP and spin_lock_init not previously
defined (e.g. by including asm/spinlock.h */ defined (e.g. by including asm/spinlock.h */
#define DEBUG_SPINLOCKS 0 /* 0 == no debugging, 1 == maintain lock state, 2 == full debug */
#if (DEBUG_SPINLOCKS < 1)
#ifndef CONFIG_PREEMPT #ifndef CONFIG_PREEMPT
#define atomic_dec_and_lock(atomic,lock) atomic_dec_and_test(atomic) # define atomic_dec_and_lock(atomic,lock) atomic_dec_and_test(atomic)
#define ATOMIC_DEC_AND_LOCK # define ATOMIC_DEC_AND_LOCK
#endif #endif
/* /*
...@@ -80,10 +76,10 @@ ...@@ -80,10 +76,10 @@
*/ */
#if (__GNUC__ > 2) #if (__GNUC__ > 2)
typedef struct { } spinlock_t; typedef struct { } spinlock_t;
#define SPIN_LOCK_UNLOCKED (spinlock_t) { } # define SPIN_LOCK_UNLOCKED (spinlock_t) { }
#else #else
typedef struct { int gcc_is_buggy; } spinlock_t; typedef struct { int gcc_is_buggy; } spinlock_t;
#define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 } # define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
#endif #endif
#define spin_lock_init(lock) do { (void)(lock); } while(0) #define spin_lock_init(lock) do { (void)(lock); } while(0)
...@@ -93,42 +89,6 @@ ...@@ -93,42 +89,6 @@
#define spin_unlock_wait(lock) do { (void)(lock); } while(0) #define spin_unlock_wait(lock) do { (void)(lock); } while(0)
#define _raw_spin_unlock(lock) do { (void)(lock); } while(0) #define _raw_spin_unlock(lock) do { (void)(lock); } while(0)
#elif (DEBUG_SPINLOCKS < 2)
typedef struct {
volatile unsigned long lock;
} spinlock_t;
#define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
#define spin_lock_init(x) do { (x)->lock = 0; } while (0)
#define spin_is_locked(lock) (test_bit(0,(lock)))
#define spin_trylock(lock) (!test_and_set_bit(0,(lock)))
#define spin_lock(x) do { (x)->lock = 1; } while (0)
#define spin_unlock_wait(x) do { } while (0)
#define spin_unlock(x) do { (x)->lock = 0; } while (0)
#else /* (DEBUG_SPINLOCKS >= 2) */
typedef struct {
volatile unsigned long lock;
volatile unsigned int babble;
const char *module;
} spinlock_t;
#define SPIN_LOCK_UNLOCKED (spinlock_t) { 0, 25, __BASE_FILE__ }
#include <linux/kernel.h>
#define spin_lock_init(x) do { (x)->lock = 0; } while (0)
#define spin_is_locked(lock) (test_bit(0,(lock)))
#define spin_trylock(lock) (!test_and_set_bit(0,(lock)))
#define spin_lock(x) do {unsigned long __spinflags; save_flags(__spinflags); cli(); if ((x)->lock&&(x)->babble) {printk("%s:%d: spin_lock(%s:%p) already locked\n", __BASE_FILE__,__LINE__, (x)->module, (x));(x)->babble--;} (x)->lock = 1; restore_flags(__spinflags);} while (0)
#define spin_unlock_wait(x) do {unsigned long __spinflags; save_flags(__spinflags); cli(); if ((x)->lock&&(x)->babble) {printk("%s:%d: spin_unlock_wait(%s:%p) deadlock\n", __BASE_FILE__,__LINE__, (x)->module, (x));(x)->babble--;} restore_flags(__spinflags);} while (0)
#define spin_unlock(x) do {unsigned long __spinflags; save_flags(__spinflags); cli(); if (!(x)->lock&&(x)->babble) {printk("%s:%d: spin_unlock(%s:%p) not locked\n", __BASE_FILE__,__LINE__, (x)->module, (x));(x)->babble--;} (x)->lock = 0; restore_flags(__spinflags);} while (0)
#endif /* DEBUG_SPINLOCKS */
/* /*
* Read-write spinlocks, allowing multiple readers * Read-write spinlocks, allowing multiple readers
* but only one writer. * but only one writer.
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <linux/swap.h> #include <linux/swap.h>
#include <linux/notifier.h> #include <linux/notifier.h>
#include <linux/config.h> #include <linux/config.h>
#include <linux/init.h>
extern unsigned char software_suspend_enabled; extern unsigned char software_suspend_enabled;
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/file.h> #include <linux/file.h>
#include <linux/binfmts.h> #include <linux/binfmts.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/mm.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/pgalloc.h> #include <asm/pgalloc.h>
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/mm.h>
#include <linux/highmem.h> #include <linux/highmem.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
......
...@@ -710,7 +710,7 @@ static struct atm_dev atmarpd_dev = { ...@@ -710,7 +710,7 @@ static struct atm_dev atmarpd_dev = {
999, /* dummy device number */ 999, /* dummy device number */
NULL,NULL, /* pretend not to have any VCCs */ NULL,NULL, /* pretend not to have any VCCs */
NULL,NULL, /* no data */ NULL,NULL, /* no data */
{ 0 }, /* no flags */ 0, /* no flags */
NULL, /* no local address */ NULL, /* no local address */
{ 0 } /* no ESI, no statistics */ { 0 } /* no ESI, no statistics */
}; };
......
...@@ -564,7 +564,7 @@ static struct atm_dev lecatm_dev = { ...@@ -564,7 +564,7 @@ static struct atm_dev lecatm_dev = {
999, /*dummy device number*/ 999, /*dummy device number*/
NULL,NULL, /*no VCCs*/ NULL,NULL, /*no VCCs*/
NULL,NULL, /*no data*/ NULL,NULL, /*no data*/
{ 0 }, /*no flags*/ 0, /*no flags*/
NULL, /* no local address*/ NULL, /* no local address*/
{ 0 } /*no ESI or rest of the atm_dev struct things*/ { 0 } /*no ESI or rest of the atm_dev struct things*/
}; };
......
...@@ -220,7 +220,7 @@ static void vc_info(struct atm_vcc *vcc,char *buf) ...@@ -220,7 +220,7 @@ static void vc_info(struct atm_vcc *vcc,char *buf)
default: default:
here += sprintf(here,"%3d",vcc->family); here += sprintf(here,"%3d",vcc->family);
} }
here += sprintf(here," %04lx %5d %7d/%7d %7d/%7d\n",vcc->flags.bits, here += sprintf(here," %04lx %5d %7d/%7d %7d/%7d\n",vcc->flags,
vcc->reply, vcc->reply,
atomic_read(&vcc->tx_inuse),vcc->sk->sndbuf, atomic_read(&vcc->tx_inuse),vcc->sk->sndbuf,
atomic_read(&vcc->rx_inuse),vcc->sk->rcvbuf); atomic_read(&vcc->rx_inuse),vcc->sk->rcvbuf);
......
...@@ -83,7 +83,7 @@ struct atm_dev *atm_find_dev(int number) ...@@ -83,7 +83,7 @@ struct atm_dev *atm_find_dev(int number)
struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops, struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops,
int number, atm_dev_flags_t *flags) int number, unsigned long *flags)
{ {
struct atm_dev *dev; struct atm_dev *dev;
......
...@@ -239,7 +239,7 @@ static struct atm_dev sigd_dev = { ...@@ -239,7 +239,7 @@ static struct atm_dev sigd_dev = {
999, /* dummy device number */ 999, /* dummy device number */
NULL,NULL, /* pretend not to have any VCCs */ NULL,NULL, /* pretend not to have any VCCs */
NULL,NULL, /* no data */ NULL,NULL, /* no data */
{ 0 }, /* no flags */ 0, /* no flags */
NULL, /* no local address */ NULL, /* no local address */
{ 0 } /* no ESI, no statistics */ { 0 } /* no ESI, no statistics */
}; };
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#define __NO_VERSION__ #define __NO_VERSION__
#include <sound/driver.h> #include <sound/driver.h>
#include <linux/time.h> #include <linux/time.h>
#include <linux/init.h>
#include <sound/core.h> #include <sound/core.h>
#include <sound/emu10k1.h> #include <sound/emu10k1.h>
......
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