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
c23ee349
Commit
c23ee349
authored
Dec 05, 2002
by
Christoph Hellwig
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] move all sgtable handling in one place
We only need it in scsi_lib.c so the helper should be there aswell.
parent
d9841db4
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
116 additions
and
135 deletions
+116
-135
drivers/scsi/scsi.c
drivers/scsi/scsi.c
+3
-104
drivers/scsi/scsi.h
drivers/scsi/scsi.h
+2
-9
drivers/scsi/scsi_lib.c
drivers/scsi/scsi_lib.c
+111
-22
No files found.
drivers/scsi/scsi.c
View file @
c23ee349
...
...
@@ -55,7 +55,6 @@
#include <linux/init.h>
#include <linux/smp_lock.h>
#include <linux/completion.h>
#include <linux/mempool.h>
#define __KERNEL_SYSCALLS__
...
...
@@ -74,24 +73,6 @@
#include <linux/kmod.h>
#endif
#define SG_MEMPOOL_NR 5
#define SG_MEMPOOL_SIZE 32
struct
scsi_host_sg_pool
{
int
size
;
char
*
name
;
kmem_cache_t
*
slab
;
mempool_t
*
pool
;
};
#define SP(x) { x, "sgpool-" #x }
struct
scsi_host_sg_pool
scsi_sg_pools
[
SG_MEMPOOL_NR
]
=
{
SP
(
8
),
SP
(
16
),
SP
(
32
),
SP
(
64
),
SP
(
MAX_PHYS_SEGMENTS
)
};
#undef SP
/*
static const char RCSid[] = "$Header: /vger/u4/cvs/linux/drivers/scsi/scsi.c,v 1.38 1997/01/19 23:07:18 davem Exp $";
*/
/*
* Definitions and constants.
...
...
@@ -668,10 +649,7 @@ int scsi_mlqueue_insert(Scsi_Cmnd * cmd, int reason)
*/
void
scsi_release_command
(
Scsi_Cmnd
*
SCpnt
)
{
request_queue_t
*
q
;
Scsi_Device
*
SDpnt
;
SDpnt
=
SCpnt
->
device
;
request_queue_t
*
q
=
&
SCpnt
->
device
->
request_queue
;
__scsi_release_command
(
SCpnt
);
...
...
@@ -681,7 +659,6 @@ void scsi_release_command(Scsi_Cmnd * SCpnt)
* This won't block - if the device cannot take any more, life
* will go on.
*/
q
=
&
SDpnt
->
request_queue
;
scsi_queue_next_request
(
q
,
NULL
);
}
...
...
@@ -2084,81 +2061,12 @@ static int __init setup_scsi_default_dev_flags(char *str)
__setup
(
"scsi_default_dev_flags="
,
setup_scsi_default_dev_flags
);
#endif
static
void
*
scsi_pool_alloc
(
int
gfp_mask
,
void
*
data
)
{
return
kmem_cache_alloc
(
data
,
gfp_mask
);
}
static
void
scsi_pool_free
(
void
*
ptr
,
void
*
data
)
{
kmem_cache_free
(
data
,
ptr
);
}
struct
scatterlist
*
scsi_alloc_sgtable
(
Scsi_Cmnd
*
SCpnt
,
int
gfp_mask
)
{
struct
scsi_host_sg_pool
*
sgp
;
struct
scatterlist
*
sgl
;
int
pf_flags
;
BUG_ON
(
!
SCpnt
->
use_sg
);
switch
(
SCpnt
->
use_sg
)
{
case
1
...
8
:
SCpnt
->
sglist_len
=
0
;
break
;
case
9
...
16
:
SCpnt
->
sglist_len
=
1
;
break
;
case
17
...
32
:
SCpnt
->
sglist_len
=
2
;
break
;
case
33
...
64
:
SCpnt
->
sglist_len
=
3
;
break
;
case
65
...
MAX_PHYS_SEGMENTS
:
SCpnt
->
sglist_len
=
4
;
break
;
default:
return
NULL
;
}
sgp
=
scsi_sg_pools
+
SCpnt
->
sglist_len
;
pf_flags
=
current
->
flags
;
current
->
flags
|=
PF_NOWARN
;
sgl
=
mempool_alloc
(
sgp
->
pool
,
gfp_mask
);
current
->
flags
=
pf_flags
;
if
(
sgl
)
{
memset
(
sgl
,
0
,
sgp
->
size
);
return
sgl
;
}
return
sgl
;
}
void
scsi_free_sgtable
(
struct
scatterlist
*
sgl
,
int
index
)
{
struct
scsi_host_sg_pool
*
sgp
=
scsi_sg_pools
+
index
;
if
(
unlikely
(
index
>
SG_MEMPOOL_NR
))
{
printk
(
"scsi_free_sgtable: mempool %d
\n
"
,
index
);
BUG
();
}
mempool_free
(
sgl
,
sgp
->
pool
);
}
static
int
__init
init_scsi
(
void
)
{
int
i
;
printk
(
KERN_INFO
"SCSI subsystem driver "
REVISION
"
\n
"
);
/*
* setup sg memory pools
*/
for
(
i
=
0
;
i
<
SG_MEMPOOL_NR
;
i
++
)
{
struct
scsi_host_sg_pool
*
sgp
=
scsi_sg_pools
+
i
;
int
size
=
sgp
->
size
*
sizeof
(
struct
scatterlist
);
sgp
->
slab
=
kmem_cache_create
(
sgp
->
name
,
size
,
0
,
SLAB_HWCACHE_ALIGN
,
NULL
,
NULL
);
if
(
!
sgp
->
slab
)
printk
(
KERN_ERR
"SCSI: can't init sg slab %s
\n
"
,
sgp
->
name
);
sgp
->
pool
=
mempool_create
(
SG_MEMPOOL_SIZE
,
scsi_pool_alloc
,
scsi_pool_free
,
sgp
->
slab
);
if
(
!
sgp
->
pool
)
printk
(
KERN_ERR
"SCSI: can't init sg mempool %s
\n
"
,
sgp
->
name
);
}
scsi_init_queue
();
scsi_init_procfs
();
scsi_devfs_handle
=
devfs_mk_dir
(
NULL
,
"scsi"
,
NULL
);
scsi_host_init
();
...
...
@@ -2170,20 +2078,11 @@ static int __init init_scsi(void)
static
void
__exit
exit_scsi
(
void
)
{
int
i
;
scsi_sysfs_unregister
();
scsi_dev_info_list_delete
();
devfs_unregister
(
scsi_devfs_handle
);
scsi_exit_procfs
();
for
(
i
=
0
;
i
<
SG_MEMPOOL_NR
;
i
++
)
{
struct
scsi_host_sg_pool
*
sgp
=
scsi_sg_pools
+
i
;
mempool_destroy
(
sgp
->
pool
);
kmem_cache_destroy
(
sgp
->
slab
);
sgp
->
pool
=
NULL
;
sgp
->
slab
=
NULL
;
}
scsi_exit_queue
();
}
subsys_initcall
(
init_scsi
);
...
...
drivers/scsi/scsi.h
View file @
c23ee349
...
...
@@ -420,12 +420,6 @@ extern int scsi_partsize(unsigned char *buf, unsigned long capacity,
unsigned
int
*
cyls
,
unsigned
int
*
hds
,
unsigned
int
*
secs
);
/*
* sg list allocations
*/
struct
scatterlist
*
scsi_alloc_sgtable
(
Scsi_Cmnd
*
SCpnt
,
int
gfp_mask
);
void
scsi_free_sgtable
(
struct
scatterlist
*
sgl
,
int
index
);
/*
* Prototypes for functions in scsi_lib.c
*/
...
...
@@ -437,13 +431,13 @@ extern void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors,
extern
void
scsi_queue_next_request
(
request_queue_t
*
q
,
Scsi_Cmnd
*
SCpnt
);
extern
int
scsi_prep_fn
(
struct
request_queue
*
q
,
struct
request
*
req
);
extern
void
scsi_request_fn
(
request_queue_t
*
q
);
extern
int
scsi_starvation_completion
(
Scsi_Device
*
SDpnt
);
extern
int
scsi_init_queue
(
void
);
extern
void
scsi_exit_queue
(
void
);
/*
* Prototypes for functions in scsi.c
*/
extern
int
scsi_dispatch_cmd
(
Scsi_Cmnd
*
SCpnt
);
extern
void
scsi_bottom_half_handler
(
void
);
extern
void
scsi_release_commandblocks
(
Scsi_Device
*
SDpnt
);
extern
void
scsi_build_commandblocks
(
Scsi_Device
*
SDpnt
);
extern
void
scsi_adjust_queue_depth
(
Scsi_Device
*
,
int
,
int
);
...
...
@@ -462,7 +456,6 @@ extern void scsi_do_cmd(Scsi_Cmnd *, const void *cmnd,
void
*
buffer
,
unsigned
bufflen
,
void
(
*
done
)
(
struct
scsi_cmnd
*
),
int
timeout
,
int
retries
);
extern
int
scsi_dev_init
(
void
);
extern
int
scsi_mlqueue_insert
(
struct
scsi_cmnd
*
,
int
);
extern
int
scsi_attach_device
(
struct
scsi_device
*
);
extern
void
scsi_detach_device
(
struct
scsi_device
*
);
...
...
drivers/scsi/scsi_lib.c
View file @
c23ee349
...
...
@@ -11,12 +11,29 @@
#include <linux/blk.h>
#include <linux/completion.h>
#include <linux/kernel.h>
#include <linux/mempool.h>
#include <linux/slab.h>
#include "scsi.h"
#include "hosts.h"
#define SG_MEMPOOL_NR 5
#define SG_MEMPOOL_SIZE 32
struct
scsi_host_sg_pool
{
size_t
size
;
char
*
name
;
kmem_cache_t
*
slab
;
mempool_t
*
pool
;
};
#define SP(x) { x, "sgpool-" #x }
struct
scsi_host_sg_pool
scsi_sg_pools
[
SG_MEMPOOL_NR
]
=
{
SP
(
8
),
SP
(
16
),
SP
(
32
),
SP
(
64
),
SP
(
MAX_PHYS_SEGMENTS
)
};
#undef SP
/*
* Function: scsi_insert_special_cmd()
*
...
...
@@ -348,6 +365,51 @@ static Scsi_Cmnd *scsi_end_request(Scsi_Cmnd * SCpnt,
return
NULL
;
}
static
struct
scatterlist
*
scsi_alloc_sgtable
(
Scsi_Cmnd
*
SCpnt
,
int
gfp_mask
)
{
struct
scsi_host_sg_pool
*
sgp
;
struct
scatterlist
*
sgl
;
BUG_ON
(
!
SCpnt
->
use_sg
);
switch
(
SCpnt
->
use_sg
)
{
case
1
...
8
:
SCpnt
->
sglist_len
=
0
;
break
;
case
9
...
16
:
SCpnt
->
sglist_len
=
1
;
break
;
case
17
...
32
:
SCpnt
->
sglist_len
=
2
;
break
;
case
33
...
64
:
SCpnt
->
sglist_len
=
3
;
break
;
case
65
...
MAX_PHYS_SEGMENTS
:
SCpnt
->
sglist_len
=
4
;
break
;
default:
return
NULL
;
}
sgp
=
scsi_sg_pools
+
SCpnt
->
sglist_len
;
sgl
=
mempool_alloc
(
sgp
->
pool
,
gfp_mask
);
if
(
sgl
)
memset
(
sgl
,
0
,
sgp
->
size
);
return
sgl
;
}
static
void
scsi_free_sgtable
(
struct
scatterlist
*
sgl
,
int
index
)
{
struct
scsi_host_sg_pool
*
sgp
;
BUG_ON
(
index
>
SG_MEMPOOL_NR
);
sgp
=
scsi_sg_pools
+
index
;
mempool_free
(
sgl
,
sgp
->
pool
);
}
/*
* Function: scsi_release_buffers()
*
...
...
@@ -374,15 +436,10 @@ static void scsi_release_buffers(Scsi_Cmnd * SCpnt)
/*
* Free up any indirection buffers we allocated for DMA purposes.
*/
if
(
SCpnt
->
use_sg
)
{
struct
scatterlist
*
sgpnt
;
sgpnt
=
(
struct
scatterlist
*
)
SCpnt
->
request_buffer
;
if
(
SCpnt
->
use_sg
)
scsi_free_sgtable
(
SCpnt
->
request_buffer
,
SCpnt
->
sglist_len
);
}
else
{
if
(
SCpnt
->
request_buffer
!=
req
->
buffer
)
kfree
(
SCpnt
->
request_buffer
);
}
else
if
(
SCpnt
->
request_buffer
!=
req
->
buffer
)
kfree
(
SCpnt
->
request_buffer
);
/*
* Zero these out. They now point to freed memory, and it is
...
...
@@ -462,22 +519,16 @@ void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors,
* For the case of a READ, we need to copy the data out of the
* bounce buffer and into the real buffer.
*/
if
(
SCpnt
->
use_sg
)
{
struct
scatterlist
*
sgpnt
;
sgpnt
=
(
struct
scatterlist
*
)
SCpnt
->
buffer
;
if
(
SCpnt
->
use_sg
)
scsi_free_sgtable
(
SCpnt
->
buffer
,
SCpnt
->
sglist_len
);
}
else
{
if
(
SCpnt
->
buffer
!=
req
->
buffer
)
{
if
(
rq_data_dir
(
req
)
==
READ
)
{
unsigned
long
flags
;
char
*
to
=
bio_kmap_irq
(
req
->
bio
,
&
flags
);
memcpy
(
to
,
SCpnt
->
buffer
,
SCpnt
->
bufflen
);
bio_kunmap_irq
(
to
,
&
flags
);
}
kfree
(
SCpnt
->
buffer
);
else
if
(
SCpnt
->
buffer
!=
req
->
buffer
)
{
if
(
rq_data_dir
(
req
)
==
READ
)
{
unsigned
long
flags
;
char
*
to
=
bio_kmap_irq
(
req
->
bio
,
&
flags
);
memcpy
(
to
,
SCpnt
->
buffer
,
SCpnt
->
bufflen
);
bio_kunmap_irq
(
to
,
&
flags
);
}
kfree
(
SCpnt
->
buffer
);
}
if
(
blk_pc_request
(
req
))
{
...
...
@@ -1093,3 +1144,41 @@ void scsi_register_blocked_host(struct Scsi_Host * SHpnt)
void
scsi_deregister_blocked_host
(
struct
Scsi_Host
*
SHpnt
)
{
}
int
__init
scsi_init_queue
(
void
)
{
int
i
;
for
(
i
=
0
;
i
<
SG_MEMPOOL_NR
;
i
++
)
{
struct
scsi_host_sg_pool
*
sgp
=
scsi_sg_pools
+
i
;
int
size
=
sgp
->
size
*
sizeof
(
struct
scatterlist
);
sgp
->
slab
=
kmem_cache_create
(
sgp
->
name
,
size
,
0
,
SLAB_HWCACHE_ALIGN
,
NULL
,
NULL
);
if
(
!
sgp
->
slab
)
{
printk
(
KERN_ERR
"SCSI: can't init sg slab %s
\n
"
,
sgp
->
name
);
}
sgp
->
pool
=
mempool_create
(
SG_MEMPOOL_SIZE
,
mempool_alloc_slab
,
mempool_free_slab
,
sgp
->
slab
);
if
(
!
sgp
->
pool
)
{
printk
(
KERN_ERR
"SCSI: can't init sg mempool %s
\n
"
,
sgp
->
name
);
}
}
return
0
;
}
void
__exit
scsi_exit_lib
(
void
)
{
int
i
;
for
(
i
=
0
;
i
<
SG_MEMPOOL_NR
;
i
++
)
{
struct
scsi_host_sg_pool
*
sgp
=
scsi_sg_pools
+
i
;
mempool_destroy
(
sgp
->
pool
);
kmem_cache_destroy
(
sgp
->
slab
);
}
}
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