Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
945fb655
Commit
945fb655
authored
Oct 20, 2004
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://bart.bkbits.net/ide-2.6
into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents
a9ce9706
01b81c2d
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
194 additions
and
466 deletions
+194
-466
Documentation/block/biodoc.txt
Documentation/block/biodoc.txt
+1
-2
arch/cris/arch-v10/drivers/ide.c
arch/cris/arch-v10/drivers/ide.c
+3
-1
drivers/ide/arm/icside.c
drivers/ide/arm/icside.c
+1
-26
drivers/ide/ide-disk.c
drivers/ide/ide-disk.c
+29
-244
drivers/ide/ide-dma.c
drivers/ide/ide-dma.c
+5
-10
drivers/ide/ide-io.c
drivers/ide/ide-io.c
+37
-0
drivers/ide/ide-probe.c
drivers/ide/ide-probe.c
+10
-0
drivers/ide/ide-taskfile.c
drivers/ide/ide-taskfile.c
+65
-84
drivers/ide/ide.c
drivers/ide/ide.c
+3
-0
drivers/ide/pci/sgiioc4.c
drivers/ide/pci/sgiioc4.c
+2
-8
drivers/ide/ppc/pmac.c
drivers/ide/ppc/pmac.c
+29
-41
include/linux/ide.h
include/linux/ide.h
+9
-50
No files found.
Documentation/block/biodoc.txt
View file @
945fb655
...
...
@@ -1172,8 +1172,7 @@ PIO drivers (or drivers that need to revert to PIO transfer once in a
while (IDE for example)), where the CPU is doing the actual data
transfer a virtual mapping is needed. If the driver supports highmem I/O,
(Sec 1.1, (ii) ) it needs to use __bio_kmap_atomic and bio_kmap_irq to
temporarily map a bio into the virtual address space. See how IDE handles
this with ide_map_buffer.
temporarily map a bio into the virtual address space.
8. Prior/Related/Impacted patches
...
...
arch/cris/arch-v10/drivers/ide.c
View file @
945fb655
...
...
@@ -297,8 +297,10 @@ static int e100_dma_setup(ide_drive_t *drive)
}
/* set up the Etrax DMA descriptors */
if
(
e100_ide_build_dmatable
(
drive
))
if
(
e100_ide_build_dmatable
(
drive
))
{
ide_map_sg
(
drive
,
rq
);
return
1
;
}
return
0
;
}
...
...
drivers/ide/arm/icside.c
View file @
945fb655
...
...
@@ -206,8 +206,6 @@ static void icside_maskproc(ide_drive_t *drive, int mask)
* here, but we rely on the main IDE driver spotting that both
* interfaces use the same IRQ, which should guarantee this.
*/
#define NR_ENTRIES 256
#define TABLE_SIZE (NR_ENTRIES * 8)
static
void
icside_build_sglist
(
ide_drive_t
*
drive
,
struct
request
*
rq
)
{
...
...
@@ -527,7 +525,7 @@ static int icside_dma_lostirq(ide_drive_t *drive)
return
1
;
}
static
int
icside_dma_init
(
ide_hwif_t
*
hwif
)
static
void
icside_dma_init
(
ide_hwif_t
*
hwif
)
{
int
autodma
=
0
;
...
...
@@ -537,11 +535,6 @@ static int icside_dma_init(ide_hwif_t *hwif)
printk
(
" %s: SG-DMA"
,
hwif
->
name
);
hwif
->
sg_table
=
kmalloc
(
sizeof
(
struct
scatterlist
)
*
NR_ENTRIES
,
GFP_KERNEL
);
if
(
!
hwif
->
sg_table
)
goto
failed
;
hwif
->
atapi_dma
=
1
;
hwif
->
mwdma_mask
=
7
;
/* MW0..2 */
hwif
->
swdma_mask
=
7
;
/* SW0..2 */
...
...
@@ -569,24 +562,9 @@ static int icside_dma_init(ide_hwif_t *hwif)
hwif
->
drives
[
1
].
autodma
=
hwif
->
autodma
;
printk
(
" capable%s
\n
"
,
hwif
->
autodma
?
", auto-enable"
:
""
);
return
1
;
failed:
printk
(
" disabled, unable to allocate DMA table
\n
"
);
return
0
;
}
static
void
icside_dma_exit
(
ide_hwif_t
*
hwif
)
{
if
(
hwif
->
sg_table
)
{
kfree
(
hwif
->
sg_table
);
hwif
->
sg_table
=
NULL
;
}
}
#else
#define icside_dma_init(hwif) (0)
#define icside_dma_exit(hwif) do { } while (0)
#endif
static
ide_hwif_t
*
icside_find_hwif
(
unsigned
long
dataport
)
...
...
@@ -811,9 +789,6 @@ static void __devexit icside_remove(struct expansion_card *ec)
case
ICS_TYPE_V6
:
/* FIXME: tell IDE to stop using the interface */
icside_dma_exit
(
state
->
hwif
[
1
]);
icside_dma_exit
(
state
->
hwif
[
0
]);
if
(
ec
->
dma
!=
NO_DMA
)
free_dma
(
ec
->
dma
);
...
...
drivers/ide/ide-disk.c
View file @
945fb655
...
...
@@ -122,216 +122,6 @@ static int lba_capacity_is_ok (struct hd_driveid *id)
#ifndef CONFIG_IDE_TASKFILE_IO
/*
* read_intr() is the handler for disk read/multread interrupts
*/
static
ide_startstop_t
read_intr
(
ide_drive_t
*
drive
)
{
ide_hwif_t
*
hwif
=
HWIF
(
drive
);
u32
i
=
0
,
nsect
=
0
,
msect
=
drive
->
mult_count
;
struct
request
*
rq
;
unsigned
long
flags
;
u8
stat
;
char
*
to
;
/* new way for dealing with premature shared PCI interrupts */
if
(
!
OK_STAT
(
stat
=
hwif
->
INB
(
IDE_STATUS_REG
),
DATA_READY
,
BAD_R_STAT
))
{
if
(
stat
&
(
ERR_STAT
|
DRQ_STAT
))
{
return
DRIVER
(
drive
)
->
error
(
drive
,
"read_intr"
,
stat
);
}
/* no data yet, so wait for another interrupt */
ide_set_handler
(
drive
,
&
read_intr
,
WAIT_CMD
,
NULL
);
return
ide_started
;
}
read_next:
rq
=
HWGROUP
(
drive
)
->
rq
;
if
(
msect
)
{
if
((
nsect
=
rq
->
current_nr_sectors
)
>
msect
)
nsect
=
msect
;
msect
-=
nsect
;
}
else
nsect
=
1
;
to
=
ide_map_buffer
(
rq
,
&
flags
);
taskfile_input_data
(
drive
,
to
,
nsect
*
SECTOR_WORDS
);
#ifdef DEBUG
printk
(
"%s: read: sectors(%ld-%ld), buffer=0x%08lx, remaining=%ld
\n
"
,
drive
->
name
,
rq
->
sector
,
rq
->
sector
+
nsect
-
1
,
(
unsigned
long
)
rq
->
buffer
+
(
nsect
<<
9
),
rq
->
nr_sectors
-
nsect
);
#endif
ide_unmap_buffer
(
rq
,
to
,
&
flags
);
rq
->
sector
+=
nsect
;
rq
->
errors
=
0
;
i
=
(
rq
->
nr_sectors
-=
nsect
);
if
(((
long
)(
rq
->
current_nr_sectors
-=
nsect
))
<=
0
)
ide_end_request
(
drive
,
1
,
rq
->
hard_cur_sectors
);
/*
* Another BH Page walker and DATA INTEGRITY Questioned on ERROR.
* If passed back up on multimode read, BAD DATA could be ACKED
* to FILE SYSTEMS above ...
*/
if
(
i
>
0
)
{
if
(
msect
)
goto
read_next
;
ide_set_handler
(
drive
,
&
read_intr
,
WAIT_CMD
,
NULL
);
return
ide_started
;
}
return
ide_stopped
;
}
/*
* write_intr() is the handler for disk write interrupts
*/
static
ide_startstop_t
write_intr
(
ide_drive_t
*
drive
)
{
ide_hwgroup_t
*
hwgroup
=
HWGROUP
(
drive
);
ide_hwif_t
*
hwif
=
HWIF
(
drive
);
struct
request
*
rq
=
hwgroup
->
rq
;
u32
i
=
0
;
u8
stat
;
if
(
!
OK_STAT
(
stat
=
hwif
->
INB
(
IDE_STATUS_REG
),
DRIVE_READY
,
drive
->
bad_wstat
))
{
printk
(
"%s: write_intr error1: nr_sectors=%ld, stat=0x%02x
\n
"
,
drive
->
name
,
rq
->
nr_sectors
,
stat
);
}
else
{
#ifdef DEBUG
printk
(
"%s: write: sector %ld, buffer=0x%08lx, remaining=%ld
\n
"
,
drive
->
name
,
rq
->
sector
,
(
unsigned
long
)
rq
->
buffer
,
rq
->
nr_sectors
-
1
);
#endif
if
((
rq
->
nr_sectors
==
1
)
^
((
stat
&
DRQ_STAT
)
!=
0
))
{
rq
->
sector
++
;
rq
->
errors
=
0
;
i
=
--
rq
->
nr_sectors
;
--
rq
->
current_nr_sectors
;
if
(((
long
)
rq
->
current_nr_sectors
)
<=
0
)
ide_end_request
(
drive
,
1
,
rq
->
hard_cur_sectors
);
if
(
i
>
0
)
{
unsigned
long
flags
;
char
*
to
=
ide_map_buffer
(
rq
,
&
flags
);
taskfile_output_data
(
drive
,
to
,
SECTOR_WORDS
);
ide_unmap_buffer
(
rq
,
to
,
&
flags
);
ide_set_handler
(
drive
,
&
write_intr
,
WAIT_CMD
,
NULL
);
return
ide_started
;
}
return
ide_stopped
;
}
/* the original code did this here (?) */
return
ide_stopped
;
}
return
DRIVER
(
drive
)
->
error
(
drive
,
"write_intr"
,
stat
);
}
/*
* ide_multwrite() transfers a block of up to mcount sectors of data
* to a drive as part of a disk multiple-sector write operation.
*
* Note that we may be called from two contexts - __ide_do_rw_disk() context
* and IRQ context. The IRQ can happen any time after we've output the
* full "mcount" number of sectors, so we must make sure we update the
* state _before_ we output the final part of the data!
*
* The update and return to BH is a BLOCK Layer Fakey to get more data
* to satisfy the hardware atomic segment. If the hardware atomic segment
* is shorter or smaller than the BH segment then we should be OKAY.
* This is only valid if we can rewind the rq->current_nr_sectors counter.
*/
static
void
ide_multwrite
(
ide_drive_t
*
drive
,
unsigned
int
mcount
)
{
ide_hwgroup_t
*
hwgroup
=
HWGROUP
(
drive
);
struct
request
*
rq
=
&
hwgroup
->
wrq
;
do
{
char
*
buffer
;
int
nsect
=
rq
->
current_nr_sectors
;
unsigned
long
flags
;
if
(
nsect
>
mcount
)
nsect
=
mcount
;
mcount
-=
nsect
;
buffer
=
ide_map_buffer
(
rq
,
&
flags
);
rq
->
sector
+=
nsect
;
rq
->
nr_sectors
-=
nsect
;
rq
->
current_nr_sectors
-=
nsect
;
/* Do we move to the next bh after this? */
if
(
!
rq
->
current_nr_sectors
)
{
struct
bio
*
bio
=
rq
->
bio
;
/*
* only move to next bio, when we have processed
* all bvecs in this one.
*/
if
(
++
bio
->
bi_idx
>=
bio
->
bi_vcnt
)
{
bio
->
bi_idx
=
bio
->
bi_vcnt
-
rq
->
nr_cbio_segments
;
bio
=
bio
->
bi_next
;
}
/* end early early we ran out of requests */
if
(
!
bio
)
{
mcount
=
0
;
}
else
{
rq
->
bio
=
bio
;
rq
->
nr_cbio_segments
=
bio_segments
(
bio
);
rq
->
current_nr_sectors
=
bio_cur_sectors
(
bio
);
rq
->
hard_cur_sectors
=
rq
->
current_nr_sectors
;
}
}
/*
* Ok, we're all setup for the interrupt
* re-entering us on the last transfer.
*/
taskfile_output_data
(
drive
,
buffer
,
nsect
<<
7
);
ide_unmap_buffer
(
rq
,
buffer
,
&
flags
);
}
while
(
mcount
);
}
/*
* multwrite_intr() is the handler for disk multwrite interrupts
*/
static
ide_startstop_t
multwrite_intr
(
ide_drive_t
*
drive
)
{
ide_hwgroup_t
*
hwgroup
=
HWGROUP
(
drive
);
ide_hwif_t
*
hwif
=
HWIF
(
drive
);
struct
request
*
rq
=
&
hwgroup
->
wrq
;
struct
bio
*
bio
=
rq
->
bio
;
u8
stat
;
stat
=
hwif
->
INB
(
IDE_STATUS_REG
);
if
(
OK_STAT
(
stat
,
DRIVE_READY
,
drive
->
bad_wstat
))
{
if
(
stat
&
DRQ_STAT
)
{
/*
* The drive wants data. Remember rq is the copy
* of the request
*/
if
(
rq
->
nr_sectors
)
{
ide_multwrite
(
drive
,
drive
->
mult_count
);
ide_set_handler
(
drive
,
&
multwrite_intr
,
WAIT_CMD
,
NULL
);
return
ide_started
;
}
}
else
{
/*
* If the copy has all the blocks completed then
* we can end the original request.
*/
if
(
!
rq
->
nr_sectors
)
{
/* all done? */
bio
->
bi_idx
=
bio
->
bi_vcnt
-
rq
->
nr_cbio_segments
;
rq
=
hwgroup
->
rq
;
ide_end_request
(
drive
,
1
,
rq
->
nr_sectors
);
return
ide_stopped
;
}
}
bio
->
bi_idx
=
bio
->
bi_vcnt
-
rq
->
nr_cbio_segments
;
/* the original code did this here (?) */
return
ide_stopped
;
}
bio
->
bi_idx
=
bio
->
bi_vcnt
-
rq
->
nr_cbio_segments
;
return
DRIVER
(
drive
)
->
error
(
drive
,
"multwrite_intr"
,
stat
);
}
/*
* __ide_do_rw_disk() issues READ and WRITE commands to a disk,
* using LBA if supported, or CHS otherwise, to address sectors.
...
...
@@ -352,6 +142,11 @@ ide_startstop_t __ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector
dma
=
0
;
}
if
(
!
dma
)
{
ide_init_sg_cmd
(
drive
,
rq
);
ide_map_sg
(
drive
,
rq
);
}
if
(
IDE_CONTROL_REG
)
hwif
->
OUTB
(
drive
->
ctl
,
IDE_CONTROL_REG
);
...
...
@@ -435,44 +230,33 @@ ide_startstop_t __ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector
return
ide_started
;
}
/* fallback to PIO */
ide_init_sg_cmd
(
drive
,
rq
);
}
if
(
rq_data_dir
(
rq
)
==
READ
)
{
command
=
((
drive
->
mult_count
)
?
((
lba48
)
?
WIN_MULTREAD_EXT
:
WIN_MULTREAD
)
:
((
lba48
)
?
WIN_READ_EXT
:
WIN_READ
));
ide_execute_command
(
drive
,
command
,
&
read_intr
,
WAIT_CMD
,
NULL
);
return
ide_started
;
}
else
{
ide_startstop_t
startstop
;
command
=
((
drive
->
mult_count
)
?
((
lba48
)
?
WIN_MULTWRITE_EXT
:
WIN_MULTWRITE
)
:
((
lba48
)
?
WIN_WRITE_EXT
:
WIN_WRITE
));
hwif
->
OUTB
(
command
,
IDE_COMMAND_REG
);
if
(
ide_wait_stat
(
&
startstop
,
drive
,
DATA_READY
,
drive
->
bad_wstat
,
WAIT_DRQ
))
{
printk
(
KERN_ERR
"%s: no DRQ after issuing %s
\n
"
,
drive
->
name
,
drive
->
mult_count
?
"MULTWRITE"
:
"WRITE"
);
return
startstop
;
}
if
(
!
drive
->
unmask
)
local_irq_disable
();
if
(
drive
->
mult_count
)
{
ide_hwgroup_t
*
hwgroup
=
HWGROUP
(
drive
);
hwif
->
data_phase
=
TASKFILE_MULTI_IN
;
command
=
lba48
?
WIN_MULTREAD_EXT
:
WIN_MULTREAD
;
}
else
{
hwif
->
data_phase
=
TASKFILE_IN
;
command
=
lba48
?
WIN_READ_EXT
:
WIN_READ
;
}
hwgroup
->
wrq
=
*
rq
;
/* scratchpad */
ide_set_handler
(
drive
,
&
multwrite_intr
,
WAIT_CMD
,
NULL
);
ide_multwrite
(
drive
,
drive
->
mult_count
);
ide_execute_command
(
drive
,
command
,
&
task_in_intr
,
WAIT_CMD
,
NULL
);
return
ide_started
;
}
else
{
if
(
drive
->
mult_count
)
{
hwif
->
data_phase
=
TASKFILE_MULTI_OUT
;
command
=
lba48
?
WIN_MULTWRITE_EXT
:
WIN_MULTWRITE
;
}
else
{
unsigned
long
flags
;
char
*
to
=
ide_map_buffer
(
rq
,
&
flags
);
ide_set_handler
(
drive
,
&
write_intr
,
WAIT_CMD
,
NULL
);
taskfile_output_data
(
drive
,
to
,
SECTOR_WORDS
);
ide_unmap_buffer
(
rq
,
to
,
&
flags
);
hwif
->
data_phase
=
TASKFILE_OUT
;
command
=
lba48
?
WIN_WRITE_EXT
:
WIN_WRITE
;
}
hwif
->
OUTB
(
command
,
IDE_COMMAND_REG
);
pre_task_out_intr
(
drive
,
rq
);
return
ide_started
;
}
}
...
...
@@ -516,6 +300,11 @@ static u8 get_command(ide_drive_t *drive, struct request *rq, ide_task_t *task)
dma
=
0
;
}
if
(
!
dma
)
{
ide_init_sg_cmd
(
drive
,
rq
);
ide_map_sg
(
drive
,
rq
);
}
if
(
rq_data_dir
(
rq
)
==
READ
)
{
task
->
command_type
=
IDE_DRIVE_TASK_IN
;
if
(
dma
)
...
...
@@ -779,10 +568,6 @@ ide_startstop_t idedisk_error (ide_drive_t *drive, const char *msg, u8 stat)
ide_end_drive_cmd
(
drive
,
stat
,
err
);
return
ide_stopped
;
}
#ifdef CONFIG_IDE_TASKFILE_IO
/* make rq completion pointers new submission pointers */
blk_rq_prep_restart
(
rq
);
#endif
if
(
stat
&
BUSY_STAT
||
((
stat
&
WRERR_STAT
)
&&
!
drive
->
nowerr
))
{
/* other bits are useless when BUSY */
...
...
drivers/ide/ide-dma.c
View file @
945fb655
...
...
@@ -610,8 +610,10 @@ int ide_dma_setup(ide_drive_t *drive)
reading
=
1
<<
3
;
/* fall back to pio! */
if
(
!
ide_build_dmatable
(
drive
,
rq
))
if
(
!
ide_build_dmatable
(
drive
,
rq
))
{
ide_map_sg
(
drive
,
rq
);
return
1
;
}
/* PRD table */
hwif
->
OUTL
(
hwif
->
dmatable_dma
,
hwif
->
dma_prdtable
);
...
...
@@ -810,10 +812,6 @@ int ide_release_dma_engine (ide_hwif_t *hwif)
hwif
->
dmatable_dma
);
hwif
->
dmatable_cpu
=
NULL
;
}
if
(
hwif
->
sg_table
)
{
kfree
(
hwif
->
sg_table
);
hwif
->
sg_table
=
NULL
;
}
return
1
;
}
...
...
@@ -846,15 +844,12 @@ int ide_allocate_dma_engine (ide_hwif_t *hwif)
hwif
->
dmatable_cpu
=
pci_alloc_consistent
(
hwif
->
pci_dev
,
PRD_ENTRIES
*
PRD_BYTES
,
&
hwif
->
dmatable_dma
);
hwif
->
sg_table
=
kmalloc
(
sizeof
(
struct
scatterlist
)
*
PRD_ENTRIES
,
GFP_KERNEL
);
if
(
(
hwif
->
dmatable_cpu
)
&&
(
hwif
->
sg_table
)
)
if
(
hwif
->
dmatable_cpu
)
return
0
;
printk
(
KERN_ERR
"%s: -- Error, unable to allocate%s
%s
table(s).
\n
"
,
printk
(
KERN_ERR
"%s: -- Error, unable to allocate%s
DMA
table(s).
\n
"
,
(
hwif
->
dmatable_cpu
==
NULL
)
?
" CPU"
:
""
,
(
hwif
->
sg_table
==
NULL
)
?
" SG DMA"
:
" DMA"
,
hwif
->
cds
->
name
);
ide_release_dma_engine
(
hwif
);
...
...
drivers/ide/ide-io.c
View file @
945fb655
...
...
@@ -47,6 +47,7 @@
#include <linux/seq_file.h>
#include <linux/device.h>
#include <linux/kmod.h>
#include <linux/scatterlist.h>
#include <asm/byteorder.h>
#include <asm/irq.h>
...
...
@@ -674,6 +675,31 @@ ide_startstop_t do_special (ide_drive_t *drive)
EXPORT_SYMBOL
(
do_special
);
void
ide_map_sg
(
ide_drive_t
*
drive
,
struct
request
*
rq
)
{
ide_hwif_t
*
hwif
=
drive
->
hwif
;
struct
scatterlist
*
sg
=
hwif
->
sg_table
;
if
((
rq
->
flags
&
REQ_DRIVE_TASKFILE
)
==
0
)
{
hwif
->
sg_nents
=
blk_rq_map_sg
(
drive
->
queue
,
rq
,
sg
);
}
else
{
sg_init_one
(
sg
,
rq
->
buffer
,
rq
->
nr_sectors
*
SECTOR_SIZE
);
hwif
->
sg_nents
=
1
;
}
}
EXPORT_SYMBOL_GPL
(
ide_map_sg
);
void
ide_init_sg_cmd
(
ide_drive_t
*
drive
,
struct
request
*
rq
)
{
ide_hwif_t
*
hwif
=
drive
->
hwif
;
hwif
->
nsect
=
hwif
->
nleft
=
rq
->
nr_sectors
;
hwif
->
cursg
=
hwif
->
cursg_ofs
=
0
;
}
EXPORT_SYMBOL_GPL
(
ide_init_sg_cmd
);
/**
* execute_drive_command - issue special drive command
* @drive: the drive to issue th command on
...
...
@@ -697,6 +723,17 @@ ide_startstop_t execute_drive_cmd (ide_drive_t *drive, struct request *rq)
hwif
->
data_phase
=
args
->
data_phase
;
switch
(
hwif
->
data_phase
)
{
case
TASKFILE_MULTI_OUT
:
case
TASKFILE_OUT
:
case
TASKFILE_MULTI_IN
:
case
TASKFILE_IN
:
ide_init_sg_cmd
(
drive
,
rq
);
ide_map_sg
(
drive
,
rq
);
default:
break
;
}
if
(
args
->
tf_out_flags
.
all
!=
0
)
return
flagged_taskfile
(
drive
,
args
);
return
do_rw_taskfile
(
drive
,
args
);
...
...
drivers/ide/ide-probe.c
View file @
945fb655
...
...
@@ -1246,6 +1246,16 @@ static int hwif_init(ide_hwif_t *hwif)
if
(
register_blkdev
(
hwif
->
major
,
hwif
->
name
))
return
0
;
if
(
!
hwif
->
sg_max_nents
)
hwif
->
sg_max_nents
=
PRD_ENTRIES
;
hwif
->
sg_table
=
kmalloc
(
sizeof
(
struct
scatterlist
)
*
hwif
->
sg_max_nents
,
GFP_KERNEL
);
if
(
!
hwif
->
sg_table
)
{
printk
(
KERN_ERR
"%s: unable to allocate SG table.
\n
"
,
hwif
->
name
);
goto
out
;
}
if
(
alloc_disks
(
hwif
)
<
0
)
goto
out
;
...
...
drivers/ide/ide-taskfile.c
View file @
945fb655
...
...
@@ -5,7 +5,7 @@
* Copyright (C) 2000-2002 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2001-2002 Klaus Smolin
* IBM Storage Technology Division
* Copyright (C) 2003
Bartlomiej Zolnierkiewicz
* Copyright (C) 2003
-2004
Bartlomiej Zolnierkiewicz
*
* The big the bad and the ugly.
*
...
...
@@ -253,73 +253,6 @@ ide_startstop_t task_no_data_intr (ide_drive_t *drive)
EXPORT_SYMBOL
(
task_no_data_intr
);
static
void
task_buffer_sectors
(
ide_drive_t
*
drive
,
struct
request
*
rq
,
unsigned
nsect
,
unsigned
rw
)
{
char
*
buf
=
rq
->
buffer
+
blk_rq_offset
(
rq
);
rq
->
sector
+=
nsect
;
rq
->
current_nr_sectors
-=
nsect
;
rq
->
nr_sectors
-=
nsect
;
__task_sectors
(
drive
,
buf
,
nsect
,
rw
);
}
static
inline
void
task_buffer_multi_sectors
(
ide_drive_t
*
drive
,
struct
request
*
rq
,
unsigned
rw
)
{
unsigned
int
msect
=
drive
->
mult_count
,
nsect
;
nsect
=
rq
->
current_nr_sectors
;
if
(
nsect
>
msect
)
nsect
=
msect
;
task_buffer_sectors
(
drive
,
rq
,
nsect
,
rw
);
}
#ifdef CONFIG_IDE_TASKFILE_IO
static
void
task_sectors
(
ide_drive_t
*
drive
,
struct
request
*
rq
,
unsigned
nsect
,
unsigned
rw
)
{
if
(
rq
->
cbio
)
{
/* fs request */
rq
->
errors
=
0
;
task_bio_sectors
(
drive
,
rq
,
nsect
,
rw
);
}
else
/* task request */
task_buffer_sectors
(
drive
,
rq
,
nsect
,
rw
);
}
static
inline
void
task_bio_multi_sectors
(
ide_drive_t
*
drive
,
struct
request
*
rq
,
unsigned
rw
)
{
unsigned
int
nsect
,
msect
=
drive
->
mult_count
;
do
{
nsect
=
rq
->
current_nr_sectors
;
if
(
nsect
>
msect
)
nsect
=
msect
;
task_bio_sectors
(
drive
,
rq
,
nsect
,
rw
);
if
(
!
rq
->
nr_sectors
)
msect
=
0
;
else
msect
-=
nsect
;
}
while
(
msect
);
}
static
void
task_multi_sectors
(
ide_drive_t
*
drive
,
struct
request
*
rq
,
unsigned
rw
)
{
if
(
rq
->
cbio
)
{
/* fs request */
rq
->
errors
=
0
;
task_bio_multi_sectors
(
drive
,
rq
,
rw
);
}
else
/* task request */
task_buffer_multi_sectors
(
drive
,
rq
,
rw
);
}
#else
# define task_sectors(d, rq, nsect, rw) task_buffer_sectors(d, rq, nsect, rw)
# define task_multi_sectors(d, rq, rw) task_buffer_multi_sectors(d, rq, rw)
#endif
/* CONFIG_IDE_TASKFILE_IO */
static
u8
wait_drive_not_busy
(
ide_drive_t
*
drive
)
{
ide_hwif_t
*
hwif
=
HWIF
(
drive
);
...
...
@@ -340,37 +273,86 @@ static u8 wait_drive_not_busy(ide_drive_t *drive)
return
stat
;
}
static
void
ide_pio_sector
(
ide_drive_t
*
drive
,
unsigned
int
write
)
{
ide_hwif_t
*
hwif
=
drive
->
hwif
;
struct
scatterlist
*
sg
=
hwif
->
sg_table
;
struct
page
*
page
;
#ifdef CONFIG_HIGHMEM
unsigned
long
flags
;
#endif
u8
*
buf
;
page
=
sg
[
hwif
->
cursg
].
page
;
#ifdef CONFIG_HIGHMEM
local_irq_save
(
flags
);
#endif
buf
=
kmap_atomic
(
page
,
KM_BIO_SRC_IRQ
)
+
sg
[
hwif
->
cursg
].
offset
+
(
hwif
->
cursg_ofs
*
SECTOR_SIZE
);
hwif
->
nleft
--
;
hwif
->
cursg_ofs
++
;
if
((
hwif
->
cursg_ofs
*
SECTOR_SIZE
)
==
sg
[
hwif
->
cursg
].
length
)
{
hwif
->
cursg
++
;
hwif
->
cursg_ofs
=
0
;
}
/* do the actual data transfer */
if
(
write
)
taskfile_output_data
(
drive
,
buf
,
SECTOR_WORDS
);
else
taskfile_input_data
(
drive
,
buf
,
SECTOR_WORDS
);
kunmap_atomic
(
page
,
KM_BIO_SRC_IRQ
);
#ifdef CONFIG_HIGHMEM
local_irq_restore
(
flags
);
#endif
}
static
void
ide_pio_multi
(
ide_drive_t
*
drive
,
unsigned
int
write
)
{
unsigned
int
nsect
;
nsect
=
min_t
(
unsigned
int
,
drive
->
hwif
->
nleft
,
drive
->
mult_count
);
while
(
nsect
--
)
ide_pio_sector
(
drive
,
write
);
}
static
inline
void
ide_pio_datablock
(
ide_drive_t
*
drive
,
struct
request
*
rq
,
unsigned
int
write
)
{
if
(
rq
->
bio
)
/* fs request */
rq
->
errors
=
0
;
switch
(
drive
->
hwif
->
data_phase
)
{
case
TASKFILE_MULTI_IN
:
case
TASKFILE_MULTI_OUT
:
task_multi_sectors
(
drive
,
rq
,
write
);
ide_pio_multi
(
drive
,
write
);
break
;
default:
task_sectors
(
drive
,
rq
,
1
,
write
);
ide_pio_sector
(
drive
,
write
);
break
;
}
}
#ifdef CONFIG_IDE_TASKFILE_IO
static
ide_startstop_t
task_error
(
ide_drive_t
*
drive
,
struct
request
*
rq
,
const
char
*
s
,
u8
stat
)
{
if
(
rq
->
bio
)
{
int
sectors
=
rq
->
hard_nr_sectors
-
rq
->
nr_sectors
;
ide_hwif_t
*
hwif
=
drive
->
hwif
;
int
sectors
=
hwif
->
nsect
-
hwif
->
nleft
;
switch
(
drive
->
hwif
->
data_phase
)
{
switch
(
hwif
->
data_phase
)
{
case
TASKFILE_IN
:
if
(
rq
->
nr_sectors
)
if
(
hwif
->
nleft
)
break
;
/* fall through */
case
TASKFILE_OUT
:
sectors
--
;
break
;
case
TASKFILE_MULTI_IN
:
if
(
rq
->
nr_sectors
)
if
(
hwif
->
nleft
)
break
;
/* fall through */
case
TASKFILE_MULTI_OUT
:
...
...
@@ -384,9 +366,6 @@ static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq,
}
return
drive
->
driver
->
error
(
drive
,
s
,
stat
);
}
#else
# define task_error(d, rq, s, stat) drive->driver->error(d, s, stat)
#endif
static
void
task_end_request
(
ide_drive_t
*
drive
,
struct
request
*
rq
,
u8
stat
)
{
...
...
@@ -407,9 +386,11 @@ static void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat)
*/
ide_startstop_t
task_in_intr
(
ide_drive_t
*
drive
)
{
ide_hwif_t
*
hwif
=
drive
->
hwif
;
struct
request
*
rq
=
HWGROUP
(
drive
)
->
rq
;
u8
stat
=
HWIF
(
drive
)
->
INB
(
IDE_STATUS_REG
);
u8
stat
=
hwif
->
INB
(
IDE_STATUS_REG
);
/* new way for dealing with premature shared PCI interrupts */
if
(
!
OK_STAT
(
stat
,
DATA_READY
,
BAD_R_STAT
))
{
if
(
stat
&
(
ERR_STAT
|
DRQ_STAT
))
return
task_error
(
drive
,
rq
,
__FUNCTION__
,
stat
);
...
...
@@ -421,7 +402,7 @@ ide_startstop_t task_in_intr (ide_drive_t *drive)
ide_pio_datablock
(
drive
,
rq
,
0
);
/* If it was the last datablock check status and finish transfer. */
if
(
!
rq
->
nr_sectors
)
{
if
(
!
hwif
->
nleft
)
{
stat
=
wait_drive_not_busy
(
drive
);
if
(
!
OK_STAT
(
stat
,
0
,
BAD_R_STAT
))
return
task_error
(
drive
,
rq
,
__FUNCTION__
,
stat
);
...
...
@@ -441,18 +422,18 @@ EXPORT_SYMBOL(task_in_intr);
*/
ide_startstop_t
task_out_intr
(
ide_drive_t
*
drive
)
{
ide_hwif_t
*
hwif
=
drive
->
hwif
;
struct
request
*
rq
=
HWGROUP
(
drive
)
->
rq
;
u8
stat
;
u8
stat
=
hwif
->
INB
(
IDE_STATUS_REG
)
;
stat
=
HWIF
(
drive
)
->
INB
(
IDE_STATUS_REG
);
if
(
!
OK_STAT
(
stat
,
DRIVE_READY
,
drive
->
bad_wstat
))
return
task_error
(
drive
,
rq
,
__FUNCTION__
,
stat
);
/* Deal with unexpected ATA data phase. */
if
(((
stat
&
DRQ_STAT
)
==
0
)
^
!
rq
->
nr_sectors
)
if
(((
stat
&
DRQ_STAT
)
==
0
)
^
!
hwif
->
nleft
)
return
task_error
(
drive
,
rq
,
__FUNCTION__
,
stat
);
if
(
!
rq
->
nr_sectors
)
{
if
(
!
hwif
->
nleft
)
{
task_end_request
(
drive
,
rq
,
stat
);
return
ide_stopped
;
}
...
...
drivers/ide/ide.c
View file @
945fb655
...
...
@@ -712,6 +712,8 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
hwif
->
INSW
=
tmp_hwif
->
INSW
;
hwif
->
INSL
=
tmp_hwif
->
INSL
;
hwif
->
sg_max_nents
=
tmp_hwif
->
sg_max_nents
;
hwif
->
mmio
=
tmp_hwif
->
mmio
;
hwif
->
rqsize
=
tmp_hwif
->
rqsize
;
hwif
->
no_lba48
=
tmp_hwif
->
no_lba48
;
...
...
@@ -900,6 +902,7 @@ void ide_unregister(unsigned int index)
hwif
->
drives
[
i
].
disk
=
NULL
;
put_disk
(
disk
);
}
kfree
(
hwif
->
sg_table
);
unregister_blkdev
(
hwif
->
major
,
hwif
->
name
);
spin_lock_irq
(
&
ide_lock
);
...
...
drivers/ide/pci/sgiioc4.c
View file @
945fb655
...
...
@@ -404,11 +404,7 @@ ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base)
if
(
!
hwif
->
dmatable_cpu
)
goto
dma_alloc_failure
;
hwif
->
sg_table
=
kmalloc
(
sizeof
(
struct
scatterlist
)
*
IOC4_PRD_ENTRIES
,
GFP_KERNEL
);
if
(
!
hwif
->
sg_table
)
goto
dma_sgalloc_failure
;
hwif
->
sg_max_nents
=
IOC4_PRD_ENTRIES
;
hwif
->
dma_base2
=
(
unsigned
long
)
pci_alloc_consistent
(
hwif
->
pci_dev
,
...
...
@@ -421,9 +417,6 @@ ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base)
return
;
dma_base2alloc_failure:
kfree
(
hwif
->
sg_table
);
dma_sgalloc_failure:
pci_free_consistent
(
hwif
->
pci_dev
,
IOC4_PRD_ENTRIES
*
IOC4_PRD_BYTES
,
hwif
->
dmatable_cpu
,
hwif
->
dmatable_dma
);
...
...
@@ -584,6 +577,7 @@ static int sgiioc4_ide_dma_setup(ide_drive_t *drive)
if
(
!
(
count
=
sgiioc4_build_dma_table
(
drive
,
rq
,
ddir
)))
{
/* try PIO instead of DMA */
ide_map_sg
(
drive
,
rq
);
return
1
;
}
...
...
drivers/ide/ppc/pmac.c
View file @
945fb655
...
...
@@ -78,10 +78,6 @@ typedef struct pmac_ide_hwif {
*/
volatile
struct
dbdma_regs
__iomem
*
dma_regs
;
struct
dbdma_cmd
*
dma_table_cpu
;
dma_addr_t
dma_table_dma
;
struct
scatterlist
*
sg_table
;
int
sg_nents
;
int
sg_dma_direction
;
#endif
}
pmac_ide_hwif_t
;
...
...
@@ -1245,6 +1241,8 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
hwif
->
noprobe
=
0
;
#endif
/* CONFIG_PMAC_PBOOK */
hwif
->
sg_max_nents
=
MAX_DCMDS
;
#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
/* has a DBDMA controller channel */
if
(
pmif
->
dma_regs
)
...
...
@@ -1562,26 +1560,23 @@ pmac_ide_probe(void)
#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
/*
* This is very close to the generic ide-dma version of the function except
* that we don't use the fields in the hwif but our own copies for sg_table
* and friends. We build & map the sglist for a given request
* We build & map the sglist for a given request.
*/
static
int
__pmac
pmac_ide_build_sglist
(
ide_drive_t
*
drive
,
struct
request
*
rq
)
{
ide_hwif_t
*
hwif
=
HWIF
(
drive
);
pmac_ide_hwif_t
*
pmif
=
(
pmac_ide_hwif_t
*
)
hwif
->
hwif_data
;
struct
scatterlist
*
sg
=
pmif
->
sg_table
;
struct
scatterlist
*
sg
=
hwif
->
sg_table
;
int
nents
;
nents
=
blk_rq_map_sg
(
drive
->
queue
,
rq
,
sg
);
if
(
rq_data_dir
(
rq
)
==
READ
)
pm
if
->
sg_dma_direction
=
PCI_DMA_FROMDEVICE
;
hw
if
->
sg_dma_direction
=
PCI_DMA_FROMDEVICE
;
else
pm
if
->
sg_dma_direction
=
PCI_DMA_TODEVICE
;
hw
if
->
sg_dma_direction
=
PCI_DMA_TODEVICE
;
return
pci_map_sg
(
hwif
->
pci_dev
,
sg
,
nents
,
pm
if
->
sg_dma_direction
);
return
pci_map_sg
(
hwif
->
pci_dev
,
sg
,
nents
,
hw
if
->
sg_dma_direction
);
}
/*
...
...
@@ -1591,18 +1586,17 @@ static int __pmac
pmac_ide_raw_build_sglist
(
ide_drive_t
*
drive
,
struct
request
*
rq
)
{
ide_hwif_t
*
hwif
=
HWIF
(
drive
);
pmac_ide_hwif_t
*
pmif
=
(
pmac_ide_hwif_t
*
)
hwif
->
hwif_data
;
struct
scatterlist
*
sg
=
pmif
->
sg_table
;
struct
scatterlist
*
sg
=
hwif
->
sg_table
;
int
nents
=
0
;
ide_task_t
*
args
=
rq
->
special
;
unsigned
char
*
virt_addr
=
rq
->
buffer
;
int
sector_count
=
rq
->
nr_sectors
;
if
(
args
->
command_type
==
IDE_DRIVE_TASK_RAW_WRITE
)
pm
if
->
sg_dma_direction
=
PCI_DMA_TODEVICE
;
hw
if
->
sg_dma_direction
=
PCI_DMA_TODEVICE
;
else
pm
if
->
sg_dma_direction
=
PCI_DMA_FROMDEVICE
;
hw
if
->
sg_dma_direction
=
PCI_DMA_FROMDEVICE
;
if
(
sector_count
>
128
)
{
sg_init_one
(
&
sg
[
nents
],
virt_addr
,
128
*
SECTOR_SIZE
);
nents
++
;
...
...
@@ -1611,8 +1605,8 @@ pmac_ide_raw_build_sglist(ide_drive_t *drive, struct request *rq)
}
sg_init_one
(
&
sg
[
nents
],
virt_addr
,
sector_count
*
SECTOR_SIZE
);
nents
++
;
return
pci_map_sg
(
hwif
->
pci_dev
,
sg
,
nents
,
pm
if
->
sg_dma_direction
);
return
pci_map_sg
(
hwif
->
pci_dev
,
sg
,
nents
,
hw
if
->
sg_dma_direction
);
}
/*
...
...
@@ -1640,14 +1634,14 @@ pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
/* Build sglist */
if
(
HWGROUP
(
drive
)
->
rq
->
flags
&
REQ_DRIVE_TASKFILE
)
pm
if
->
sg_nents
=
i
=
pmac_ide_raw_build_sglist
(
drive
,
rq
);
hw
if
->
sg_nents
=
i
=
pmac_ide_raw_build_sglist
(
drive
,
rq
);
else
pm
if
->
sg_nents
=
i
=
pmac_ide_build_sglist
(
drive
,
rq
);
hw
if
->
sg_nents
=
i
=
pmac_ide_build_sglist
(
drive
,
rq
);
if
(
!
i
)
return
0
;
/* Build DBDMA commands list */
sg
=
pm
if
->
sg_table
;
sg
=
hw
if
->
sg_table
;
while
(
i
&&
sg_dma_len
(
sg
))
{
u32
cur_addr
;
u32
cur_len
;
...
...
@@ -1692,16 +1686,16 @@ pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
memset
(
table
,
0
,
sizeof
(
struct
dbdma_cmd
));
st_le16
(
&
table
->
command
,
DBDMA_STOP
);
mb
();
writel
(
pmif
->
dma_
table_dma
,
&
dma
->
cmdptr
);
writel
(
hwif
->
dma
table_dma
,
&
dma
->
cmdptr
);
return
1
;
}
printk
(
KERN_DEBUG
"%s: empty DMA table?
\n
"
,
drive
->
name
);
use_pio_instead:
pci_unmap_sg
(
hwif
->
pci_dev
,
pm
if
->
sg_table
,
pm
if
->
sg_nents
,
pm
if
->
sg_dma_direction
);
hw
if
->
sg_table
,
hw
if
->
sg_nents
,
hw
if
->
sg_dma_direction
);
return
0
;
/* revert to PIO for this request */
}
...
...
@@ -1709,14 +1703,14 @@ pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
static
void
__pmac
pmac_ide_destroy_dmatable
(
ide_drive_t
*
drive
)
{
ide_hwif_t
*
hwif
=
drive
->
hwif
;
struct
pci_dev
*
dev
=
HWIF
(
drive
)
->
pci_dev
;
pmac_ide_hwif_t
*
pmif
=
(
pmac_ide_hwif_t
*
)
HWIF
(
drive
)
->
hwif_data
;
struct
scatterlist
*
sg
=
pmif
->
sg_table
;
int
nents
=
pmif
->
sg_nents
;
struct
scatterlist
*
sg
=
hwif
->
sg_table
;
int
nents
=
hwif
->
sg_nents
;
if
(
nents
)
{
pci_unmap_sg
(
dev
,
sg
,
nents
,
pm
if
->
sg_dma_direction
);
pm
if
->
sg_nents
=
0
;
pci_unmap_sg
(
dev
,
sg
,
nents
,
hw
if
->
sg_dma_direction
);
hw
if
->
sg_nents
=
0
;
}
}
...
...
@@ -1891,8 +1885,10 @@ pmac_ide_dma_setup(ide_drive_t *drive)
return
1
;
ata4
=
(
pmif
->
kind
==
controller_kl_ata4
);
if
(
!
pmac_ide_build_dmatable
(
drive
,
rq
))
if
(
!
pmac_ide_build_dmatable
(
drive
,
rq
))
{
ide_map_sg
(
drive
,
rq
);
return
1
;
}
/* Apple adds 60ns to wrDataSetup on reads */
if
(
ata4
&&
(
pmif
->
timings
[
unit
]
&
TR_66_UDMA_EN
))
{
...
...
@@ -2065,21 +2061,13 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
pmif
->
dma_table_cpu
=
(
struct
dbdma_cmd
*
)
pci_alloc_consistent
(
hwif
->
pci_dev
,
(
MAX_DCMDS
+
2
)
*
sizeof
(
struct
dbdma_cmd
),
&
pmif
->
dma_
table_dma
);
&
hwif
->
dma
table_dma
);
if
(
pmif
->
dma_table_cpu
==
NULL
)
{
printk
(
KERN_ERR
"%s: unable to allocate DMA command list
\n
"
,
hwif
->
name
);
return
;
}
pmif
->
sg_table
=
kmalloc
(
sizeof
(
struct
scatterlist
)
*
MAX_DCMDS
,
GFP_KERNEL
);
if
(
pmif
->
sg_table
==
NULL
)
{
pci_free_consistent
(
hwif
->
pci_dev
,
(
MAX_DCMDS
+
2
)
*
sizeof
(
struct
dbdma_cmd
),
pmif
->
dma_table_cpu
,
pmif
->
dma_table_dma
);
return
;
}
hwif
->
ide_dma_off_quietly
=
&
__ide_dma_off_quietly
;
hwif
->
ide_dma_on
=
&
__ide_dma_on
;
hwif
->
ide_dma_check
=
&
pmac_ide_dma_check
;
...
...
include/linux/ide.h
View file @
945fb655
...
...
@@ -789,27 +789,6 @@ typedef struct ide_drive_s {
struct
gendisk
*
disk
;
}
ide_drive_t
;
/*
* mapping stuff, prepare for highmem...
*
* temporarily mapping a (possible) highmem bio for PIO transfer
*/
#ifndef CONFIG_IDE_TASKFILE_IO
#define ide_rq_offset(rq) \
(((rq)->hard_cur_sectors - (rq)->current_nr_sectors) << 9)
static
inline
void
*
ide_map_buffer
(
struct
request
*
rq
,
unsigned
long
*
flags
)
{
return
bio_kmap_irq
(
rq
->
bio
,
flags
)
+
ide_rq_offset
(
rq
);
}
static
inline
void
ide_unmap_buffer
(
struct
request
*
rq
,
char
*
buffer
,
unsigned
long
*
flags
)
{
bio_kunmap_irq
(
buffer
,
flags
);
}
#endif
/* !CONFIG_IDE_TASKFILE_IO */
#define IDE_CHIPSET_PCI_MASK \
((1<<ide_pci)|(1<<ide_cmd646)|(1<<ide_ali14xx))
#define IDE_CHIPSET_IS_PCI(c) ((IDE_CHIPSET_PCI_MASK >> (c)) & 1)
...
...
@@ -920,12 +899,18 @@ typedef struct hwif_s {
dma_addr_t
dmatable_dma
;
/* Scatter-gather list used to build the above */
struct
scatterlist
*
sg_table
;
int
sg_max_nents
;
/* Maximum number of entries in it */
int
sg_nents
;
/* Current number of entries in it */
int
sg_dma_direction
;
/* dma transfer direction */
/* data phase of the active command (currently only valid for PIO/DMA) */
int
data_phase
;
unsigned
int
nsect
;
unsigned
int
nleft
;
unsigned
int
cursg
;
unsigned
int
cursg_ofs
;
int
mmio
;
/* hosts iomio (0) or custom (2) select */
int
rqsize
;
/* max sectors per request */
int
irq
;
/* our irq number */
...
...
@@ -1369,35 +1354,6 @@ extern void atapi_output_bytes(ide_drive_t *, void *, u32);
extern
void
taskfile_input_data
(
ide_drive_t
*
,
void
*
,
u32
);
extern
void
taskfile_output_data
(
ide_drive_t
*
,
void
*
,
u32
);
#define IDE_PIO_IN 0
#define IDE_PIO_OUT 1
static
inline
void
__task_sectors
(
ide_drive_t
*
drive
,
char
*
buf
,
unsigned
nsect
,
unsigned
rw
)
{
/*
* IRQ can happen instantly after reading/writing
* last sector of the datablock.
*/
if
(
rw
==
IDE_PIO_OUT
)
taskfile_output_data
(
drive
,
buf
,
nsect
*
SECTOR_WORDS
);
else
taskfile_input_data
(
drive
,
buf
,
nsect
*
SECTOR_WORDS
);
}
#ifdef CONFIG_IDE_TASKFILE_IO
static
inline
void
task_bio_sectors
(
ide_drive_t
*
drive
,
struct
request
*
rq
,
unsigned
nsect
,
unsigned
rw
)
{
unsigned
long
flags
;
char
*
buf
=
rq_map_buffer
(
rq
,
&
flags
);
process_that_request_first
(
rq
,
nsect
);
__task_sectors
(
drive
,
buf
,
nsect
,
rw
);
rq_unmap_buffer
(
buf
,
&
flags
);
}
#endif
/* CONFIG_IDE_TASKFILE_IO */
extern
int
drive_is_ready
(
ide_drive_t
*
);
extern
int
wait_for_ready
(
ide_drive_t
*
,
int
/* timeout */
);
...
...
@@ -1528,6 +1484,9 @@ typedef struct ide_pci_device_s {
extern
void
ide_setup_pci_device
(
struct
pci_dev
*
,
ide_pci_device_t
*
);
extern
void
ide_setup_pci_devices
(
struct
pci_dev
*
,
struct
pci_dev
*
,
ide_pci_device_t
*
);
void
ide_map_sg
(
ide_drive_t
*
,
struct
request
*
);
void
ide_init_sg_cmd
(
ide_drive_t
*
,
struct
request
*
);
#define BAD_DMA_DRIVE 0
#define GOOD_DMA_DRIVE 1
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment