aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/scsi_debug.c277
1 files changed, 133 insertions, 144 deletions
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 1b6a6d8e5d27..07103c399fe0 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -218,8 +218,6 @@ static DEFINE_RWLOCK(atomic_rw);
218 218
219static char sdebug_proc_name[] = "scsi_debug"; 219static char sdebug_proc_name[] = "scsi_debug";
220 220
221static int sdebug_driver_probe(struct device *);
222static int sdebug_driver_remove(struct device *);
223static struct bus_type pseudo_lld_bus; 221static struct bus_type pseudo_lld_bus;
224 222
225static struct device_driver sdebug_driverfs_driver = { 223static struct device_driver sdebug_driverfs_driver = {
@@ -235,18 +233,42 @@ static unsigned char ctrl_m_pg[] = {0xa, 10, 2, 0, 0, 0, 0, 0,
235static unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0, 233static unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0,
236 0, 0, 0x0, 0x0}; 234 0, 0, 0x0, 0x0};
237 235
238static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev);
239static void mk_sense_buffer(struct sdebug_dev_info * devip, int key,
240 int asc, int asq);
241static void stop_all_queued(void);
242static int stop_queued_cmnd(struct scsi_cmnd * cmnd);
243
244static int sdebug_add_adapter(void); 236static int sdebug_add_adapter(void);
245static void sdebug_remove_adapter(void); 237static void sdebug_remove_adapter(void);
246static void sdebug_max_tgts_luns(void);
247 238
248static struct device pseudo_primary; 239static void sdebug_max_tgts_luns(void)
249static struct bus_type pseudo_lld_bus; 240{
241 struct sdebug_host_info *sdbg_host;
242 struct Scsi_Host *hpnt;
243
244 spin_lock(&sdebug_host_list_lock);
245 list_for_each_entry(sdbg_host, &sdebug_host_list, host_list) {
246 hpnt = sdbg_host->shost;
247 if ((hpnt->this_id >= 0) &&
248 (scsi_debug_num_tgts > hpnt->this_id))
249 hpnt->max_id = scsi_debug_num_tgts + 1;
250 else
251 hpnt->max_id = scsi_debug_num_tgts;
252 /* scsi_debug_max_luns; */
253 hpnt->max_lun = SAM2_WLUN_REPORT_LUNS;
254 }
255 spin_unlock(&sdebug_host_list_lock);
256}
257
258static void mk_sense_buffer(struct sdebug_dev_info *devip, int key,
259 int asc, int asq)
260{
261 unsigned char *sbuff;
262
263 sbuff = devip->sense_buff;
264 memset(sbuff, 0, SDEBUG_SENSE_LEN);
265
266 scsi_build_sense_buffer(scsi_debug_dsense, sbuff, key, asc, asq);
267
268 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
269 printk(KERN_INFO "scsi_debug: [sense_key,asc,ascq]: "
270 "[0x%x,0x%x,0x%x]\n", key, asc, asq);
271}
250 272
251static void get_data_transfer_info(unsigned char *cmd, 273static void get_data_transfer_info(unsigned char *cmd,
252 unsigned long long *lba, unsigned int *num) 274 unsigned long long *lba, unsigned int *num)
@@ -1680,52 +1702,9 @@ static void timer_intr_handler(unsigned long indx)
1680 spin_unlock_irqrestore(&queued_arr_lock, iflags); 1702 spin_unlock_irqrestore(&queued_arr_lock, iflags);
1681} 1703}
1682 1704
1683static int scsi_debug_slave_alloc(struct scsi_device * sdp)
1684{
1685 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
1686 printk(KERN_INFO "scsi_debug: slave_alloc <%u %u %u %u>\n",
1687 sdp->host->host_no, sdp->channel, sdp->id, sdp->lun);
1688 set_bit(QUEUE_FLAG_BIDI, &sdp->request_queue->queue_flags);
1689 return 0;
1690}
1691
1692static int scsi_debug_slave_configure(struct scsi_device * sdp)
1693{
1694 struct sdebug_dev_info * devip;
1695
1696 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
1697 printk(KERN_INFO "scsi_debug: slave_configure <%u %u %u %u>\n",
1698 sdp->host->host_no, sdp->channel, sdp->id, sdp->lun);
1699 if (sdp->host->max_cmd_len != SCSI_DEBUG_MAX_CMD_LEN)
1700 sdp->host->max_cmd_len = SCSI_DEBUG_MAX_CMD_LEN;
1701 devip = devInfoReg(sdp);
1702 if (NULL == devip)
1703 return 1; /* no resources, will be marked offline */
1704 sdp->hostdata = devip;
1705 if (sdp->host->cmd_per_lun)
1706 scsi_adjust_queue_depth(sdp, SDEBUG_TAGGED_QUEUING,
1707 sdp->host->cmd_per_lun);
1708 blk_queue_max_segment_size(sdp->request_queue, 256 * 1024);
1709 return 0;
1710}
1711
1712static void scsi_debug_slave_destroy(struct scsi_device * sdp)
1713{
1714 struct sdebug_dev_info * devip =
1715 (struct sdebug_dev_info *)sdp->hostdata;
1716 1705
1717 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) 1706static struct sdebug_dev_info *
1718 printk(KERN_INFO "scsi_debug: slave_destroy <%u %u %u %u>\n", 1707sdebug_device_create(struct sdebug_host_info *sdbg_host, gfp_t flags)
1719 sdp->host->host_no, sdp->channel, sdp->id, sdp->lun);
1720 if (devip) {
1721 /* make this slot avaliable for re-use */
1722 devip->used = 0;
1723 sdp->hostdata = NULL;
1724 }
1725}
1726
1727struct sdebug_dev_info *sdebug_device_create(struct sdebug_host_info *sdbg_host,
1728 gfp_t flags)
1729{ 1708{
1730 struct sdebug_dev_info *devip; 1709 struct sdebug_dev_info *devip;
1731 1710
@@ -1789,19 +1768,88 @@ static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev)
1789 return open_devip; 1768 return open_devip;
1790} 1769}
1791 1770
1792static void mk_sense_buffer(struct sdebug_dev_info * devip, int key, 1771static int scsi_debug_slave_alloc(struct scsi_device *sdp)
1793 int asc, int asq)
1794{ 1772{
1795 unsigned char *sbuff; 1773 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
1774 printk(KERN_INFO "scsi_debug: slave_alloc <%u %u %u %u>\n",
1775 sdp->host->host_no, sdp->channel, sdp->id, sdp->lun);
1776 set_bit(QUEUE_FLAG_BIDI, &sdp->request_queue->queue_flags);
1777 return 0;
1778}
1796 1779
1797 sbuff = devip->sense_buff; 1780static int scsi_debug_slave_configure(struct scsi_device *sdp)
1798 memset(sbuff, 0, SDEBUG_SENSE_LEN); 1781{
1782 struct sdebug_dev_info *devip;
1799 1783
1800 scsi_build_sense_buffer(scsi_debug_dsense, sbuff, key, asc, asq); 1784 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
1785 printk(KERN_INFO "scsi_debug: slave_configure <%u %u %u %u>\n",
1786 sdp->host->host_no, sdp->channel, sdp->id, sdp->lun);
1787 if (sdp->host->max_cmd_len != SCSI_DEBUG_MAX_CMD_LEN)
1788 sdp->host->max_cmd_len = SCSI_DEBUG_MAX_CMD_LEN;
1789 devip = devInfoReg(sdp);
1790 if (NULL == devip)
1791 return 1; /* no resources, will be marked offline */
1792 sdp->hostdata = devip;
1793 if (sdp->host->cmd_per_lun)
1794 scsi_adjust_queue_depth(sdp, SDEBUG_TAGGED_QUEUING,
1795 sdp->host->cmd_per_lun);
1796 blk_queue_max_segment_size(sdp->request_queue, 256 * 1024);
1797 return 0;
1798}
1799
1800static void scsi_debug_slave_destroy(struct scsi_device *sdp)
1801{
1802 struct sdebug_dev_info *devip =
1803 (struct sdebug_dev_info *)sdp->hostdata;
1801 1804
1802 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) 1805 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
1803 printk(KERN_INFO "scsi_debug: [sense_key,asc,ascq]: " 1806 printk(KERN_INFO "scsi_debug: slave_destroy <%u %u %u %u>\n",
1804 "[0x%x,0x%x,0x%x]\n", key, asc, asq); 1807 sdp->host->host_no, sdp->channel, sdp->id, sdp->lun);
1808 if (devip) {
1809 /* make this slot avaliable for re-use */
1810 devip->used = 0;
1811 sdp->hostdata = NULL;
1812 }
1813}
1814
1815/* Returns 1 if found 'cmnd' and deleted its timer. else returns 0 */
1816static int stop_queued_cmnd(struct scsi_cmnd *cmnd)
1817{
1818 unsigned long iflags;
1819 int k;
1820 struct sdebug_queued_cmd *sqcp;
1821
1822 spin_lock_irqsave(&queued_arr_lock, iflags);
1823 for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) {
1824 sqcp = &queued_arr[k];
1825 if (sqcp->in_use && (cmnd == sqcp->a_cmnd)) {
1826 del_timer_sync(&sqcp->cmnd_timer);
1827 sqcp->in_use = 0;
1828 sqcp->a_cmnd = NULL;
1829 break;
1830 }
1831 }
1832 spin_unlock_irqrestore(&queued_arr_lock, iflags);
1833 return (k < SCSI_DEBUG_CANQUEUE) ? 1 : 0;
1834}
1835
1836/* Deletes (stops) timers of all queued commands */
1837static void stop_all_queued(void)
1838{
1839 unsigned long iflags;
1840 int k;
1841 struct sdebug_queued_cmd *sqcp;
1842
1843 spin_lock_irqsave(&queued_arr_lock, iflags);
1844 for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) {
1845 sqcp = &queued_arr[k];
1846 if (sqcp->in_use && sqcp->a_cmnd) {
1847 del_timer_sync(&sqcp->cmnd_timer);
1848 sqcp->in_use = 0;
1849 sqcp->a_cmnd = NULL;
1850 }
1851 }
1852 spin_unlock_irqrestore(&queued_arr_lock, iflags);
1805} 1853}
1806 1854
1807static int scsi_debug_abort(struct scsi_cmnd * SCpnt) 1855static int scsi_debug_abort(struct scsi_cmnd * SCpnt)
@@ -1891,46 +1939,6 @@ static int scsi_debug_host_reset(struct scsi_cmnd * SCpnt)
1891 return SUCCESS; 1939 return SUCCESS;
1892} 1940}
1893 1941
1894/* Returns 1 if found 'cmnd' and deleted its timer. else returns 0 */
1895static int stop_queued_cmnd(struct scsi_cmnd * cmnd)
1896{
1897 unsigned long iflags;
1898 int k;
1899 struct sdebug_queued_cmd * sqcp;
1900
1901 spin_lock_irqsave(&queued_arr_lock, iflags);
1902 for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) {
1903 sqcp = &queued_arr[k];
1904 if (sqcp->in_use && (cmnd == sqcp->a_cmnd)) {
1905 del_timer_sync(&sqcp->cmnd_timer);
1906 sqcp->in_use = 0;
1907 sqcp->a_cmnd = NULL;
1908 break;
1909 }
1910 }
1911 spin_unlock_irqrestore(&queued_arr_lock, iflags);
1912 return (k < SCSI_DEBUG_CANQUEUE) ? 1 : 0;
1913}
1914
1915/* Deletes (stops) timers of all queued commands */
1916static void stop_all_queued(void)
1917{
1918 unsigned long iflags;
1919 int k;
1920 struct sdebug_queued_cmd * sqcp;
1921
1922 spin_lock_irqsave(&queued_arr_lock, iflags);
1923 for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) {
1924 sqcp = &queued_arr[k];
1925 if (sqcp->in_use && sqcp->a_cmnd) {
1926 del_timer_sync(&sqcp->cmnd_timer);
1927 sqcp->in_use = 0;
1928 sqcp->a_cmnd = NULL;
1929 }
1930 }
1931 spin_unlock_irqrestore(&queued_arr_lock, iflags);
1932}
1933
1934/* Initializes timers in queued array */ 1942/* Initializes timers in queued array */
1935static void __init init_all_queued(void) 1943static void __init init_all_queued(void)
1936{ 1944{
@@ -2055,7 +2063,6 @@ static int schedule_resp(struct scsi_cmnd * cmnd,
2055 return 0; 2063 return 0;
2056 } 2064 }
2057} 2065}
2058
2059/* Note: The following macros create attribute files in the 2066/* Note: The following macros create attribute files in the
2060 /sys/module/scsi_debug/parameters directory. Unfortunately this 2067 /sys/module/scsi_debug/parameters directory. Unfortunately this
2061 driver is unaware of a change and cannot trigger auxiliary actions 2068 driver is unaware of a change and cannot trigger auxiliary actions
@@ -2474,6 +2481,17 @@ static void do_remove_driverfs_files(void)
2474 driver_remove_file(&sdebug_driverfs_driver, &driver_attr_add_host); 2481 driver_remove_file(&sdebug_driverfs_driver, &driver_attr_add_host);
2475} 2482}
2476 2483
2484static void pseudo_0_release(struct device *dev)
2485{
2486 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
2487 printk(KERN_INFO "scsi_debug: pseudo_0_release() called\n");
2488}
2489
2490static struct device pseudo_primary = {
2491 .bus_id = "pseudo_0",
2492 .release = pseudo_0_release,
2493};
2494
2477static int __init scsi_debug_init(void) 2495static int __init scsi_debug_init(void)
2478{ 2496{
2479 unsigned long sz; 2497 unsigned long sz;
@@ -2588,30 +2606,6 @@ static void __exit scsi_debug_exit(void)
2588device_initcall(scsi_debug_init); 2606device_initcall(scsi_debug_init);
2589module_exit(scsi_debug_exit); 2607module_exit(scsi_debug_exit);
2590 2608
2591static void pseudo_0_release(struct device * dev)
2592{
2593 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
2594 printk(KERN_INFO "scsi_debug: pseudo_0_release() called\n");
2595}
2596
2597static struct device pseudo_primary = {
2598 .bus_id = "pseudo_0",
2599 .release = pseudo_0_release,
2600};
2601
2602static int pseudo_lld_bus_match(struct device *dev,
2603 struct device_driver *dev_driver)
2604{
2605 return 1;
2606}
2607
2608static struct bus_type pseudo_lld_bus = {
2609 .name = "pseudo",
2610 .match = pseudo_lld_bus_match,
2611 .probe = sdebug_driver_probe,
2612 .remove = sdebug_driver_remove,
2613};
2614
2615static void sdebug_release_adapter(struct device * dev) 2609static void sdebug_release_adapter(struct device * dev)
2616{ 2610{
2617 struct sdebug_host_info *sdbg_host; 2611 struct sdebug_host_info *sdbg_host;
@@ -3011,20 +3005,15 @@ static int sdebug_driver_remove(struct device * dev)
3011 return 0; 3005 return 0;
3012} 3006}
3013 3007
3014static void sdebug_max_tgts_luns(void) 3008static int pseudo_lld_bus_match(struct device *dev,
3009 struct device_driver *dev_driver)
3015{ 3010{
3016 struct sdebug_host_info * sdbg_host; 3011 return 1;
3017 struct Scsi_Host *hpnt;
3018
3019 spin_lock(&sdebug_host_list_lock);
3020 list_for_each_entry(sdbg_host, &sdebug_host_list, host_list) {
3021 hpnt = sdbg_host->shost;
3022 if ((hpnt->this_id >= 0) &&
3023 (scsi_debug_num_tgts > hpnt->this_id))
3024 hpnt->max_id = scsi_debug_num_tgts + 1;
3025 else
3026 hpnt->max_id = scsi_debug_num_tgts;
3027 hpnt->max_lun = SAM2_WLUN_REPORT_LUNS; /* scsi_debug_max_luns; */
3028 }
3029 spin_unlock(&sdebug_host_list_lock);
3030} 3012}
3013
3014static struct bus_type pseudo_lld_bus = {
3015 .name = "pseudo",
3016 .match = pseudo_lld_bus_match,
3017 .probe = sdebug_driver_probe,
3018 .remove = sdebug_driver_remove,
3019};