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
525f0d54
Commit
525f0d54
authored
Feb 20, 2004
by
Ben Collins
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
IEEE1394/SBP2(r1144): Convert sbp2 to do one scsi_host per unit-directory.
parent
193c0042
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
215 additions
and
362 deletions
+215
-362
drivers/ieee1394/sbp2.c
drivers/ieee1394/sbp2.c
+190
-303
drivers/ieee1394/sbp2.h
drivers/ieee1394/sbp2.h
+25
-59
No files found.
drivers/ieee1394/sbp2.c
View file @
525f0d54
...
@@ -231,6 +231,9 @@ static Scsi_Host_Template scsi_driver_template;
...
@@ -231,6 +231,9 @@ static Scsi_Host_Template scsi_driver_template;
const
u8
sbp2_speedto_max_payload
[]
=
{
0x7
,
0x8
,
0x9
,
0xA
,
0xB
,
0xC
};
const
u8
sbp2_speedto_max_payload
[]
=
{
0x7
,
0x8
,
0x9
,
0xA
,
0xB
,
0xC
};
static
void
sbp2_remove_host
(
struct
hpsb_host
*
host
);
static
void
sbp2_host_reset
(
struct
hpsb_host
*
host
);
static
struct
hpsb_highlevel
sbp2_highlevel
=
{
static
struct
hpsb_highlevel
sbp2_highlevel
=
{
.
name
=
SBP2_DEVICE_NAME
,
.
name
=
SBP2_DEVICE_NAME
,
.
remove_host
=
sbp2_remove_host
,
.
remove_host
=
sbp2_remove_host
,
...
@@ -403,7 +406,7 @@ static int sbp2util_create_command_orb_pool(struct scsi_id_instance_data *scsi_i
...
@@ -403,7 +406,7 @@ static int sbp2util_create_command_orb_pool(struct scsi_id_instance_data *scsi_i
unsigned
long
flags
,
orbs
;
unsigned
long
flags
,
orbs
;
struct
sbp2_command_info
*
command
;
struct
sbp2_command_info
*
command
;
orbs
=
serialize_io
?
2
:
SBP2_MAX_C
OMMAND_ORB
S
;
orbs
=
serialize_io
?
2
:
SBP2_MAX_C
MD
S
;
spin_lock_irqsave
(
&
scsi_id
->
sbp2_command_orb_lock
,
flags
);
spin_lock_irqsave
(
&
scsi_id
->
sbp2_command_orb_lock
,
flags
);
for
(
i
=
0
;
i
<
orbs
;
i
++
)
{
for
(
i
=
0
;
i
<
orbs
;
i
++
)
{
...
@@ -541,15 +544,17 @@ static struct sbp2_command_info *sbp2util_allocate_command_orb(
...
@@ -541,15 +544,17 @@ static struct sbp2_command_info *sbp2util_allocate_command_orb(
/* Free our DMA's */
/* Free our DMA's */
static
void
sbp2util_free_command_dma
(
struct
sbp2_command_info
*
command
)
static
void
sbp2util_free_command_dma
(
struct
sbp2_command_info
*
command
)
{
{
struct
scsi_id_instance_data
*
scsi_id
=
(
struct
scsi_id_instance_data
*
)
command
->
Current_SCpnt
->
device
->
host
->
hostdata
[
0
];
struct
hpsb_host
*
host
;
struct
hpsb_host
*
host
;
host
=
hpsb_get_host_bykey
(
&
sbp2_highlevel
,
if
(
!
scsi_id
)
{
(
unsigned
long
)
command
->
Current_SCpnt
->
device
->
host
);
printk
(
KERN_ERR
"%s: scsi_id == NULL
\n
"
,
__FUNCTION__
);
if
(
!
host
)
{
printk
(
KERN_ERR
"%s: host == NULL
\n
"
,
__FUNCTION__
);
return
;
return
;
}
}
host
=
scsi_id
->
ud
->
ne
->
host
;
if
(
command
->
cmd_dma
)
{
if
(
command
->
cmd_dma
)
{
if
(
command
->
dma_type
==
CMD_DMA_SINGLE
)
{
if
(
command
->
dma_type
==
CMD_DMA_SINGLE
)
{
pci_unmap_single
(
host
->
pdev
,
command
->
cmd_dma
,
pci_unmap_single
(
host
->
pdev
,
command
->
cmd_dma
,
...
@@ -591,13 +596,14 @@ static void sbp2util_mark_command_completed(struct scsi_id_instance_data *scsi_i
...
@@ -591,13 +596,14 @@ static void sbp2util_mark_command_completed(struct scsi_id_instance_data *scsi_i
/*********************************************
/*********************************************
* IEEE-1394 core driver stack related section
* IEEE-1394 core driver stack related section
*********************************************/
*********************************************/
static
struct
scsi_id_instance_data
*
sbp2_alloc_device
(
struct
unit_directory
*
ud
);
static
int
sbp2_probe
(
struct
device
*
dev
)
static
int
sbp2_probe
(
struct
device
*
dev
)
{
{
struct
unit_directory
*
ud
;
struct
unit_directory
*
ud
;
struct
s
bp2scsi_host_info
*
hi
;
struct
s
csi_id_instance_data
*
scsi_id
;
SBP2_DEBUG
(
__FUNCTION__
);
SBP2_DEBUG
(
"sbp2_probe"
);
ud
=
container_of
(
dev
,
struct
unit_directory
,
device
);
ud
=
container_of
(
dev
,
struct
unit_directory
,
device
);
...
@@ -606,210 +612,184 @@ static int sbp2_probe(struct device *dev)
...
@@ -606,210 +612,184 @@ static int sbp2_probe(struct device *dev)
if
(
ud
->
flags
&
UNIT_DIRECTORY_HAS_LUN_DIRECTORY
)
if
(
ud
->
flags
&
UNIT_DIRECTORY_HAS_LUN_DIRECTORY
)
return
-
ENODEV
;
return
-
ENODEV
;
/* This will only add it if it doesn't exist */
scsi_id
=
sbp2_alloc_device
(
ud
);
hi
=
sbp2_add_host
(
ud
->
ne
->
host
);
if
(
!
hi
)
if
(
!
scsi_id
)
return
-
ENODEV
;
return
-
ENOMEM
;
sbp2_parse_unit_directory
(
scsi_id
,
ud
);
return
sbp2_start_ud
(
hi
,
u
d
);
return
sbp2_start_device
(
scsi_i
d
);
}
}
static
int
sbp2_remove
(
struct
device
*
dev
)
static
int
sbp2_remove
(
struct
device
*
dev
)
{
{
struct
scsi_id_group
*
scsi_group
;
struct
list_head
*
lh
,
*
next
;
struct
unit_directory
*
ud
;
struct
unit_directory
*
ud
;
struct
scsi_id_instance_data
*
scsi_id
;
struct
scsi_id_instance_data
*
scsi_id
;
SBP2_DEBUG
(
__FUNCTION__
);
SBP2_DEBUG
(
"sbp2_remove"
);
ud
=
container_of
(
dev
,
struct
unit_directory
,
device
);
ud
=
container_of
(
dev
,
struct
unit_directory
,
device
);
scsi_group
=
ud
->
device
.
driver_data
;
scsi_id
=
ud
->
device
.
driver_data
;
ud
->
device
.
driver_data
=
NULL
;
list_for_each_safe
(
lh
,
next
,
&
scsi_group
->
scsi_id_list
)
{
scsi_id
=
list_entry
(
lh
,
struct
scsi_id_instance_data
,
list
);
if
(
scsi_id
!=
NULL
)
{
sbp2_logout_device
(
scsi_id
);
sbp2_logout_device
(
scsi_id
);
sbp2_remove_device
(
scsi_id
);
sbp2_remove_device
(
scsi_id
);
}
}
kfree
(
scsi_group
);
return
0
;
return
0
;
}
}
static
void
sbp2_update
(
struct
unit_directory
*
ud
)
static
void
sbp2_update
(
struct
unit_directory
*
ud
)
{
{
struct
sbp2scsi_host_info
*
hi
;
struct
scsi_id_instance_data
*
scsi_id
=
ud
->
device
.
driver_data
;
struct
scsi_id_group
*
scsi_group
=
ud
->
device
.
driver_data
;
struct
sbp2scsi_host_info
*
hi
=
scsi_id
->
hi
;
struct
list_head
*
lh
,
*
next
;
struct
scsi_id_instance_data
*
scsi_id
;
unsigned
long
flags
;
SBP2_DEBUG
(
"sbp2_update"
);
SBP2_DEBUG
(
"sbp2_update"
);
list_for_each_safe
(
lh
,
next
,
&
scsi_group
->
scsi_id_list
)
{
hi
=
scsi_id
->
hi
;
scsi_id
=
list_entry
(
lh
,
struct
scsi_id_instance_data
,
list
);
hi
=
scsi_id
->
hi
;
if
(
sbp2_reconnect_device
(
scsi_id
))
{
if
(
sbp2_reconnect_device
(
scsi_id
))
{
/*
/*
* Ok, reconnect has failed. Perhaps we didn't
* Ok, reconnect has failed. Perhaps we didn't
* reconnect fast enough. Try doing a regular login.
* reconnect fast enough. Try doing a regular login.
*/
*/
sbp2_logout_device
(
scsi_id
);
sbp2_logout_device
(
scsi_id
);
if
(
sbp2_login_device
(
scsi_id
))
{
if
(
sbp2_login_device
(
scsi_id
))
{
/* Login failed too, just remove the device. */
/* Login failed too, just remove the device. */
SBP2_ERR
(
"sbp2_reconnect_device failed!"
);
SBP2_ERR
(
"sbp2_reconnect_device failed!"
);
sbp2_remove_device
(
scsi_id
);
sbp2_remove_device
(
scsi_id
);
return
;
return
;
}
}
}
}
/* Set max retries to something large on the device. */
/* Set max retries to something large on the device. */
sbp2_set_busy_timeout
(
scsi_id
);
sbp2_set_busy_timeout
(
scsi_id
);
/* Do a SBP-2 fetch agent reset. */
/* Do a SBP-2 fetch agent reset. */
sbp2_agent_reset
(
scsi_id
,
1
);
sbp2_agent_reset
(
scsi_id
,
1
);
/* Get the max speed and packet size that we can use. */
sbp2_max_speed_and_size
(
scsi_id
);
/* Complete any pending commands with busy (so they get
/* Get the max speed and packet size that we can use. */
* retried) and remove them from our queue
sbp2_max_speed_and_size
(
scsi_id
);
*/
spin_lock_irqsave
(
&
hi
->
sbp2_command_lock
,
flags
);
/* Complete any pending commands with busy (so they get
sbp2scsi_complete_all_commands
(
scsi_id
,
DID_BUS_BUSY
);
* retried) and remove them from our queue
spin_unlock_irqrestore
(
&
hi
->
sbp2_command_lock
,
flags
);
*/
}
sbp2scsi_complete_all_commands
(
scsi_id
,
DID_BUS_BUSY
);
}
}
/* This functions is called by the sbp2_probe, for each new device. If the
/* This functions is called by the sbp2_probe, for each new device. We now
* host_info already exists, it will return it. If not, it allocated a new
* allocate one scsi host for each scsi_id (unit directory). */
* host_info entry and a corresponding scsi_host. */
static
struct
scsi_id_instance_data
*
sbp2_alloc_device
(
struct
unit_directory
*
ud
)
static
struct
sbp2scsi_host_info
*
sbp2_add_host
(
struct
hpsb_host
*
host
)
{
{
struct
sbp2scsi_host_info
*
hi
;
struct
sbp2scsi_host_info
*
hi
;
struct
Scsi_Host
*
scsi_host
;
struct
Scsi_Host
*
scsi_host
=
NULL
;
struct
scsi_id_instance_data
*
scsi_id
=
NULL
;
SBP2_DEBUG
(
"sbp2_add_host"
);
hi
=
hpsb_get_hostinfo
(
&
sbp2_highlevel
,
host
);
SBP2_DEBUG
(
"sbp2_alloc_device"
);
if
(
hi
)
return
hi
;
/* Register our host with the SCSI stack. */
scsi_id
=
kmalloc
(
sizeof
(
*
scsi_id
),
GFP_KERNEL
);
scsi_host
=
scsi_host_alloc
(
&
scsi_driver_template
,
0
);
if
(
!
scsi_id
)
{
if
(
!
scsi_host
)
{
SBP2_ERR
(
"failed to create scsi_id"
);
SBP2_ERR
(
"failed to register scsi host"
);
goto
failed_alloc
;
return
NULL
;
}
}
memset
(
scsi_id
,
0
,
sizeof
(
*
scsi_id
));
/* Register our sbp2 status address space... */
scsi_id
->
ne
=
ud
->
ne
;
hpsb_register_addrspace
(
&
sbp2_highlevel
,
host
,
&
sbp2_ops
,
scsi_id
->
ud
=
ud
;
SBP2_STATUS_FIFO_ADDRESS
,
scsi_id
->
speed_code
=
IEEE1394_SPEED_100
;
SBP2_STATUS_FIFO_ADDRESS
+
scsi_id
->
max_payload_size
=
sbp2_speedto_max_payload
[
IEEE1394_SPEED_100
];
SBP2_STATUS_FIFO_ENTRY_TO_OFFSET
(
SBP2SCSI_MAX_SCSI_IDS
+
1
));
atomic_set
(
&
scsi_id
->
sbp2_login_complete
,
0
);
INIT_LIST_HEAD
(
&
scsi_id
->
sbp2_command_orb_inuse
);
INIT_LIST_HEAD
(
&
scsi_id
->
sbp2_command_orb_completed
);
INIT_LIST_HEAD
(
&
scsi_id
->
scsi_list
);
scsi_id
->
sbp2_command_orb_lock
=
SPIN_LOCK_UNLOCKED
;
scsi_id
->
sbp2_device_type_and_lun
=
SBP2_DEVICE_TYPE_LUN_UNINITIALIZED
;
/* Handle data movement if physical dma is not enabled/supported
ud
->
device
.
driver_data
=
scsi_id
;
* on host controller */
#ifdef CONFIG_IEEE1394_SBP2_PHYS_DMA
hpsb_register_addrspace
(
&
sbp2_highlevel
,
host
,
&
sbp2_physdma_ops
,
0x0ULL
,
0xfffffffcULL
);
#endif
hi
=
hpsb_
create_hostinfo
(
&
sbp2_highlevel
,
host
,
sizeof
(
*
hi
)
);
hi
=
hpsb_
get_hostinfo
(
&
sbp2_highlevel
,
ud
->
ne
->
host
);
if
(
!
hi
)
{
if
(
!
hi
)
{
SBP2_ERR
(
"failed to allocate hostinfo"
);
hi
=
hpsb_create_hostinfo
(
&
sbp2_highlevel
,
ud
->
ne
->
host
,
sizeof
(
*
hi
));
scsi_host_put
(
hi
->
scsi_host
);
if
(
!
hi
)
{
SBP2_ERR
(
"failed to allocate hostinfo"
);
goto
failed_alloc
;
}
SBP2_DEBUG
(
"sbp2_alloc_device: allocated hostinfo"
);
hi
->
host
=
ud
->
ne
->
host
;
INIT_LIST_HEAD
(
&
hi
->
scsi_ids
);
/* Register our sbp2 status address space... */
hpsb_register_addrspace
(
&
sbp2_highlevel
,
ud
->
ne
->
host
,
&
sbp2_ops
,
SBP2_STATUS_FIFO_ADDRESS
,
SBP2_STATUS_FIFO_ADDRESS
+
SBP2_STATUS_FIFO_ENTRY_TO_OFFSET
(
SBP2_MAX_UDS_PER_NODE
+
1
));
#ifdef CONFIG_IEEE1394_SBP2_PHYS_DMA
/* Handle data movement if physical dma is not
* enabled/supportedon host controller */
hpsb_register_addrspace
(
&
sbp2_highlevel
,
host
,
&
sbp2_physdma_ops
,
0x0ULL
,
0xfffffffcULL
);
#endif
}
}
hpsb_set_hostinfo_key
(
&
sbp2_highlevel
,
host
,
(
unsigned
long
)
scsi_host
)
;
scsi_id
->
hi
=
hi
;
hi
->
scsi_host
=
scsi_host
;
list_add_tail
(
&
scsi_id
->
scsi_list
,
&
hi
->
scsi_ids
);
hi
->
host
=
host
;
hi
->
sbp2_command_lock
=
SPIN_LOCK_UNLOCKED
;
hi
->
scsi_host
->
max_id
=
SBP2SCSI_MAX_SCSI_IDS
;
/* XXX We need a device to pass here as the scsi-host class. Can't
/* Register our host with the SCSI stack. */
* use the PCI device, since it is already bound to the ieee1394
scsi_host
=
scsi_host_alloc
(
&
scsi_driver_template
,
0
);
* host. Can't use the fw-host device since it is multi-class
if
(
!
scsi_host
)
{
* enabled (scsi-host uses classdata member of the device). */
SBP2_ERR
(
"failed to register scsi host"
);
if
(
scsi_add_host
(
hi
->
scsi_host
,
NULL
))
{
goto
failed_alloc
;
SBP2_ERR
(
"failed to add scsi host"
);
scsi_host_put
(
hi
->
scsi_host
);
hpsb_destroy_hostinfo
(
&
sbp2_highlevel
,
host
);
return
NULL
;
}
}
return
hi
;
scsi_host
->
hostdata
[
0
]
=
(
unsigned
long
)
scsi_id
;
if
(
!
scsi_add_host
(
scsi_host
,
&
ud
->
device
))
{
scsi_id
->
scsi_host
=
scsi_host
;
return
scsi_id
;
}
SBP2_ERR
(
"failed to add scsi host"
);
scsi_host_put
(
scsi_host
);
failed_alloc:
sbp2_remove_device
(
scsi_id
);
return
NULL
;
}
}
/*
static
void
sbp2_host_reset
(
struct
hpsb_host
*
host
)
* This function is called when a host is removed.
*/
static
void
sbp2_remove_host
(
struct
hpsb_host
*
host
)
{
{
struct
sbp2scsi_host_info
*
hi
;
struct
sbp2scsi_host_info
*
hi
;
struct
scsi_id_instance_data
*
scsi_id
;
SBP2_DEBUG
(
"sbp2_remove_host"
);
hi
=
hpsb_get_hostinfo
(
&
sbp2_highlevel
,
host
);
hi
=
hpsb_get_hostinfo
(
&
sbp2_highlevel
,
host
);
if
(
hi
)
{
if
(
hi
)
{
scsi_remove_host
(
hi
->
scsi_host
);
list_for_each_entry
(
scsi_id
,
&
hi
->
scsi_ids
,
scsi_list
)
scsi_host_put
(
hi
->
scsi_host
);
scsi_block_requests
(
scsi_id
->
scsi_host
);
}
}
}
}
static
int
sbp2_start_ud
(
struct
sbp2scsi_host_info
*
hi
,
struct
unit_directory
*
ud
)
{
struct
scsi_id_instance_data
*
scsi_id
,
*
scsi_id_tmp
;
struct
scsi_id_group
*
scsi_group
;
SBP2_DEBUG
(
"sbp2_start_ud"
);
scsi_group
=
kmalloc
(
sizeof
(
*
scsi_group
),
GFP_KERNEL
);
if
(
!
scsi_group
)
{
SBP2_ERR
(
"Could not allocate memory for scsi_group"
);
return
-
ENOMEM
;
}
INIT_LIST_HEAD
(
&
scsi_group
->
scsi_id_list
);
ud
->
device
.
driver_data
=
scsi_group
;
sbp2_parse_unit_directory
(
scsi_group
,
ud
,
hi
);
/* Make sure the scsi_host is ready for this */
scsi_unblock_requests
(
hi
->
scsi_host
);
list_for_each_entry_safe
(
scsi_id
,
scsi_id_tmp
,
&
scsi_group
->
scsi_id_list
,
list
)
sbp2_start_device
(
scsi_id
);
/* Check to see if any of our devices survived the ordeal */
if
(
list_empty
(
&
scsi_group
->
scsi_id_list
))
{
kfree
(
scsi_group
);
return
-
ENODEV
;
}
return
0
;
}
static
void
sbp2_
host_rese
t
(
struct
hpsb_host
*
host
)
static
void
sbp2_
remove_hos
t
(
struct
hpsb_host
*
host
)
{
{
struct
sbp2scsi_host_info
*
hi
;
struct
sbp2scsi_host_info
*
hi
;
SBP2_DEBUG
(
"sbp2_remove_host"
);
hi
=
hpsb_get_hostinfo
(
&
sbp2_highlevel
,
host
);
hi
=
hpsb_get_hostinfo
(
&
sbp2_highlevel
,
host
);
if
(
hi
)
if
(
hi
)
{
scsi_block_requests
(
hi
->
scsi_host
);
struct
scsi_id_instance_data
*
scsi_id
;
list_for_each_entry
(
scsi_id
,
&
hi
->
scsi_ids
,
scsi_list
)
{
down_write
(
&
scsi_id
->
ud
->
device
.
bus
->
subsys
.
rwsem
);
device_release_driver
(
&
scsi_id
->
ud
->
device
);
up_write
(
&
scsi_id
->
ud
->
device
.
bus
->
subsys
.
rwsem
);
}
}
}
}
...
@@ -821,7 +801,6 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id)
...
@@ -821,7 +801,6 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id)
{
{
struct
sbp2scsi_host_info
*
hi
=
scsi_id
->
hi
;
struct
sbp2scsi_host_info
*
hi
=
scsi_id
->
hi
;
struct
scsi_device
*
sdev
;
struct
scsi_device
*
sdev
;
int
i
;
SBP2_DEBUG
(
"sbp2_start_device"
);
SBP2_DEBUG
(
"sbp2_start_device"
);
...
@@ -913,7 +892,7 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id)
...
@@ -913,7 +892,7 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id)
kfree
(
scsi_id
);
kfree
(
scsi_id
);
list_del
(
&
scsi_id
->
list
);
list_del
(
&
scsi_id
->
scsi_
list
);
SBP2_ERR
(
"Could not allocate memory for scsi_id"
);
SBP2_ERR
(
"Could not allocate memory for scsi_id"
);
...
@@ -921,17 +900,7 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id)
...
@@ -921,17 +900,7 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id)
}
}
SBP2_DMA_ALLOC
(
"consistent DMA region for login ORB"
);
SBP2_DMA_ALLOC
(
"consistent DMA region for login ORB"
);
/*
SBP2_DEBUG
(
"New SBP-2 device inserted, SCSI ID = %x"
,
scsi_id
->
ud
->
id
);
* Find an empty spot to stick our scsi id instance data.
*/
for
(
i
=
0
;
i
<
hi
->
scsi_host
->
max_id
;
i
++
)
{
if
(
!
hi
->
scsi_id
[
i
])
{
hi
->
scsi_id
[
i
]
=
scsi_id
;
scsi_id
->
id
=
i
;
SBP2_DEBUG
(
"New SBP-2 device inserted, SCSI ID = %x"
,
(
unsigned
int
)
i
);
break
;
}
}
/*
/*
* Create our command orb pool
* Create our command orb pool
...
@@ -942,15 +911,6 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id)
...
@@ -942,15 +911,6 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id)
return
-
ENOMEM
;
return
-
ENOMEM
;
}
}
/*
* Make sure we are not out of space
*/
if
(
i
==
hi
->
scsi_host
->
max_id
)
{
SBP2_ERR
(
"No slots left for SBP-2 device"
);
sbp2_remove_device
(
scsi_id
);
return
-
EBUSY
;
}
/* Schedule a timeout here. The reason is that we may be so close
/* Schedule a timeout here. The reason is that we may be so close
* to a bus reset, that the device is not available for logins.
* to a bus reset, that the device is not available for logins.
* This can happen when the bus reset is caused by the host
* This can happen when the bus reset is caused by the host
...
@@ -986,15 +946,12 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id)
...
@@ -986,15 +946,12 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id)
sbp2_max_speed_and_size
(
scsi_id
);
sbp2_max_speed_and_size
(
scsi_id
);
/* Add this device to the scsi layer now */
/* Add this device to the scsi layer now */
sdev
=
scsi_add_device
(
hi
->
scsi_host
,
0
,
scsi_i
d
->
id
,
0
);
sdev
=
scsi_add_device
(
scsi_id
->
scsi_host
,
0
,
scsi_id
->
u
d
->
id
,
0
);
if
(
IS_ERR
(
sdev
))
{
if
(
IS_ERR
(
sdev
))
{
SBP2_ERR
(
"scsi_add_device failed"
);
SBP2_ERR
(
"scsi_add_device failed"
);
return
PTR_ERR
(
sdev
);
return
PTR_ERR
(
sdev
);
}
}
sdev
->
hostdata
=
scsi_id
;
scsi_id
->
sdev
=
sdev
;
return
0
;
return
0
;
}
}
...
@@ -1003,22 +960,24 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id)
...
@@ -1003,22 +960,24 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id)
*/
*/
static
void
sbp2_remove_device
(
struct
scsi_id_instance_data
*
scsi_id
)
static
void
sbp2_remove_device
(
struct
scsi_id_instance_data
*
scsi_id
)
{
{
struct
sbp2scsi_host_info
*
hi
=
scsi_id
->
hi
;
struct
sbp2scsi_host_info
*
hi
;
SBP2_DEBUG
(
"sbp2_remove_device"
);
SBP2_DEBUG
(
"sbp2_remove_device"
);
/* Complete any pending commands with selection timeout */
if
(
!
scsi_id
)
sbp2scsi_complete_all_commands
(
scsi_id
,
DID_NO_CONNECT
);
return
;
hi
=
scsi_id
->
hi
;
/*
Remove it from the scsi layer now
*/
/*
This will remove our scsi device aswell
*/
if
(
scsi_id
->
s
dev
)
{
if
(
scsi_id
->
s
csi_host
)
{
scsi_remove_
device
(
scsi_id
->
sdev
);
scsi_remove_
host
(
scsi_id
->
scsi_host
);
//scsi_device_put(scsi_id->sdev
);
scsi_host_put
(
scsi_id
->
scsi_host
);
}
}
sbp2util_remove_command_orb_pool
(
scsi_id
);
sbp2util_remove_command_orb_pool
(
scsi_id
);
hi
->
scsi_id
[
scsi_id
->
id
]
=
NULL
;
list_del
(
&
scsi_id
->
scsi_list
)
;
if
(
scsi_id
->
login_response
)
{
if
(
scsi_id
->
login_response
)
{
pci_free_consistent
(
hi
->
host
->
pdev
,
pci_free_consistent
(
hi
->
host
->
pdev
,
...
@@ -1068,9 +1027,9 @@ static void sbp2_remove_device(struct scsi_id_instance_data *scsi_id)
...
@@ -1068,9 +1027,9 @@ static void sbp2_remove_device(struct scsi_id_instance_data *scsi_id)
SBP2_DMA_FREE
(
"single query logins data"
);
SBP2_DMA_FREE
(
"single query logins data"
);
}
}
SBP2_DEBUG
(
"SBP-2 device removed, SCSI ID = %d"
,
scsi_id
->
id
)
;
scsi_id
->
ud
->
device
.
driver_data
=
NULL
;
list_del
(
&
scsi_id
->
list
);
SBP2_DEBUG
(
"SBP-2 device removed, SCSI ID = %d"
,
scsi_id
->
ud
->
id
);
kfree
(
scsi_id
);
kfree
(
scsi_id
);
}
}
...
@@ -1158,7 +1117,7 @@ static int sbp2_query_logins(struct scsi_id_instance_data *scsi_id)
...
@@ -1158,7 +1117,7 @@ static int sbp2_query_logins(struct scsi_id_instance_data *scsi_id)
SBP2_DEBUG
(
"sbp2_query_logins: reserved_resp_length initialized"
);
SBP2_DEBUG
(
"sbp2_query_logins: reserved_resp_length initialized"
);
scsi_id
->
query_logins_orb
->
status_FIFO_lo
=
SBP2_STATUS_FIFO_ADDRESS_LO
+
scsi_id
->
query_logins_orb
->
status_FIFO_lo
=
SBP2_STATUS_FIFO_ADDRESS_LO
+
SBP2_STATUS_FIFO_ENTRY_TO_OFFSET
(
scsi_id
->
id
);
SBP2_STATUS_FIFO_ENTRY_TO_OFFSET
(
scsi_id
->
ud
->
id
);
scsi_id
->
query_logins_orb
->
status_FIFO_hi
=
(
ORB_SET_NODE_ID
(
hi
->
host
->
node_id
)
|
scsi_id
->
query_logins_orb
->
status_FIFO_hi
=
(
ORB_SET_NODE_ID
(
hi
->
host
->
node_id
)
|
SBP2_STATUS_FIFO_ADDRESS_HI
);
SBP2_STATUS_FIFO_ADDRESS_HI
);
SBP2_DEBUG
(
"sbp2_query_logins: status FIFO initialized"
);
SBP2_DEBUG
(
"sbp2_query_logins: status FIFO initialized"
);
...
@@ -1272,7 +1231,7 @@ static int sbp2_login_device(struct scsi_id_instance_data *scsi_id)
...
@@ -1272,7 +1231,7 @@ static int sbp2_login_device(struct scsi_id_instance_data *scsi_id)
SBP2_DEBUG
(
"sbp2_login_device: passwd_resp_lengths initialized"
);
SBP2_DEBUG
(
"sbp2_login_device: passwd_resp_lengths initialized"
);
scsi_id
->
login_orb
->
status_FIFO_lo
=
SBP2_STATUS_FIFO_ADDRESS_LO
+
scsi_id
->
login_orb
->
status_FIFO_lo
=
SBP2_STATUS_FIFO_ADDRESS_LO
+
SBP2_STATUS_FIFO_ENTRY_TO_OFFSET
(
scsi_id
->
id
);
SBP2_STATUS_FIFO_ENTRY_TO_OFFSET
(
scsi_id
->
ud
->
id
);
scsi_id
->
login_orb
->
status_FIFO_hi
=
(
ORB_SET_NODE_ID
(
hi
->
host
->
node_id
)
|
scsi_id
->
login_orb
->
status_FIFO_hi
=
(
ORB_SET_NODE_ID
(
hi
->
host
->
node_id
)
|
SBP2_STATUS_FIFO_ADDRESS_HI
);
SBP2_STATUS_FIFO_ADDRESS_HI
);
SBP2_DEBUG
(
"sbp2_login_device: status FIFO initialized"
);
SBP2_DEBUG
(
"sbp2_login_device: status FIFO initialized"
);
...
@@ -1388,7 +1347,7 @@ static int sbp2_logout_device(struct scsi_id_instance_data *scsi_id)
...
@@ -1388,7 +1347,7 @@ static int sbp2_logout_device(struct scsi_id_instance_data *scsi_id)
scsi_id
->
logout_orb
->
reserved5
=
0x0
;
scsi_id
->
logout_orb
->
reserved5
=
0x0
;
scsi_id
->
logout_orb
->
status_FIFO_lo
=
SBP2_STATUS_FIFO_ADDRESS_LO
+
scsi_id
->
logout_orb
->
status_FIFO_lo
=
SBP2_STATUS_FIFO_ADDRESS_LO
+
SBP2_STATUS_FIFO_ENTRY_TO_OFFSET
(
scsi_id
->
id
);
SBP2_STATUS_FIFO_ENTRY_TO_OFFSET
(
scsi_id
->
ud
->
id
);
scsi_id
->
logout_orb
->
status_FIFO_hi
=
(
ORB_SET_NODE_ID
(
hi
->
host
->
node_id
)
|
scsi_id
->
logout_orb
->
status_FIFO_hi
=
(
ORB_SET_NODE_ID
(
hi
->
host
->
node_id
)
|
SBP2_STATUS_FIFO_ADDRESS_HI
);
SBP2_STATUS_FIFO_ADDRESS_HI
);
...
@@ -1448,7 +1407,7 @@ static int sbp2_reconnect_device(struct scsi_id_instance_data *scsi_id)
...
@@ -1448,7 +1407,7 @@ static int sbp2_reconnect_device(struct scsi_id_instance_data *scsi_id)
scsi_id
->
reconnect_orb
->
reserved5
=
0x0
;
scsi_id
->
reconnect_orb
->
reserved5
=
0x0
;
scsi_id
->
reconnect_orb
->
status_FIFO_lo
=
SBP2_STATUS_FIFO_ADDRESS_LO
+
scsi_id
->
reconnect_orb
->
status_FIFO_lo
=
SBP2_STATUS_FIFO_ADDRESS_LO
+
SBP2_STATUS_FIFO_ENTRY_TO_OFFSET
(
scsi_id
->
id
);
SBP2_STATUS_FIFO_ENTRY_TO_OFFSET
(
scsi_id
->
ud
->
id
);
scsi_id
->
reconnect_orb
->
status_FIFO_hi
=
scsi_id
->
reconnect_orb
->
status_FIFO_hi
=
(
ORB_SET_NODE_ID
(
hi
->
host
->
node_id
)
|
SBP2_STATUS_FIFO_ADDRESS_HI
);
(
ORB_SET_NODE_ID
(
hi
->
host
->
node_id
)
|
SBP2_STATUS_FIFO_ADDRESS_HI
);
...
@@ -1532,45 +1491,16 @@ static int sbp2_set_busy_timeout(struct scsi_id_instance_data *scsi_id)
...
@@ -1532,45 +1491,16 @@ static int sbp2_set_busy_timeout(struct scsi_id_instance_data *scsi_id)
}
}
static
struct
scsi_id_instance_data
*
sbp2_alloc_scsi_id
(
struct
scsi_id_group
*
scsi_group
,
struct
unit_directory
*
ud
,
struct
sbp2scsi_host_info
*
hi
)
{
struct
scsi_id_instance_data
*
scsi_id
=
kmalloc
(
sizeof
(
*
scsi_id
),
GFP_KERNEL
);
if
(
!
scsi_id
)
return
NULL
;
memset
(
scsi_id
,
0
,
sizeof
(
*
scsi_id
));
scsi_id
->
ne
=
ud
->
ne
;
scsi_id
->
hi
=
hi
;
scsi_id
->
ud
=
ud
;
scsi_id
->
speed_code
=
IEEE1394_SPEED_100
;
scsi_id
->
max_payload_size
=
sbp2_speedto_max_payload
[
IEEE1394_SPEED_100
];
atomic_set
(
&
scsi_id
->
sbp2_login_complete
,
0
);
INIT_LIST_HEAD
(
&
scsi_id
->
sbp2_command_orb_inuse
);
INIT_LIST_HEAD
(
&
scsi_id
->
sbp2_command_orb_completed
);
scsi_id
->
sbp2_command_orb_lock
=
SPIN_LOCK_UNLOCKED
;
scsi_id
->
sbp2_device_type_and_lun
=
SBP2_DEVICE_TYPE_LUN_UNINITIALIZED
;
list_add_tail
(
&
scsi_id
->
list
,
&
scsi_group
->
scsi_id_list
);
return
scsi_id
;
}
/*
/*
* This function is called to parse sbp2 device's config rom unit
* This function is called to parse sbp2 device's config rom unit
* directory. Used to determine things like sbp2 management agent offset,
* directory. Used to determine things like sbp2 management agent offset,
* and command set used (SCSI or RBC).
* and command set used (SCSI or RBC).
*/
*/
static
void
sbp2_parse_unit_directory
(
struct
scsi_id_group
*
scsi_group
,
static
void
sbp2_parse_unit_directory
(
struct
scsi_id_instance_data
*
scsi_id
,
struct
unit_directory
*
ud
,
struct
unit_directory
*
ud
)
struct
sbp2scsi_host_info
*
hi
)
{
{
struct
csr1212_keyval
*
kv
;
struct
csr1212_keyval
*
kv
;
struct
csr1212_dentry
*
dentry
;
struct
csr1212_dentry
*
dentry
;
struct
scsi_id_instance_data
*
scsi_id
;
u64
management_agent_addr
;
u64
management_agent_addr
;
u32
command_set_spec_id
,
command_set
,
unit_characteristics
,
u32
command_set_spec_id
,
command_set
,
unit_characteristics
,
firmware_revision
,
workarounds
;
firmware_revision
,
workarounds
;
...
@@ -1596,19 +1526,8 @@ static void sbp2_parse_unit_directory(struct scsi_id_group *scsi_group,
...
@@ -1596,19 +1526,8 @@ static void sbp2_parse_unit_directory(struct scsi_id_group *scsi_group,
SBP2_DEBUG
(
"sbp2_management_agent_addr = %x"
,
SBP2_DEBUG
(
"sbp2_management_agent_addr = %x"
,
(
unsigned
int
)
management_agent_addr
);
(
unsigned
int
)
management_agent_addr
);
}
else
{
}
else
/*
* Device type and lun (used for
* detemining type of sbp2 device)
*/
scsi_id
=
sbp2_alloc_scsi_id
(
scsi_group
,
ud
,
hi
);
if
(
!
scsi_id
)
{
SBP2_ERR
(
"Out of memory adding scsi_id, not all LUN's will be added"
);
break
;
}
scsi_id
->
sbp2_device_type_and_lun
=
kv
->
value
.
immediate
;
scsi_id
->
sbp2_device_type_and_lun
=
kv
->
value
.
immediate
;
}
break
;
break
;
case
SBP2_COMMAND_SET_SPEC_ID_KEY
:
case
SBP2_COMMAND_SET_SPEC_ID_KEY
:
...
@@ -1687,31 +1606,18 @@ static void sbp2_parse_unit_directory(struct scsi_id_group *scsi_group,
...
@@ -1687,31 +1606,18 @@ static void sbp2_parse_unit_directory(struct scsi_id_group *scsi_group,
}
}
/* If this is a logical unit directory entry, process the parent
/* If this is a logical unit directory entry, process the parent
* to get the
common
values. */
* to get the values. */
if
(
ud
->
flags
&
UNIT_DIRECTORY_LUN_DIRECTORY
)
{
if
(
ud
->
flags
&
UNIT_DIRECTORY_LUN_DIRECTORY
)
{
struct
unit_directory
*
parent_ud
=
struct
unit_directory
*
parent_ud
=
container_of
(
ud
->
device
.
parent
,
struct
unit_directory
,
device
);
container_of
(
ud
->
device
.
parent
,
struct
unit_directory
,
device
);
sbp2_parse_unit_directory
(
scsi_
group
,
parent_ud
,
hi
);
sbp2_parse_unit_directory
(
scsi_
id
,
parent_ud
);
}
else
{
}
else
{
/* If our list is empty, add a base scsi_id (happens in a normal
scsi_id
->
sbp2_management_agent_addr
=
management_agent_addr
;
* case where there is no logical_unit_number entry */
scsi_id
->
sbp2_command_set_spec_id
=
command_set_spec_id
;
if
(
list_empty
(
&
scsi_group
->
scsi_id_list
))
{
scsi_id
->
sbp2_command_set
=
command_set
;
scsi_id
=
sbp2_alloc_scsi_id
(
scsi_group
,
ud
,
hi
);
scsi_id
->
sbp2_unit_characteristics
=
unit_characteristics
;
if
(
!
scsi_id
)
{
scsi_id
->
sbp2_firmware_revision
=
firmware_revision
;
SBP2_ERR
(
"Out of memory adding scsi_id"
);
scsi_id
->
workarounds
=
workarounds
;
return
;
}
}
/* Update the generic fields in all the LUN's */
list_for_each_entry
(
scsi_id
,
&
scsi_group
->
scsi_id_list
,
list
)
{
scsi_id
->
sbp2_management_agent_addr
=
management_agent_addr
;
scsi_id
->
sbp2_command_set_spec_id
=
command_set_spec_id
;
scsi_id
->
sbp2_command_set
=
command_set
;
scsi_id
->
sbp2_unit_characteristics
=
unit_characteristics
;
scsi_id
->
sbp2_firmware_revision
=
firmware_revision
;
scsi_id
->
workarounds
=
workarounds
;
}
}
}
}
}
...
@@ -2409,10 +2315,9 @@ static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id,
...
@@ -2409,10 +2315,9 @@ static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id,
static
int
sbp2_handle_status_write
(
struct
hpsb_host
*
host
,
int
nodeid
,
int
destid
,
static
int
sbp2_handle_status_write
(
struct
hpsb_host
*
host
,
int
nodeid
,
int
destid
,
quadlet_t
*
data
,
u64
addr
,
size_t
length
,
u16
fl
)
quadlet_t
*
data
,
u64
addr
,
size_t
length
,
u16
fl
)
{
{
struct
sbp2scsi_host_info
*
hi
=
NULL
;
struct
sbp2scsi_host_info
*
hi
;
struct
scsi_id_instance_data
*
scsi_id
=
NULL
;
struct
scsi_id_instance_data
*
scsi_id
=
NULL
,
*
scsi_id_tmp
;
u32
id
;
u32
id
;
unsigned
long
flags
;
Scsi_Cmnd
*
SCpnt
=
NULL
;
Scsi_Cmnd
*
SCpnt
=
NULL
;
u32
scsi_status
=
SBP2_SCSI_STATUS_GOOD
;
u32
scsi_status
=
SBP2_SCSI_STATUS_GOOD
;
struct
sbp2_command_info
*
command
;
struct
sbp2_command_info
*
command
;
...
@@ -2433,18 +2338,20 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest
...
@@ -2433,18 +2338,20 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest
return
(
RCODE_ADDRESS_ERROR
);
return
(
RCODE_ADDRESS_ERROR
);
}
}
spin_lock_irqsave
(
&
hi
->
sbp2_command_lock
,
flags
);
/*
/*
* Find our scsi_id structure by looking at the status fifo address written to by
* Find our scsi_id structure by looking at the status fifo address written to by
* the sbp2 device.
* the sbp2 device.
*/
*/
id
=
SBP2_STATUS_FIFO_OFFSET_TO_ENTRY
((
u32
)(
addr
-
SBP2_STATUS_FIFO_ADDRESS
));
id
=
SBP2_STATUS_FIFO_OFFSET_TO_ENTRY
((
u32
)(
addr
-
SBP2_STATUS_FIFO_ADDRESS
));
scsi_id
=
hi
->
scsi_id
[
id
];
list_for_each_entry
(
scsi_id_tmp
,
&
hi
->
scsi_ids
,
scsi_list
)
{
if
(
scsi_id_tmp
->
ne
->
nodeid
==
nodeid
&&
scsi_id_tmp
->
ud
->
id
==
id
)
{
scsi_id
=
scsi_id_tmp
;
break
;
}
}
if
(
!
scsi_id
)
{
if
(
!
scsi_id
)
{
SBP2_ERR
(
"scsi_id is NULL - device is gone?"
);
SBP2_ERR
(
"scsi_id is NULL - device is gone?"
);
spin_unlock_irqrestore
(
&
hi
->
sbp2_command_lock
,
flags
);
return
(
RCODE_ADDRESS_ERROR
);
return
(
RCODE_ADDRESS_ERROR
);
}
}
...
@@ -2532,18 +2439,9 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest
...
@@ -2532,18 +2439,9 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest
}
}
}
}
spin_unlock_irqrestore
(
&
hi
->
sbp2_command_lock
,
flags
);
if
(
SCpnt
)
{
if
(
SCpnt
)
{
/*
/* Complete the SCSI command. */
* Complete the SCSI command.
*
* Only do it after we've released the sbp2_command_lock,
* as it might otherwise deadlock with the
* io_request_lock (in sbp2scsi_queuecommand).
*/
SBP2_DEBUG
(
"Completing SCSI command"
);
SBP2_DEBUG
(
"Completing SCSI command"
);
sbp2scsi_complete_command
(
scsi_id
,
scsi_status
,
SCpnt
,
sbp2scsi_complete_command
(
scsi_id
,
scsi_status
,
SCpnt
,
command
->
Current_done
);
command
->
Current_done
);
...
@@ -2564,31 +2462,26 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest
...
@@ -2564,31 +2462,26 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest
*/
*/
static
int
sbp2scsi_queuecommand
(
Scsi_Cmnd
*
SCpnt
,
void
(
*
done
)(
Scsi_Cmnd
*
))
static
int
sbp2scsi_queuecommand
(
Scsi_Cmnd
*
SCpnt
,
void
(
*
done
)(
Scsi_Cmnd
*
))
{
{
struct
s
bp2scsi_host_info
*
hi
=
NULL
;
struct
s
csi_id_instance_data
*
scsi_id
=
struct
scsi_id_instance_data
*
scsi_id
=
NULL
;
(
struct
scsi_id_instance_data
*
)
SCpnt
->
device
->
host
->
hostdata
[
0
]
;
unsigned
long
flags
;
struct
sbp2scsi_host_info
*
hi
;
SBP2_DEBUG
(
"sbp2scsi_queuecommand"
);
SBP2_DEBUG
(
"sbp2scsi_queuecommand"
);
/*
/*
* Pull our host info and scsi id instance data from the scsi command
* If scsi_id is null, it means there is no device in this slot,
* so we should return selection timeout.
*/
*/
hi
=
hpsb_get_hostinfo_bykey
(
&
sbp2_highlevel
,
(
unsigned
long
)
SCpnt
->
device
->
host
);
if
(
!
scsi_id
)
{
if
(
!
hi
)
{
SBP2_ERR
(
"sbp2scsi_host_info is NULL - this is bad!"
);
SCpnt
->
result
=
DID_NO_CONNECT
<<
16
;
SCpnt
->
result
=
DID_NO_CONNECT
<<
16
;
done
(
SCpnt
);
done
(
SCpnt
);
return
(
0
)
;
return
0
;
}
}
scsi_id
=
hi
->
scsi_id
[
SCpnt
->
device
->
id
]
;
hi
=
scsi_id
->
hi
;
/*
if
(
!
hi
)
{
* If scsi_id is null, it means there is no device in this slot,
SBP2_ERR
(
"sbp2scsi_host_info is NULL - this is bad!"
);
* so we should return selection timeout.
*/
if
(
!
scsi_id
)
{
SCpnt
->
result
=
DID_NO_CONNECT
<<
16
;
SCpnt
->
result
=
DID_NO_CONNECT
<<
16
;
done
(
SCpnt
);
done
(
SCpnt
);
return
(
0
);
return
(
0
);
...
@@ -2629,13 +2522,11 @@ static int sbp2scsi_queuecommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
...
@@ -2629,13 +2522,11 @@ static int sbp2scsi_queuecommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
/*
/*
* Try and send our SCSI command
* Try and send our SCSI command
*/
*/
spin_lock_irqsave
(
&
hi
->
sbp2_command_lock
,
flags
);
if
(
sbp2_send_command
(
scsi_id
,
SCpnt
,
done
))
{
if
(
sbp2_send_command
(
scsi_id
,
SCpnt
,
done
))
{
SBP2_ERR
(
"Error sending SCSI command"
);
SBP2_ERR
(
"Error sending SCSI command"
);
sbp2scsi_complete_command
(
scsi_id
,
SBP2_SCSI_STATUS_SELECTION_TIMEOUT
,
sbp2scsi_complete_command
(
scsi_id
,
SBP2_SCSI_STATUS_SELECTION_TIMEOUT
,
SCpnt
,
done
);
SCpnt
,
done
);
}
}
spin_unlock_irqrestore
(
&
hi
->
sbp2_command_lock
,
flags
);
return
(
0
);
return
(
0
);
}
}
...
@@ -2651,7 +2542,7 @@ static void sbp2scsi_complete_all_commands(struct scsi_id_instance_data *scsi_id
...
@@ -2651,7 +2542,7 @@ static void sbp2scsi_complete_all_commands(struct scsi_id_instance_data *scsi_id
struct
list_head
*
lh
;
struct
list_head
*
lh
;
struct
sbp2_command_info
*
command
;
struct
sbp2_command_info
*
command
;
SBP2_DEBUG
(
"sbp2_complete_all_commands"
);
SBP2_DEBUG
(
"sbp2
scsi
_complete_all_commands"
);
while
(
!
list_empty
(
&
scsi_id
->
sbp2_command_orb_inuse
))
{
while
(
!
list_empty
(
&
scsi_id
->
sbp2_command_orb_inuse
))
{
SBP2_DEBUG
(
"Found pending command to complete"
);
SBP2_DEBUG
(
"Found pending command to complete"
);
...
@@ -2671,7 +2562,7 @@ static void sbp2scsi_complete_all_commands(struct scsi_id_instance_data *scsi_id
...
@@ -2671,7 +2562,7 @@ static void sbp2scsi_complete_all_commands(struct scsi_id_instance_data *scsi_id
}
}
}
}
scsi_unblock_requests
(
hi
->
scsi_host
);
scsi_unblock_requests
(
scsi_id
->
scsi_host
);
return
;
return
;
}
}
...
@@ -2785,9 +2676,9 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id,
...
@@ -2785,9 +2676,9 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id,
/*
/*
* Tell scsi stack that we're done with this command
* Tell scsi stack that we're done with this command
*/
*/
spin_lock_irqsave
(
scsi_id
->
hi
->
scsi_host
->
host_lock
,
flags
);
spin_lock_irqsave
(
scsi_id
->
scsi_host
->
host_lock
,
flags
);
done
(
SCpnt
);
done
(
SCpnt
);
spin_unlock_irqrestore
(
scsi_id
->
hi
->
scsi_host
->
host_lock
,
flags
);
spin_unlock_irqrestore
(
scsi_id
->
scsi_host
->
host_lock
,
flags
);
return
;
return
;
}
}
...
@@ -2798,11 +2689,10 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id,
...
@@ -2798,11 +2689,10 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id,
*/
*/
static
int
sbp2scsi_abort
(
Scsi_Cmnd
*
SCpnt
)
static
int
sbp2scsi_abort
(
Scsi_Cmnd
*
SCpnt
)
{
{
struct
s
bp2scsi_host_info
*
hi
=
hpsb_get_hostinfo_bykey
(
&
sbp2_highlevel
,
struct
s
csi_id_instance_data
*
scsi_id
=
(
unsigned
long
)
SCpnt
->
device
->
host
)
;
(
struct
scsi_id_instance_data
*
)
SCpnt
->
device
->
host
->
hostdata
[
0
]
;
struct
s
csi_id_instance_data
*
scsi_id
=
hi
->
scsi_id
[
SCpnt
->
device
->
id
]
;
struct
s
bp2scsi_host_info
*
hi
=
scsi_id
->
hi
;
struct
sbp2_command_info
*
command
;
struct
sbp2_command_info
*
command
;
unsigned
long
flags
;
SBP2_ERR
(
"aborting sbp2 command"
);
SBP2_ERR
(
"aborting sbp2 command"
);
print_command
(
SCpnt
->
cmnd
);
print_command
(
SCpnt
->
cmnd
);
...
@@ -2813,7 +2703,6 @@ static int sbp2scsi_abort (Scsi_Cmnd *SCpnt)
...
@@ -2813,7 +2703,6 @@ static int sbp2scsi_abort (Scsi_Cmnd *SCpnt)
* Right now, just return any matching command structures
* Right now, just return any matching command structures
* to the free pool.
* to the free pool.
*/
*/
spin_lock_irqsave
(
&
hi
->
sbp2_command_lock
,
flags
);
command
=
sbp2util_find_command_for_SCpnt
(
scsi_id
,
SCpnt
);
command
=
sbp2util_find_command_for_SCpnt
(
scsi_id
,
SCpnt
);
if
(
command
)
{
if
(
command
)
{
SBP2_DEBUG
(
"Found command to abort"
);
SBP2_DEBUG
(
"Found command to abort"
);
...
@@ -2838,7 +2727,6 @@ static int sbp2scsi_abort (Scsi_Cmnd *SCpnt)
...
@@ -2838,7 +2727,6 @@ static int sbp2scsi_abort (Scsi_Cmnd *SCpnt)
*/
*/
sbp2_agent_reset
(
scsi_id
,
0
);
sbp2_agent_reset
(
scsi_id
,
0
);
sbp2scsi_complete_all_commands
(
scsi_id
,
DID_BUS_BUSY
);
sbp2scsi_complete_all_commands
(
scsi_id
,
DID_BUS_BUSY
);
spin_unlock_irqrestore
(
&
hi
->
sbp2_command_lock
,
flags
);
}
}
return
(
SUCCESS
);
return
(
SUCCESS
);
...
@@ -2849,9 +2737,8 @@ static int sbp2scsi_abort (Scsi_Cmnd *SCpnt)
...
@@ -2849,9 +2737,8 @@ static int sbp2scsi_abort (Scsi_Cmnd *SCpnt)
*/
*/
static
int
sbp2scsi_reset
(
Scsi_Cmnd
*
SCpnt
)
static
int
sbp2scsi_reset
(
Scsi_Cmnd
*
SCpnt
)
{
{
struct
sbp2scsi_host_info
*
hi
=
hpsb_get_hostinfo_bykey
(
&
sbp2_highlevel
,
struct
scsi_id_instance_data
*
scsi_id
=
(
unsigned
long
)
SCpnt
->
device
->
host
);
(
struct
scsi_id_instance_data
*
)
SCpnt
->
device
->
host
->
hostdata
[
0
];
struct
scsi_id_instance_data
*
scsi_id
=
hi
->
scsi_id
[
SCpnt
->
device
->
id
];
SBP2_ERR
(
"reset requested"
);
SBP2_ERR
(
"reset requested"
);
...
@@ -2877,7 +2764,7 @@ static ssize_t sbp2_sysfs_ieee1394_id_show(struct device *dev, char *buf)
...
@@ -2877,7 +2764,7 @@ static ssize_t sbp2_sysfs_ieee1394_id_show(struct device *dev, char *buf)
if
(
!
(
sdev
=
to_scsi_device
(
dev
)))
if
(
!
(
sdev
=
to_scsi_device
(
dev
)))
return
0
;
return
0
;
if
(
!
(
scsi_id
=
sdev
->
hostdata
))
if
(
!
(
scsi_id
=
(
struct
scsi_id_instance_data
*
)
sdev
->
host
->
hostdata
[
0
]
))
return
0
;
return
0
;
if
(
scsi_id
->
sbp2_device_type_and_lun
==
SBP2_DEVICE_TYPE_LUN_UNINITIALIZED
)
if
(
scsi_id
->
sbp2_device_type_and_lun
==
SBP2_DEVICE_TYPE_LUN_UNINITIALIZED
)
...
@@ -2914,8 +2801,8 @@ static Scsi_Host_Template scsi_driver_template = {
...
@@ -2914,8 +2801,8 @@ static Scsi_Host_Template scsi_driver_template = {
.
this_id
=
-
1
,
.
this_id
=
-
1
,
.
sg_tablesize
=
SG_ALL
,
.
sg_tablesize
=
SG_ALL
,
.
use_clustering
=
ENABLE_CLUSTERING
,
.
use_clustering
=
ENABLE_CLUSTERING
,
.
cmd_per_lun
=
SBP2_MAX_CMDS
_PER_LUN
,
.
cmd_per_lun
=
SBP2_MAX_CMDS
,
.
can_queue
=
SBP2_MAX_
SCSI_QUEUE
,
.
can_queue
=
SBP2_MAX_
CMDS
,
.
emulated
=
1
,
.
emulated
=
1
,
.
sdev_attrs
=
sbp2_sysfs_sdev_attrs
,
.
sdev_attrs
=
sbp2_sysfs_sdev_attrs
,
};
};
...
...
drivers/ieee1394/sbp2.h
View file @
525f0d54
...
@@ -195,20 +195,22 @@ struct sbp2_status_block {
...
@@ -195,20 +195,22 @@ struct sbp2_status_block {
* Miscellaneous SBP2 related config rom defines
* Miscellaneous SBP2 related config rom defines
*/
*/
/*
/*
The status fifo address definition below is used as a base for each
*
The status fifo address definition below is used as a status base, with a chunk
*
node, which a chunk seperately assigned to each unit directory in the
*
separately assigned for each sbp2 device detected. For example, 0xfffe00000000ULL
*
node. For example, 0xfffe00000000ULL is used for the first sbp2 device
*
is used for the first sbp2 device detected, 0xfffe00000020ULL for the next sbp2
*
detected on node 0, 0xfffe00000020ULL for the next sbp2 device on node
*
device
, and so on.
*
0
, and so on.
*
*
* Note: We could use a single status fifo address for all sbp2 devices, and figure
* Note: We could use a single status fifo address for all sbp2 devices,
* out which sbp2 device the status belongs to by looking at the source node id of
* and figure out which sbp2 device the status belongs to by looking at
* the status write... but, using separate addresses for each sbp2 device allows for
* the source node id of the status write... but, using separate addresses
* better code and the ability to support multiple luns within a single 1394 node.
* for each sbp2 unit directory allows for better code and the ability to
* support multiple luns within a single 1394 node.
*
*
* Also note that we choose the address range below as it is a region specified for
* Also note that we choose the address range below as it is a region
* write posting, where the ohci controller will automatically send an ack_complete
* specified for write posting, where the ohci controller will
* when the status is written by the sbp2 device... saving a split transaction. =)
* automatically send an ack_complete when the status is written by the
* sbp2 device... saving a split transaction. =)
*/
*/
#define SBP2_STATUS_FIFO_ADDRESS 0xfffe00000000ULL
#define SBP2_STATUS_FIFO_ADDRESS 0xfffe00000000ULL
#define SBP2_STATUS_FIFO_ADDRESS_HI 0xfffe
#define SBP2_STATUS_FIFO_ADDRESS_HI 0xfffe
...
@@ -261,7 +263,7 @@ struct sbp2_status_block {
...
@@ -261,7 +263,7 @@ struct sbp2_status_block {
*/
*/
#define SBP2_MAX_SG_ELEMENT_LENGTH 0xf000
#define SBP2_MAX_SG_ELEMENT_LENGTH 0xf000
#define SBP2
SCSI_MAX_SCSI_IDS 32
/* Max sbp2 device instances supported
*/
#define SBP2
_MAX_UDS_PER_NODE 16
/* Maximum scsi devices per node
*/
#define SBP2_MAX_SECTORS 255
/* Max sectors supported */
#define SBP2_MAX_SECTORS 255
/* Max sectors supported */
#ifndef TYPE_SDAD
#ifndef TYPE_SDAD
...
@@ -304,11 +306,8 @@ static unchar sbp2scsi_direction_table[0x100] = {
...
@@ -304,11 +306,8 @@ static unchar sbp2scsi_direction_table[0x100] = {
DUN
,
DUN
,
DUN
,
DUN
,
DUN
,
DUN
,
DUN
,
DUN
,
DUN
,
DUN
,
DUN
,
DUN
,
DUN
,
DUN
,
DUN
,
DUN
DUN
,
DUN
,
DUN
,
DUN
,
DUN
,
DUN
,
DUN
,
DUN
,
DUN
,
DUN
,
DUN
,
DUN
,
DUN
,
DUN
,
DUN
,
DUN
};
};
/* This should be safe. If there's more than one LUN per node, we could
/* This should be safe */
* saturate the tlabel's though. */
#define SBP2_MAX_CMDS 8
#define SBP2_MAX_CMDS_PER_LUN 8
#define SBP2_MAX_SCSI_QUEUE (SBP2_MAX_CMDS_PER_LUN * SBP2SCSI_MAX_SCSI_IDS)
#define SBP2_MAX_COMMAND_ORBS SBP2_MAX_SCSI_QUEUE
/* This is the two dma types we use for cmd_dma below */
/* This is the two dma types we use for cmd_dma below */
enum
cmd_dma_types
{
enum
cmd_dma_types
{
...
@@ -351,9 +350,6 @@ struct sbp2scsi_host_info;
...
@@ -351,9 +350,6 @@ struct sbp2scsi_host_info;
* Information needed on a per scsi id basis (one for each sbp2 device)
* Information needed on a per scsi id basis (one for each sbp2 device)
*/
*/
struct
scsi_id_instance_data
{
struct
scsi_id_instance_data
{
/* SCSI ID */
int
id
;
/*
/*
* Various sbp2 specific structures
* Various sbp2 specific structures
*/
*/
...
@@ -402,7 +398,7 @@ struct scsi_id_instance_data {
...
@@ -402,7 +398,7 @@ struct scsi_id_instance_data {
struct
list_head
sbp2_command_orb_inuse
;
struct
list_head
sbp2_command_orb_inuse
;
struct
list_head
sbp2_command_orb_completed
;
struct
list_head
sbp2_command_orb_completed
;
struct
list_head
list
;
struct
list_head
scsi_
list
;
/* Node entry, as retrieved from NodeMgr entries */
/* Node entry, as retrieved from NodeMgr entries */
struct
node_entry
*
ne
;
struct
node_entry
*
ne
;
...
@@ -411,42 +407,19 @@ struct scsi_id_instance_data {
...
@@ -411,42 +407,19 @@ struct scsi_id_instance_data {
/* A backlink to our host_info */
/* A backlink to our host_info */
struct
sbp2scsi_host_info
*
hi
;
struct
sbp2scsi_host_info
*
hi
;
/*
The scsi_device associated with this scsi_id
*/
/*
SCSI related pointers
*/
struct
scsi_device
*
sdev
;
struct
scsi_device
*
sdev
;
struct
Scsi_Host
*
scsi_host
;
/* Device specific workarounds/brokeness */
/* Device specific workarounds/brokeness */
u32
workarounds
;
u32
workarounds
;
};
};
/* Describes a per-ud scsi_id group */
/* Sbp2 host data structure (one per IEEE1394 host) */
struct
scsi_id_group
{
struct
list_head
scsi_id_list
;
};
/*
* Sbp2 host data structure (one per sbp2 host)
*/
struct
sbp2scsi_host_info
{
struct
sbp2scsi_host_info
{
struct
hpsb_host
*
host
;
struct
hpsb_host
*
host
;
/* IEEE1394 host */
struct
list_head
scsi_ids
;
/* List of scsi ids on this host */
/*
* Spin locks for command processing
*/
spinlock_t
sbp2_command_lock
;
/*
* This is the scsi host we register with the scsi mid level.
* We keep a reference to it here, so we can unregister it
* when the hpsb_host is removed.
*/
struct
Scsi_Host
*
scsi_host
;
/*
* SCSI ID instance data (one for each sbp2 device instance possible)
*/
struct
scsi_id_instance_data
*
scsi_id
[
SBP2SCSI_MAX_SCSI_IDS
];
};
};
/*
/*
...
@@ -469,16 +442,10 @@ static void sbp2util_mark_command_completed(struct scsi_id_instance_data *scsi_i
...
@@ -469,16 +442,10 @@ static void sbp2util_mark_command_completed(struct scsi_id_instance_data *scsi_i
/*
/*
* IEEE-1394 core driver related prototypes
* IEEE-1394 core driver related prototypes
*/
*/
static
struct
sbp2scsi_host_info
*
sbp2_add_host
(
struct
hpsb_host
*
host
);
static
void
sbp2_remove_host
(
struct
hpsb_host
*
host
);
static
void
sbp2_host_reset
(
struct
hpsb_host
*
host
);
static
int
sbp2_probe
(
struct
device
*
dev
);
static
int
sbp2_probe
(
struct
device
*
dev
);
static
int
sbp2_remove
(
struct
device
*
dev
);
static
int
sbp2_remove
(
struct
device
*
dev
);
static
void
sbp2_update
(
struct
unit_directory
*
ud
);
static
void
sbp2_update
(
struct
unit_directory
*
ud
);
static
int
sbp2_start_ud
(
struct
sbp2scsi_host_info
*
hi
,
struct
unit_directory
*
ud
);
static
int
sbp2_start_device
(
struct
scsi_id_instance_data
*
scsi_id
);
static
int
sbp2_start_device
(
struct
scsi_id_instance_data
*
scsi_id
);
static
void
sbp2_remove_device
(
struct
scsi_id_instance_data
*
scsi_id
);
static
void
sbp2_remove_device
(
struct
scsi_id_instance_data
*
scsi_id
);
...
@@ -513,9 +480,8 @@ static int sbp2_send_command(struct scsi_id_instance_data *scsi_id,
...
@@ -513,9 +480,8 @@ static int sbp2_send_command(struct scsi_id_instance_data *scsi_id,
static
unsigned
int
sbp2_status_to_sense_data
(
unchar
*
sbp2_status
,
unchar
*
sense_data
);
static
unsigned
int
sbp2_status_to_sense_data
(
unchar
*
sbp2_status
,
unchar
*
sense_data
);
static
void
sbp2_check_sbp2_command
(
struct
scsi_id_instance_data
*
scsi_id
,
unchar
*
cmd
);
static
void
sbp2_check_sbp2_command
(
struct
scsi_id_instance_data
*
scsi_id
,
unchar
*
cmd
);
static
void
sbp2_check_sbp2_response
(
struct
scsi_id_instance_data
*
scsi_id
,
Scsi_Cmnd
*
SCpnt
);
static
void
sbp2_check_sbp2_response
(
struct
scsi_id_instance_data
*
scsi_id
,
Scsi_Cmnd
*
SCpnt
);
static
void
sbp2_parse_unit_directory
(
struct
scsi_id_group
*
scsi_group
,
static
void
sbp2_parse_unit_directory
(
struct
scsi_id_instance_data
*
scsi_id
,
struct
unit_directory
*
ud
,
struct
unit_directory
*
ud
);
struct
sbp2scsi_host_info
*
hi
);
static
int
sbp2_set_busy_timeout
(
struct
scsi_id_instance_data
*
scsi_id
);
static
int
sbp2_set_busy_timeout
(
struct
scsi_id_instance_data
*
scsi_id
);
static
int
sbp2_max_speed_and_size
(
struct
scsi_id_instance_data
*
scsi_id
);
static
int
sbp2_max_speed_and_size
(
struct
scsi_id_instance_data
*
scsi_id
);
...
...
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