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
nexedi
linux
Commits
80edba61
Commit
80edba61
authored
Oct 30, 2003
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://kernel.bkbits.net/davem/net-2.5
into home.osdl.org:/home/torvalds/v2.5/linux
parents
be2153ef
d475450e
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
721 additions
and
138 deletions
+721
-138
drivers/net/8139cp.c
drivers/net/8139cp.c
+1
-1
drivers/scsi/Kconfig
drivers/scsi/Kconfig
+1
-1
drivers/scsi/ata_piix.c
drivers/scsi/ata_piix.c
+6
-0
drivers/scsi/constants.c
drivers/scsi/constants.c
+8
-12
drivers/scsi/libata-core.c
drivers/scsi/libata-core.c
+50
-14
drivers/scsi/osst_options.h
drivers/scsi/osst_options.h
+1
-1
drivers/scsi/sata_promise.c
drivers/scsi/sata_promise.c
+634
-109
drivers/scsi/sata_sil.c
drivers/scsi/sata_sil.c
+2
-0
drivers/scsi/sata_svw.c
drivers/scsi/sata_svw.c
+2
-0
drivers/scsi/sata_via.c
drivers/scsi/sata_via.c
+3
-0
include/linux/libata.h
include/linux/libata.h
+13
-0
No files found.
drivers/net/8139cp.c
View file @
80edba61
...
...
@@ -615,8 +615,8 @@ static int cp_rx_poll (struct net_device *dev, int *budget)
if
(
cpr16
(
IntrStatus
)
&
cp_rx_intr_mask
)
goto
rx_status_loop
;
cpw16_f
(
IntrMask
,
cp_intr_mask
);
netif_rx_complete
(
dev
);
cpw16_f
(
IntrMask
,
cp_intr_mask
);
return
0
;
/* done */
}
...
...
drivers/scsi/Kconfig
View file @
80edba61
...
...
@@ -457,7 +457,7 @@ config SCSI_SATA_VIA
config SCSI_BUSLOGIC
tristate "BusLogic SCSI support"
depends on (PCI || ISA) && SCSI
depends on (PCI || ISA
|| MCA
) && SCSI
---help---
This is support for BusLogic MultiMaster and FlashPoint SCSI Host
Adapters. Consult the SCSI-HOWTO, available from
...
...
drivers/scsi/ata_piix.c
View file @
80edba61
...
...
@@ -117,6 +117,9 @@ static struct ata_port_operations piix_pata_ops = {
.
eng_timeout
=
ata_eng_timeout
,
.
irq_handler
=
ata_interrupt
,
.
port_start
=
ata_port_start
,
.
port_stop
=
ata_port_stop
,
};
static
struct
ata_port_operations
piix_sata_ops
=
{
...
...
@@ -137,6 +140,9 @@ static struct ata_port_operations piix_sata_ops = {
.
eng_timeout
=
ata_eng_timeout
,
.
irq_handler
=
ata_interrupt
,
.
port_start
=
ata_port_start
,
.
port_stop
=
ata_port_stop
,
};
static
struct
ata_port_info
piix_port_info
[]
=
{
...
...
drivers/scsi/constants.c
View file @
80edba61
...
...
@@ -915,15 +915,15 @@ scsi_show_extd_sense(unsigned char asc, unsigned char ascq) {
/* Print sense information */
static
void
print_sense_internal
(
const
char
*
devclass
,
const
unsigned
char
*
sense_buffer
,
print_sense_internal
(
const
char
*
devclass
,
const
unsigned
char
*
sense_buffer
,
struct
request
*
req
)
{
int
s
,
sense_class
,
valid
,
code
,
info
;
const
char
*
error
=
NULL
;
const
char
*
error
=
NULL
;
unsigned
char
asc
,
ascq
;
const
char
*
sense_txt
;
c
har
*
name
=
req
->
rq_disk
?
req
->
rq_disk
->
disk_name
:
"?"
;
c
onst
char
*
name
=
req
->
rq_disk
?
req
->
rq_disk
->
disk_name
:
devclass
;
sense_class
=
(
sense_buffer
[
0
]
>>
4
)
&
0x07
;
code
=
sense_buffer
[
0
]
&
0xf
;
...
...
@@ -966,11 +966,9 @@ print_sense_internal(const char * devclass,
sense_txt
=
scsi_sense_key_string
(
sense_buffer
[
2
]);
if
(
sense_txt
)
printk
(
"%s%s: sense key %s
\n
"
,
devclass
,
name
,
sense_txt
);
printk
(
"%s: sense key %s
\n
"
,
name
,
sense_txt
);
else
printk
(
"%s%s: sense = %2x %2x
\n
"
,
devclass
,
name
,
printk
(
"%s: sense = %2x %2x
\n
"
,
name
,
sense_buffer
[
0
],
sense_buffer
[
2
]);
asc
=
ascq
=
0
;
...
...
@@ -993,11 +991,9 @@ print_sense_internal(const char * devclass,
sense_txt
=
scsi_sense_key_string
(
sense_buffer
[
0
]);
if
(
sense_txt
)
printk
(
"%s%s: old sense key %s
\n
"
,
devclass
,
name
,
sense_txt
);
printk
(
"%s: old sense key %s
\n
"
,
name
,
sense_txt
);
else
printk
(
"%s%s: sense = %2x %2x
\n
"
,
devclass
,
name
,
printk
(
"%s: sense = %2x %2x
\n
"
,
name
,
sense_buffer
[
0
],
sense_buffer
[
2
]);
printk
(
"Non-extended sense class %d code 0x%0x
\n
"
,
...
...
drivers/scsi/libata-core.c
View file @
80edba61
...
...
@@ -1058,10 +1058,12 @@ void sata_phy_reset(struct ata_port *ap)
u32
sstatus
;
unsigned
long
timeout
=
jiffies
+
(
HZ
*
5
);
scr_write
(
ap
,
SCR_CONTROL
,
0x301
);
/* issue phy wake/reset */
scr_read
(
ap
,
SCR_CONTROL
);
/* dummy read; flush */
udelay
(
400
);
/* FIXME: a guess */
scr_write
(
ap
,
SCR_CONTROL
,
0x300
);
/* issue phy wake/reset */
if
(
ap
->
flags
&
ATA_FLAG_SATA_RESET
)
{
scr_write
(
ap
,
SCR_CONTROL
,
0x301
);
/* issue phy wake/reset */
scr_read
(
ap
,
SCR_STATUS
);
/* dummy read; flush */
udelay
(
400
);
/* FIXME: a guess */
}
scr_write
(
ap
,
SCR_CONTROL
,
0x300
);
/* issue phy wake/clear reset */
/* wait for phy to become ready, if necessary */
do
{
...
...
@@ -1084,6 +1086,11 @@ void sata_phy_reset(struct ata_port *ap)
if
(
ap
->
flags
&
ATA_FLAG_PORT_DISABLED
)
return
;
if
(
ata_busy_sleep
(
ap
,
ATA_TMOUT_BOOT_QUICK
,
ATA_TMOUT_BOOT
))
{
ata_port_disable
(
ap
);
return
;
}
ata_bus_reset
(
ap
);
}
...
...
@@ -1337,9 +1344,13 @@ void ata_bus_reset(struct ata_port *ap)
outb
(
ap
->
ctl
,
ioaddr
->
ctl_addr
);
/* determine if device 0/1 are present */
dev0
=
ata_dev_devchk
(
ap
,
0
);
if
(
slave_possible
)
dev1
=
ata_dev_devchk
(
ap
,
1
);
if
(
ap
->
flags
&
ATA_FLAG_SATA_RESET
)
dev0
=
1
;
else
{
dev0
=
ata_dev_devchk
(
ap
,
0
);
if
(
slave_possible
)
dev1
=
ata_dev_devchk
(
ap
,
1
);
}
if
(
dev0
)
devmask
|=
(
1
<<
0
);
...
...
@@ -2569,7 +2580,8 @@ static int ata_thread (void *data)
printk
(
KERN_DEBUG
"ata%u: thread exiting
\n
"
,
ap
->
id
);
ap
->
thr_pid
=
-
1
;
complete_and_exit
(
&
ap
->
thr_exited
,
0
);
del_timer_sync
(
&
ap
->
thr_timer
);
complete_and_exit
(
&
ap
->
thr_exited
,
0
);
}
/**
...
...
@@ -2664,6 +2676,26 @@ static void atapi_cdb_send(struct ata_port *ap)
goto
out
;
}
int
ata_port_start
(
struct
ata_port
*
ap
)
{
struct
pci_dev
*
pdev
=
ap
->
host_set
->
pdev
;
ap
->
prd
=
pci_alloc_consistent
(
pdev
,
ATA_PRD_TBL_SZ
,
&
ap
->
prd_dma
);
if
(
!
ap
->
prd
)
return
-
ENOMEM
;
DPRINTK
(
"prd alloc, virt %p, dma %x
\n
"
,
ap
->
prd
,
ap
->
prd_dma
);
return
0
;
}
void
ata_port_stop
(
struct
ata_port
*
ap
)
{
struct
pci_dev
*
pdev
=
ap
->
host_set
->
pdev
;
pci_free_consistent
(
pdev
,
ATA_PRD_TBL_SZ
,
ap
->
prd
,
ap
->
prd_dma
);
}
/**
* ata_host_remove -
* @ap:
...
...
@@ -2683,7 +2715,7 @@ static void ata_host_remove(struct ata_port *ap, unsigned int do_unregister)
ata_thread_kill
(
ap
);
/* FIXME: check return val */
pci_free_consistent
(
ap
->
host_set
->
pdev
,
ATA_PRD_TBL_SZ
,
ap
->
prd
,
ap
->
prd_dma
);
ap
->
ops
->
port_stop
(
ap
);
}
/**
...
...
@@ -2764,9 +2796,9 @@ static struct ata_port * ata_host_add(struct ata_probe_ent *ent,
struct
ata_host_set
*
host_set
,
unsigned
int
port_no
)
{
struct
pci_dev
*
pdev
=
ent
->
pdev
;
struct
Scsi_Host
*
host
;
struct
ata_port
*
ap
;
int
rc
;
DPRINTK
(
"ENTER
\n
"
);
host
=
scsi_host_alloc
(
ent
->
sht
,
sizeof
(
struct
ata_port
));
...
...
@@ -2777,10 +2809,9 @@ static struct ata_port * ata_host_add(struct ata_probe_ent *ent,
ata_host_init
(
ap
,
host
,
host_set
,
ent
,
port_no
);
ap
->
prd
=
pci_alloc_consistent
(
pdev
,
ATA_PRD_TBL_SZ
,
&
ap
->
prd_dma
);
if
(
!
ap
->
prd
)
rc
=
ap
->
ops
->
port_start
(
ap
);
if
(
rc
)
goto
err_out
;
DPRINTK
(
"prd alloc, virt %p, dma %x
\n
"
,
ap
->
prd
,
ap
->
prd_dma
);
ap
->
thr_pid
=
kernel_thread
(
ata_thread
,
ap
,
CLONE_FS
|
CLONE_FILES
);
if
(
ap
->
thr_pid
<
0
)
{
...
...
@@ -2792,7 +2823,7 @@ static struct ata_port * ata_host_add(struct ata_probe_ent *ent,
return
ap
;
err_out_free:
pci_free_consistent
(
ap
->
host_set
->
pdev
,
ATA_PRD_TBL_SZ
,
ap
->
prd
,
ap
->
prd_dma
);
ap
->
ops
->
port_stop
(
ap
);
err_out:
scsi_host_put
(
host
);
...
...
@@ -2828,6 +2859,7 @@ int ata_device_add(struct ata_probe_ent *ent)
host_set
->
n_ports
=
ent
->
n_ports
;
host_set
->
irq
=
ent
->
irq
;
host_set
->
mmio_base
=
ent
->
mmio_base
;
host_set
->
private_data
=
ent
->
private_data
;
/* register each port bound to this device */
for
(
i
=
0
;
i
<
ent
->
n_ports
;
i
++
)
{
...
...
@@ -3170,6 +3202,8 @@ void ata_pci_remove_one (struct pci_dev *pdev)
free_irq
(
host_set
->
irq
,
host_set
);
if
(
host_set
->
mmio_base
)
iounmap
(
host_set
->
mmio_base
);
if
(
host_set
->
ports
[
0
]
->
ops
->
host_stop
)
host_set
->
ports
[
0
]
->
ops
->
host_stop
(
host_set
);
for
(
i
=
0
;
i
<
host_set
->
n_ports
;
i
++
)
{
Scsi_Host_Template
*
sht
;
...
...
@@ -3274,6 +3308,8 @@ EXPORT_SYMBOL_GPL(ata_check_status_pio);
EXPORT_SYMBOL_GPL
(
ata_check_status_mmio
);
EXPORT_SYMBOL_GPL
(
ata_exec_command_pio
);
EXPORT_SYMBOL_GPL
(
ata_exec_command_mmio
);
EXPORT_SYMBOL_GPL
(
ata_port_start
);
EXPORT_SYMBOL_GPL
(
ata_port_stop
);
EXPORT_SYMBOL_GPL
(
ata_interrupt
);
EXPORT_SYMBOL_GPL
(
ata_fill_sg
);
EXPORT_SYMBOL_GPL
(
ata_bmdma_start_pio
);
...
...
drivers/scsi/osst_options.h
View file @
80edba61
...
...
@@ -57,7 +57,7 @@
/* The size of the first scatter/gather segments (determines the maximum block
size for SCSI adapters not supporting scatter/gather). The default is set
to try to allocate the buffer as one chunk. */
#define OSST_FIRST_ORDER
5
#define OSST_FIRST_ORDER
(15-PAGE_SHIFT)
/* The following lines define defaults for properties that can be set
...
...
drivers/scsi/sata_promise.c
View file @
80edba61
...
...
@@ -32,22 +32,46 @@
#include "scsi.h"
#include "hosts.h"
#include <linux/libata.h>
#include <asm/io.h>
#undef DIRECT_HDMA
#define DRV_NAME "sata_promise"
#define DRV_VERSION "0.8
3
"
#define DRV_VERSION "0.8
4
"
enum
{
PDC_PRD_TBL
=
0x44
,
/* Direct command DMA table addr */
PDC_PKT_SUBMIT
=
0x40
,
/* Command packet pointer addr */
PDC_HDMA_PKT_SUBMIT
=
0x100
,
/* Host DMA packet pointer addr */
PDC_INT_SEQMASK
=
0x40
,
/* Mask of asserted SEQ INTs */
PDC_TBG_MODE
=
0x41
,
/* TBG mode */
PDC_FLASH_CTL
=
0x44
,
/* Flash control register */
PDC_CTLSTAT
=
0x60
,
/* IDE control and status register */
PDC_SATA_PLUG_CSR
=
0x6C
,
/* SATA Plug control/status reg */
PDC_SLEW_CTL
=
0x470
,
/* slew rate control reg */
PDC_HDMA_CTLSTAT
=
0x12C
,
/* Host DMA control / status */
PDC_20621_SEQCTL
=
0x400
,
PDC_20621_SEQMASK
=
0x480
,
PDC_20621_PAGE_SIZE
=
(
32
*
1024
),
/* chosen, not constant, values; we design our own DIMM mem map */
PDC_20621_DIMM_WINDOW
=
0x0C
,
/* page# for 32K DIMM window */
PDC_20621_DIMM_BASE
=
0x00200000
,
PDC_20621_DIMM_DATA
=
(
64
*
1024
),
PDC_DIMM_DATA_STEP
=
(
256
*
1024
),
PDC_DIMM_WINDOW_STEP
=
(
8
*
1024
),
PDC_DIMM_HOST_PRD
=
(
6
*
1024
),
PDC_DIMM_HOST_PKT
=
(
128
*
0
),
PDC_DIMM_HPKT_PRD
=
(
128
*
1
),
PDC_DIMM_ATA_PKT
=
(
128
*
2
),
PDC_DIMM_APKT_PRD
=
(
128
*
3
),
PDC_DIMM_HEADER_SZ
=
PDC_DIMM_APKT_PRD
+
128
,
PDC_PAGE_WINDOW
=
0x40
,
PDC_PAGE_DATA
=
PDC_PAGE_WINDOW
+
(
PDC_20621_DIMM_DATA
/
PDC_20621_PAGE_SIZE
),
PDC_PAGE_SET
=
PDC_DIMM_DATA_STEP
/
PDC_20621_PAGE_SIZE
,
PDC_CHIP0_OFS
=
0xC0000
,
/* offset of chip #0 */
...
...
@@ -56,6 +80,14 @@ enum {
board_20621
=
2
,
/* FastTrak S150 SX4 */
PDC_FLAG_20621
=
(
1
<<
30
),
/* we have a 20621 */
PDC_HDMA_RESET
=
(
1
<<
11
),
/* HDMA reset */
};
struct
pdc_port_priv
{
u8
dimm_buf
[(
ATA_PRD_SZ
*
ATA_MAX_PRD
)
+
512
];
u8
*
pkt
;
dma_addr_t
pkt_dma
;
};
...
...
@@ -67,9 +99,20 @@ static void pdc_sata_set_udmamode (struct ata_port *ap, struct ata_device *adev,
unsigned
int
udma
);
static
int
pdc_sata_init_one
(
struct
pci_dev
*
pdev
,
const
struct
pci_device_id
*
ent
);
static
void
pdc_dma_start
(
struct
ata_queued_cmd
*
qc
);
static
void
pdc20621_dma_start
(
struct
ata_queued_cmd
*
qc
);
static
irqreturn_t
pdc_interrupt
(
int
irq
,
void
*
dev_instance
,
struct
pt_regs
*
regs
);
static
irqreturn_t
pdc20621_interrupt
(
int
irq
,
void
*
dev_instance
,
struct
pt_regs
*
regs
);
static
void
pdc_eng_timeout
(
struct
ata_port
*
ap
);
static
void
pdc_20621_phy_reset
(
struct
ata_port
*
ap
);
static
int
pdc_port_start
(
struct
ata_port
*
ap
);
static
void
pdc_port_stop
(
struct
ata_port
*
ap
);
static
void
pdc_fill_sg
(
struct
ata_queued_cmd
*
qc
);
static
void
pdc20621_fill_sg
(
struct
ata_queued_cmd
*
qc
);
static
void
pdc_tf_load_mmio
(
struct
ata_port
*
ap
,
struct
ata_taskfile
*
tf
);
static
void
pdc_exec_command_mmio
(
struct
ata_port
*
ap
,
struct
ata_taskfile
*
tf
);
static
void
pdc20621_host_stop
(
struct
ata_host_set
*
host_set
);
static
inline
void
pdc_dma_complete
(
struct
ata_port
*
ap
,
struct
ata_queued_cmd
*
qc
);
static
Scsi_Host_Template
pdc_sata_sht
=
{
...
...
@@ -93,34 +136,39 @@ static struct ata_port_operations pdc_sata_ops = {
.
port_disable
=
ata_port_disable
,
.
set_piomode
=
pdc_sata_set_piomode
,
.
set_udmamode
=
pdc_sata_set_udmamode
,
.
tf_load
=
ata
_tf_load_mmio
,
.
tf_load
=
pdc
_tf_load_mmio
,
.
tf_read
=
ata_tf_read_mmio
,
.
check_status
=
ata_check_status_mmio
,
.
exec_command
=
ata
_exec_command_mmio
,
.
exec_command
=
pdc
_exec_command_mmio
,
.
phy_reset
=
sata_phy_reset
,
.
phy_config
=
pata_phy_config
,
/* not a typo */
.
bmdma_start
=
pdc_dma_start
,
.
fill_sg
=
ata
_fill_sg
,
.
fill_sg
=
pdc
_fill_sg
,
.
eng_timeout
=
pdc_eng_timeout
,
.
irq_handler
=
pdc_interrupt
,
.
scr_read
=
pdc_sata_scr_read
,
.
scr_write
=
pdc_sata_scr_write
,
.
port_start
=
pdc_port_start
,
.
port_stop
=
pdc_port_stop
,
};
static
struct
ata_port_operations
pdc_20621_ops
=
{
.
port_disable
=
ata_port_disable
,
.
set_piomode
=
pdc_sata_set_piomode
,
.
set_udmamode
=
pdc_sata_set_udmamode
,
.
tf_load
=
ata
_tf_load_mmio
,
.
tf_load
=
pdc
_tf_load_mmio
,
.
tf_read
=
ata_tf_read_mmio
,
.
check_status
=
ata_check_status_mmio
,
.
exec_command
=
ata
_exec_command_mmio
,
.
exec_command
=
pdc
_exec_command_mmio
,
.
phy_reset
=
pdc_20621_phy_reset
,
.
phy_config
=
pata_phy_config
,
/* not a typo */
.
bmdma_start
=
pdc_dma_start
,
.
fill_sg
=
ata
_fill_sg
,
.
bmdma_start
=
pdc
20621
_dma_start
,
.
fill_sg
=
pdc20621
_fill_sg
,
.
eng_timeout
=
pdc_eng_timeout
,
.
irq_handler
=
pdc_interrupt
,
.
irq_handler
=
pdc20621_interrupt
,
.
port_start
=
pdc_port_start
,
.
port_stop
=
pdc_port_stop
,
.
host_stop
=
pdc20621_host_stop
,
};
static
struct
ata_port_info
pdc_port_info
[]
=
{
...
...
@@ -160,16 +208,16 @@ static struct ata_port_info pdc_port_info[] = {
static
struct
pci_device_id
pdc_sata_pci_tbl
[]
=
{
{
PCI_VENDOR_ID_PROMISE
,
0x3371
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
board_2037x
},
{
PCI_VENDOR_ID_PROMISE
,
0x3373
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
board_2037x
},
{
PCI_VENDOR_ID_PROMISE
,
0x3375
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
board_2037x
},
{
PCI_VENDOR_ID_PROMISE
,
0x3318
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
board_20319
},
{
PCI_VENDOR_ID_PROMISE
,
0x3319
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
board_20319
},
#if 0 /* broken currently */
{
PCI_VENDOR_ID_PROMISE
,
0x6622
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
board_20621
},
#endif
{
}
/* terminate list */
};
...
...
@@ -182,6 +230,60 @@ static struct pci_driver pdc_sata_pci_driver = {
};
static
void
pdc20621_host_stop
(
struct
ata_host_set
*
host_set
)
{
void
*
mmio
=
host_set
->
private_data
;
assert
(
mmio
!=
NULL
);
iounmap
(
mmio
);
}
static
int
pdc_port_start
(
struct
ata_port
*
ap
)
{
struct
pci_dev
*
pdev
=
ap
->
host_set
->
pdev
;
struct
pdc_port_priv
*
pp
;
int
rc
;
rc
=
ata_port_start
(
ap
);
if
(
rc
)
return
rc
;
pp
=
kmalloc
(
sizeof
(
*
pp
),
GFP_KERNEL
);
if
(
!
pp
)
{
rc
=
-
ENOMEM
;
goto
err_out
;
}
pp
->
pkt
=
pci_alloc_consistent
(
pdev
,
128
,
&
pp
->
pkt_dma
);
if
(
!
pp
->
pkt
)
{
rc
=
-
ENOMEM
;
goto
err_out_kfree
;
}
ap
->
private_data
=
pp
;
return
0
;
err_out_kfree:
kfree
(
pp
);
err_out:
ata_port_stop
(
ap
);
return
rc
;
}
static
void
pdc_port_stop
(
struct
ata_port
*
ap
)
{
struct
pci_dev
*
pdev
=
ap
->
host_set
->
pdev
;
struct
pdc_port_priv
*
pp
=
ap
->
private_data
;
ap
->
private_data
=
NULL
;
pci_free_consistent
(
pdev
,
128
,
pp
->
pkt
,
pp
->
pkt_dma
);
kfree
(
pp
);
ata_port_stop
(
ap
);
}
static
void
pdc_20621_phy_reset
(
struct
ata_port
*
ap
)
{
VPRINTK
(
"ENTER
\n
"
);
...
...
@@ -231,8 +333,9 @@ enum pdc_packet_bits {
PDC_REG_DEVCTL
=
(
1
<<
3
)
|
(
1
<<
2
)
|
(
1
<<
1
),
};
static
inline
void
pdc_pkt_header
(
struct
ata_taskfile
*
tf
,
dma_addr_t
sg_table
,
unsigned
int
devno
,
u8
*
buf
)
static
inline
unsigned
int
pdc_pkt_header
(
struct
ata_taskfile
*
tf
,
dma_addr_t
sg_table
,
unsigned
int
devno
,
u8
*
buf
)
{
u8
dev_reg
;
u32
*
buf32
=
(
u32
*
)
buf
;
...
...
@@ -273,9 +376,11 @@ static inline void pdc_pkt_header(struct ata_taskfile *tf, dma_addr_t sg_table,
/* device control register */
buf
[
14
]
=
(
1
<<
5
)
|
PDC_REG_DEVCTL
;
buf
[
15
]
=
tf
->
ctl
;
return
16
;
/* offset of next byte */
}
static
inline
void
pdc_pkt_footer
(
struct
ata_taskfile
*
tf
,
u8
*
buf
,
static
inline
unsigned
int
pdc_pkt_footer
(
struct
ata_taskfile
*
tf
,
u8
*
buf
,
unsigned
int
i
)
{
if
(
tf
->
flags
&
ATA_TFLAG_DEVICE
)
{
...
...
@@ -286,19 +391,14 @@ static inline void pdc_pkt_footer(struct ata_taskfile *tf, u8 *buf,
/* and finally the command itself; also includes end-of-pkt marker */
buf
[
i
++
]
=
(
1
<<
5
)
|
PDC_LAST_REG
|
ATA_REG_CMD
;
buf
[
i
++
]
=
tf
->
command
;
return
i
;
}
static
void
pdc_prep_lba28
(
struct
ata_taskfile
*
tf
,
dma_addr_t
sg_table
,
unsigned
int
devno
,
u8
*
buf
)
static
inline
unsigned
int
pdc_prep_lba28
(
struct
ata_taskfile
*
tf
,
u8
*
buf
,
unsigned
int
i
)
{
unsigned
int
i
;
pdc_pkt_header
(
tf
,
sg_table
,
devno
,
buf
);
/* the "(1 << 5)" should be read "(count << 5)" */
i
=
16
;
/* ATA command block registers */
buf
[
i
++
]
=
(
1
<<
5
)
|
ATA_REG_FEATURE
;
buf
[
i
++
]
=
tf
->
feature
;
...
...
@@ -315,20 +415,13 @@ static void pdc_prep_lba28(struct ata_taskfile *tf, dma_addr_t sg_table,
buf
[
i
++
]
=
(
1
<<
5
)
|
ATA_REG_LBAH
;
buf
[
i
++
]
=
tf
->
lbah
;
pdc_pkt_footer
(
tf
,
buf
,
i
)
;
return
i
;
}
static
void
pdc_prep_lba48
(
struct
ata_taskfile
*
tf
,
dma_addr_t
sg_table
,
unsigned
int
devno
,
u8
*
buf
)
static
inline
unsigned
int
pdc_prep_lba48
(
struct
ata_taskfile
*
tf
,
u8
*
buf
,
unsigned
int
i
)
{
unsigned
int
i
;
pdc_pkt_header
(
tf
,
sg_table
,
devno
,
buf
);
/* the "(2 << 5)" should be read "(count << 5)" */
i
=
16
;
/* ATA command block registers */
buf
[
i
++
]
=
(
2
<<
5
)
|
ATA_REG_FEATURE
;
buf
[
i
++
]
=
tf
->
hob_feature
;
...
...
@@ -350,28 +443,461 @@ static void pdc_prep_lba48(struct ata_taskfile *tf, dma_addr_t sg_table,
buf
[
i
++
]
=
tf
->
hob_lbah
;
buf
[
i
++
]
=
tf
->
lbah
;
pdc_pkt_footer
(
tf
,
buf
,
i
)
;
return
i
;
}
static
inline
void
__pdc_dma_complete
(
struct
ata_port
*
ap
,
struct
ata_queued_cmd
*
qc
)
static
inline
void
pdc20621_ata_sg
(
struct
ata_taskfile
*
tf
,
u8
*
buf
,
unsigned
int
portno
,
unsigned
int
total_len
)
{
void
*
dmactl
=
(
void
*
)
ap
->
ioaddr
.
cmd_addr
+
PDC_CTLSTAT
;
u32
val
;
u32
addr
;
unsigned
int
dw
=
PDC_DIMM_APKT_PRD
>>
2
;
u32
*
buf32
=
(
u32
*
)
buf
;
/* output ATA packet S/G table */
addr
=
PDC_20621_DIMM_BASE
+
PDC_20621_DIMM_DATA
+
(
PDC_DIMM_DATA_STEP
*
portno
);
VPRINTK
(
"ATA sg addr 0x%x, %d
\n
"
,
addr
,
addr
);
buf32
[
dw
]
=
cpu_to_le32
(
addr
);
buf32
[
dw
+
1
]
=
cpu_to_le32
(
total_len
|
ATA_PRD_EOT
);
VPRINTK
(
"ATA PSG @ %x == (0x%x, 0x%x)
\n
"
,
PDC_20621_DIMM_BASE
+
(
PDC_DIMM_WINDOW_STEP
*
portno
)
+
PDC_DIMM_APKT_PRD
,
buf32
[
dw
],
buf32
[
dw
+
1
]);
}
static
inline
void
pdc20621_host_sg
(
struct
ata_taskfile
*
tf
,
u8
*
buf
,
unsigned
int
portno
,
unsigned
int
total_len
)
{
u32
addr
;
unsigned
int
dw
=
PDC_DIMM_HPKT_PRD
>>
2
;
u32
*
buf32
=
(
u32
*
)
buf
;
/*
clear DMA start/stop bit (bit 7)
*/
val
=
readl
(
dmactl
);
writel
(
val
&
~
(
1
<<
7
),
dmactl
);
/*
output Host DMA packet S/G table
*/
addr
=
PDC_20621_DIMM_BASE
+
PDC_20621_DIMM_DATA
+
(
PDC_DIMM_DATA_STEP
*
portno
);
/* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
ata_altstatus
(
ap
);
/* dummy read */
buf32
[
dw
]
=
cpu_to_le32
(
addr
);
buf32
[
dw
+
1
]
=
cpu_to_le32
(
total_len
|
ATA_PRD_EOT
);
VPRINTK
(
"HOST PSG @ %x == (0x%x, 0x%x)
\n
"
,
PDC_20621_DIMM_BASE
+
(
PDC_DIMM_WINDOW_STEP
*
portno
)
+
PDC_DIMM_HPKT_PRD
,
buf32
[
dw
],
buf32
[
dw
+
1
]);
}
static
inline
unsigned
int
pdc20621_ata_pkt
(
struct
ata_taskfile
*
tf
,
unsigned
int
devno
,
u8
*
buf
,
unsigned
int
portno
)
{
unsigned
int
i
,
dw
;
u32
*
buf32
=
(
u32
*
)
buf
;
u8
dev_reg
;
unsigned
int
dimm_sg
=
PDC_20621_DIMM_BASE
+
(
PDC_DIMM_WINDOW_STEP
*
portno
)
+
PDC_DIMM_APKT_PRD
;
VPRINTK
(
"ENTER, dimm_sg == 0x%x, %d
\n
"
,
dimm_sg
,
dimm_sg
);
i
=
PDC_DIMM_ATA_PKT
;
/*
* Set up ATA packet
*/
if
(
tf
->
protocol
==
ATA_PROT_DMA_READ
)
buf
[
i
++
]
=
PDC_PKT_READ
;
else
if
(
tf
->
protocol
==
ATA_PROT_NODATA
)
buf
[
i
++
]
=
PDC_PKT_NODATA
;
else
buf
[
i
++
]
=
0
;
buf
[
i
++
]
=
0
;
/* reserved */
buf
[
i
++
]
=
portno
+
1
;
/* seq. id */
buf
[
i
++
]
=
0xff
;
/* delay seq. id */
/* dimm dma S/G, and next-pkt */
dw
=
i
>>
2
;
buf32
[
dw
]
=
cpu_to_le32
(
dimm_sg
);
buf32
[
dw
+
1
]
=
0
;
i
+=
8
;
if
(
devno
==
0
)
dev_reg
=
ATA_DEVICE_OBS
;
else
dev_reg
=
ATA_DEVICE_OBS
|
ATA_DEV1
;
/* select device */
buf
[
i
++
]
=
(
1
<<
5
)
|
PDC_PKT_CLEAR_BSY
|
ATA_REG_DEVICE
;
buf
[
i
++
]
=
dev_reg
;
/* device control register */
buf
[
i
++
]
=
(
1
<<
5
)
|
PDC_REG_DEVCTL
;
buf
[
i
++
]
=
tf
->
ctl
;
return
i
;
}
static
inline
void
pdc20621_host_pkt
(
struct
ata_taskfile
*
tf
,
u8
*
buf
,
unsigned
int
portno
)
{
unsigned
int
dw
;
u32
tmp
,
*
buf32
=
(
u32
*
)
buf
;
unsigned
int
host_sg
=
PDC_20621_DIMM_BASE
+
(
PDC_DIMM_WINDOW_STEP
*
portno
)
+
PDC_DIMM_HOST_PRD
;
unsigned
int
dimm_sg
=
PDC_20621_DIMM_BASE
+
(
PDC_DIMM_WINDOW_STEP
*
portno
)
+
PDC_DIMM_HPKT_PRD
;
VPRINTK
(
"ENTER, dimm_sg == 0x%x, %d
\n
"
,
dimm_sg
,
dimm_sg
);
VPRINTK
(
"host_sg == 0x%x, %d
\n
"
,
host_sg
,
host_sg
);
dw
=
PDC_DIMM_HOST_PKT
>>
2
;
/*
* Set up Host DMA packet
*/
if
(
tf
->
protocol
==
ATA_PROT_DMA_READ
)
tmp
=
PDC_PKT_READ
;
else
tmp
=
0
;
tmp
|=
((
portno
+
1
+
4
)
<<
16
);
/* seq. id */
tmp
|=
(
0xff
<<
24
);
/* delay seq. id */
buf32
[
dw
+
0
]
=
cpu_to_le32
(
tmp
);
buf32
[
dw
+
1
]
=
cpu_to_le32
(
host_sg
);
buf32
[
dw
+
2
]
=
cpu_to_le32
(
dimm_sg
);
buf32
[
dw
+
3
]
=
0
;
VPRINTK
(
"HOST PKT @ %x == (0x%x 0x%x 0x%x 0x%x)
\n
"
,
PDC_20621_DIMM_BASE
+
(
PDC_DIMM_WINDOW_STEP
*
portno
)
+
PDC_DIMM_HOST_PKT
,
buf32
[
dw
+
0
],
buf32
[
dw
+
1
],
buf32
[
dw
+
2
],
buf32
[
dw
+
3
]);
}
static
void
pdc20621_fill_sg
(
struct
ata_queued_cmd
*
qc
)
{
struct
scatterlist
*
sg
=
qc
->
sg
;
struct
ata_port
*
ap
=
qc
->
ap
;
struct
pdc_port_priv
*
pp
=
ap
->
private_data
;
void
*
dimm_mmio
=
ap
->
host_set
->
private_data
;
unsigned
int
portno
=
ap
->
port_no
;
unsigned
int
i
,
last
,
idx
,
total_len
=
0
,
sgt_len
;
u32
*
buf
=
(
u32
*
)
&
pp
->
dimm_buf
[
PDC_DIMM_HEADER_SZ
];
VPRINTK
(
"ata%u: ENTER
\n
"
,
ap
->
id
);
/*
* Build S/G table
*/
last
=
qc
->
n_elem
;
idx
=
0
;
for
(
i
=
0
;
i
<
last
;
i
++
)
{
buf
[
idx
++
]
=
cpu_to_le32
(
sg
[
i
].
dma_address
);
buf
[
idx
++
]
=
cpu_to_le32
(
sg
[
i
].
length
);
total_len
+=
sg
[
i
].
length
;
}
buf
[
idx
-
1
]
|=
cpu_to_le32
(
ATA_PRD_EOT
);
sgt_len
=
idx
*
4
;
/*
* Build ATA, host DMA packets
*/
pdc20621_host_sg
(
&
qc
->
tf
,
&
pp
->
dimm_buf
[
0
],
portno
,
total_len
);
pdc20621_host_pkt
(
&
qc
->
tf
,
&
pp
->
dimm_buf
[
0
],
portno
);
pdc20621_ata_sg
(
&
qc
->
tf
,
&
pp
->
dimm_buf
[
0
],
portno
,
total_len
);
i
=
pdc20621_ata_pkt
(
&
qc
->
tf
,
qc
->
dev
->
devno
,
&
pp
->
dimm_buf
[
0
],
portno
);
if
(
qc
->
tf
.
flags
&
ATA_TFLAG_LBA48
)
i
=
pdc_prep_lba48
(
&
qc
->
tf
,
&
pp
->
dimm_buf
[
0
],
i
);
else
i
=
pdc_prep_lba28
(
&
qc
->
tf
,
&
pp
->
dimm_buf
[
0
],
i
);
pdc_pkt_footer
(
&
qc
->
tf
,
&
pp
->
dimm_buf
[
0
],
i
);
/* copy three S/G tables and two packets to DIMM MMIO window */
memcpy_toio
(
dimm_mmio
+
(
portno
*
PDC_DIMM_WINDOW_STEP
),
&
pp
->
dimm_buf
,
PDC_DIMM_HEADER_SZ
);
memcpy_toio
(
dimm_mmio
+
(
portno
*
PDC_DIMM_WINDOW_STEP
)
+
PDC_DIMM_HOST_PRD
,
&
pp
->
dimm_buf
[
PDC_DIMM_HEADER_SZ
],
sgt_len
);
VPRINTK
(
"ata pkt buf ofs %u, prd size %u, mmio copied
\n
"
,
i
,
sgt_len
);
}
#ifdef DIRECT_HDMA
static
void
pdc20621_push_hdma
(
struct
ata_queued_cmd
*
qc
)
{
struct
ata_port
*
ap
=
qc
->
ap
;
struct
ata_host_set
*
host_set
=
ap
->
host_set
;
unsigned
int
port_no
=
ap
->
port_no
;
void
*
mmio
=
host_set
->
mmio_base
;
unsigned
int
rw
=
(
qc
->
flags
&
ATA_QCFLAG_WRITE
);
u32
tmp
;
unsigned
int
host_sg
=
PDC_20621_DIMM_BASE
+
(
PDC_DIMM_WINDOW_STEP
*
port_no
)
+
PDC_DIMM_HOST_PRD
;
unsigned
int
dimm_sg
=
PDC_20621_DIMM_BASE
+
(
PDC_DIMM_WINDOW_STEP
*
port_no
)
+
PDC_DIMM_HPKT_PRD
;
/* hard-code chip #0 */
mmio
+=
PDC_CHIP0_OFS
;
tmp
=
readl
(
mmio
+
PDC_HDMA_CTLSTAT
)
&
0xffffff00
;
tmp
|=
port_no
+
1
+
4
;
/* seq. ID */
if
(
!
rw
)
tmp
|=
(
1
<<
6
);
/* hdma data direction */
writel
(
tmp
,
mmio
+
PDC_HDMA_CTLSTAT
);
/* note: stops DMA, if active */
readl
(
mmio
+
PDC_HDMA_CTLSTAT
);
/* flush */
writel
(
host_sg
,
mmio
+
0x108
);
writel
(
dimm_sg
,
mmio
+
0x10C
);
writel
(
0
,
mmio
+
0x128
);
tmp
|=
(
1
<<
7
);
writel
(
tmp
,
mmio
+
PDC_HDMA_CTLSTAT
);
readl
(
mmio
+
PDC_HDMA_CTLSTAT
);
/* flush */
}
#endif
#ifdef ATA_VERBOSE_DEBUG
static
void
pdc20621_dump_hdma
(
struct
ata_queued_cmd
*
qc
)
{
struct
ata_port
*
ap
=
qc
->
ap
;
unsigned
int
port_no
=
ap
->
port_no
;
void
*
dimm_mmio
=
ap
->
host_set
->
private_data
;
dimm_mmio
+=
(
port_no
*
PDC_DIMM_WINDOW_STEP
);
dimm_mmio
+=
PDC_DIMM_HOST_PKT
;
printk
(
KERN_ERR
"HDMA[0] == 0x%08X
\n
"
,
readl
(
dimm_mmio
));
printk
(
KERN_ERR
"HDMA[1] == 0x%08X
\n
"
,
readl
(
dimm_mmio
+
4
));
printk
(
KERN_ERR
"HDMA[2] == 0x%08X
\n
"
,
readl
(
dimm_mmio
+
8
));
printk
(
KERN_ERR
"HDMA[3] == 0x%08X
\n
"
,
readl
(
dimm_mmio
+
12
));
}
#else
static
inline
void
pdc20621_dump_hdma
(
struct
ata_queued_cmd
*
qc
)
{
}
#endif
/* ATA_VERBOSE_DEBUG */
static
void
pdc20621_dma_start
(
struct
ata_queued_cmd
*
qc
)
{
struct
ata_port
*
ap
=
qc
->
ap
;
struct
ata_host_set
*
host_set
=
ap
->
host_set
;
unsigned
int
port_no
=
ap
->
port_no
;
void
*
mmio
=
host_set
->
mmio_base
;
unsigned
int
rw
=
(
qc
->
flags
&
ATA_QCFLAG_WRITE
);
u8
seq
=
(
u8
)
(
port_no
+
1
);
unsigned
int
doing_hdma
=
0
,
port_ofs
;
/* hard-code chip #0 */
mmio
+=
PDC_CHIP0_OFS
;
VPRINTK
(
"ata%u: ENTER
\n
"
,
ap
->
id
);
port_ofs
=
PDC_20621_DIMM_BASE
+
(
PDC_DIMM_WINDOW_STEP
*
port_no
);
/* if writing, we (1) DMA to DIMM, then (2) do ATA command */
if
(
rw
)
{
doing_hdma
=
1
;
seq
+=
4
;
}
wmb
();
/* flush PRD, pkt writes */
writel
(
0x00000001
,
mmio
+
PDC_20621_SEQCTL
+
(
seq
*
4
));
if
(
doing_hdma
)
{
pdc20621_dump_hdma
(
qc
);
#ifdef DIRECT_HDMA
pdc20621_push_hdma
(
qc
);
#else
writel
(
port_ofs
+
PDC_DIMM_HOST_PKT
,
mmio
+
PDC_HDMA_PKT_SUBMIT
);
#endif
VPRINTK
(
"submitted ofs 0x%x (%u), seq %u
\n
"
,
port_ofs
+
PDC_DIMM_HOST_PKT
,
port_ofs
+
PDC_DIMM_HOST_PKT
,
seq
);
}
else
{
writel
(
port_ofs
+
PDC_DIMM_ATA_PKT
,
(
void
*
)
ap
->
ioaddr
.
cmd_addr
+
PDC_PKT_SUBMIT
);
VPRINTK
(
"submitted ofs 0x%x (%u), seq %u
\n
"
,
port_ofs
+
PDC_DIMM_ATA_PKT
,
port_ofs
+
PDC_DIMM_ATA_PKT
,
seq
);
}
}
static
inline
unsigned
int
pdc20621_host_intr
(
struct
ata_port
*
ap
,
struct
ata_queued_cmd
*
qc
,
unsigned
int
doing_hdma
,
void
*
mmio
)
{
unsigned
int
port_no
=
ap
->
port_no
;
unsigned
int
port_ofs
=
PDC_20621_DIMM_BASE
+
(
PDC_DIMM_WINDOW_STEP
*
port_no
);
u8
status
;
unsigned
int
handled
=
0
;
VPRINTK
(
"ENTER
\n
"
);
switch
(
qc
->
tf
.
protocol
)
{
case
ATA_PROT_DMA_READ
:
/* step two - DMA from DIMM to host */
if
(
doing_hdma
)
{
VPRINTK
(
"ata%u: read hdma, 0x%x 0x%x
\n
"
,
ap
->
id
,
readl
(
mmio
+
0x104
),
readl
(
mmio
+
PDC_HDMA_CTLSTAT
));
pdc_dma_complete
(
ap
,
qc
);
}
/* step one - exec ATA command */
else
{
u8
seq
=
(
u8
)
(
port_no
+
1
+
4
);
VPRINTK
(
"ata%u: read ata, 0x%x 0x%x
\n
"
,
ap
->
id
,
readl
(
mmio
+
0x104
),
readl
(
mmio
+
PDC_HDMA_CTLSTAT
));
/* submit hdma pkt */
pdc20621_dump_hdma
(
qc
);
writel
(
0x00000001
,
mmio
+
PDC_20621_SEQCTL
+
(
seq
*
4
));
#ifdef DIRECT_HDMA
pdc20621_push_hdma
(
qc
);
#else
writel
(
port_ofs
+
PDC_DIMM_HOST_PKT
,
mmio
+
PDC_HDMA_PKT_SUBMIT
);
#endif
}
handled
=
1
;
break
;
case
ATA_PROT_DMA_WRITE
:
/* step one - DMA from host to DIMM */
if
(
doing_hdma
)
{
u8
seq
=
(
u8
)
(
port_no
+
1
);
VPRINTK
(
"ata%u: write hdma, 0x%x 0x%x
\n
"
,
ap
->
id
,
readl
(
mmio
+
0x104
),
readl
(
mmio
+
PDC_HDMA_CTLSTAT
));
/* submit ata pkt */
writel
(
0x00000001
,
mmio
+
PDC_20621_SEQCTL
+
(
seq
*
4
));
writel
(
port_ofs
+
PDC_DIMM_ATA_PKT
,
(
void
*
)
ap
->
ioaddr
.
cmd_addr
+
PDC_PKT_SUBMIT
);
}
/* step two - execute ATA command */
else
{
VPRINTK
(
"ata%u: write ata, 0x%x 0x%x
\n
"
,
ap
->
id
,
readl
(
mmio
+
0x104
),
readl
(
mmio
+
PDC_HDMA_CTLSTAT
));
pdc_dma_complete
(
ap
,
qc
);
}
handled
=
1
;
break
;
case
ATA_PROT_NODATA
:
/* command completion, but no data xfer */
status
=
ata_busy_wait
(
ap
,
ATA_BUSY
|
ATA_DRQ
,
1000
);
DPRINTK
(
"BUS_NODATA (drv_stat 0x%X)
\n
"
,
status
);
ata_qc_complete
(
qc
,
status
,
0
);
handled
=
1
;
break
;
default:
ap
->
stats
.
idle_irq
++
;
break
;
}
return
handled
;
}
static
irqreturn_t
pdc20621_interrupt
(
int
irq
,
void
*
dev_instance
,
struct
pt_regs
*
regs
)
{
struct
ata_host_set
*
host_set
=
dev_instance
;
struct
ata_port
*
ap
;
u32
mask
=
0
;
unsigned
int
i
,
tmp
,
port_no
;
unsigned
int
handled
=
0
;
void
*
mmio_base
;
VPRINTK
(
"ENTER
\n
"
);
if
(
!
host_set
||
!
host_set
->
mmio_base
)
{
VPRINTK
(
"QUICK EXIT
\n
"
);
return
IRQ_NONE
;
}
mmio_base
=
host_set
->
mmio_base
;
/* reading should also clear interrupts */
mmio_base
+=
PDC_CHIP0_OFS
;
mask
=
readl
(
mmio_base
+
PDC_20621_SEQMASK
);
VPRINTK
(
"mask == 0x%x
\n
"
,
mask
);
if
(
mask
==
0xffffffff
)
{
VPRINTK
(
"QUICK EXIT 2
\n
"
);
return
IRQ_NONE
;
}
mask
&=
0xf
;
/* only 16 tags possible */
if
(
!
mask
)
{
VPRINTK
(
"QUICK EXIT 3
\n
"
);
return
IRQ_NONE
;
}
spin_lock_irq
(
&
host_set
->
lock
);
for
(
i
=
1
;
i
<
9
;
i
++
)
{
port_no
=
i
-
1
;
if
(
port_no
>
3
)
port_no
-=
4
;
if
(
port_no
>=
host_set
->
n_ports
)
ap
=
NULL
;
else
ap
=
host_set
->
ports
[
port_no
];
tmp
=
mask
&
(
1
<<
i
);
VPRINTK
(
"seq %u, port_no %u, ap %p, tmp %x
\n
"
,
i
,
port_no
,
ap
,
tmp
);
if
(
tmp
&&
ap
&&
(
!
(
ap
->
flags
&
ATA_FLAG_PORT_DISABLED
)))
{
struct
ata_queued_cmd
*
qc
;
qc
=
ata_qc_from_tag
(
ap
,
ap
->
active_tag
);
if
(
qc
&&
((
qc
->
flags
&
ATA_QCFLAG_POLL
)
==
0
))
handled
+=
pdc20621_host_intr
(
ap
,
qc
,
(
i
>
4
),
mmio_base
);
}
}
spin_unlock_irq
(
&
host_set
->
lock
);
VPRINTK
(
"mask == 0x%x
\n
"
,
mask
);
VPRINTK
(
"EXIT
\n
"
);
return
IRQ_RETVAL
(
handled
);
}
static
void
pdc_fill_sg
(
struct
ata_queued_cmd
*
qc
)
{
struct
pdc_port_priv
*
pp
=
qc
->
ap
->
private_data
;
unsigned
int
i
;
VPRINTK
(
"ENTER
\n
"
);
ata_fill_sg
(
qc
);
i
=
pdc_pkt_header
(
&
qc
->
tf
,
qc
->
ap
->
prd_dma
,
qc
->
dev
->
devno
,
pp
->
pkt
);
if
(
qc
->
tf
.
flags
&
ATA_TFLAG_LBA48
)
i
=
pdc_prep_lba48
(
&
qc
->
tf
,
pp
->
pkt
,
i
);
else
i
=
pdc_prep_lba28
(
&
qc
->
tf
,
pp
->
pkt
,
i
);
pdc_pkt_footer
(
&
qc
->
tf
,
pp
->
pkt
,
i
);
}
static
inline
void
pdc_dma_complete
(
struct
ata_port
*
ap
,
struct
ata_queued_cmd
*
qc
)
{
__pdc_dma_complete
(
ap
,
qc
);
/* get drive status; clear intr; complete txn */
ata_qc_complete
(
ata_qc_from_tag
(
ap
,
ap
->
active_tag
),
ata_wait_idle
(
ap
),
0
);
...
...
@@ -395,7 +921,6 @@ static void pdc_eng_timeout(struct ata_port *ap)
case
ATA_PROT_DMA_READ
:
case
ATA_PROT_DMA_WRITE
:
printk
(
KERN_ERR
"ata%u: DMA timeout
\n
"
,
ap
->
id
);
__pdc_dma_complete
(
ap
,
qc
);
ata_qc_complete
(
ata_qc_from_tag
(
ap
,
ap
->
active_tag
),
ata_wait_idle
(
ap
)
|
ATA_ERR
,
0
);
break
;
...
...
@@ -457,7 +982,7 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *r
struct
ata_port
*
ap
;
u32
mask
=
0
;
unsigned
int
i
,
tmp
;
unsigned
int
handled
=
0
,
have_20621
=
0
;
unsigned
int
handled
=
0
;
void
*
mmio_base
;
VPRINTK
(
"ENTER
\n
"
);
...
...
@@ -469,21 +994,8 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *r
mmio_base
=
host_set
->
mmio_base
;
for
(
i
=
0
;
i
<
host_set
->
n_ports
;
i
++
)
{
ap
=
host_set
->
ports
[
i
];
if
(
ap
&&
(
ap
->
flags
&
PDC_FLAG_20621
))
{
have_20621
=
1
;
break
;
}
}
/* reading should also clear interrupts */
if
(
have_20621
)
{
mmio_base
+=
PDC_CHIP0_OFS
;
mask
=
readl
(
mmio_base
+
PDC_20621_SEQMASK
);
}
else
{
mask
=
readl
(
mmio_base
+
PDC_INT_SEQMASK
);
}
mask
=
readl
(
mmio_base
+
PDC_INT_SEQMASK
);
if
(
mask
==
0xffffffff
)
{
VPRINTK
(
"QUICK EXIT 2
\n
"
);
...
...
@@ -520,56 +1032,35 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *r
static
void
pdc_dma_start
(
struct
ata_queued_cmd
*
qc
)
{
struct
ata_port
*
ap
=
qc
->
ap
;
struct
ata_host_set
*
host_set
=
ap
->
host_set
;
struct
pdc_port_priv
*
pp
=
ap
->
private_data
;
unsigned
int
port_no
=
ap
->
port_no
;
void
*
mmio
=
host_set
->
mmio_base
;
void
*
dmactl
=
(
void
*
)
ap
->
ioaddr
.
cmd_addr
+
PDC_CTLSTAT
;
unsigned
int
rw
=
(
qc
->
flags
&
ATA_QCFLAG_WRITE
);
u32
val
;
u8
seq
=
(
u8
)
(
port_no
+
1
);
wmb
();
/* flush writes made to PRD table in DMA memory */
VPRINTK
(
"ENTER, ap %p
\n
"
,
ap
);
if
(
ap
->
flags
&
PDC_FLAG_20621
)
mmio
+=
PDC_CHIP0_OFS
;
writel
(
0x00000001
,
ap
->
host_set
->
mmio_base
+
(
seq
*
4
));
VPRINTK
(
"ENTER, ap %p, mmio %p
\n
"
,
ap
,
mmio
);
/* indicate where our S/G table is to chip */
writel
(
ap
->
prd_dma
,
(
void
*
)
ap
->
ioaddr
.
cmd_addr
+
PDC_PRD_TBL
);
/* clear dma start bit (paranoia), clear intr seq id (paranoia),
* set DMA direction (bit 6 == from chip -> drive)
*/
val
=
readl
(
dmactl
);
VPRINTK
(
"val == %x
\n
"
,
val
);
val
&=
~
(
1
<<
7
);
/* clear dma start/stop bit */
if
(
rw
)
/* set/clear dma direction bit */
val
|=
(
1
<<
6
);
else
val
&=
~
(
1
<<
6
);
if
(
qc
->
tf
.
ctl
&
ATA_NIEN
)
/* set/clear irq-mask bit */
val
|=
(
1
<<
10
);
else
val
&=
~
(
1
<<
10
);
writel
(
val
,
dmactl
);
val
=
readl
(
dmactl
);
VPRINTK
(
"val == %x
\n
"
,
val
);
pp
->
pkt
[
2
]
=
seq
;
wmb
();
/* flush PRD, pkt writes */
writel
(
pp
->
pkt_dma
,
(
void
*
)
ap
->
ioaddr
.
cmd_addr
+
PDC_PKT_SUBMIT
);
}
/* FIXME: clear any intr status bits here? */
static
void
pdc_tf_load_mmio
(
struct
ata_port
*
ap
,
struct
ata_taskfile
*
tf
)
{
if
((
tf
->
protocol
!=
ATA_PROT_DMA_READ
)
&&
(
tf
->
protocol
!=
ATA_PROT_DMA_WRITE
))
ata_tf_load_mmio
(
ap
,
tf
);
}
ata_exec_command_mmio
(
ap
,
&
qc
->
tf
);
VPRINTK
(
"FIVE
\n
"
);
if
(
ap
->
flags
&
PDC_FLAG_20621
)
writel
(
0x00000001
,
mmio
+
PDC_20621_SEQCTL
+
(
seq
*
4
));
else
writel
(
0x00000001
,
mmio
+
(
seq
*
4
));
/* start host DMA transaction */
writel
(
val
|
seq
|
(
1
<<
7
),
dmactl
);
static
void
pdc_exec_command_mmio
(
struct
ata_port
*
ap
,
struct
ata_taskfile
*
tf
)
{
if
((
tf
->
protocol
!=
ATA_PROT_DMA_READ
)
&&
(
tf
->
protocol
!=
ATA_PROT_DMA_WRITE
))
ata_exec_command_mmio
(
ap
,
tf
);
}
static
void
pdc_sata_setup_port
(
struct
ata_ioports
*
port
,
unsigned
long
base
)
{
port
->
cmd_addr
=
base
;
...
...
@@ -586,6 +1077,32 @@ static void pdc_sata_setup_port(struct ata_ioports *port, unsigned long base)
static
void
pdc_20621_init
(
struct
ata_probe_ent
*
pe
)
{
u32
tmp
;
void
*
mmio
=
pe
->
mmio_base
;
mmio
+=
PDC_CHIP0_OFS
;
/*
* Select page 0x40 for our 32k DIMM window
*/
tmp
=
readl
(
mmio
+
PDC_20621_DIMM_WINDOW
)
&
0xffff0000
;
tmp
|=
PDC_PAGE_WINDOW
;
/* page 40h; arbitrarily selected */
writel
(
tmp
,
mmio
+
PDC_20621_DIMM_WINDOW
);
/*
* Reset Host DMA
*/
tmp
=
readl
(
mmio
+
PDC_HDMA_CTLSTAT
);
tmp
|=
PDC_HDMA_RESET
;
writel
(
tmp
,
mmio
+
PDC_HDMA_CTLSTAT
);
readl
(
mmio
+
PDC_HDMA_CTLSTAT
);
/* flush */
udelay
(
10
);
tmp
=
readl
(
mmio
+
PDC_HDMA_CTLSTAT
);
tmp
&=
~
PDC_HDMA_RESET
;
writel
(
tmp
,
mmio
+
PDC_HDMA_CTLSTAT
);
readl
(
mmio
+
PDC_HDMA_CTLSTAT
);
/* flush */
}
static
void
pdc_host_init
(
unsigned
int
chip_id
,
struct
ata_probe_ent
*
pe
)
...
...
@@ -629,8 +1146,9 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
static
int
printed_version
;
struct
ata_probe_ent
*
probe_ent
=
NULL
;
unsigned
long
base
;
void
*
mmio_base
;
void
*
mmio_base
,
*
dimm_mmio
=
NULL
;
unsigned
int
board_idx
=
(
unsigned
int
)
ent
->
driver_data
;
unsigned
int
have_20621
=
(
board_idx
==
board_20621
);
int
rc
;
if
(
!
printed_version
++
)
...
...
@@ -670,6 +1188,15 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
}
base
=
(
unsigned
long
)
mmio_base
;
if
(
have_20621
)
{
dimm_mmio
=
ioremap
(
pci_resource_start
(
pdev
,
4
),
pci_resource_len
(
pdev
,
4
));
if
(
!
dimm_mmio
)
{
rc
=
-
ENOMEM
;
goto
err_out_iounmap
;
}
}
probe_ent
->
sht
=
pdc_port_info
[
board_idx
].
sht
;
probe_ent
->
host_flags
=
pdc_port_info
[
board_idx
].
host_flags
;
probe_ent
->
pio_mask
=
pdc_port_info
[
board_idx
].
pio_mask
;
...
...
@@ -680,8 +1207,10 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
probe_ent
->
irq_flags
=
SA_SHIRQ
;
probe_ent
->
mmio_base
=
mmio_base
;
if
(
board_idx
==
board_20621
)
if
(
have_20621
)
{
probe_ent
->
private_data
=
dimm_mmio
;
base
+=
PDC_CHIP0_OFS
;
}
pdc_sata_setup_port
(
&
probe_ent
->
port
[
0
],
base
+
0x200
);
probe_ent
->
port
[
0
].
scr_addr
=
base
+
0x400
;
...
...
@@ -712,15 +1241,10 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
pci_set_master
(
pdev
);
/* initialize adapter */
switch
(
board_idx
)
{
case
board_20621
:
if
(
have_20621
)
pdc_20621_init
(
probe_ent
);
break
;
default:
else
pdc_host_init
(
board_idx
,
probe_ent
);
break
;
}
/* FIXME: check ata_device_add return value */
ata_device_add
(
probe_ent
);
...
...
@@ -728,6 +1252,8 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
return
0
;
err_out_iounmap:
iounmap
(
mmio_base
);
err_out_free_ent:
kfree
(
probe_ent
);
err_out_regions:
...
...
@@ -738,7 +1264,6 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
}
static
int
__init
pdc_sata_init
(
void
)
{
int
rc
;
...
...
drivers/scsi/sata_sil.c
View file @
80edba61
...
...
@@ -106,6 +106,8 @@ static struct ata_port_operations sil_ops = {
.
irq_handler
=
ata_interrupt
,
.
scr_read
=
sil_scr_read
,
.
scr_write
=
sil_scr_write
,
.
port_start
=
ata_port_start
,
.
port_stop
=
ata_port_stop
,
};
static
struct
ata_port_info
sil_port_info
[]
=
{
...
...
drivers/scsi/sata_svw.c
View file @
80edba61
...
...
@@ -235,6 +235,8 @@ static struct ata_port_operations k2_sata_ops = {
.
irq_handler
=
ata_interrupt
,
.
scr_read
=
k2_sata_scr_read
,
.
scr_write
=
k2_sata_scr_write
,
.
port_start
=
ata_port_start
,
.
port_stop
=
ata_port_stop
,
};
...
...
drivers/scsi/sata_via.c
View file @
80edba61
...
...
@@ -98,6 +98,9 @@ static struct ata_port_operations svia_sata_ops = {
.
eng_timeout
=
ata_eng_timeout
,
.
irq_handler
=
ata_interrupt
,
.
port_start
=
ata_port_start
,
.
port_stop
=
ata_port_stop
,
};
static
struct
ata_port_info
svia_port_info
[]
=
{
...
...
include/linux/libata.h
View file @
80edba61
...
...
@@ -207,6 +207,7 @@ struct ata_probe_ent {
unsigned
int
irq_flags
;
unsigned
long
host_flags
;
void
*
mmio_base
;
void
*
private_data
;
};
struct
ata_host_set
{
...
...
@@ -215,6 +216,7 @@ struct ata_host_set {
unsigned
long
irq
;
void
*
mmio_base
;
unsigned
int
n_ports
;
void
*
private_data
;
struct
ata_port
*
ports
[
0
];
};
...
...
@@ -264,6 +266,8 @@ struct ata_queued_cmd {
ata_qc_cb_t
callback
;
struct
semaphore
sem
;
void
*
private_data
;
};
struct
ata_host_stats
{
...
...
@@ -333,6 +337,8 @@ struct ata_port {
struct
semaphore
thr_sem
;
struct
timer_list
thr_timer
;
unsigned
long
thr_timeout
;
void
*
private_data
;
};
struct
ata_port_operations
{
...
...
@@ -363,6 +369,11 @@ struct ata_port_operations {
u32
(
*
scr_read
)
(
struct
ata_port
*
ap
,
unsigned
int
sc_reg
);
void
(
*
scr_write
)
(
struct
ata_port
*
ap
,
unsigned
int
sc_reg
,
u32
val
);
int
(
*
port_start
)
(
struct
ata_port
*
ap
);
void
(
*
port_stop
)
(
struct
ata_port
*
ap
);
void
(
*
host_stop
)
(
struct
ata_host_set
*
host_set
);
};
struct
ata_port_info
{
...
...
@@ -406,6 +417,8 @@ extern u8 ata_check_status_pio(struct ata_port *ap);
extern
u8
ata_check_status_mmio
(
struct
ata_port
*
ap
);
extern
void
ata_exec_command_pio
(
struct
ata_port
*
ap
,
struct
ata_taskfile
*
tf
);
extern
void
ata_exec_command_mmio
(
struct
ata_port
*
ap
,
struct
ata_taskfile
*
tf
);
extern
int
ata_port_start
(
struct
ata_port
*
ap
);
extern
void
ata_port_stop
(
struct
ata_port
*
ap
);
extern
irqreturn_t
ata_interrupt
(
int
irq
,
void
*
dev_instance
,
struct
pt_regs
*
regs
);
extern
void
ata_fill_sg
(
struct
ata_queued_cmd
*
qc
);
extern
void
ata_bmdma_start_mmio
(
struct
ata_queued_cmd
*
qc
);
...
...
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