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
d0b8bb9f
Commit
d0b8bb9f
authored
Jan 27, 2003
by
James Bottomley
Browse files
Options
Browse Files
Download
Plain Diff
Merge raven.il.steeleye.com:/home/jejb/BK/scsi-aic-2.5
into raven.il.steeleye.com:/home/jejb/BK/scsi-combine-2.5
parents
c8e0f645
b06ab129
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
130 additions
and
112 deletions
+130
-112
drivers/scsi/hosts.h
drivers/scsi/hosts.h
+2
-2
drivers/scsi/ide-scsi.c
drivers/scsi/ide-scsi.c
+108
-109
include/scsi/scsi.h
include/scsi/scsi.h
+20
-1
No files found.
drivers/scsi/hosts.h
View file @
d0b8bb9f
...
...
@@ -605,8 +605,8 @@ static inline Scsi_Device *scsi_find_device(struct Scsi_Host *shost,
list_for_each_entry
(
sdev
,
&
shost
->
my_devices
,
siblings
)
if
(
sdev
->
channel
==
channel
&&
sdev
->
id
==
pun
&&
sdev
->
lun
==
lun
)
break
;
return
sdev
;
return
sdev
;
return
NULL
;
}
/*
...
...
drivers/scsi/ide-scsi.c
View file @
d0b8bb9f
...
...
@@ -96,9 +96,18 @@ typedef struct {
unsigned
long
flags
;
/* Status/Action flags */
unsigned
long
transform
;
/* SCSI cmd translation layer */
unsigned
long
log
;
/* log flags */
int
id
;
}
idescsi_scsi_t
;
static
inline
idescsi_scsi_t
*
scsihost_to_idescsi
(
struct
Scsi_Host
*
host
)
{
return
(
idescsi_scsi_t
*
)
(
&
host
[
1
]);
}
static
inline
idescsi_scsi_t
*
drive_to_idescsi
(
ide_drive_t
*
ide_drive
)
{
return
scsihost_to_idescsi
(
ide_drive
->
driver_data
);
}
/*
* Per ATAPI device status bits.
*/
...
...
@@ -262,7 +271,7 @@ static void hexdump(u8 *x, int len)
static
int
idescsi_check_condition
(
ide_drive_t
*
drive
,
struct
request
*
failed_command
)
{
idescsi_scsi_t
*
scsi
=
drive
->
driver_data
;
idescsi_scsi_t
*
scsi
=
drive
_to_idescsi
(
drive
)
;
idescsi_pc_t
*
pc
;
struct
request
*
rq
;
u8
*
buf
;
...
...
@@ -299,7 +308,7 @@ static int idescsi_check_condition(ide_drive_t *drive, struct request *failed_co
static
int
idescsi_end_request
(
ide_drive_t
*
drive
,
int
uptodate
,
int
nrsecs
)
{
idescsi_scsi_t
*
scsi
=
drive
->
driver_data
;
idescsi_scsi_t
*
scsi
=
drive
_to_idescsi
(
drive
)
;
struct
request
*
rq
=
HWGROUP
(
drive
)
->
rq
;
idescsi_pc_t
*
pc
=
(
idescsi_pc_t
*
)
rq
->
special
;
int
log
=
test_bit
(
IDESCSI_LOG_CMD
,
&
scsi
->
log
);
...
...
@@ -369,7 +378,7 @@ static inline unsigned long get_timeout(idescsi_pc_t *pc)
*/
static
ide_startstop_t
idescsi_pc_intr
(
ide_drive_t
*
drive
)
{
idescsi_scsi_t
*
scsi
=
drive
->
driver_data
;
idescsi_scsi_t
*
scsi
=
drive
_to_idescsi
(
drive
)
;
idescsi_pc_t
*
pc
=
scsi
->
pc
;
struct
request
*
rq
=
pc
->
rq
;
atapi_bcount_t
bcount
;
...
...
@@ -463,7 +472,7 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
static
ide_startstop_t
idescsi_transfer_pc
(
ide_drive_t
*
drive
)
{
idescsi_scsi_t
*
scsi
=
drive
->
driver_data
;
idescsi_scsi_t
*
scsi
=
drive
_to_idescsi
(
drive
)
;
idescsi_pc_t
*
pc
=
scsi
->
pc
;
atapi_ireason_t
ireason
;
ide_startstop_t
startstop
;
...
...
@@ -493,7 +502,7 @@ static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive)
*/
static
ide_startstop_t
idescsi_issue_pc
(
ide_drive_t
*
drive
,
idescsi_pc_t
*
pc
)
{
idescsi_scsi_t
*
scsi
=
drive
->
driver_data
;
idescsi_scsi_t
*
scsi
=
drive
_to_idescsi
(
drive
)
;
atapi_feature_t
feature
;
atapi_bcount_t
bcount
;
struct
request
*
rq
=
pc
->
rq
;
...
...
@@ -555,11 +564,9 @@ static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *r
return
ide_stopped
;
}
static
ide_drive_t
*
idescsi_drives
[
MAX_HWIFS
*
MAX_DRIVES
];
static
void
idescsi_add_settings
(
ide_drive_t
*
drive
)
{
idescsi_scsi_t
*
scsi
=
drive
->
driver_data
;
idescsi_scsi_t
*
scsi
=
drive
_to_idescsi
(
drive
)
;
/*
* drive setting name read/write ioctl ioctl data type min max mul_factor div_factor data pointer set function
...
...
@@ -574,15 +581,10 @@ static void idescsi_add_settings(ide_drive_t *drive)
/*
* Driver initialization.
*/
static
void
idescsi_setup
(
ide_drive_t
*
drive
,
idescsi_scsi_t
*
scsi
,
int
id
)
static
void
idescsi_setup
(
ide_drive_t
*
drive
,
idescsi_scsi_t
*
scsi
)
{
DRIVER
(
drive
)
->
busy
++
;
idescsi_drives
[
id
]
=
drive
;
drive
->
driver_data
=
scsi
;
drive
->
ready_stat
=
0
;
memset
(
scsi
,
0
,
sizeof
(
idescsi_scsi_t
));
scsi
->
drive
=
drive
;
scsi
->
id
=
id
;
if
(
drive
->
id
&&
(
drive
->
id
->
config
&
0x0060
)
==
0x20
)
set_bit
(
IDESCSI_DRQ_INTERRUPT
,
&
scsi
->
flags
);
set_bit
(
IDESCSI_TRANSFORM
,
&
scsi
->
transform
);
...
...
@@ -596,13 +598,17 @@ static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi, int id)
static
int
idescsi_cleanup
(
ide_drive_t
*
drive
)
{
idescsi_scsi_t
*
scsi
=
drive
->
driver_data
;
struct
Scsi_Host
*
scsihost
=
drive
->
driver_data
;
if
(
ide_unregister_subdriver
(
drive
))
return
1
;
/* FIXME?: Are these two statements necessary? */
drive
->
driver_data
=
NULL
;
drive
->
disk
->
fops
=
ide_fops
;
kfree
(
scsi
);
scsi_remove_host
(
scsihost
);
scsi_unregister
(
scsihost
);
return
0
;
}
...
...
@@ -654,52 +660,23 @@ static struct block_device_operations idescsi_ops = {
.
ioctl
=
idescsi_ide_ioctl
,
};
static
int
idescsi_attach
(
ide_drive_t
*
drive
)
{
idescsi_scsi_t
*
scsi
;
int
id
;
if
(
!
strstr
(
"ide-scsi"
,
drive
->
driver_req
))
goto
failed
;
if
(
!
drive
->
present
)
goto
failed
;
/* we accept everything except ide-disk */
if
(
drive
->
media
==
ide_disk
)
goto
failed
;
if
((
scsi
=
(
idescsi_scsi_t
*
)
kmalloc
(
sizeof
(
idescsi_scsi_t
),
GFP_KERNEL
))
==
NULL
)
{
printk
(
KERN_ERR
"ide-scsi: %s: Can't allocate a scsi structure
\n
"
,
drive
->
name
);
goto
failed
;
}
if
(
ide_register_subdriver
(
drive
,
&
idescsi_driver
,
IDE_SUBDRIVER_VERSION
))
{
printk
(
KERN_ERR
"ide-scsi: %s: Failed to register the driver with ide.c
\n
"
,
drive
->
name
);
kfree
(
scsi
);
goto
failed
;
}
for
(
id
=
0
;
id
<
MAX_HWIFS
*
MAX_DRIVES
&&
idescsi_drives
[
id
];
id
++
)
;
idescsi_setup
(
drive
,
scsi
,
id
);
drive
->
disk
->
fops
=
&
idescsi_ops
;
return
0
;
failed:
return
1
;
}
static
int
idescsi_attach
(
ide_drive_t
*
drive
);
int
idescsi_slave_configure
(
Scsi_Device
*
sdp
)
static
int
idescsi_slave_configure
(
Scsi_Device
*
sdp
)
{
/* Configure detected device */
scsi_adjust_queue_depth
(
sdp
,
MSG_SIMPLE_TAG
,
sdp
->
host
->
cmd_per_lun
);
return
0
;
}
const
char
*
idescsi_info
(
struct
Scsi_Host
*
host
)
static
const
char
*
idescsi_info
(
struct
Scsi_Host
*
host
)
{
return
"SCSI host adapter emulation for IDE ATAPI devices"
;
}
int
idescsi_ioctl
(
Scsi_Device
*
dev
,
int
cmd
,
void
*
arg
)
static
int
idescsi_ioctl
(
Scsi_Device
*
dev
,
int
cmd
,
void
*
arg
)
{
ide_drive_t
*
drive
=
idescsi_drives
[
dev
->
id
];
idescsi_scsi_t
*
scsi
=
drive
->
driver_data
;
idescsi_scsi_t
*
scsi
=
scsihost_to_idescsi
(
dev
->
host
);
if
(
cmd
==
SG_SET_TRANSFORM
)
{
if
(
arg
)
...
...
@@ -789,7 +766,7 @@ static inline struct bio *idescsi_dma_bio(ide_drive_t *drive, idescsi_pc_t *pc)
static
inline
int
should_transform
(
ide_drive_t
*
drive
,
Scsi_Cmnd
*
cmd
)
{
idescsi_scsi_t
*
scsi
=
drive
->
driver_data
;
idescsi_scsi_t
*
scsi
=
drive
_to_idescsi
(
drive
)
;
struct
gendisk
*
disk
=
cmd
->
request
->
rq_disk
;
if
(
disk
)
{
...
...
@@ -800,10 +777,10 @@ static inline int should_transform(ide_drive_t *drive, Scsi_Cmnd *cmd)
return
test_bit
(
IDESCSI_TRANSFORM
,
&
scsi
->
transform
);
}
int
idescsi_queue
(
Scsi_Cmnd
*
cmd
,
void
(
*
done
)(
Scsi_Cmnd
*
))
static
int
idescsi_queue
(
Scsi_Cmnd
*
cmd
,
void
(
*
done
)(
Scsi_Cmnd
*
))
{
ide
_drive_t
*
drive
=
idescsi_drives
[
cmd
->
target
]
;
ide
scsi_scsi_t
*
scsi
;
ide
scsi_scsi_t
*
scsi
=
scsihost_to_idescsi
(
cmd
->
host
)
;
ide
_drive_t
*
drive
=
scsi
->
drive
;
struct
request
*
rq
=
NULL
;
idescsi_pc_t
*
pc
=
NULL
;
...
...
@@ -811,7 +788,7 @@ int idescsi_queue (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
printk
(
KERN_ERR
"ide-scsi: drive id %d not present
\n
"
,
cmd
->
target
);
goto
abort
;
}
scsi
=
drive
->
driver_data
;
scsi
=
drive
_to_idescsi
(
drive
)
;
pc
=
kmalloc
(
sizeof
(
idescsi_pc_t
),
GFP_ATOMIC
);
rq
=
kmalloc
(
sizeof
(
struct
request
),
GFP_ATOMIC
);
if
(
rq
==
NULL
||
pc
==
NULL
)
{
...
...
@@ -865,43 +842,43 @@ int idescsi_queue (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
return
1
;
}
int
idescsi_abort
(
Scsi_Cmnd
*
cmd
)
static
int
idescsi_abort
(
Scsi_Cmnd
*
cmd
)
{
int
countdown
=
8
;
unsigned
long
flags
;
ide
_drive_t
*
drive
=
idescsi_drives
[
cmd
->
target
]
;
ide
scsi_scsi_t
*
scsi
;
ide
scsi_scsi_t
*
scsi
=
scsihost_to_idescsi
(
cmd
->
host
)
;
ide
_drive_t
*
drive
=
scsi
->
drive
;
printk
(
KERN_ERR
"ide-scsi: abort called for %lu
\n
"
,
cmd
->
serial_number
);
if
(
drive
&&
(
scsi
=
drive
->
driver_data
))
while
(
countdown
--
)
{
/* is cmd active?
* need to lock so this stuff doesn't change under us */
spin_lock_irqsave
(
&
ide_lock
,
flags
);
if
(
scsi
->
pc
&&
scsi
->
pc
->
scsi_cmd
&&
scsi
->
pc
->
scsi_cmd
->
serial_number
==
cmd
->
serial_number
)
{
/* yep - let's give it some more time -
* we can do that, we're in _our_ error kernel thread */
spin_unlock_irqrestore
(
&
ide_lock
,
flags
);
scsi_sleep
(
HZ
);
continue
;
}
/* no, but is it queued in the ide subsystem? */
if
(
elv_queue_empty
(
&
drive
->
queue
))
{
spin_unlock_irqrestore
(
&
ide_lock
,
flags
);
return
SUCCESS
;
}
while
(
countdown
--
)
{
/* is cmd active?
* need to lock so this stuff doesn't change under us */
spin_lock_irqsave
(
&
ide_lock
,
flags
);
if
(
scsi
->
pc
&&
scsi
->
pc
->
scsi_cmd
&&
scsi
->
pc
->
scsi_cmd
->
serial_number
==
cmd
->
serial_number
)
{
/* yep - let's give it some more time -
* we can do that, we're in _our_ error kernel thread */
spin_unlock_irqrestore
(
&
ide_lock
,
flags
);
scsi_sleep
(
HZ
);
continue
;
}
/* no, but is it queued in the ide subsystem? */
if
(
elv_queue_empty
(
&
drive
->
queue
))
{
spin_unlock_irqrestore
(
&
ide_lock
,
flags
);
schedule_timeout
(
HZ
/
10
)
;
return
SUCCESS
;
}
spin_unlock_irqrestore
(
&
ide_lock
,
flags
);
schedule_timeout
(
HZ
/
10
);
}
return
FAILED
;
}
int
idescsi_reset
(
Scsi_Cmnd
*
cmd
)
static
int
idescsi_reset
(
Scsi_Cmnd
*
cmd
)
{
unsigned
long
flags
;
struct
request
*
req
;
ide_drive_t
*
drive
=
idescsi_drives
[
cmd
->
target
];
idescsi_scsi_t
*
idescsi
=
scsihost_to_idescsi
(
cmd
->
host
);
ide_drive_t
*
drive
=
idescsi
->
drive
;
printk
(
KERN_ERR
"ide-scsi: reset called for %lu
\n
"
,
cmd
->
serial_number
);
/* first null the handler for the drive and let any process
...
...
@@ -919,7 +896,8 @@ int idescsi_reset (Scsi_Cmnd *cmd)
}
/* FIXME - this will probably leak memory */
HWGROUP
(
drive
)
->
rq
=
NULL
;
if
(
drive
->
driver_data
)
((
idescsi_scsi_t
*
)
drive
->
driver_data
)
->
pc
=
NULL
;
if
(
drive_to_idescsi
(
drive
))
drive_to_idescsi
(
drive
)
->
pc
=
NULL
;
spin_unlock_irqrestore
(
&
ide_lock
,
flags
);
/* finally, reset the drive (and its partner on the bus...) */
ide_do_reset
(
drive
);
...
...
@@ -929,7 +907,8 @@ int idescsi_reset (Scsi_Cmnd *cmd)
static
int
idescsi_bios
(
struct
scsi_device
*
sdev
,
struct
block_device
*
bdev
,
sector_t
capacity
,
int
*
parm
)
{
ide_drive_t
*
drive
=
idescsi_drives
[
sdev
->
id
];
idescsi_scsi_t
*
idescsi
=
scsihost_to_idescsi
(
sdev
->
host
);
ide_drive_t
*
drive
=
idescsi
->
drive
;
if
(
drive
->
bios_cyl
&&
drive
->
bios_head
&&
drive
->
bios_sect
)
{
parm
[
0
]
=
drive
->
bios_head
;
...
...
@@ -956,10 +935,9 @@ static Scsi_Host_Template idescsi_template = {
.
max_sectors
=
128
,
.
use_clustering
=
DISABLE_CLUSTERING
,
.
emulated
=
1
,
.
proc_name
=
"ide-scsi"
,
};
static
struct
Scsi_Host
*
idescsi_host
;
static
struct
device
idescsi_primary
=
{
.
name
=
"Ide-scsi Parent"
,
.
bus_id
=
"ide-scsi"
,
...
...
@@ -968,39 +946,60 @@ static struct bus_type idescsi_emu_bus = {
.
name
=
"ide-scsi"
,
};
static
int
__init
init_idescsi_module
(
void
)
static
int
idescsi_attach
(
ide_drive_t
*
drive
)
{
int
id
;
int
last_lun
=
0
;
idescsi_scsi_t
*
idescsi
;
struct
Scsi_Host
*
host
;
int
err
;
ide_register_driver
(
&
idescsi_driver
);
device_register
(
&
idescsi_primary
);
bus_register
(
&
idescsi_emu_bus
);
idescsi_template
.
proc_name
=
"ide-scsi"
;
idescsi_host
=
scsi_register
(
&
idescsi_template
,
0
);
if
(
idescsi_host
==
NULL
)
if
(
!
strstr
(
"ide-scsi"
,
drive
->
driver_req
)
||
!
drive
->
present
||
drive
->
media
==
ide_disk
||
!
(
host
=
scsi_register
(
&
idescsi_template
,
sizeof
(
idescsi_scsi_t
))))
return
1
;
for
(
id
=
0
;
id
<
MAX_HWIFS
*
MAX_DRIVES
&&
idescsi_drives
[
id
];
id
++
)
last_lun
=
IDE_MAX
(
last_lun
,
idescsi_drives
[
id
]
->
last_lun
);
idescsi_host
->
max_id
=
id
;
idescsi_host
->
max_lun
=
last_lun
+
1
;
scsi_add_host
(
idescsi_host
,
&
idescsi_primary
);
return
0
;
host
->
max_id
=
1
;
host
->
max_lun
=
1
;
drive
->
driver_data
=
host
;
idescsi
=
scsihost_to_idescsi
(
host
);
idescsi
->
drive
=
drive
;
err
=
ide_register_subdriver
(
drive
,
&
idescsi_driver
,
IDE_SUBDRIVER_VERSION
);
if
(
!
err
)
{
idescsi_setup
(
drive
,
idescsi
);
drive
->
disk
->
fops
=
&
idescsi_ops
;
err
=
scsi_add_host
(
host
,
&
idescsi_primary
);
if
(
!
err
)
return
0
;
/* fall through on error */
ide_unregister_subdriver
(
drive
);
}
scsi_unregister
(
host
);
return
err
;
}
static
void
__exit
ex
it_idescsi_module
(
void
)
static
int
__init
in
it_idescsi_module
(
void
)
{
ide_drive_t
*
drive
;
int
id
;
int
err
;
scsi_remove_host
(
idescsi_host
);
for
(
id
=
0
;
id
<
MAX_HWIFS
*
MAX_DRIVES
;
id
++
)
{
drive
=
idescsi_drives
[
id
];
if
(
drive
)
DRIVER
(
drive
)
->
busy
=
0
;
err
=
bus_register
(
&
idescsi_emu_bus
);
if
(
!
err
)
{
err
=
device_register
(
&
idescsi_primary
);
if
(
!
err
)
{
err
=
ide_register_driver
(
&
idescsi_driver
);
if
(
!
err
)
return
0
;
device_unregister
(
&
idescsi_primary
);
}
bus_unregister
(
&
idescsi_emu_bus
);
}
scsi_unregister
(
idescsi_host
);
return
err
;
}
static
void
__exit
exit_idescsi_module
(
void
)
{
device_unregister
(
&
idescsi_primary
);
bus_unregister
(
&
idescsi_emu_bus
);
ide_unregister_driver
(
&
idescsi_driver
);
...
...
include/scsi/scsi.h
View file @
d0b8bb9f
...
...
@@ -104,7 +104,26 @@ extern const unsigned char scsi_command_size[8];
/*
* Status codes
* SCSI Architecture Model (SAM) Status codes. Taken from SAM-3 draft
* T10/1561-D Revision 4 Draft dated 7th November 2002.
*/
#define SAM_STAT_GOOD 0x00
#define SAM_STAT_CHECK_CONDITION 0x02
#define SAM_STAT_CONDITION_MET 0x04
#define SAM_STAT_BUSY 0x08
#define SAM_STAT_IMMEDIATE 0x10
#define SAM_STAT_IMMEDIATE_CONDITION_MET 0x14
#define SAM_STAT_RESERVATION_CONFLICT 0x18
#define SAM_STAT_COMMAND_TERMINATED 0x22
/* obsolete in SAM-3 */
#define SAM_STAT_TASK_SET_FULL 0x28
#define SAM_STAT_ACA_ACTIVE 0x30
#define SAM_STAT_TASK_ABORTED 0x40
/*
* Status codes. These are deprecated as they are shifted 1 bit right
* from those found in the SCSI standards. This causes confusion for
* applications that are ported to several OSes. Prefer SAM Status codes
* above.
*/
#define GOOD 0x00
...
...
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