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
428a467d
Commit
428a467d
authored
Mar 26, 2004
by
Jeff Garzik
Browse files
Options
Browse Files
Download
Plain Diff
Merge redhat.com:/spare/repo/linux-2.6
into redhat.com:/spare/repo/libata-2.6
parents
4e6e2877
12517cba
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
812 additions
and
407 deletions
+812
-407
drivers/scsi/Kconfig
drivers/scsi/Kconfig
+8
-0
drivers/scsi/Makefile
drivers/scsi/Makefile
+1
-0
drivers/scsi/ata_piix.c
drivers/scsi/ata_piix.c
+60
-109
drivers/scsi/libata-core.c
drivers/scsi/libata-core.c
+201
-71
drivers/scsi/libata-scsi.c
drivers/scsi/libata-scsi.c
+235
-146
drivers/scsi/libata.h
drivers/scsi/libata.h
+2
-5
drivers/scsi/sata_promise.c
drivers/scsi/sata_promise.c
+43
-36
drivers/scsi/sata_sis.c
drivers/scsi/sata_sis.c
+214
-0
include/linux/ata.h
include/linux/ata.h
+41
-10
include/linux/libata.h
include/linux/libata.h
+6
-30
include/linux/pci_ids.h
include/linux/pci_ids.h
+1
-0
No files found.
drivers/scsi/Kconfig
View file @
428a467d
...
...
@@ -449,6 +449,14 @@ config SCSI_SATA_SIL
If unsure, say N.
config SCSI_SATA_SIS
tristate "SiS 964/180 SATA support"
depends on SCSI_SATA && PCI
help
This option enables support for SiS Serial ATA 964/180.
If unsure, say N.
config SCSI_SATA_VIA
tristate "VIA SATA support"
depends on SCSI_SATA && PCI && EXPERIMENTAL
...
...
drivers/scsi/Makefile
View file @
428a467d
...
...
@@ -123,6 +123,7 @@ obj-$(CONFIG_SCSI_SATA_PROMISE) += libata.o sata_promise.o
obj-$(CONFIG_SCSI_SATA_SIL)
+=
libata.o sata_sil.o
obj-$(CONFIG_SCSI_SATA_VIA)
+=
libata.o sata_via.o
obj-$(CONFIG_SCSI_SATA_VITESSE)
+=
libata.o sata_vsc.o
obj-$(CONFIG_SCSI_SATA_SIS)
+=
libata.o sata_sis.o
obj-$(CONFIG_ARM)
+=
arm/
...
...
drivers/scsi/ata_piix.c
View file @
428a467d
...
...
@@ -28,17 +28,24 @@
#include <linux/libata.h>
#define DRV_NAME "ata_piix"
#define DRV_VERSION "1.0
1
"
#define DRV_VERSION "1.0
2
"
enum
{
PIIX_IOCFG
=
0x54
,
/* IDE I/O configuration register */
ICH5_PMR
=
0x90
,
/* port mapping register */
ICH5_PCS
=
0x92
,
/* port control and status */
PIIX_FLAG_CHECKINTR
=
(
1
<<
29
),
/* make sure PCI INTx enabled */
PIIX_FLAG_COMBINED
=
(
1
<<
30
),
/* combined mode possible */
PIIX_COMB_PRI
=
(
1
<<
0
),
/* combined mode, PATA primary */
PIIX_COMB_SEC
=
(
1
<<
1
),
/* combined mode, PATA secondary */
/* combined mode. if set, PATA is channel 0.
* if clear, PATA is channel 1.
*/
PIIX_COMB_PATA_P0
=
(
1
<<
1
),
PIIX_COMB
=
(
1
<<
2
),
/* combined mode enabled? */
PIIX_PORT_PRESENT
=
(
1
<<
0
),
PIIX_PORT_ENABLED
=
(
1
<<
4
),
PIIX_80C_PRI
=
(
1
<<
5
)
|
(
1
<<
4
),
PIIX_80C_SEC
=
(
1
<<
7
)
|
(
1
<<
6
),
...
...
@@ -53,7 +60,6 @@ static int piix_init_one (struct pci_dev *pdev,
static
void
piix_pata_phy_reset
(
struct
ata_port
*
ap
);
static
void
piix_sata_phy_reset
(
struct
ata_port
*
ap
);
static
void
piix_sata_port_disable
(
struct
ata_port
*
ap
);
static
void
piix_set_piomode
(
struct
ata_port
*
ap
,
struct
ata_device
*
adev
,
unsigned
int
pio
);
static
void
piix_set_udmamode
(
struct
ata_port
*
ap
,
struct
ata_device
*
adev
,
...
...
@@ -137,7 +143,7 @@ static struct ata_port_operations piix_pata_ops = {
};
static
struct
ata_port_operations
piix_sata_ops
=
{
.
port_disable
=
piix_s
ata_port_disable
,
.
port_disable
=
ata_port_disable
,
.
set_piomode
=
piix_set_piomode
,
.
set_udmamode
=
piix_set_udmamode
,
...
...
@@ -259,54 +265,48 @@ static void piix_pata_phy_reset(struct ata_port *ap)
}
/**
* piix_pcs_probe - Probe SATA port configuration and status register
* @ap: Port to probe
* @have_port: (output) Non-zero if SATA port is enabled
* @have_device: (output) Non-zero if SATA phy indicates device present
* piix_sata_probe - Probe PCI device for present SATA devices
* @pdev: PCI device to probe
*
* Reads SATA PCI device's PCI config register Port Configuration
* and Status (PCS) to determine port and device availability.
*
* LOCKING:
* None (inherited from caller).
*/
static
void
piix_pcs_probe
(
struct
ata_port
*
ap
,
unsigned
int
*
have_port
,
unsigned
int
*
have_device
)
{
struct
pci_dev
*
pdev
=
ap
->
host_set
->
pdev
;
u16
pcs
;
pci_read_config_word
(
pdev
,
ICH5_PCS
,
&
pcs
);
/* is SATA port enabled? */
if
(
pcs
&
(
1
<<
ap
->
port_no
))
{
*
have_port
=
1
;
if
(
pcs
&
(
1
<<
(
ap
->
port_no
+
4
)))
*
have_device
=
1
;
}
}
/**
* piix_pcs_disable - Disable SATA port
* @ap: Port to disable
*
* Disable SATA phy for specified port.
*
*
LOCKING
:
* Non
e (inherited from caller)
.
*
RETURNS
:
* Non
-zero if device detected, zero otherwise
.
*/
static
void
piix_pcs_disabl
e
(
struct
ata_port
*
ap
)
static
int
piix_sata_prob
e
(
struct
ata_port
*
ap
)
{
struct
pci_dev
*
pdev
=
ap
->
host_set
->
pdev
;
u16
pcs
;
int
combined
=
(
ap
->
flags
&
ATA_FLAG_SLAVE_POSS
);
int
orig_mask
,
mask
,
i
;
u8
pcs
;
mask
=
(
PIIX_PORT_PRESENT
<<
ap
->
port_no
)
|
(
PIIX_PORT_ENABLED
<<
ap
->
port_no
);
pci_read_config_byte
(
pdev
,
ICH5_PCS
,
&
pcs
);
orig_mask
=
(
int
)
pcs
&
0xff
;
/* TODO: this is vaguely wrong for ICH6 combined mode,
* where only two of the four SATA ports are mapped
* onto a single ATA channel. It is also vaguely inaccurate
* for ICH5, which has only two ports. However, this is ok,
* as further device presence detection code will handle
* any false positives produced here.
*/
pci_read_config_word
(
pdev
,
ICH5_PCS
,
&
pcs
);
for
(
i
=
0
;
i
<
4
;
i
++
)
{
mask
=
(
PIIX_PORT_PRESENT
<<
i
)
|
(
PIIX_PORT_ENABLED
<<
i
);
if
(
pcs
&
(
1
<<
ap
->
port_no
))
{
pcs
&=
~
(
1
<<
ap
->
port_no
);
pci_write_config_word
(
pdev
,
ICH5_PCS
,
pcs
)
;
if
((
orig_mask
&
mask
)
==
mask
)
if
(
combined
||
(
i
==
ap
->
port_no
))
return
1
;
}
return
0
;
}
/**
...
...
@@ -321,8 +321,6 @@ static void piix_pcs_disable (struct ata_port *ap)
static
void
piix_sata_phy_reset
(
struct
ata_port
*
ap
)
{
unsigned
int
have_port
=
0
,
have_dev
=
0
;
if
(
!
pci_test_config_bits
(
ap
->
host_set
->
pdev
,
&
piix_enable_bits
[
ap
->
port_no
]))
{
ata_port_disable
(
ap
);
...
...
@@ -330,21 +328,9 @@ static void piix_sata_phy_reset(struct ata_port *ap)
return
;
}
piix_pcs_probe
(
ap
,
&
have_port
,
&
have_dev
);
/* if port not enabled, exit */
if
(
!
have_port
)
{
if
(
!
piix_sata_probe
(
ap
))
{
ata_port_disable
(
ap
);
printk
(
KERN_INFO
"ata%u: SATA port disabled. ignoring.
\n
"
,
ap
->
id
);
return
;
}
/* if port enabled but no device, disable port and exit */
if
(
!
have_dev
)
{
piix_sata_port_disable
(
ap
);
printk
(
KERN_INFO
"ata%u: SATA port has no device. disabling.
\n
"
,
ap
->
id
);
printk
(
KERN_INFO
"ata%u: SATA port has no device.
\n
"
,
ap
->
id
);
return
;
}
...
...
@@ -355,22 +341,6 @@ static void piix_sata_phy_reset(struct ata_port *ap)
ata_bus_reset
(
ap
);
}
/**
* piix_sata_port_disable - Disable SATA port
* @ap: Port to disable.
*
* Disable SATA port.
*
* LOCKING:
* None (inherited from caller).
*/
static
void
piix_sata_port_disable
(
struct
ata_port
*
ap
)
{
ata_port_disable
(
ap
);
piix_pcs_disable
(
ap
);
}
/**
* piix_set_piomode - Initialize host controller PATA PIO timings
* @ap: Port whose timings we are configuring
...
...
@@ -493,31 +463,6 @@ static void piix_set_udmamode (struct ata_port *ap, struct ata_device *adev,
}
}
/**
* piix_probe_combined - Determine if PATA and SATA are combined
* @pdev: PCI device to examine
* @mask: (output) zero, %PIIX_COMB_PRI or %PIIX_COMB_SEC
*
* Determine if BIOS has secretly stuffed a PATA port into our
* otherwise-beautiful SATA PCI device.
*
* LOCKING:
* Inherited from PCI layer (may sleep).
*/
static
void
piix_probe_combined
(
struct
pci_dev
*
pdev
,
unsigned
int
*
mask
)
{
u8
tmp
;
pci_read_config_byte
(
pdev
,
0x90
,
&
tmp
);
/* combined mode reg */
tmp
&=
0x6
;
/* interesting bits 2:1, PATA primary/secondary */
/* backwards from what one might expect */
if
(
tmp
==
0x4
)
/* bits 10x */
*
mask
|=
PIIX_COMB_SEC
;
if
(
tmp
==
0x6
)
/* bits 11x */
*
mask
|=
PIIX_COMB_PRI
;
}
/* move to PCI layer, integrate w/ MSI stuff */
static
void
pci_enable_intx
(
struct
pci_dev
*
pdev
)
{
...
...
@@ -550,7 +495,7 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
static
int
printed_version
;
struct
ata_port_info
*
port_info
[
2
];
unsigned
int
combined
=
0
,
n_ports
=
1
;
unsigned
int
pata_c
omb
=
0
,
sata_comb
=
0
;
unsigned
int
pata_c
han
=
0
,
sata_chan
=
0
;
if
(
!
printed_version
++
)
printk
(
KERN_DEBUG
DRV_NAME
" version "
DRV_VERSION
"
\n
"
);
...
...
@@ -561,8 +506,19 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
port_info
[
0
]
=
&
piix_port_info
[
ent
->
driver_data
];
port_info
[
1
]
=
NULL
;
if
(
port_info
[
0
]
->
host_flags
&
PIIX_FLAG_COMBINED
)
piix_probe_combined
(
pdev
,
&
combined
);
if
(
port_info
[
0
]
->
host_flags
&
PIIX_FLAG_COMBINED
)
{
u8
tmp
;
pci_read_config_byte
(
pdev
,
ICH5_PMR
,
&
tmp
);
if
(
tmp
&
PIIX_COMB
)
{
combined
=
1
;
if
(
tmp
&
PIIX_COMB_PATA_P0
)
sata_chan
=
1
;
else
pata_chan
=
1
;
}
}
/* On ICH5, some BIOSen disable the interrupt using the
* PCI_COMMAND_INTX_DISABLE bit added in PCI 2.3.
...
...
@@ -573,15 +529,10 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if
(
port_info
[
0
]
->
host_flags
&
PIIX_FLAG_CHECKINTR
)
pci_enable_intx
(
pdev
);
if
(
combined
&
PIIX_COMB_PRI
)
sata_comb
=
1
;
else
if
(
combined
&
PIIX_COMB_SEC
)
pata_comb
=
1
;
if
(
pata_comb
||
sata_comb
)
{
port_info
[
sata_comb
]
=
&
piix_port_info
[
ent
->
driver_data
];
port_info
[
sata_comb
]
->
host_flags
|=
ATA_FLAG_SLAVE_POSS
;
/* sigh */
port_info
[
pata_comb
]
=
&
piix_port_info
[
ich5_pata
];
/*ich5-specific*/
if
(
combined
)
{
port_info
[
sata_chan
]
=
&
piix_port_info
[
ent
->
driver_data
];
port_info
[
sata_chan
]
->
host_flags
|=
ATA_FLAG_SLAVE_POSS
;
port_info
[
pata_chan
]
=
&
piix_port_info
[
ich5_pata
];
n_ports
++
;
printk
(
KERN_WARNING
DRV_NAME
": combined mode detected
\n
"
);
...
...
drivers/scsi/libata-core.c
View file @
428a467d
...
...
@@ -439,6 +439,81 @@ u8 ata_check_status_mmio(struct ata_port *ap)
return
readb
((
void
*
)
ap
->
ioaddr
.
status_addr
);
}
/**
* ata_prot_to_cmd - determine which read/write opcodes to use
* @protocol: ATA_PROT_xxx taskfile protocol
* @lba48: true is lba48 is present
*
* Given necessary input, determine which read/write commands
* to use to transfer data.
*
* LOCKING:
* None.
*/
static
int
ata_prot_to_cmd
(
int
protocol
,
int
lba48
)
{
int
rcmd
=
0
,
wcmd
=
0
;
switch
(
protocol
)
{
case
ATA_PROT_PIO
:
if
(
lba48
)
{
rcmd
=
ATA_CMD_PIO_READ_EXT
;
wcmd
=
ATA_CMD_PIO_WRITE_EXT
;
}
else
{
rcmd
=
ATA_CMD_PIO_READ
;
wcmd
=
ATA_CMD_PIO_WRITE
;
}
break
;
case
ATA_PROT_DMA
:
if
(
lba48
)
{
rcmd
=
ATA_CMD_READ_EXT
;
wcmd
=
ATA_CMD_WRITE_EXT
;
}
else
{
rcmd
=
ATA_CMD_READ
;
wcmd
=
ATA_CMD_WRITE
;
}
break
;
default:
return
-
1
;
}
return
rcmd
|
(
wcmd
<<
8
);
}
/**
* ata_dev_set_protocol - set taskfile protocol and r/w commands
* @dev: device to examine and configure
*
* Examine the device configuration, after we have
* read the identify-device page and configured the
* data transfer mode. Set internal state related to
* the ATA taskfile protocol (pio, pio mult, dma, etc.)
* and calculate the proper read/write commands to use.
*
* LOCKING:
* caller.
*/
static
void
ata_dev_set_protocol
(
struct
ata_device
*
dev
)
{
int
pio
=
(
dev
->
flags
&
ATA_DFLAG_PIO
);
int
lba48
=
(
dev
->
flags
&
ATA_DFLAG_LBA48
);
int
proto
,
cmd
;
if
(
pio
)
proto
=
dev
->
xfer_protocol
=
ATA_PROT_PIO
;
else
proto
=
dev
->
xfer_protocol
=
ATA_PROT_DMA
;
cmd
=
ata_prot_to_cmd
(
proto
,
lba48
);
if
(
cmd
<
0
)
BUG
();
dev
->
read_cmd
=
cmd
&
0xff
;
dev
->
write_cmd
=
(
cmd
>>
8
)
&
0xff
;
}
static
const
char
*
udma_str
[]
=
{
"UDMA/16"
,
"UDMA/25"
,
...
...
@@ -478,12 +553,21 @@ static const char *ata_udma_string(unsigned int udma_mask)
}
/**
* ata_pio_devchk -
* @ap:
* @device:
* ata_pio_devchk -
PATA device presence detection
* @ap:
ATA channel to examine
* @device:
Device to examine (starting at zero)
*
* LOCKING:
* This technique was originally described in
* Hale Landis's ATADRVR (www.ata-atapi.com), and
* later found its way into the ATA/ATAPI spec.
*
* Write a pattern to the ATA shadow registers,
* and if a device is present, it will respond by
* correctly storing and echoing back the
* ATA shadow register contents.
*
* LOCKING:
* caller.
*/
static
unsigned
int
ata_pio_devchk
(
struct
ata_port
*
ap
,
...
...
@@ -513,12 +597,21 @@ static unsigned int ata_pio_devchk(struct ata_port *ap,
}
/**
* ata_mmio_devchk -
* @ap:
* @device:
* ata_mmio_devchk -
PATA device presence detection
* @ap:
ATA channel to examine
* @device:
Device to examine (starting at zero)
*
* LOCKING:
* This technique was originally described in
* Hale Landis's ATADRVR (www.ata-atapi.com), and
* later found its way into the ATA/ATAPI spec.
*
* Write a pattern to the ATA shadow registers,
* and if a device is present, it will respond by
* correctly storing and echoing back the
* ATA shadow register contents.
*
* LOCKING:
* caller.
*/
static
unsigned
int
ata_mmio_devchk
(
struct
ata_port
*
ap
,
...
...
@@ -548,12 +641,16 @@ static unsigned int ata_mmio_devchk(struct ata_port *ap,
}
/**
* ata_dev_devchk -
* @ap:
* @device:
* ata_dev_devchk -
PATA device presence detection
* @ap:
ATA channel to examine
* @device:
Device to examine (starting at zero)
*
* LOCKING:
* Dispatch ATA device presence detection, depending
* on whether we are using PIO or MMIO to talk to the
* ATA shadow registers.
*
* LOCKING:
* caller.
*/
static
unsigned
int
ata_dev_devchk
(
struct
ata_port
*
ap
,
...
...
@@ -604,16 +701,24 @@ static unsigned int ata_dev_classify(struct ata_taskfile *tf)
}
/**
* ata_dev_try_classify -
* @ap:
* @device:
* ata_dev_try_classify -
Parse returned ATA device signature
* @ap:
ATA channel to examine
* @device:
Device to examine (starting at zero)
*
* LOCKING:
* After an event -- SRST, E.D.D., or SATA COMRESET -- occurs,
* an ATA/ATAPI-defined set of values is placed in the ATA
* shadow registers, indicating the results of device detection
* and diagnostics.
*
* Select the ATA device, and read the values from the ATA shadow
* registers. Then parse according to the Error register value,
* and the spec-defined values examined by ata_dev_classify().
*
* LOCKING:
* caller.
*/
static
u8
ata_dev_try_classify
(
struct
ata_port
*
ap
,
unsigned
int
device
,
unsigned
int
maybe_have_dev
)
static
u8
ata_dev_try_classify
(
struct
ata_port
*
ap
,
unsigned
int
device
)
{
struct
ata_device
*
dev
=
&
ap
->
device
[
device
];
struct
ata_taskfile
tf
;
...
...
@@ -650,44 +755,51 @@ static u8 ata_dev_try_classify(struct ata_port *ap, unsigned int device,
}
/**
* ata_dev_id_string -
* @dev:
* @s:
* @ofs:
* @len:
* ata_dev_id_string -
Convert IDENTIFY DEVICE page into string
* @dev:
Device whose IDENTIFY DEVICE results we will examine
* @s:
string into which data is output
* @ofs:
offset into identify device page
* @len:
length of string to return
*
*
LOCKING:
*
*
RETURNS:
*
The strings in the IDENTIFY DEVICE page are broken up into
*
16-bit chunks. Run through the string, and output each
*
8-bit chunk linearly, regardless of platform.
*
* LOCKING:
* caller.
*/
unsigned
int
ata_dev_id_string
(
struct
ata_device
*
dev
,
unsigned
char
*
s
,
unsigned
int
ofs
,
unsigned
int
len
)
void
ata_dev_id_string
(
struct
ata_device
*
dev
,
unsigned
char
*
s
,
unsigned
int
ofs
,
unsigned
int
len
)
{
unsigned
int
c
,
ret
=
0
;
unsigned
int
c
;
while
(
len
>
0
)
{
c
=
dev
->
id
[
ofs
]
>>
8
;
*
s
=
c
;
s
++
;
ret
=
c
=
dev
->
id
[
ofs
]
&
0xff
;
c
=
dev
->
id
[
ofs
]
&
0xff
;
*
s
=
c
;
s
++
;
ofs
++
;
len
-=
2
;
}
return
ret
;
}
/**
* ata_dev_parse_strings -
* @dev:
* ata_dev_parse_strings - Store useful IDENTIFY DEVICE page strings
* @dev: Device whose IDENTIFY DEVICE page info we use
*
* We store 'vendor' and 'product' strings read from the device,
* for later use in the SCSI simulator's INQUIRY data.
*
* Set these strings here, in the case of 'product', using
* data read from the ATA IDENTIFY DEVICE page.
*
* LOCKING:
* caller.
*/
static
void
ata_dev_parse_strings
(
struct
ata_device
*
dev
)
...
...
@@ -700,12 +812,16 @@ static void ata_dev_parse_strings(struct ata_device *dev)
}
/**
* __ata_dev_select -
* @ap:
* @device:
* __ata_dev_select -
Select device 0/1 on ATA bus
* @ap:
ATA channel to manipulate
* @device:
ATA device (numbered from zero) to select
*
* LOCKING:
* Use the method defined in the ATA specification to
* make either device 0, or device 1, active on the
* ATA channel.
*
* LOCKING:
* caller.
*/
static
void
__ata_dev_select
(
struct
ata_port
*
ap
,
unsigned
int
device
)
...
...
@@ -726,16 +842,22 @@ static void __ata_dev_select (struct ata_port *ap, unsigned int device)
}
/**
* ata_dev_select -
* @ap:
* @device:
* @wait:
* @can_sleep:
* ata_dev_select -
Select device 0/1 on ATA bus
* @ap:
ATA channel to manipulate
* @device:
ATA device (numbered from zero) to select
* @wait:
non-zero to wait for Status register BSY bit to clear
* @can_sleep:
non-zero if context allows sleeping
*
* LOCKING:
* Use the method defined in the ATA specification to
* make either device 0, or device 1, active on the
* ATA channel.
*
* RETURNS:
* This is a high-level version of __ata_dev_select(),
* which additionally provides the services of inserting
* the proper pauses and status polling, where needed.
*
* LOCKING:
* caller.
*/
void
ata_dev_select
(
struct
ata_port
*
ap
,
unsigned
int
device
,
...
...
@@ -757,10 +879,14 @@ void ata_dev_select(struct ata_port *ap, unsigned int device,
}
/**
* ata_dump_id -
* @dev:
* ata_dump_id - IDENTIFY DEVICE info debugging output
* @dev: Device whose IDENTIFY DEVICE page we will dump
*
* Dump selected 16-bit words from a detected device's
* IDENTIFY PAGE page.
*
* LOCKING:
* caller.
*/
static
inline
void
ata_dump_id
(
struct
ata_device
*
dev
)
...
...
@@ -843,7 +969,7 @@ static void ata_dev_identify(struct ata_port *ap, unsigned int device)
retry:
ata_tf_init
(
ap
,
&
tf
,
device
);
tf
.
ctl
|=
ATA_NIEN
;
tf
.
protocol
=
ATA_PROT_PIO
_READ
;
tf
.
protocol
=
ATA_PROT_PIO
;
if
(
dev
->
class
==
ATA_DEV_ATA
)
{
tf
.
command
=
ATA_CMD_ID_ATA
;
...
...
@@ -1129,7 +1255,7 @@ void ata_port_disable(struct ata_port *ap)
*/
static
void
ata_set_mode
(
struct
ata_port
*
ap
)
{
unsigned
int
force_pio
;
unsigned
int
force_pio
,
i
;
ata_host_set_pio
(
ap
);
if
(
ap
->
flags
&
ATA_FLAG_PORT_DISABLED
)
...
...
@@ -1148,19 +1274,21 @@ static void ata_set_mode(struct ata_port *ap)
if
(
force_pio
)
{
ata_dev_set_pio
(
ap
,
0
);
ata_dev_set_pio
(
ap
,
1
);
if
(
ap
->
flags
&
ATA_FLAG_PORT_DISABLED
)
return
;
}
else
{
ata_dev_set_udma
(
ap
,
0
);
ata_dev_set_udma
(
ap
,
1
);
if
(
ap
->
flags
&
ATA_FLAG_PORT_DISABLED
)
return
;
}
if
(
ap
->
flags
&
ATA_FLAG_PORT_DISABLED
)
return
;
if
(
ap
->
ops
->
post_set_mode
)
ap
->
ops
->
post_set_mode
(
ap
);
for
(
i
=
0
;
i
<
2
;
i
++
)
{
struct
ata_device
*
dev
=
&
ap
->
device
[
i
];
ata_dev_set_protocol
(
dev
);
}
}
/**
...
...
@@ -1386,9 +1514,9 @@ void ata_bus_reset(struct ata_port *ap)
/*
* determine by signature whether we have ATA or ATAPI devices
*/
err
=
ata_dev_try_classify
(
ap
,
0
,
dev0
);
err
=
ata_dev_try_classify
(
ap
,
0
);
if
((
slave_possible
)
&&
(
err
!=
0x81
))
ata_dev_try_classify
(
ap
,
1
,
dev1
);
ata_dev_try_classify
(
ap
,
1
);
/* re-enable interrupts */
ata_irq_on
(
ap
);
...
...
@@ -1725,6 +1853,7 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc)
int
dir
=
scsi_to_pci_dma_dir
(
cmd
->
sc_data_direction
);
struct
scatterlist
*
sg
=
qc
->
sg
;
unsigned
int
have_sg
=
(
qc
->
flags
&
ATA_QCFLAG_SG
);
dma_addr_t
dma_address
;
assert
(
sg
==
&
qc
->
sgent
);
assert
(
qc
->
n_elem
==
1
);
...
...
@@ -1736,12 +1865,15 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc)
if
(
!
have_sg
)
return
0
;
sg_dma_address
(
sg
)
=
pci_map_single
(
ap
->
host_set
->
pdev
,
cmd
->
request_buffer
,
cmd
->
request_bufflen
,
dir
);
dma_address
=
pci_map_single
(
ap
->
host_set
->
pdev
,
cmd
->
request_buffer
,
cmd
->
request_bufflen
,
dir
);
if
(
pci_dma_mapping_error
(
dma_address
))
return
-
1
;
sg_dma_address
(
sg
)
=
dma_address
;
DPRINTK
(
"mapped buffer of %d bytes for %s
\n
"
,
cmd
->
request_bufflen
,
qc
->
flags
&
ATA_QC
FLAG_WRITE
?
"write"
:
"read"
);
qc
->
tf
.
flags
&
ATA_T
FLAG_WRITE
?
"write"
:
"read"
);
return
0
;
}
...
...
@@ -1842,8 +1974,7 @@ static void ata_pio_start (struct ata_queued_cmd *qc)
{
struct
ata_port
*
ap
=
qc
->
ap
;
assert
((
qc
->
tf
.
protocol
==
ATA_PROT_PIO_READ
)
||
(
qc
->
tf
.
protocol
==
ATA_PROT_PIO_WRITE
));
assert
(
qc
->
tf
.
protocol
==
ATA_PROT_PIO
);
qc
->
flags
|=
ATA_QCFLAG_POLL
;
qc
->
tf
.
ctl
|=
ATA_NIEN
;
/* disable interrupts */
...
...
@@ -1963,12 +2094,12 @@ static void ata_pio_sector(struct ata_port *ap)
}
DPRINTK
(
"data %s, drv_stat 0x%X
\n
"
,
qc
->
flags
&
ATA_QC
FLAG_WRITE
?
"write"
:
"read"
,
qc
->
tf
.
flags
&
ATA_T
FLAG_WRITE
?
"write"
:
"read"
,
status
);
/* do the actual data transfer */
/* FIXME: mmio-ize */
if
(
qc
->
flags
&
ATA_QC
FLAG_WRITE
)
if
(
qc
->
tf
.
flags
&
ATA_T
FLAG_WRITE
)
outsl
(
ap
->
ioaddr
.
data_addr
,
buf
,
ATA_SECT_DWORDS
);
else
insl
(
ap
->
ioaddr
.
data_addr
,
buf
,
ATA_SECT_DWORDS
);
...
...
@@ -2033,8 +2164,7 @@ void ata_eng_timeout(struct ata_port *ap)
qc
->
scsidone
=
scsi_finish_command
;
switch
(
qc
->
tf
.
protocol
)
{
case
ATA_PROT_DMA_READ
:
case
ATA_PROT_DMA_WRITE
:
case
ATA_PROT_DMA
:
if
(
ap
->
flags
&
ATA_FLAG_MMIO
)
{
void
*
mmio
=
(
void
*
)
ap
->
ioaddr
.
bmdma_addr
;
host_stat
=
readb
(
mmio
+
ATA_DMA_STATUS
);
...
...
@@ -2258,7 +2388,7 @@ int ata_qc_issue(struct ata_queued_cmd *qc)
void
ata_bmdma_start_mmio
(
struct
ata_queued_cmd
*
qc
)
{
struct
ata_port
*
ap
=
qc
->
ap
;
unsigned
int
rw
=
(
qc
->
flags
&
ATA_QC
FLAG_WRITE
);
unsigned
int
rw
=
(
qc
->
tf
.
flags
&
ATA_T
FLAG_WRITE
);
u8
host_stat
,
dmactl
;
void
*
mmio
=
(
void
*
)
ap
->
ioaddr
.
bmdma_addr
;
...
...
@@ -2307,7 +2437,7 @@ void ata_bmdma_start_mmio (struct ata_queued_cmd *qc)
void
ata_bmdma_start_pio
(
struct
ata_queued_cmd
*
qc
)
{
struct
ata_port
*
ap
=
qc
->
ap
;
unsigned
int
rw
=
(
qc
->
flags
&
ATA_QC
FLAG_WRITE
);
unsigned
int
rw
=
(
qc
->
tf
.
flags
&
ATA_T
FLAG_WRITE
);
u8
host_stat
,
dmactl
;
/* load PRD table addr. */
...
...
@@ -2402,8 +2532,7 @@ inline unsigned int ata_host_intr (struct ata_port *ap,
unsigned
int
handled
=
0
;
switch
(
qc
->
tf
.
protocol
)
{
case
ATA_PROT_DMA_READ
:
case
ATA_PROT_DMA_WRITE
:
case
ATA_PROT_DMA
:
if
(
ap
->
flags
&
ATA_FLAG_MMIO
)
{
void
*
mmio
=
(
void
*
)
ap
->
ioaddr
.
bmdma_addr
;
host_stat
=
readb
(
mmio
+
ATA_DMA_STATUS
);
...
...
@@ -2810,6 +2939,7 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host,
host
->
unique_id
=
ata_unique_id
++
;
host
->
max_cmd_len
=
12
;
scsi_set_device
(
host
,
&
ent
->
pdev
->
dev
);
scsi_assign_lock
(
host
,
&
host_set
->
lock
);
ap
->
flags
=
ATA_FLAG_PORT_DISABLED
;
ap
->
id
=
host
->
unique_id
;
...
...
drivers/scsi/libata-scsi.c
View file @
428a467d
...
...
@@ -32,17 +32,28 @@
#include "libata.h"
static
void
ata_scsi_simulate
(
struct
ata_port
*
ap
,
struct
ata_device
*
dev
,
struct
scsi_cmnd
*
cmd
,
void
(
*
done
)(
struct
scsi_cmnd
*
));
/**
* ata_std_bios_param - generic bios head/sector/cylinder calculator
* used by sd. Most BIOSes nowadays expect a XXX/255/16 (CHS)
* mapping. Some situations may arise where the disk is not
* bootable if this is not used.
* ata_std_bios_param - generic bios head/sector/cylinder calculator used by sd.
* @sdev: SCSI device for which BIOS geometry is to be determined
* @bdev: block device associated with @sdev
* @capacity: capacity of SCSI device
* @geom: location to which geometry will be output
*
* Generic bios head/sector/cylinder calculator
* used by sd. Most BIOSes nowadays expect a XXX/255/16 (CHS)
* mapping. Some situations may arise where the disk is not
* bootable if this is not used.
*
* LOCKING:
* Defined by the SCSI layer. We don't really care.
*
* RETURNS:
*
*
Zero.
*/
int
ata_std_bios_param
(
struct
scsi_device
*
sdev
,
struct
block_device
*
bdev
,
sector_t
capacity
,
int
geom
[])
...
...
@@ -56,6 +67,27 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev,
}
/**
* ata_scsi_qc_new - acquire new ata_queued_cmd reference
* @ap: ATA port to which the new command is attached
* @dev: ATA device to which the new command is attached
* @cmd: SCSI command that originated this ATA command
* @done: SCSI command completion function
*
* Obtain a reference to an unused ata_queued_cmd structure,
* which is the basic libata structure representing a single
* ATA command sent to the hardware.
*
* If a command was available, fill in the SCSI-specific
* portions of the structure with information on the
* current command.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
*
* RETURNS:
* Command allocated, or %NULL if none available.
*/
struct
ata_queued_cmd
*
ata_scsi_qc_new
(
struct
ata_port
*
ap
,
struct
ata_device
*
dev
,
struct
scsi_cmnd
*
cmd
,
...
...
@@ -84,11 +116,18 @@ struct ata_queued_cmd *ata_scsi_qc_new(struct ata_port *ap,
}
/**
* ata_to_sense_error -
* @qc:
* @cmd:
* ata_to_sense_error - convert ATA error to SCSI error
* @qc: Command that we are erroring out
*
* Converts an ATA error into a SCSI error.
*
* Right now, this routine is laughably primitive. We
* don't even examine what ATA told us, we just look at
* the command data direction, and return a fatal SCSI
* sense error based on that.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
*/
void
ata_to_sense_error
(
struct
ata_queued_cmd
*
qc
)
...
...
@@ -102,7 +141,7 @@ void ata_to_sense_error(struct ata_queued_cmd *qc)
cmd
->
sense_buffer
[
7
]
=
14
-
8
;
/* addnl. sense len. FIXME: correct? */
/* additional-sense-code[-qualifier] */
if
(
(
qc
->
flags
&
ATA_QCFLAG_WRITE
)
==
0
)
{
if
(
cmd
->
sc_data_direction
==
SCSI_DATA_READ
)
{
cmd
->
sense_buffer
[
12
]
=
0x11
;
/* "unrecovered read error" */
cmd
->
sense_buffer
[
13
]
=
0x04
;
}
else
{
...
...
@@ -112,11 +151,15 @@ void ata_to_sense_error(struct ata_queued_cmd *qc)
}
/**
* ata_scsi_slave_config -
* @sdev:
* ata_scsi_slave_config -
Set SCSI device attributes
* @sdev:
SCSI device to examine
*
* LOCKING:
* This is called before we actually start reading
* and writing to the device, to configure certain
* SCSI mid-layer behaviors.
*
* LOCKING:
* Defined by SCSI layer. We don't really care.
*/
int
ata_scsi_slave_config
(
struct
scsi_device
*
sdev
)
...
...
@@ -155,24 +198,29 @@ int ata_scsi_error(struct Scsi_Host *host)
}
/**
* ata_scsi_rw_xlat -
* @qc:
* @scsicmd:
* @cmd_size:
* ata_scsi_rw_xlat - Translate SCSI r/w command into an ATA one
* @qc: Storage for translated ATA taskfile
* @scsicmd: SCSI command to translate
*
* Converts any of six SCSI read/write commands into the
* ATA counterpart, including starting sector (LBA),
* sector count, and taking into account the device's LBA48
* support.
*
* Commands %READ_6, %READ_10, %READ_16, %WRITE_6, %WRITE_10, and
* %WRITE_16 are currently supported.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
*
* RETURNS:
*
*
Zero on success, non-zero on error.
*/
static
unsigned
int
ata_scsi_rw_xlat
(
struct
ata_queued_cmd
*
qc
,
u8
*
scsicmd
,
unsigned
int
cmd_size
)
static
unsigned
int
ata_scsi_rw_xlat
(
struct
ata_queued_cmd
*
qc
,
u8
*
scsicmd
)
{
struct
ata_taskfile
*
tf
=
&
qc
->
tf
;
unsigned
int
lba48
=
tf
->
flags
&
ATA_TFLAG_LBA48
;
unsigned
int
dma
=
qc
->
flags
&
ATA_QCFLAG_DMA
;
qc
->
cursect
=
qc
->
cursg
=
qc
->
cursg_ofs
=
0
;
tf
->
flags
|=
ATA_TFLAG_ISADDR
|
ATA_TFLAG_DEVICE
;
...
...
@@ -180,43 +228,19 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd,
tf
->
hob_lbal
=
0
;
tf
->
hob_lbam
=
0
;
tf
->
hob_lbah
=
0
;
tf
->
protocol
=
qc
->
dev
->
xfer_protocol
;
if
(
scsicmd
[
0
]
==
READ_10
||
scsicmd
[
0
]
==
READ_6
||
scsicmd
[
0
]
==
READ_16
)
{
if
(
likely
(
dma
))
{
if
(
lba48
)
tf
->
command
=
ATA_CMD_READ_EXT
;
else
tf
->
command
=
ATA_CMD_READ
;
tf
->
protocol
=
ATA_PROT_DMA_READ
;
}
else
{
if
(
lba48
)
tf
->
command
=
ATA_CMD_PIO_READ_EXT
;
else
tf
->
command
=
ATA_CMD_PIO_READ
;
tf
->
protocol
=
ATA_PROT_PIO_READ
;
}
qc
->
flags
&=
~
ATA_QCFLAG_WRITE
;
tf
->
command
=
qc
->
dev
->
read_cmd
;
VPRINTK
(
"reading
\n
"
);
}
else
{
if
(
likely
(
dma
))
{
if
(
lba48
)
tf
->
command
=
ATA_CMD_WRITE_EXT
;
else
tf
->
command
=
ATA_CMD_WRITE
;
tf
->
protocol
=
ATA_PROT_DMA_WRITE
;
}
else
{
if
(
lba48
)
tf
->
command
=
ATA_CMD_PIO_WRITE_EXT
;
else
tf
->
command
=
ATA_CMD_PIO_WRITE
;
tf
->
protocol
=
ATA_PROT_PIO_WRITE
;
}
qc
->
flags
|=
ATA_QCFLAG_WRITE
;
tf
->
command
=
qc
->
dev
->
write_cmd
;
tf
->
flags
|=
ATA_TFLAG_WRITE
;
VPRINTK
(
"writing
\n
"
);
}
if
(
cmd_size
==
10
)
{
if
(
scsicmd
[
0
]
==
READ_10
||
scsicmd
[
0
]
==
WRITE_
10
)
{
if
(
lba48
)
{
tf
->
hob_nsect
=
scsicmd
[
7
];
tf
->
hob_lbal
=
scsicmd
[
2
];
...
...
@@ -245,7 +269,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd,
return
0
;
}
if
(
cmd_size
==
6
)
{
if
(
scsicmd
[
0
]
==
READ_6
||
scsicmd
[
0
]
==
WRITE_
6
)
{
qc
->
nsect
=
tf
->
nsect
=
scsicmd
[
4
];
tf
->
lbal
=
scsicmd
[
3
];
tf
->
lbam
=
scsicmd
[
2
];
...
...
@@ -255,7 +279,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd,
return
0
;
}
if
(
cmd_size
==
16
)
{
if
(
scsicmd
[
0
]
==
READ_16
||
scsicmd
[
0
]
==
WRITE_
16
)
{
/* rule out impossible LBAs and sector counts */
if
(
scsicmd
[
2
]
||
scsicmd
[
3
]
||
scsicmd
[
10
]
||
scsicmd
[
11
])
return
1
;
...
...
@@ -295,20 +319,26 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd,
}
/**
* ata_scsi_rw_queue -
* @ap:
* @dev:
* @cmd:
* @done:
* @cmd_size:
* ata_scsi_translate - Translate then issue SCSI command to ATA device
* @ap: ATA port to which the command is addressed
* @dev: ATA device to which the command is addressed
* @cmd: SCSI command to execute
* @done: SCSI command completion function
*
* Our ->queuecommand() function has decided that the SCSI
* command issued can be directly translated into an ATA
* command, rather than handled internally.
*
* This function sets up an ata_queued_cmd structure for the
* SCSI command, and sends that ata_queued_cmd to the hardware.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
*/
void
ata_scsi_rw_queu
e
(
struct
ata_port
*
ap
,
struct
ata_device
*
dev
,
struct
scsi_cmnd
*
cmd
,
void
(
*
done
)(
struct
scsi_cmnd
*
)
,
unsigned
int
cmd_size
)
static
void
ata_scsi_translat
e
(
struct
ata_port
*
ap
,
struct
ata_device
*
dev
,
struct
scsi_cmnd
*
cmd
,
void
(
*
done
)(
struct
scsi_cmnd
*
)
)
{
struct
ata_queued_cmd
*
qc
;
u8
*
scsicmd
=
cmd
->
cmnd
;
...
...
@@ -327,7 +357,7 @@ void ata_scsi_rw_queue(struct ata_port *ap, struct ata_device *dev,
qc
->
flags
|=
ATA_QCFLAG_SG
;
/* data is present; dma-map it */
if
(
ata_scsi_rw_xlat
(
qc
,
scsicmd
,
cmd_size
))
if
(
ata_scsi_rw_xlat
(
qc
,
scsicmd
))
goto
err_out
;
/* select device, send command to hardware */
...
...
@@ -351,7 +381,6 @@ void ata_scsi_rw_queue(struct ata_port *ap, struct ata_device *dev,
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
* FIXME: kmap inside spin_lock_irqsave ok?
*
* RETURNS:
* Length of response buffer.
...
...
@@ -366,7 +395,7 @@ static unsigned int ata_scsi_rbuf_get(struct scsi_cmnd *cmd, u8 **buf_out)
struct
scatterlist
*
sg
;
sg
=
(
struct
scatterlist
*
)
cmd
->
request_buffer
;
buf
=
kmap
(
sg
->
page
)
+
sg
->
offset
;
buf
=
kmap
_atomic
(
sg
->
page
,
KM_USER0
)
+
sg
->
offset
;
buflen
=
sg
->
length
;
}
else
{
buf
=
cmd
->
request_buffer
;
...
...
@@ -394,7 +423,7 @@ static inline void ata_scsi_rbuf_put(struct scsi_cmnd *cmd)
struct
scatterlist
*
sg
;
sg
=
(
struct
scatterlist
*
)
cmd
->
request_buffer
;
kunmap
(
sg
->
page
);
kunmap
_atomic
(
sg
->
page
,
KM_USER0
);
}
}
...
...
@@ -647,9 +676,9 @@ static void ata_msense_push(u8 **ptr_io, const u8 *last,
/**
* ata_msense_caching - Simulate MODE SENSE caching info page
* @dev:
* @ptr_io:
* @last:
* @dev:
Device associated with this MODE SENSE command
* @ptr_io:
(input/output) Location to store more output data
* @last:
End of output data buffer
*
* Generate a caching info page, which conditionally indicates
* write caching to the SCSI layer, depending on device
...
...
@@ -672,9 +701,9 @@ static unsigned int ata_msense_caching(struct ata_device *dev, u8 **ptr_io,
/**
* ata_msense_ctl_mode - Simulate MODE SENSE control mode page
* @dev:
* @ptr_io:
* @last:
* @dev:
Device associated with this MODE SENSE command
* @ptr_io:
(input/output) Location to store more output data
* @last:
End of output data buffer
*
* Generate a generic MODE SENSE control mode page.
*
...
...
@@ -832,11 +861,15 @@ unsigned int ata_scsiop_report_luns(struct ata_scsi_args *args, u8 *rbuf,
}
/**
* ata_scsi_badcmd -
* @cmd:
* @done:
* @asc:
* @ascq:
* ata_scsi_badcmd - End a SCSI request with an error
* @cmd: SCSI request to be handled
* @done: SCSI command completion function
* @asc: SCSI-defined additional sense code
* @ascq: SCSI-defined additional sense code qualifier
*
* Helper function that completes a SCSI command with
* %SAM_STAT_CHECK_CONDITION, with a sense key %ILLEGAL_REQUEST
* and the specified additional sense codes.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
...
...
@@ -910,7 +943,7 @@ static void atapi_scsi_queuecmd(struct ata_port *ap, struct ata_device *dev,
qc
->
tf
.
flags
|=
ATA_TFLAG_ISADDR
|
ATA_TFLAG_DEVICE
;
if
(
cmd
->
sc_data_direction
==
SCSI_DATA_WRITE
)
{
qc
->
flags
|=
ATA_QC
FLAG_WRITE
;
qc
->
tf
.
flags
|=
ATA_T
FLAG_WRITE
;
DPRINTK
(
"direction: write
\n
"
);
}
...
...
@@ -964,6 +997,99 @@ static void atapi_scsi_queuecmd(struct ata_port *ap, struct ata_device *dev,
DPRINTK
(
"EXIT - badcmd
\n
"
);
}
/**
* ata_scsi_find_dev - lookup ata_device from scsi_cmnd
* @ap: ATA port to which the device is attached
* @cmd: SCSI command to be sent to the device
*
* Given various information provided in struct scsi_cmnd,
* map that onto an ATA bus, and using that mapping
* determine which ata_device is associated with the
* SCSI command to be sent.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
*
* RETURNS:
* Associated ATA device, or %NULL if not found.
*/
static
inline
struct
ata_device
*
ata_scsi_find_dev
(
struct
ata_port
*
ap
,
struct
scsi_cmnd
*
cmd
)
{
struct
ata_device
*
dev
;
/* skip commands not addressed to targets we simulate */
if
(
likely
(
cmd
->
device
->
id
<
ATA_MAX_DEVICES
))
dev
=
&
ap
->
device
[
cmd
->
device
->
id
];
else
return
NULL
;
if
(
unlikely
((
cmd
->
device
->
channel
!=
0
)
||
(
cmd
->
device
->
lun
!=
0
)))
return
NULL
;
if
(
unlikely
(
!
ata_dev_present
(
dev
)))
return
NULL
;
#ifndef ATA_ENABLE_ATAPI
if
(
unlikely
(
dev
->
class
==
ATA_DEV_ATAPI
))
return
NULL
;
#endif
return
dev
;
}
/**
* ata_scsi_xlat_possible - check if SCSI to ATA translation is possible
* @cmd: SCSI command opcode to consider
*
* Look up the SCSI command given, and determine whether the
* SCSI command is to be translated or simulated.
*
* RETURNS:
* Non-zero if possible, zero if not.
*/
static
inline
int
ata_scsi_xlat_possible
(
u8
cmd
)
{
switch
(
cmd
)
{
case
READ_6
:
case
READ_10
:
case
READ_16
:
case
WRITE_6
:
case
WRITE_10
:
case
WRITE_16
:
return
1
;
}
return
0
;
}
/**
* ata_scsi_dump_cdb - dump SCSI command contents to dmesg
* @ap: ATA port to which the command was being sent
* @cmd: SCSI command to dump
*
* Prints the contents of a SCSI command via printk().
*/
static
inline
void
ata_scsi_dump_cdb
(
struct
ata_port
*
ap
,
struct
scsi_cmnd
*
cmd
)
{
#ifdef ATA_DEBUG
u8
*
scsicmd
=
cmd
->
cmnd
;
DPRINTK
(
"CDB (%u:%d,%d,%d) %02x %02x %02x %02x %02x %02x %02x %02x %02x
\n
"
,
ap
->
id
,
cmd
->
device
->
channel
,
cmd
->
device
->
id
,
cmd
->
device
->
lun
,
scsicmd
[
0
],
scsicmd
[
1
],
scsicmd
[
2
],
scsicmd
[
3
],
scsicmd
[
4
],
scsicmd
[
5
],
scsicmd
[
6
],
scsicmd
[
7
],
scsicmd
[
8
]);
#endif
}
/**
* ata_scsi_queuecmd - Issue SCSI cdb to libata-managed device
* @cmd: SCSI command to be sent
...
...
@@ -985,83 +1111,52 @@ static void atapi_scsi_queuecmd(struct ata_port *ap, struct ata_device *dev,
int
ata_scsi_queuecmd
(
struct
scsi_cmnd
*
cmd
,
void
(
*
done
)(
struct
scsi_cmnd
*
))
{
u8
*
scsicmd
=
cmd
->
cmnd
;
struct
ata_port
*
ap
;
struct
ata_device
*
dev
;
struct
ata_scsi_args
args
;
const
unsigned
int
atapi_support
=
#ifdef ATA_ENABLE_ATAPI
1
;
#else
0
;
#endif
/* Note: spin_lock_irqsave is held by caller... */
spin_unlock
(
cmd
->
device
->
host
->
host_lock
);
ap
=
(
struct
ata_port
*
)
&
cmd
->
device
->
host
->
hostdata
[
0
];
DPRINTK
(
"CDB (%u:%d,%d,%d) %02x %02x %02x %02x %02x %02x %02x %02x %02x
\n
"
,
ap
->
id
,
cmd
->
device
->
channel
,
cmd
->
device
->
id
,
cmd
->
device
->
lun
,
scsicmd
[
0
],
scsicmd
[
1
],
scsicmd
[
2
],
scsicmd
[
3
],
scsicmd
[
4
],
scsicmd
[
5
],
scsicmd
[
6
],
scsicmd
[
7
],
scsicmd
[
8
]);
ata_scsi_dump_cdb
(
ap
,
cmd
);
/* skip commands not addressed to targets we care about */
if
((
cmd
->
device
->
channel
!=
0
)
||
(
cmd
->
device
->
lun
!=
0
)
||
(
cmd
->
device
->
id
>=
ATA_MAX_DEVICES
))
{
cmd
->
result
=
(
DID_BAD_TARGET
<<
16
);
/* FIXME: correct? */
dev
=
ata_scsi_find_dev
(
ap
,
cmd
);
if
(
unlikely
(
!
dev
))
{
cmd
->
result
=
(
DID_BAD_TARGET
<<
16
);
done
(
cmd
);
goto
out
;
}
spin_lock
(
&
ap
->
host_set
->
lock
);
dev
=
&
ap
->
device
[
cmd
->
device
->
id
];
if
(
!
ata_dev_present
(
dev
))
{
DPRINTK
(
"no device
\n
"
);
cmd
->
result
=
(
DID_BAD_TARGET
<<
16
);
/* FIXME: correct? */
done
(
cmd
);
goto
out_unlock
;
}
if
(
dev
->
class
==
ATA_DEV_ATAPI
)
{
if
(
atapi_support
)
atapi_scsi_queuecmd
(
ap
,
dev
,
cmd
,
done
);
else
{
cmd
->
result
=
(
DID_BAD_TARGET
<<
16
);
/* correct? */
done
(
cmd
);
}
goto
out_unlock
;
}
/* fast path */
switch
(
scsicmd
[
0
])
{
case
READ_6
:
case
WRITE_6
:
ata_scsi_rw_queue
(
ap
,
dev
,
cmd
,
done
,
6
);
goto
out_unlock
;
case
READ_10
:
case
WRITE_10
:
ata_scsi_rw_queue
(
ap
,
dev
,
cmd
,
done
,
10
);
goto
out_unlock
;
if
(
dev
->
class
==
ATA_DEV_ATA
)
{
if
(
ata_scsi_xlat_possible
(
cmd
->
cmnd
[
0
]))
ata_scsi_translate
(
ap
,
dev
,
cmd
,
done
);
else
ata_scsi_simulate
(
ap
,
dev
,
cmd
,
done
);
}
else
atapi_scsi_queuecmd
(
ap
,
dev
,
cmd
,
done
);
case
READ_16
:
case
WRITE_16
:
ata_scsi_rw_queue
(
ap
,
dev
,
cmd
,
done
,
16
);
goto
out_unlock
;
out_unlock:
return
0
;
}
default:
/* do nothing */
break
;
}
/**
* ata_scsi_simulate - simulate SCSI command on ATA device
* @ap: Port to which ATA device is attached.
* @dev: Target device for CDB.
* @cmd: SCSI command being sent to device.
* @done: SCSI command completion function.
*
* Interprets and directly executes a select list of SCSI commands
* that can be handled internally.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
*/
/*
* slow path
*/
static
void
ata_scsi_simulate
(
struct
ata_port
*
ap
,
struct
ata_device
*
dev
,
struct
scsi_cmnd
*
cmd
,
void
(
*
done
)(
struct
scsi_cmnd
*
))
{
struct
ata_scsi_args
args
;
u8
*
scsicmd
=
cmd
->
cmnd
;
args
.
ap
=
ap
;
args
.
dev
=
dev
;
...
...
@@ -1130,11 +1225,5 @@ int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
ata_bad_scsiop
(
cmd
,
done
);
break
;
}
out_unlock:
spin_unlock
(
&
ap
->
host_set
->
lock
);
out:
spin_lock
(
cmd
->
device
->
host
->
host_lock
);
return
0
;
}
drivers/scsi/libata.h
View file @
428a467d
...
...
@@ -37,8 +37,8 @@ struct ata_scsi_args {
/* libata-core.c */
extern
unsigned
int
ata_dev_id_string
(
struct
ata_device
*
dev
,
unsigned
char
*
s
,
unsigned
int
ofs
,
unsigned
int
len
);
extern
void
ata_dev_id_string
(
struct
ata_device
*
dev
,
unsigned
char
*
s
,
unsigned
int
ofs
,
unsigned
int
len
);
extern
struct
ata_queued_cmd
*
ata_qc_new_init
(
struct
ata_port
*
ap
,
struct
ata_device
*
dev
);
extern
int
ata_qc_issue
(
struct
ata_queued_cmd
*
qc
);
...
...
@@ -50,9 +50,6 @@ extern void ata_thread_wake(struct ata_port *ap, unsigned int thr_state);
/* libata-scsi.c */
extern
void
ata_to_sense_error
(
struct
ata_queued_cmd
*
qc
);
extern
void
ata_scsi_rw_queue
(
struct
ata_port
*
ap
,
struct
ata_device
*
dev
,
struct
scsi_cmnd
*
cmd
,
void
(
*
done
)(
struct
scsi_cmnd
*
),
unsigned
int
cmd_size
);
extern
int
ata_scsi_error
(
struct
Scsi_Host
*
host
);
extern
unsigned
int
ata_scsiop_inq_std
(
struct
ata_scsi_args
*
args
,
u8
*
rbuf
,
unsigned
int
buflen
);
...
...
drivers/scsi/sata_promise.c
View file @
428a467d
...
...
@@ -28,6 +28,7 @@
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include "scsi.h"
#include "hosts.h"
#include <linux/libata.h>
...
...
@@ -45,6 +46,7 @@ enum {
PDC_INT_SEQMASK
=
0x40
,
/* Mask of asserted SEQ INTs */
PDC_TBG_MODE
=
0x41
,
/* TBG mode */
PDC_FLASH_CTL
=
0x44
,
/* Flash control register */
PDC_PCI_CTL
=
0x48
,
/* PCI control and status 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 */
...
...
@@ -77,6 +79,8 @@ enum {
board_20319
=
1
,
/* FastTrak S150 TX4 */
board_20621
=
2
,
/* FastTrak S150 SX4 */
PDC_HAS_PATA
=
(
1
<<
1
),
/* PDC20375 has PATA */
PDC_FLAG_20621
=
(
1
<<
30
),
/* we have a 20621 */
PDC_HDMA_RESET
=
(
1
<<
11
),
/* HDMA reset */
...
...
@@ -390,12 +394,11 @@ static inline unsigned int pdc_pkt_header(struct ata_taskfile *tf,
* and seq id (byte 2)
*/
switch
(
tf
->
protocol
)
{
case
ATA_PROT_DMA_READ
:
buf32
[
0
]
=
cpu_to_le32
(
PDC_PKT_READ
);
break
;
case
ATA_PROT_DMA_WRITE
:
buf32
[
0
]
=
0
;
case
ATA_PROT_DMA
:
if
(
!
(
tf
->
flags
&
ATA_TFLAG_WRITE
))
buf32
[
0
]
=
cpu_to_le32
(
PDC_PKT_READ
);
else
buf32
[
0
]
=
0
;
break
;
case
ATA_PROT_NODATA
:
...
...
@@ -554,7 +557,7 @@ static inline unsigned int pdc20621_ata_pkt(struct ata_taskfile *tf,
/*
* Set up ATA packet
*/
if
(
tf
->
protocol
==
ATA_PROT_DMA_READ
)
if
(
(
tf
->
protocol
==
ATA_PROT_DMA
)
&&
(
!
(
tf
->
flags
&
ATA_TFLAG_WRITE
))
)
buf
[
i
++
]
=
PDC_PKT_READ
;
else
if
(
tf
->
protocol
==
ATA_PROT_NODATA
)
buf
[
i
++
]
=
PDC_PKT_NODATA
;
...
...
@@ -606,7 +609,7 @@ static inline void pdc20621_host_pkt(struct ata_taskfile *tf, u8 *buf,
/*
* Set up Host DMA packet
*/
if
(
tf
->
protocol
==
ATA_PROT_DMA_READ
)
if
(
(
tf
->
protocol
==
ATA_PROT_DMA
)
&&
(
!
(
tf
->
flags
&
ATA_TFLAG_WRITE
))
)
tmp
=
PDC_PKT_READ
;
else
tmp
=
0
;
...
...
@@ -768,7 +771,7 @@ static void pdc20621_dma_start(struct ata_queued_cmd *qc)
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_QC
FLAG_WRITE
);
unsigned
int
rw
=
(
qc
->
tf
.
flags
&
ATA_T
FLAG_WRITE
);
u8
seq
=
(
u8
)
(
port_no
+
1
);
unsigned
int
doing_hdma
=
0
,
port_ofs
;
...
...
@@ -821,8 +824,9 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
VPRINTK
(
"ENTER
\n
"
);
switch
(
qc
->
tf
.
protocol
)
{
case
ATA_PROT_DMA_READ
:
if
((
qc
->
tf
.
protocol
==
ATA_PROT_DMA
)
&&
/* read */
(
!
(
qc
->
tf
.
flags
&
ATA_TFLAG_WRITE
)))
{
/* step two - DMA from DIMM to host */
if
(
doing_hdma
)
{
VPRINTK
(
"ata%u: read hdma, 0x%x 0x%x
\n
"
,
ap
->
id
,
...
...
@@ -843,9 +847,9 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
port_ofs
+
PDC_DIMM_HOST_PKT
);
}
handled
=
1
;
break
;
case
ATA_PROT_DMA_WRITE
:
}
else
if
(
qc
->
tf
.
protocol
==
ATA_PROT_DMA
)
{
/* write */
/* step one - DMA from host to DIMM */
if
(
doing_hdma
)
{
u8
seq
=
(
u8
)
(
port_no
+
1
);
...
...
@@ -868,21 +872,20 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
pdc20621_pop_hdma
(
qc
);
}
handled
=
1
;
break
;
case
ATA_PROT_NODATA
:
/* command completion, but no data xfer */
/* command completion, but no data xfer */
}
else
if
(
qc
->
tf
.
protocol
==
ATA_PROT_NODATA
)
{
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
;
}
}
else
{
ap
->
stats
.
idle_irq
++
;
}
return
handled
;
return
handled
;
}
static
irqreturn_t
pdc20621_interrupt
(
int
irq
,
void
*
dev_instance
,
struct
pt_regs
*
regs
)
...
...
@@ -999,8 +1002,7 @@ static void pdc_eng_timeout(struct ata_port *ap)
qc
->
scsidone
=
scsi_finish_command
;
switch
(
qc
->
tf
.
protocol
)
{
case
ATA_PROT_DMA_READ
:
case
ATA_PROT_DMA_WRITE
:
case
ATA_PROT_DMA
:
printk
(
KERN_ERR
"ata%u: DMA timeout
\n
"
,
ap
->
id
);
ata_qc_complete
(
ata_qc_from_tag
(
ap
,
ap
->
active_tag
),
ata_wait_idle
(
ap
)
|
ATA_ERR
,
0
);
...
...
@@ -1036,8 +1038,7 @@ static inline unsigned int pdc_host_intr( struct ata_port *ap,
unsigned
int
handled
=
0
;
switch
(
qc
->
tf
.
protocol
)
{
case
ATA_PROT_DMA_READ
:
case
ATA_PROT_DMA_WRITE
:
case
ATA_PROT_DMA
:
pdc_dma_complete
(
ap
,
qc
);
handled
=
1
;
break
;
...
...
@@ -1130,16 +1131,14 @@ static void pdc_dma_start(struct ata_queued_cmd *qc)
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
))
if
(
tf
->
protocol
!=
ATA_PROT_DMA
)
ata_tf_load_mmio
(
ap
,
tf
);
}
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
))
if
(
tf
->
protocol
!=
ATA_PROT_DMA
)
ata_exec_command_mmio
(
ap
,
tf
);
}
...
...
@@ -1610,14 +1609,18 @@ static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
u32
tmp
;
if
(
chip_id
==
board_20621
)
return
;
BUG
()
;
/* change FIFO_SHD to 8 dwords. Promise driver does this...
* dunno why.
/*
* Except for the hotplug stuff, this is voodoo from the
* Promise driver. Label this entire section
* "TODO: figure out why we do this"
*/
/* change FIFO_SHD to 8 dwords, enable BMR_BURST */
tmp
=
readl
(
mmio
+
PDC_FLASH_CTL
);
if
((
tmp
&
(
1
<<
16
))
==
0
)
writel
(
tmp
|
(
1
<<
16
)
,
mmio
+
PDC_FLASH_CTL
);
tmp
|=
0x12000
;
/* bit 16 (fifo 8 dw) and 13 (bmr burst?) */
writel
(
tmp
,
mmio
+
PDC_FLASH_CTL
);
/* clear plug/unplug flags for all ports */
tmp
=
readl
(
mmio
+
PDC_SATA_PLUG_CSR
);
...
...
@@ -1627,13 +1630,17 @@ static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
tmp
=
readl
(
mmio
+
PDC_SATA_PLUG_CSR
);
writel
(
tmp
|
0xff0000
,
mmio
+
PDC_SATA_PLUG_CSR
);
/* reduce TBG clock to 133 Mhz.
FIXME: why?
*/
/* reduce TBG clock to 133 Mhz. */
tmp
=
readl
(
mmio
+
PDC_TBG_MODE
);
tmp
&=
~
0x30000
;
/* clear bit 17, 16*/
tmp
|=
0x10000
;
/* set bit 17:16 = 0:1 */
writel
(
tmp
,
mmio
+
PDC_TBG_MODE
);
/* adjust slew rate control register. FIXME: why? */
readl
(
mmio
+
PDC_TBG_MODE
);
/* flush */
set_current_state
(
TASK_UNINTERRUPTIBLE
);
schedule_timeout
(
msecs_to_jiffies
(
10
));
/* adjust slew rate control register. */
tmp
=
readl
(
mmio
+
PDC_SLEW_CTL
);
tmp
&=
0xFFFFF03F
;
/* clear bit 11 ~ 6 */
tmp
|=
0x00000900
;
/* set bit 11-9 = 100b , bit 8-6 = 100 */
...
...
drivers/scsi/sata_sis.c
0 → 100644
View file @
428a467d
/*
* sata_sis.c - Silicon Integrated Systems SATA
*
* Copyright 2004 Uwe Koziolek
*
* The contents of this file are subject to the Open
* Software License version 1.1 that can be found at
* http://www.opensource.org/licenses/osl-1.1.txt and is included herein
* by reference.
*
* Alternatively, the contents of this file may be used under the terms
* of the GNU General Public License version 2 (the "GPL") as distributed
* in the kernel source COPYING file, in which case the provisions of
* the GPL are applicable instead of the above. If you wish to allow
* the use of your version of this file only under the terms of the
* GPL and not to allow others to use your version of this file under
* the OSL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the GPL.
* If you do not delete the provisions above, a recipient may use your
* version of this file under either the OSL or the GPL.
*
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include "scsi.h"
#include "hosts.h"
#include <linux/libata.h>
#define DRV_NAME "sata_sis"
#define DRV_VERSION "0.04"
enum
{
sis_180
=
0
,
};
static
int
sis_init_one
(
struct
pci_dev
*
pdev
,
const
struct
pci_device_id
*
ent
);
static
u32
sis_scr_read
(
struct
ata_port
*
ap
,
unsigned
int
sc_reg
);
static
void
sis_scr_write
(
struct
ata_port
*
ap
,
unsigned
int
sc_reg
,
u32
val
);
static
struct
pci_device_id
sis_pci_tbl
[]
=
{
{
PCI_VENDOR_ID_SI
,
PCI_DEVICE_ID_SI_180
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
sis_180
},
{
}
/* terminate list */
};
static
struct
pci_driver
sis_pci_driver
=
{
.
name
=
DRV_NAME
,
.
id_table
=
sis_pci_tbl
,
.
probe
=
sis_init_one
,
.
remove
=
ata_pci_remove_one
,
};
static
Scsi_Host_Template
sis_sht
=
{
.
module
=
THIS_MODULE
,
.
name
=
DRV_NAME
,
.
queuecommand
=
ata_scsi_queuecmd
,
.
eh_strategy_handler
=
ata_scsi_error
,
.
can_queue
=
ATA_DEF_QUEUE
,
.
this_id
=
ATA_SHT_THIS_ID
,
.
sg_tablesize
=
ATA_MAX_PRD
,
.
max_sectors
=
ATA_MAX_SECTORS
,
.
cmd_per_lun
=
ATA_SHT_CMD_PER_LUN
,
.
emulated
=
ATA_SHT_EMULATED
,
.
use_clustering
=
ATA_SHT_USE_CLUSTERING
,
.
proc_name
=
DRV_NAME
,
.
dma_boundary
=
ATA_DMA_BOUNDARY
,
.
slave_configure
=
ata_scsi_slave_config
,
.
bios_param
=
ata_std_bios_param
,
};
static
struct
ata_port_operations
sis_ops
=
{
.
port_disable
=
ata_port_disable
,
.
tf_load
=
ata_tf_load_pio
,
.
tf_read
=
ata_tf_read_pio
,
.
check_status
=
ata_check_status_pio
,
.
exec_command
=
ata_exec_command_pio
,
.
phy_reset
=
sata_phy_reset
,
.
bmdma_start
=
ata_bmdma_start_pio
,
.
fill_sg
=
ata_fill_sg
,
.
eng_timeout
=
ata_eng_timeout
,
.
irq_handler
=
ata_interrupt
,
.
scr_read
=
sis_scr_read
,
.
scr_write
=
sis_scr_write
,
.
port_start
=
ata_port_start
,
.
port_stop
=
ata_port_stop
,
};
MODULE_AUTHOR
(
"Uwe Koziolek"
);
MODULE_DESCRIPTION
(
"low-level driver for Silicon Integratad Systems SATA controller"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_DEVICE_TABLE
(
pci
,
sis_pci_tbl
);
static
u32
sis_scr_read
(
struct
ata_port
*
ap
,
unsigned
int
sc_reg
)
{
if
(
sc_reg
>=
16
)
return
0xffffffffU
;
return
inl
(
ap
->
ioaddr
.
scr_addr
+
(
sc_reg
*
4
));
}
static
void
sis_scr_write
(
struct
ata_port
*
ap
,
unsigned
int
sc_reg
,
u32
val
)
{
if
(
sc_reg
>=
16
)
return
;
outl
(
val
,
ap
->
ioaddr
.
scr_addr
+
(
sc_reg
*
4
));
}
/* move to PCI layer, integrate w/ MSI stuff */
static
void
pci_enable_intx
(
struct
pci_dev
*
pdev
)
{
u16
pci_command
;
pci_read_config_word
(
pdev
,
PCI_COMMAND
,
&
pci_command
);
if
(
pci_command
&
PCI_COMMAND_INTX_DISABLE
)
{
pci_command
&=
~
PCI_COMMAND_INTX_DISABLE
;
pci_write_config_word
(
pdev
,
PCI_COMMAND
,
pci_command
);
}
}
static
int
sis_init_one
(
struct
pci_dev
*
pdev
,
const
struct
pci_device_id
*
ent
)
{
struct
ata_probe_ent
*
probe_ent
=
NULL
;
int
rc
;
rc
=
pci_enable_device
(
pdev
);
if
(
rc
)
return
rc
;
rc
=
pci_request_regions
(
pdev
,
DRV_NAME
);
if
(
rc
)
goto
err_out
;
rc
=
pci_set_dma_mask
(
pdev
,
ATA_DMA_MASK
);
if
(
rc
)
goto
err_out_regions
;
rc
=
pci_set_consistent_dma_mask
(
pdev
,
ATA_DMA_MASK
);
if
(
rc
)
goto
err_out_regions
;
probe_ent
=
kmalloc
(
sizeof
(
*
probe_ent
),
GFP_KERNEL
);
if
(
!
probe_ent
)
{
rc
=
-
ENOMEM
;
goto
err_out_regions
;
}
memset
(
probe_ent
,
0
,
sizeof
(
*
probe_ent
));
probe_ent
->
pdev
=
pdev
;
INIT_LIST_HEAD
(
&
probe_ent
->
node
);
probe_ent
->
sht
=
&
sis_sht
;
probe_ent
->
host_flags
=
ATA_FLAG_SATA
|
ATA_FLAG_SATA_RESET
|
ATA_FLAG_NO_LEGACY
;
probe_ent
->
pio_mask
=
0x03
;
probe_ent
->
udma_mask
=
0x7f
;
probe_ent
->
port_ops
=
&
sis_ops
;
probe_ent
->
port
[
0
].
cmd_addr
=
pci_resource_start
(
pdev
,
0
);
ata_std_ports
(
&
probe_ent
->
port
[
0
]);
probe_ent
->
port
[
0
].
ctl_addr
=
pci_resource_start
(
pdev
,
1
)
|
ATA_PCI_CTL_OFS
;
probe_ent
->
port
[
0
].
bmdma_addr
=
pci_resource_start
(
pdev
,
4
);
probe_ent
->
port
[
0
].
scr_addr
=
pci_resource_start
(
pdev
,
5
);
probe_ent
->
port
[
1
].
cmd_addr
=
pci_resource_start
(
pdev
,
2
);
ata_std_ports
(
&
probe_ent
->
port
[
1
]);
probe_ent
->
port
[
1
].
ctl_addr
=
pci_resource_start
(
pdev
,
3
)
|
ATA_PCI_CTL_OFS
;
probe_ent
->
port
[
1
].
bmdma_addr
=
pci_resource_start
(
pdev
,
4
)
+
8
;
probe_ent
->
port
[
1
].
scr_addr
=
pci_resource_start
(
pdev
,
5
)
+
64
;
probe_ent
->
n_ports
=
2
;
probe_ent
->
irq
=
pdev
->
irq
;
probe_ent
->
irq_flags
=
SA_SHIRQ
;
pci_set_master
(
pdev
);
pci_enable_intx
(
pdev
);
/* FIXME: check ata_device_add return value */
ata_device_add
(
probe_ent
);
kfree
(
probe_ent
);
return
0
;
err_out_regions:
pci_release_regions
(
pdev
);
err_out:
pci_disable_device
(
pdev
);
return
rc
;
}
static
int
__init
sis_init
(
void
)
{
return
pci_module_init
(
&
sis_pci_driver
);
}
static
void
__exit
sis_exit
(
void
)
{
pci_unregister_driver
(
&
sis_pci_driver
);
}
module_init
(
sis_init
);
module_exit
(
sis_exit
);
include/linux/ata.h
View file @
428a467d
...
...
@@ -102,16 +102,6 @@ enum {
ATA_REG_DEVSEL
=
ATA_REG_DEVICE
,
ATA_REG_IRQ
=
ATA_REG_NSECT
,
/* ATA taskfile protocols */
ATA_PROT_UNKNOWN
=
0
,
ATA_PROT_NODATA
=
1
,
ATA_PROT_PIO_READ
=
2
,
ATA_PROT_PIO_WRITE
=
3
,
ATA_PROT_DMA_READ
=
4
,
ATA_PROT_DMA_WRITE
=
5
,
ATA_PROT_ATAPI
=
6
,
ATA_PROT_ATAPI_DMA
=
7
,
/* ATA device commands */
ATA_CMD_EDD
=
0x90
,
/* execute device diagnostic */
ATA_CMD_ID_ATA
=
0xEC
,
...
...
@@ -156,14 +146,55 @@ enum {
SCR_CONTROL
=
2
,
SCR_ACTIVE
=
3
,
SCR_NOTIFICATION
=
4
,
/* struct ata_taskfile flags */
ATA_TFLAG_LBA48
=
(
1
<<
0
),
/* enable 48-bit LBA and "HOB" */
ATA_TFLAG_ISADDR
=
(
1
<<
1
),
/* enable r/w to nsect/lba regs */
ATA_TFLAG_DEVICE
=
(
1
<<
2
),
/* enable r/w to device reg */
ATA_TFLAG_WRITE
=
(
1
<<
3
),
/* data dir: host->dev==1 (write) */
};
enum
ata_tf_protocols
{
/* ATA taskfile protocols */
ATA_PROT_UNKNOWN
,
/* unknown/invalid */
ATA_PROT_NODATA
,
/* no data */
ATA_PROT_PIO
,
/* PIO single sector */
ATA_PROT_PIO_MULT
,
/* PIO multiple sector */
ATA_PROT_DMA
,
/* DMA */
ATA_PROT_ATAPI
,
/* packet command */
ATA_PROT_ATAPI_DMA
,
/* packet command with special DMA sauce */
};
/* core structures */
struct
ata_prd
{
u32
addr
;
u32
flags_len
;
}
__attribute__
((
packed
));
struct
ata_taskfile
{
unsigned
long
flags
;
/* ATA_TFLAG_xxx */
u8
protocol
;
/* ATA_PROT_xxx */
u8
ctl
;
/* control reg */
u8
hob_feature
;
/* additional data */
u8
hob_nsect
;
/* to support LBA48 */
u8
hob_lbal
;
u8
hob_lbam
;
u8
hob_lbah
;
u8
feature
;
u8
nsect
;
u8
lbal
;
u8
lbam
;
u8
lbah
;
u8
device
;
u8
command
;
/* IO operation */
};
#define ata_id_is_ata(dev) (((dev)->id[0] & (1 << 15)) == 0)
#define ata_id_has_lba48(dev) ((dev)->id[83] & (1 << 10))
#define ata_id_has_lba(dev) ((dev)->id[49] & (1 << 8))
...
...
include/linux/libata.h
View file @
428a467d
...
...
@@ -107,12 +107,6 @@ enum {
ATA_FLAG_MMIO
=
(
1
<<
6
),
/* use MMIO, not PIO */
ATA_FLAG_SATA_RESET
=
(
1
<<
7
),
/* use COMRESET */
/* struct ata_taskfile flags */
ATA_TFLAG_LBA48
=
(
1
<<
0
),
ATA_TFLAG_ISADDR
=
(
1
<<
1
),
/* enable r/w to nsect/lba regs */
ATA_TFLAG_DEVICE
=
(
1
<<
2
),
/* enable r/w to device reg */
ATA_QCFLAG_WRITE
=
(
1
<<
0
),
/* read==0, write==1 */
ATA_QCFLAG_ACTIVE
=
(
1
<<
1
),
/* cmd not yet ack'd to scsi lyer */
ATA_QCFLAG_DMA
=
(
1
<<
2
),
/* data delivered via DMA */
ATA_QCFLAG_ATAPI
=
(
1
<<
3
),
/* is ATAPI packet command? */
...
...
@@ -223,29 +217,6 @@ struct ata_host_set {
struct
ata_port
*
ports
[
0
];
};
struct
ata_taskfile
{
unsigned
long
flags
;
/* ATA_TFLAG_xxx */
u8
protocol
;
/* ATA_PROT_xxx */
u8
ctl
;
/* control reg */
u8
hob_feature
;
/* additional data */
u8
hob_nsect
;
/* to support LBA48 */
u8
hob_lbal
;
u8
hob_lbam
;
u8
hob_lbah
;
u8
feature
;
u8
nsect
;
u8
lbal
;
u8
lbam
;
u8
lbah
;
u8
device
;
u8
command
;
/* IO operation */
};
struct
ata_queued_cmd
{
struct
ata_port
*
ap
;
struct
ata_device
*
dev
;
...
...
@@ -293,6 +264,11 @@ struct ata_device {
* ATAPI7 spec size, 40 ASCII
* characters
*/
/* cache info about current transfer mode */
u8
xfer_protocol
;
/* taskfile xfer protocol */
u8
read_cmd
;
/* opcode to use on read */
u8
write_cmd
;
/* opcode to use on write */
};
struct
ata_engine
{
...
...
@@ -408,7 +384,6 @@ extern int ata_scsi_detect(Scsi_Host_Template *sht);
extern
int
ata_scsi_queuecmd
(
struct
scsi_cmnd
*
cmd
,
void
(
*
done
)(
struct
scsi_cmnd
*
));
extern
int
ata_scsi_error
(
struct
Scsi_Host
*
host
);
extern
int
ata_scsi_release
(
struct
Scsi_Host
*
host
);
extern
int
ata_scsi_slave_config
(
struct
scsi_device
*
sdev
);
extern
unsigned
int
ata_host_intr
(
struct
ata_port
*
ap
,
struct
ata_queued_cmd
*
qc
);
/*
* Default driver ops implementations
...
...
@@ -433,6 +408,7 @@ extern void ata_eng_timeout(struct ata_port *ap);
extern
int
ata_std_bios_param
(
struct
scsi_device
*
sdev
,
struct
block_device
*
bdev
,
sector_t
capacity
,
int
geom
[]);
extern
int
ata_scsi_slave_config
(
struct
scsi_device
*
sdev
);
static
inline
unsigned
long
msecs_to_jiffies
(
unsigned
long
msecs
)
...
...
include/linux/pci_ids.h
View file @
428a467d
...
...
@@ -572,6 +572,7 @@
#define PCI_DEVICE_ID_SI_503 0x0008
#define PCI_DEVICE_ID_SI_ACPI 0x0009
#define PCI_DEVICE_ID_SI_LPC 0x0018
#define PCI_DEVICE_ID_SI_180 0x0180
#define PCI_DEVICE_ID_SI_5597_VGA 0x0200
#define PCI_DEVICE_ID_SI_6205 0x0205
#define PCI_DEVICE_ID_SI_501 0x0406
...
...
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