diff options
27 files changed, 1861 insertions, 1783 deletions
diff --git a/block/bsg.c b/block/bsg.c index 420a5a9f1b23..e5214c148096 100644 --- a/block/bsg.c +++ b/block/bsg.c | |||
@@ -1008,7 +1008,7 @@ int bsg_register_queue(struct request_queue *q, struct device *parent, | |||
1008 | /* | 1008 | /* |
1009 | * we need a proper transport to send commands, not a stacked device | 1009 | * we need a proper transport to send commands, not a stacked device |
1010 | */ | 1010 | */ |
1011 | if (!q->request_fn) | 1011 | if (!queue_is_rq_based(q)) |
1012 | return 0; | 1012 | return 0; |
1013 | 1013 | ||
1014 | bcd = &q->bsg_dev; | 1014 | bcd = &q->bsg_dev; |
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 73894ca33956..4595c22f33f7 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -4080,7 +4080,7 @@ static void cciss_interrupt_mode(ctlr_info_t *h) | |||
4080 | goto default_int_mode; | 4080 | goto default_int_mode; |
4081 | 4081 | ||
4082 | if (pci_find_capability(h->pdev, PCI_CAP_ID_MSIX)) { | 4082 | if (pci_find_capability(h->pdev, PCI_CAP_ID_MSIX)) { |
4083 | err = pci_enable_msix(h->pdev, cciss_msix_entries, 4); | 4083 | err = pci_enable_msix_exact(h->pdev, cciss_msix_entries, 4); |
4084 | if (!err) { | 4084 | if (!err) { |
4085 | h->intr[0] = cciss_msix_entries[0].vector; | 4085 | h->intr[0] = cciss_msix_entries[0].vector; |
4086 | h->intr[1] = cciss_msix_entries[1].vector; | 4086 | h->intr[1] = cciss_msix_entries[1].vector; |
@@ -4088,10 +4088,6 @@ static void cciss_interrupt_mode(ctlr_info_t *h) | |||
4088 | h->intr[3] = cciss_msix_entries[3].vector; | 4088 | h->intr[3] = cciss_msix_entries[3].vector; |
4089 | h->msix_vector = 1; | 4089 | h->msix_vector = 1; |
4090 | return; | 4090 | return; |
4091 | } | ||
4092 | if (err > 0) { | ||
4093 | dev_warn(&h->pdev->dev, | ||
4094 | "only %d MSI-X vectors available\n", err); | ||
4095 | } else { | 4091 | } else { |
4096 | dev_warn(&h->pdev->dev, | 4092 | dev_warn(&h->pdev->dev, |
4097 | "MSI-X init failed %d\n", err); | 4093 | "MSI-X init failed %d\n", err); |
diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c index 90ae4ba8f9ee..05a1780ffa85 100644 --- a/drivers/block/drbd/drbd_actlog.c +++ b/drivers/block/drbd/drbd_actlog.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/drbd_limits.h> | 29 | #include <linux/drbd_limits.h> |
30 | #include <linux/dynamic_debug.h> | 30 | #include <linux/dynamic_debug.h> |
31 | #include "drbd_int.h" | 31 | #include "drbd_int.h" |
32 | #include "drbd_wrappers.h" | ||
33 | 32 | ||
34 | 33 | ||
35 | enum al_transaction_types { | 34 | enum al_transaction_types { |
@@ -204,7 +203,7 @@ int drbd_md_sync_page_io(struct drbd_device *device, struct drbd_backing_dev *bd | |||
204 | 203 | ||
205 | BUG_ON(!bdev->md_bdev); | 204 | BUG_ON(!bdev->md_bdev); |
206 | 205 | ||
207 | drbd_dbg(device, "meta_data io: %s [%d]:%s(,%llus,%s) %pS\n", | 206 | dynamic_drbd_dbg(device, "meta_data io: %s [%d]:%s(,%llus,%s) %pS\n", |
208 | current->comm, current->pid, __func__, | 207 | current->comm, current->pid, __func__, |
209 | (unsigned long long)sector, (rw & WRITE) ? "WRITE" : "READ", | 208 | (unsigned long long)sector, (rw & WRITE) ? "WRITE" : "READ", |
210 | (void*)_RET_IP_ ); | 209 | (void*)_RET_IP_ ); |
@@ -276,7 +275,6 @@ bool drbd_al_begin_io_fastpath(struct drbd_device *device, struct drbd_interval | |||
276 | return _al_get(device, first, true); | 275 | return _al_get(device, first, true); |
277 | } | 276 | } |
278 | 277 | ||
279 | static | ||
280 | bool drbd_al_begin_io_prepare(struct drbd_device *device, struct drbd_interval *i) | 278 | bool drbd_al_begin_io_prepare(struct drbd_device *device, struct drbd_interval *i) |
281 | { | 279 | { |
282 | /* for bios crossing activity log extent boundaries, | 280 | /* for bios crossing activity log extent boundaries, |
@@ -846,7 +844,7 @@ void __drbd_set_in_sync(struct drbd_device *device, sector_t sector, int size, | |||
846 | int wake_up = 0; | 844 | int wake_up = 0; |
847 | unsigned long flags; | 845 | unsigned long flags; |
848 | 846 | ||
849 | if (size <= 0 || !IS_ALIGNED(size, 512) || size > DRBD_MAX_BIO_SIZE) { | 847 | if (size <= 0 || !IS_ALIGNED(size, 512) || size > DRBD_MAX_DISCARD_SIZE) { |
850 | drbd_err(device, "drbd_set_in_sync: sector=%llus size=%d nonsense!\n", | 848 | drbd_err(device, "drbd_set_in_sync: sector=%llus size=%d nonsense!\n", |
851 | (unsigned long long)sector, size); | 849 | (unsigned long long)sector, size); |
852 | return; | 850 | return; |
@@ -920,7 +918,7 @@ int __drbd_set_out_of_sync(struct drbd_device *device, sector_t sector, int size | |||
920 | if (size == 0) | 918 | if (size == 0) |
921 | return 0; | 919 | return 0; |
922 | 920 | ||
923 | if (size < 0 || !IS_ALIGNED(size, 512) || size > DRBD_MAX_BIO_SIZE) { | 921 | if (size < 0 || !IS_ALIGNED(size, 512) || size > DRBD_MAX_DISCARD_SIZE) { |
924 | drbd_err(device, "sector: %llus, size: %d\n", | 922 | drbd_err(device, "sector: %llus, size: %d\n", |
925 | (unsigned long long)sector, size); | 923 | (unsigned long long)sector, size); |
926 | return 0; | 924 | return 0; |
@@ -1023,8 +1021,7 @@ int drbd_rs_begin_io(struct drbd_device *device, sector_t sector) | |||
1023 | unsigned int enr = BM_SECT_TO_EXT(sector); | 1021 | unsigned int enr = BM_SECT_TO_EXT(sector); |
1024 | struct bm_extent *bm_ext; | 1022 | struct bm_extent *bm_ext; |
1025 | int i, sig; | 1023 | int i, sig; |
1026 | int sa = 200; /* Step aside 200 times, then grab the extent and let app-IO wait. | 1024 | bool sa; |
1027 | 200 times -> 20 seconds. */ | ||
1028 | 1025 | ||
1029 | retry: | 1026 | retry: |
1030 | sig = wait_event_interruptible(device->al_wait, | 1027 | sig = wait_event_interruptible(device->al_wait, |
@@ -1035,12 +1032,15 @@ retry: | |||
1035 | if (test_bit(BME_LOCKED, &bm_ext->flags)) | 1032 | if (test_bit(BME_LOCKED, &bm_ext->flags)) |
1036 | return 0; | 1033 | return 0; |
1037 | 1034 | ||
1035 | /* step aside only while we are above c-min-rate; unless disabled. */ | ||
1036 | sa = drbd_rs_c_min_rate_throttle(device); | ||
1037 | |||
1038 | for (i = 0; i < AL_EXT_PER_BM_SECT; i++) { | 1038 | for (i = 0; i < AL_EXT_PER_BM_SECT; i++) { |
1039 | sig = wait_event_interruptible(device->al_wait, | 1039 | sig = wait_event_interruptible(device->al_wait, |
1040 | !_is_in_al(device, enr * AL_EXT_PER_BM_SECT + i) || | 1040 | !_is_in_al(device, enr * AL_EXT_PER_BM_SECT + i) || |
1041 | test_bit(BME_PRIORITY, &bm_ext->flags)); | 1041 | (sa && test_bit(BME_PRIORITY, &bm_ext->flags))); |
1042 | 1042 | ||
1043 | if (sig || (test_bit(BME_PRIORITY, &bm_ext->flags) && sa)) { | 1043 | if (sig || (sa && test_bit(BME_PRIORITY, &bm_ext->flags))) { |
1044 | spin_lock_irq(&device->al_lock); | 1044 | spin_lock_irq(&device->al_lock); |
1045 | if (lc_put(device->resync, &bm_ext->lce) == 0) { | 1045 | if (lc_put(device->resync, &bm_ext->lce) == 0) { |
1046 | bm_ext->flags = 0; /* clears BME_NO_WRITES and eventually BME_PRIORITY */ | 1046 | bm_ext->flags = 0; /* clears BME_NO_WRITES and eventually BME_PRIORITY */ |
@@ -1052,9 +1052,6 @@ retry: | |||
1052 | return -EINTR; | 1052 | return -EINTR; |
1053 | if (schedule_timeout_interruptible(HZ/10)) | 1053 | if (schedule_timeout_interruptible(HZ/10)) |
1054 | return -EINTR; | 1054 | return -EINTR; |
1055 | if (sa && --sa == 0) | ||
1056 | drbd_warn(device, "drbd_rs_begin_io() stepped aside for 20sec." | ||
1057 | "Resync stalled?\n"); | ||
1058 | goto retry; | 1055 | goto retry; |
1059 | } | 1056 | } |
1060 | } | 1057 | } |
@@ -1288,7 +1285,7 @@ void drbd_rs_failed_io(struct drbd_device *device, sector_t sector, int size) | |||
1288 | sector_t esector, nr_sectors; | 1285 | sector_t esector, nr_sectors; |
1289 | int wake_up = 0; | 1286 | int wake_up = 0; |
1290 | 1287 | ||
1291 | if (size <= 0 || !IS_ALIGNED(size, 512) || size > DRBD_MAX_BIO_SIZE) { | 1288 | if (size <= 0 || !IS_ALIGNED(size, 512) || size > DRBD_MAX_DISCARD_SIZE) { |
1292 | drbd_err(device, "drbd_rs_failed_io: sector=%llus size=%d nonsense!\n", | 1289 | drbd_err(device, "drbd_rs_failed_io: sector=%llus size=%d nonsense!\n", |
1293 | (unsigned long long)sector, size); | 1290 | (unsigned long long)sector, size); |
1294 | return; | 1291 | return; |
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index e7093d4291f1..a76ceb344d64 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h | |||
@@ -382,6 +382,12 @@ enum { | |||
382 | __EE_CALL_AL_COMPLETE_IO, | 382 | __EE_CALL_AL_COMPLETE_IO, |
383 | __EE_MAY_SET_IN_SYNC, | 383 | __EE_MAY_SET_IN_SYNC, |
384 | 384 | ||
385 | /* is this a TRIM aka REQ_DISCARD? */ | ||
386 | __EE_IS_TRIM, | ||
387 | /* our lower level cannot handle trim, | ||
388 | * and we want to fall back to zeroout instead */ | ||
389 | __EE_IS_TRIM_USE_ZEROOUT, | ||
390 | |||
385 | /* In case a barrier failed, | 391 | /* In case a barrier failed, |
386 | * we need to resubmit without the barrier flag. */ | 392 | * we need to resubmit without the barrier flag. */ |
387 | __EE_RESUBMITTED, | 393 | __EE_RESUBMITTED, |
@@ -405,7 +411,9 @@ enum { | |||
405 | }; | 411 | }; |
406 | #define EE_CALL_AL_COMPLETE_IO (1<<__EE_CALL_AL_COMPLETE_IO) | 412 | #define EE_CALL_AL_COMPLETE_IO (1<<__EE_CALL_AL_COMPLETE_IO) |
407 | #define EE_MAY_SET_IN_SYNC (1<<__EE_MAY_SET_IN_SYNC) | 413 | #define EE_MAY_SET_IN_SYNC (1<<__EE_MAY_SET_IN_SYNC) |
408 | #define EE_RESUBMITTED (1<<__EE_RESUBMITTED) | 414 | #define EE_IS_TRIM (1<<__EE_IS_TRIM) |
415 | #define EE_IS_TRIM_USE_ZEROOUT (1<<__EE_IS_TRIM_USE_ZEROOUT) | ||
416 | #define EE_RESUBMITTED (1<<__EE_RESUBMITTED) | ||
409 | #define EE_WAS_ERROR (1<<__EE_WAS_ERROR) | 417 | #define EE_WAS_ERROR (1<<__EE_WAS_ERROR) |
410 | #define EE_HAS_DIGEST (1<<__EE_HAS_DIGEST) | 418 | #define EE_HAS_DIGEST (1<<__EE_HAS_DIGEST) |
411 | #define EE_RESTART_REQUESTS (1<<__EE_RESTART_REQUESTS) | 419 | #define EE_RESTART_REQUESTS (1<<__EE_RESTART_REQUESTS) |
@@ -579,6 +587,7 @@ struct drbd_resource { | |||
579 | struct list_head resources; | 587 | struct list_head resources; |
580 | struct res_opts res_opts; | 588 | struct res_opts res_opts; |
581 | struct mutex conf_update; /* mutex for ready-copy-update of net_conf and disk_conf */ | 589 | struct mutex conf_update; /* mutex for ready-copy-update of net_conf and disk_conf */ |
590 | struct mutex adm_mutex; /* mutex to serialize administrative requests */ | ||
582 | spinlock_t req_lock; | 591 | spinlock_t req_lock; |
583 | 592 | ||
584 | unsigned susp:1; /* IO suspended by user */ | 593 | unsigned susp:1; /* IO suspended by user */ |
@@ -609,6 +618,7 @@ struct drbd_connection { | |||
609 | struct drbd_socket data; /* data/barrier/cstate/parameter packets */ | 618 | struct drbd_socket data; /* data/barrier/cstate/parameter packets */ |
610 | struct drbd_socket meta; /* ping/ack (metadata) packets */ | 619 | struct drbd_socket meta; /* ping/ack (metadata) packets */ |
611 | int agreed_pro_version; /* actually used protocol version */ | 620 | int agreed_pro_version; /* actually used protocol version */ |
621 | u32 agreed_features; | ||
612 | unsigned long last_received; /* in jiffies, either socket */ | 622 | unsigned long last_received; /* in jiffies, either socket */ |
613 | unsigned int ko_count; | 623 | unsigned int ko_count; |
614 | 624 | ||
@@ -814,6 +824,28 @@ struct drbd_device { | |||
814 | struct submit_worker submit; | 824 | struct submit_worker submit; |
815 | }; | 825 | }; |
816 | 826 | ||
827 | struct drbd_config_context { | ||
828 | /* assigned from drbd_genlmsghdr */ | ||
829 | unsigned int minor; | ||
830 | /* assigned from request attributes, if present */ | ||
831 | unsigned int volume; | ||
832 | #define VOLUME_UNSPECIFIED (-1U) | ||
833 | /* pointer into the request skb, | ||
834 | * limited lifetime! */ | ||
835 | char *resource_name; | ||
836 | struct nlattr *my_addr; | ||
837 | struct nlattr *peer_addr; | ||
838 | |||
839 | /* reply buffer */ | ||
840 | struct sk_buff *reply_skb; | ||
841 | /* pointer into reply buffer */ | ||
842 | struct drbd_genlmsghdr *reply_dh; | ||
843 | /* resolved from attributes, if possible */ | ||
844 | struct drbd_device *device; | ||
845 | struct drbd_resource *resource; | ||
846 | struct drbd_connection *connection; | ||
847 | }; | ||
848 | |||
817 | static inline struct drbd_device *minor_to_device(unsigned int minor) | 849 | static inline struct drbd_device *minor_to_device(unsigned int minor) |
818 | { | 850 | { |
819 | return (struct drbd_device *)idr_find(&drbd_devices, minor); | 851 | return (struct drbd_device *)idr_find(&drbd_devices, minor); |
@@ -821,7 +853,7 @@ static inline struct drbd_device *minor_to_device(unsigned int minor) | |||
821 | 853 | ||
822 | static inline struct drbd_peer_device *first_peer_device(struct drbd_device *device) | 854 | static inline struct drbd_peer_device *first_peer_device(struct drbd_device *device) |
823 | { | 855 | { |
824 | return list_first_entry(&device->peer_devices, struct drbd_peer_device, peer_devices); | 856 | return list_first_entry_or_null(&device->peer_devices, struct drbd_peer_device, peer_devices); |
825 | } | 857 | } |
826 | 858 | ||
827 | #define for_each_resource(resource, _resources) \ | 859 | #define for_each_resource(resource, _resources) \ |
@@ -1139,6 +1171,12 @@ struct bm_extent { | |||
1139 | #define DRBD_MAX_SIZE_H80_PACKET (1U << 15) /* Header 80 only allows packets up to 32KiB data */ | 1171 | #define DRBD_MAX_SIZE_H80_PACKET (1U << 15) /* Header 80 only allows packets up to 32KiB data */ |
1140 | #define DRBD_MAX_BIO_SIZE_P95 (1U << 17) /* Protocol 95 to 99 allows bios up to 128KiB */ | 1172 | #define DRBD_MAX_BIO_SIZE_P95 (1U << 17) /* Protocol 95 to 99 allows bios up to 128KiB */ |
1141 | 1173 | ||
1174 | /* For now, don't allow more than one activity log extent worth of data | ||
1175 | * to be discarded in one go. We may need to rework drbd_al_begin_io() | ||
1176 | * to allow for even larger discard ranges */ | ||
1177 | #define DRBD_MAX_DISCARD_SIZE AL_EXTENT_SIZE | ||
1178 | #define DRBD_MAX_DISCARD_SECTORS (DRBD_MAX_DISCARD_SIZE >> 9) | ||
1179 | |||
1142 | extern int drbd_bm_init(struct drbd_device *device); | 1180 | extern int drbd_bm_init(struct drbd_device *device); |
1143 | extern int drbd_bm_resize(struct drbd_device *device, sector_t sectors, int set_new_bits); | 1181 | extern int drbd_bm_resize(struct drbd_device *device, sector_t sectors, int set_new_bits); |
1144 | extern void drbd_bm_cleanup(struct drbd_device *device); | 1182 | extern void drbd_bm_cleanup(struct drbd_device *device); |
@@ -1229,9 +1267,9 @@ extern struct bio *bio_alloc_drbd(gfp_t gfp_mask); | |||
1229 | extern rwlock_t global_state_lock; | 1267 | extern rwlock_t global_state_lock; |
1230 | 1268 | ||
1231 | extern int conn_lowest_minor(struct drbd_connection *connection); | 1269 | extern int conn_lowest_minor(struct drbd_connection *connection); |
1232 | enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned int minor, int vnr); | 1270 | extern enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsigned int minor); |
1233 | extern void drbd_destroy_device(struct kref *kref); | 1271 | extern void drbd_destroy_device(struct kref *kref); |
1234 | extern void drbd_delete_device(struct drbd_device *mdev); | 1272 | extern void drbd_delete_device(struct drbd_device *device); |
1235 | 1273 | ||
1236 | extern struct drbd_resource *drbd_create_resource(const char *name); | 1274 | extern struct drbd_resource *drbd_create_resource(const char *name); |
1237 | extern void drbd_free_resource(struct drbd_resource *resource); | 1275 | extern void drbd_free_resource(struct drbd_resource *resource); |
@@ -1257,7 +1295,7 @@ extern int is_valid_ar_handle(struct drbd_request *, sector_t); | |||
1257 | 1295 | ||
1258 | 1296 | ||
1259 | /* drbd_nl.c */ | 1297 | /* drbd_nl.c */ |
1260 | extern int drbd_msg_put_info(const char *info); | 1298 | extern int drbd_msg_put_info(struct sk_buff *skb, const char *info); |
1261 | extern void drbd_suspend_io(struct drbd_device *device); | 1299 | extern void drbd_suspend_io(struct drbd_device *device); |
1262 | extern void drbd_resume_io(struct drbd_device *device); | 1300 | extern void drbd_resume_io(struct drbd_device *device); |
1263 | extern char *ppsize(char *buf, unsigned long long size); | 1301 | extern char *ppsize(char *buf, unsigned long long size); |
@@ -1283,6 +1321,10 @@ extern void conn_try_outdate_peer_async(struct drbd_connection *connection); | |||
1283 | extern int drbd_khelper(struct drbd_device *device, char *cmd); | 1321 | extern int drbd_khelper(struct drbd_device *device, char *cmd); |
1284 | 1322 | ||
1285 | /* drbd_worker.c */ | 1323 | /* drbd_worker.c */ |
1324 | /* bi_end_io handlers */ | ||
1325 | extern void drbd_md_io_complete(struct bio *bio, int error); | ||
1326 | extern void drbd_peer_request_endio(struct bio *bio, int error); | ||
1327 | extern void drbd_request_endio(struct bio *bio, int error); | ||
1286 | extern int drbd_worker(struct drbd_thread *thi); | 1328 | extern int drbd_worker(struct drbd_thread *thi); |
1287 | enum drbd_ret_code drbd_resync_after_valid(struct drbd_device *device, int o_minor); | 1329 | enum drbd_ret_code drbd_resync_after_valid(struct drbd_device *device, int o_minor); |
1288 | void drbd_resync_after_changed(struct drbd_device *device); | 1330 | void drbd_resync_after_changed(struct drbd_device *device); |
@@ -1332,16 +1374,20 @@ extern int w_start_resync(struct drbd_work *, int); | |||
1332 | extern void resync_timer_fn(unsigned long data); | 1374 | extern void resync_timer_fn(unsigned long data); |
1333 | extern void start_resync_timer_fn(unsigned long data); | 1375 | extern void start_resync_timer_fn(unsigned long data); |
1334 | 1376 | ||
1377 | extern void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req); | ||
1378 | |||
1335 | /* drbd_receiver.c */ | 1379 | /* drbd_receiver.c */ |
1336 | extern int drbd_receiver(struct drbd_thread *thi); | 1380 | extern int drbd_receiver(struct drbd_thread *thi); |
1337 | extern int drbd_asender(struct drbd_thread *thi); | 1381 | extern int drbd_asender(struct drbd_thread *thi); |
1338 | extern int drbd_rs_should_slow_down(struct drbd_device *device, sector_t sector); | 1382 | extern bool drbd_rs_c_min_rate_throttle(struct drbd_device *device); |
1383 | extern bool drbd_rs_should_slow_down(struct drbd_device *device, sector_t sector); | ||
1339 | extern int drbd_submit_peer_request(struct drbd_device *, | 1384 | extern int drbd_submit_peer_request(struct drbd_device *, |
1340 | struct drbd_peer_request *, const unsigned, | 1385 | struct drbd_peer_request *, const unsigned, |
1341 | const int); | 1386 | const int); |
1342 | extern int drbd_free_peer_reqs(struct drbd_device *, struct list_head *); | 1387 | extern int drbd_free_peer_reqs(struct drbd_device *, struct list_head *); |
1343 | extern struct drbd_peer_request *drbd_alloc_peer_req(struct drbd_peer_device *, u64, | 1388 | extern struct drbd_peer_request *drbd_alloc_peer_req(struct drbd_peer_device *, u64, |
1344 | sector_t, unsigned int, | 1389 | sector_t, unsigned int, |
1390 | bool, | ||
1345 | gfp_t) __must_hold(local); | 1391 | gfp_t) __must_hold(local); |
1346 | extern void __drbd_free_peer_req(struct drbd_device *, struct drbd_peer_request *, | 1392 | extern void __drbd_free_peer_req(struct drbd_device *, struct drbd_peer_request *, |
1347 | int); | 1393 | int); |
@@ -1401,6 +1447,37 @@ static inline void drbd_tcp_quickack(struct socket *sock) | |||
1401 | (char*)&val, sizeof(val)); | 1447 | (char*)&val, sizeof(val)); |
1402 | } | 1448 | } |
1403 | 1449 | ||
1450 | /* sets the number of 512 byte sectors of our virtual device */ | ||
1451 | static inline void drbd_set_my_capacity(struct drbd_device *device, | ||
1452 | sector_t size) | ||
1453 | { | ||
1454 | /* set_capacity(device->this_bdev->bd_disk, size); */ | ||
1455 | set_capacity(device->vdisk, size); | ||
1456 | device->this_bdev->bd_inode->i_size = (loff_t)size << 9; | ||
1457 | } | ||
1458 | |||
1459 | /* | ||
1460 | * used to submit our private bio | ||
1461 | */ | ||
1462 | static inline void drbd_generic_make_request(struct drbd_device *device, | ||
1463 | int fault_type, struct bio *bio) | ||
1464 | { | ||
1465 | __release(local); | ||
1466 | if (!bio->bi_bdev) { | ||
1467 | printk(KERN_ERR "drbd%d: drbd_generic_make_request: " | ||
1468 | "bio->bi_bdev == NULL\n", | ||
1469 | device_to_minor(device)); | ||
1470 | dump_stack(); | ||
1471 | bio_endio(bio, -ENODEV); | ||
1472 | return; | ||
1473 | } | ||
1474 | |||
1475 | if (drbd_insert_fault(device, fault_type)) | ||
1476 | bio_endio(bio, -EIO); | ||
1477 | else | ||
1478 | generic_make_request(bio); | ||
1479 | } | ||
1480 | |||
1404 | void drbd_bump_write_ordering(struct drbd_connection *connection, enum write_ordering_e wo); | 1481 | void drbd_bump_write_ordering(struct drbd_connection *connection, enum write_ordering_e wo); |
1405 | 1482 | ||
1406 | /* drbd_proc.c */ | 1483 | /* drbd_proc.c */ |
@@ -1410,6 +1487,7 @@ extern const char *drbd_conn_str(enum drbd_conns s); | |||
1410 | extern const char *drbd_role_str(enum drbd_role s); | 1487 | extern const char *drbd_role_str(enum drbd_role s); |
1411 | 1488 | ||
1412 | /* drbd_actlog.c */ | 1489 | /* drbd_actlog.c */ |
1490 | extern bool drbd_al_begin_io_prepare(struct drbd_device *device, struct drbd_interval *i); | ||
1413 | extern int drbd_al_begin_io_nonblock(struct drbd_device *device, struct drbd_interval *i); | 1491 | extern int drbd_al_begin_io_nonblock(struct drbd_device *device, struct drbd_interval *i); |
1414 | extern void drbd_al_begin_io_commit(struct drbd_device *device, bool delegate); | 1492 | extern void drbd_al_begin_io_commit(struct drbd_device *device, bool delegate); |
1415 | extern bool drbd_al_begin_io_fastpath(struct drbd_device *device, struct drbd_interval *i); | 1493 | extern bool drbd_al_begin_io_fastpath(struct drbd_device *device, struct drbd_interval *i); |
@@ -2144,7 +2222,7 @@ static inline void drbd_md_flush(struct drbd_device *device) | |||
2144 | 2222 | ||
2145 | static inline struct drbd_connection *first_connection(struct drbd_resource *resource) | 2223 | static inline struct drbd_connection *first_connection(struct drbd_resource *resource) |
2146 | { | 2224 | { |
2147 | return list_first_entry(&resource->connections, | 2225 | return list_first_entry_or_null(&resource->connections, |
2148 | struct drbd_connection, connections); | 2226 | struct drbd_connection, connections); |
2149 | } | 2227 | } |
2150 | 2228 | ||
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 331e5cc1227d..960645c26e6f 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c | |||
@@ -1607,8 +1607,8 @@ static u32 bio_flags_to_wire(struct drbd_connection *connection, unsigned long b | |||
1607 | return bi_rw & REQ_SYNC ? DP_RW_SYNC : 0; | 1607 | return bi_rw & REQ_SYNC ? DP_RW_SYNC : 0; |
1608 | } | 1608 | } |
1609 | 1609 | ||
1610 | /* Used to send write requests | 1610 | /* Used to send write or TRIM aka REQ_DISCARD requests |
1611 | * R_PRIMARY -> Peer (P_DATA) | 1611 | * R_PRIMARY -> Peer (P_DATA, P_TRIM) |
1612 | */ | 1612 | */ |
1613 | int drbd_send_dblock(struct drbd_peer_device *peer_device, struct drbd_request *req) | 1613 | int drbd_send_dblock(struct drbd_peer_device *peer_device, struct drbd_request *req) |
1614 | { | 1614 | { |
@@ -1640,6 +1640,16 @@ int drbd_send_dblock(struct drbd_peer_device *peer_device, struct drbd_request * | |||
1640 | dp_flags |= DP_SEND_WRITE_ACK; | 1640 | dp_flags |= DP_SEND_WRITE_ACK; |
1641 | } | 1641 | } |
1642 | p->dp_flags = cpu_to_be32(dp_flags); | 1642 | p->dp_flags = cpu_to_be32(dp_flags); |
1643 | |||
1644 | if (dp_flags & DP_DISCARD) { | ||
1645 | struct p_trim *t = (struct p_trim*)p; | ||
1646 | t->size = cpu_to_be32(req->i.size); | ||
1647 | err = __send_command(peer_device->connection, device->vnr, sock, P_TRIM, sizeof(*t), NULL, 0); | ||
1648 | goto out; | ||
1649 | } | ||
1650 | |||
1651 | /* our digest is still only over the payload. | ||
1652 | * TRIM does not carry any payload. */ | ||
1643 | if (dgs) | 1653 | if (dgs) |
1644 | drbd_csum_bio(peer_device->connection->integrity_tfm, req->master_bio, p + 1); | 1654 | drbd_csum_bio(peer_device->connection->integrity_tfm, req->master_bio, p + 1); |
1645 | err = __send_command(peer_device->connection, device->vnr, sock, P_DATA, sizeof(*p) + dgs, NULL, req->i.size); | 1655 | err = __send_command(peer_device->connection, device->vnr, sock, P_DATA, sizeof(*p) + dgs, NULL, req->i.size); |
@@ -1675,6 +1685,7 @@ int drbd_send_dblock(struct drbd_peer_device *peer_device, struct drbd_request * | |||
1675 | ... Be noisy about digest too large ... | 1685 | ... Be noisy about digest too large ... |
1676 | } */ | 1686 | } */ |
1677 | } | 1687 | } |
1688 | out: | ||
1678 | mutex_unlock(&sock->mutex); /* locked by drbd_prepare_command() */ | 1689 | mutex_unlock(&sock->mutex); /* locked by drbd_prepare_command() */ |
1679 | 1690 | ||
1680 | return err; | 1691 | return err; |
@@ -2570,6 +2581,7 @@ struct drbd_resource *drbd_create_resource(const char *name) | |||
2570 | INIT_LIST_HEAD(&resource->connections); | 2581 | INIT_LIST_HEAD(&resource->connections); |
2571 | list_add_tail_rcu(&resource->resources, &drbd_resources); | 2582 | list_add_tail_rcu(&resource->resources, &drbd_resources); |
2572 | mutex_init(&resource->conf_update); | 2583 | mutex_init(&resource->conf_update); |
2584 | mutex_init(&resource->adm_mutex); | ||
2573 | spin_lock_init(&resource->req_lock); | 2585 | spin_lock_init(&resource->req_lock); |
2574 | return resource; | 2586 | return resource; |
2575 | 2587 | ||
@@ -2687,14 +2699,16 @@ static int init_submitter(struct drbd_device *device) | |||
2687 | return 0; | 2699 | return 0; |
2688 | } | 2700 | } |
2689 | 2701 | ||
2690 | enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned int minor, int vnr) | 2702 | enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsigned int minor) |
2691 | { | 2703 | { |
2704 | struct drbd_resource *resource = adm_ctx->resource; | ||
2692 | struct drbd_connection *connection; | 2705 | struct drbd_connection *connection; |
2693 | struct drbd_device *device; | 2706 | struct drbd_device *device; |
2694 | struct drbd_peer_device *peer_device, *tmp_peer_device; | 2707 | struct drbd_peer_device *peer_device, *tmp_peer_device; |
2695 | struct gendisk *disk; | 2708 | struct gendisk *disk; |
2696 | struct request_queue *q; | 2709 | struct request_queue *q; |
2697 | int id; | 2710 | int id; |
2711 | int vnr = adm_ctx->volume; | ||
2698 | enum drbd_ret_code err = ERR_NOMEM; | 2712 | enum drbd_ret_code err = ERR_NOMEM; |
2699 | 2713 | ||
2700 | device = minor_to_device(minor); | 2714 | device = minor_to_device(minor); |
@@ -2763,7 +2777,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned i | |||
2763 | if (id < 0) { | 2777 | if (id < 0) { |
2764 | if (id == -ENOSPC) { | 2778 | if (id == -ENOSPC) { |
2765 | err = ERR_MINOR_EXISTS; | 2779 | err = ERR_MINOR_EXISTS; |
2766 | drbd_msg_put_info("requested minor exists already"); | 2780 | drbd_msg_put_info(adm_ctx->reply_skb, "requested minor exists already"); |
2767 | } | 2781 | } |
2768 | goto out_no_minor_idr; | 2782 | goto out_no_minor_idr; |
2769 | } | 2783 | } |
@@ -2773,7 +2787,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned i | |||
2773 | if (id < 0) { | 2787 | if (id < 0) { |
2774 | if (id == -ENOSPC) { | 2788 | if (id == -ENOSPC) { |
2775 | err = ERR_MINOR_EXISTS; | 2789 | err = ERR_MINOR_EXISTS; |
2776 | drbd_msg_put_info("requested minor exists already"); | 2790 | drbd_msg_put_info(adm_ctx->reply_skb, "requested minor exists already"); |
2777 | } | 2791 | } |
2778 | goto out_idr_remove_minor; | 2792 | goto out_idr_remove_minor; |
2779 | } | 2793 | } |
@@ -2794,7 +2808,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned i | |||
2794 | if (id < 0) { | 2808 | if (id < 0) { |
2795 | if (id == -ENOSPC) { | 2809 | if (id == -ENOSPC) { |
2796 | err = ERR_INVALID_REQUEST; | 2810 | err = ERR_INVALID_REQUEST; |
2797 | drbd_msg_put_info("requested volume exists already"); | 2811 | drbd_msg_put_info(adm_ctx->reply_skb, "requested volume exists already"); |
2798 | } | 2812 | } |
2799 | goto out_idr_remove_from_resource; | 2813 | goto out_idr_remove_from_resource; |
2800 | } | 2814 | } |
@@ -2803,7 +2817,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned i | |||
2803 | 2817 | ||
2804 | if (init_submitter(device)) { | 2818 | if (init_submitter(device)) { |
2805 | err = ERR_NOMEM; | 2819 | err = ERR_NOMEM; |
2806 | drbd_msg_put_info("unable to create submit workqueue"); | 2820 | drbd_msg_put_info(adm_ctx->reply_skb, "unable to create submit workqueue"); |
2807 | goto out_idr_remove_vol; | 2821 | goto out_idr_remove_vol; |
2808 | } | 2822 | } |
2809 | 2823 | ||
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 526414bc2cab..1b35c45c92b7 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include "drbd_int.h" | 34 | #include "drbd_int.h" |
35 | #include "drbd_protocol.h" | 35 | #include "drbd_protocol.h" |
36 | #include "drbd_req.h" | 36 | #include "drbd_req.h" |
37 | #include "drbd_wrappers.h" | ||
38 | #include <asm/unaligned.h> | 37 | #include <asm/unaligned.h> |
39 | #include <linux/drbd_limits.h> | 38 | #include <linux/drbd_limits.h> |
40 | #include <linux/kthread.h> | 39 | #include <linux/kthread.h> |
@@ -82,32 +81,6 @@ int drbd_adm_get_status_all(struct sk_buff *skb, struct netlink_callback *cb); | |||
82 | /* used blkdev_get_by_path, to claim our meta data device(s) */ | 81 | /* used blkdev_get_by_path, to claim our meta data device(s) */ |
83 | static char *drbd_m_holder = "Hands off! this is DRBD's meta data device."; | 82 | static char *drbd_m_holder = "Hands off! this is DRBD's meta data device."; |
84 | 83 | ||
85 | /* Configuration is strictly serialized, because generic netlink message | ||
86 | * processing is strictly serialized by the genl_lock(). | ||
87 | * Which means we can use one static global drbd_config_context struct. | ||
88 | */ | ||
89 | static struct drbd_config_context { | ||
90 | /* assigned from drbd_genlmsghdr */ | ||
91 | unsigned int minor; | ||
92 | /* assigned from request attributes, if present */ | ||
93 | unsigned int volume; | ||
94 | #define VOLUME_UNSPECIFIED (-1U) | ||
95 | /* pointer into the request skb, | ||
96 | * limited lifetime! */ | ||
97 | char *resource_name; | ||
98 | struct nlattr *my_addr; | ||
99 | struct nlattr *peer_addr; | ||
100 | |||
101 | /* reply buffer */ | ||
102 | struct sk_buff *reply_skb; | ||
103 | /* pointer into reply buffer */ | ||
104 | struct drbd_genlmsghdr *reply_dh; | ||
105 | /* resolved from attributes, if possible */ | ||
106 | struct drbd_device *device; | ||
107 | struct drbd_resource *resource; | ||
108 | struct drbd_connection *connection; | ||
109 | } adm_ctx; | ||
110 | |||
111 | static void drbd_adm_send_reply(struct sk_buff *skb, struct genl_info *info) | 84 | static void drbd_adm_send_reply(struct sk_buff *skb, struct genl_info *info) |
112 | { | 85 | { |
113 | genlmsg_end(skb, genlmsg_data(nlmsg_data(nlmsg_hdr(skb)))); | 86 | genlmsg_end(skb, genlmsg_data(nlmsg_data(nlmsg_hdr(skb)))); |
@@ -117,9 +90,8 @@ static void drbd_adm_send_reply(struct sk_buff *skb, struct genl_info *info) | |||
117 | 90 | ||
118 | /* Used on a fresh "drbd_adm_prepare"d reply_skb, this cannot fail: The only | 91 | /* Used on a fresh "drbd_adm_prepare"d reply_skb, this cannot fail: The only |
119 | * reason it could fail was no space in skb, and there are 4k available. */ | 92 | * reason it could fail was no space in skb, and there are 4k available. */ |
120 | int drbd_msg_put_info(const char *info) | 93 | int drbd_msg_put_info(struct sk_buff *skb, const char *info) |
121 | { | 94 | { |
122 | struct sk_buff *skb = adm_ctx.reply_skb; | ||
123 | struct nlattr *nla; | 95 | struct nlattr *nla; |
124 | int err = -EMSGSIZE; | 96 | int err = -EMSGSIZE; |
125 | 97 | ||
@@ -143,42 +115,46 @@ int drbd_msg_put_info(const char *info) | |||
143 | * and per-family private info->pointers. | 115 | * and per-family private info->pointers. |
144 | * But we need to stay compatible with older kernels. | 116 | * But we need to stay compatible with older kernels. |
145 | * If it returns successfully, adm_ctx members are valid. | 117 | * If it returns successfully, adm_ctx members are valid. |
118 | * | ||
119 | * At this point, we still rely on the global genl_lock(). | ||
120 | * If we want to avoid that, and allow "genl_family.parallel_ops", we may need | ||
121 | * to add additional synchronization against object destruction/modification. | ||
146 | */ | 122 | */ |
147 | #define DRBD_ADM_NEED_MINOR 1 | 123 | #define DRBD_ADM_NEED_MINOR 1 |
148 | #define DRBD_ADM_NEED_RESOURCE 2 | 124 | #define DRBD_ADM_NEED_RESOURCE 2 |
149 | #define DRBD_ADM_NEED_CONNECTION 4 | 125 | #define DRBD_ADM_NEED_CONNECTION 4 |
150 | static int drbd_adm_prepare(struct sk_buff *skb, struct genl_info *info, | 126 | static int drbd_adm_prepare(struct drbd_config_context *adm_ctx, |
151 | unsigned flags) | 127 | struct sk_buff *skb, struct genl_info *info, unsigned flags) |
152 | { | 128 | { |
153 | struct drbd_genlmsghdr *d_in = info->userhdr; | 129 | struct drbd_genlmsghdr *d_in = info->userhdr; |
154 | const u8 cmd = info->genlhdr->cmd; | 130 | const u8 cmd = info->genlhdr->cmd; |
155 | int err; | 131 | int err; |
156 | 132 | ||
157 | memset(&adm_ctx, 0, sizeof(adm_ctx)); | 133 | memset(adm_ctx, 0, sizeof(*adm_ctx)); |
158 | 134 | ||
159 | /* genl_rcv_msg only checks for CAP_NET_ADMIN on "GENL_ADMIN_PERM" :( */ | 135 | /* genl_rcv_msg only checks for CAP_NET_ADMIN on "GENL_ADMIN_PERM" :( */ |
160 | if (cmd != DRBD_ADM_GET_STATUS && !capable(CAP_NET_ADMIN)) | 136 | if (cmd != DRBD_ADM_GET_STATUS && !capable(CAP_NET_ADMIN)) |
161 | return -EPERM; | 137 | return -EPERM; |
162 | 138 | ||
163 | adm_ctx.reply_skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); | 139 | adm_ctx->reply_skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); |
164 | if (!adm_ctx.reply_skb) { | 140 | if (!adm_ctx->reply_skb) { |
165 | err = -ENOMEM; | 141 | err = -ENOMEM; |
166 | goto fail; | 142 | goto fail; |
167 | } | 143 | } |
168 | 144 | ||
169 | adm_ctx.reply_dh = genlmsg_put_reply(adm_ctx.reply_skb, | 145 | adm_ctx->reply_dh = genlmsg_put_reply(adm_ctx->reply_skb, |
170 | info, &drbd_genl_family, 0, cmd); | 146 | info, &drbd_genl_family, 0, cmd); |
171 | /* put of a few bytes into a fresh skb of >= 4k will always succeed. | 147 | /* put of a few bytes into a fresh skb of >= 4k will always succeed. |
172 | * but anyways */ | 148 | * but anyways */ |
173 | if (!adm_ctx.reply_dh) { | 149 | if (!adm_ctx->reply_dh) { |
174 | err = -ENOMEM; | 150 | err = -ENOMEM; |
175 | goto fail; | 151 | goto fail; |
176 | } | 152 | } |
177 | 153 | ||
178 | adm_ctx.reply_dh->minor = d_in->minor; | 154 | adm_ctx->reply_dh->minor = d_in->minor; |
179 | adm_ctx.reply_dh->ret_code = NO_ERROR; | 155 | adm_ctx->reply_dh->ret_code = NO_ERROR; |
180 | 156 | ||
181 | adm_ctx.volume = VOLUME_UNSPECIFIED; | 157 | adm_ctx->volume = VOLUME_UNSPECIFIED; |
182 | if (info->attrs[DRBD_NLA_CFG_CONTEXT]) { | 158 | if (info->attrs[DRBD_NLA_CFG_CONTEXT]) { |
183 | struct nlattr *nla; | 159 | struct nlattr *nla; |
184 | /* parse and validate only */ | 160 | /* parse and validate only */ |
@@ -188,111 +164,131 @@ static int drbd_adm_prepare(struct sk_buff *skb, struct genl_info *info, | |||
188 | 164 | ||
189 | /* It was present, and valid, | 165 | /* It was present, and valid, |
190 | * copy it over to the reply skb. */ | 166 | * copy it over to the reply skb. */ |
191 | err = nla_put_nohdr(adm_ctx.reply_skb, | 167 | err = nla_put_nohdr(adm_ctx->reply_skb, |
192 | info->attrs[DRBD_NLA_CFG_CONTEXT]->nla_len, | 168 | info->attrs[DRBD_NLA_CFG_CONTEXT]->nla_len, |
193 | info->attrs[DRBD_NLA_CFG_CONTEXT]); | 169 | info->attrs[DRBD_NLA_CFG_CONTEXT]); |
194 | if (err) | 170 | if (err) |
195 | goto fail; | 171 | goto fail; |
196 | 172 | ||
197 | /* and assign stuff to the global adm_ctx */ | 173 | /* and assign stuff to the adm_ctx */ |
198 | nla = nested_attr_tb[__nla_type(T_ctx_volume)]; | 174 | nla = nested_attr_tb[__nla_type(T_ctx_volume)]; |
199 | if (nla) | 175 | if (nla) |
200 | adm_ctx.volume = nla_get_u32(nla); | 176 | adm_ctx->volume = nla_get_u32(nla); |
201 | nla = nested_attr_tb[__nla_type(T_ctx_resource_name)]; | 177 | nla = nested_attr_tb[__nla_type(T_ctx_resource_name)]; |
202 | if (nla) | 178 | if (nla) |
203 | adm_ctx.resource_name = nla_data(nla); | 179 | adm_ctx->resource_name = nla_data(nla); |
204 | adm_ctx.my_addr = nested_attr_tb[__nla_type(T_ctx_my_addr)]; | 180 | adm_ctx->my_addr = nested_attr_tb[__nla_type(T_ctx_my_addr)]; |
205 | adm_ctx.peer_addr = nested_attr_tb[__nla_type(T_ctx_peer_addr)]; | 181 | adm_ctx->peer_addr = nested_attr_tb[__nla_type(T_ctx_peer_addr)]; |
206 | if ((adm_ctx.my_addr && | 182 | if ((adm_ctx->my_addr && |
207 | nla_len(adm_ctx.my_addr) > sizeof(adm_ctx.connection->my_addr)) || | 183 | nla_len(adm_ctx->my_addr) > sizeof(adm_ctx->connection->my_addr)) || |
208 | (adm_ctx.peer_addr && | 184 | (adm_ctx->peer_addr && |
209 | nla_len(adm_ctx.peer_addr) > sizeof(adm_ctx.connection->peer_addr))) { | 185 | nla_len(adm_ctx->peer_addr) > sizeof(adm_ctx->connection->peer_addr))) { |
210 | err = -EINVAL; | 186 | err = -EINVAL; |
211 | goto fail; | 187 | goto fail; |
212 | } | 188 | } |
213 | } | 189 | } |
214 | 190 | ||
215 | adm_ctx.minor = d_in->minor; | 191 | adm_ctx->minor = d_in->minor; |
216 | adm_ctx.device = minor_to_device(d_in->minor); | 192 | adm_ctx->device = minor_to_device(d_in->minor); |
217 | if (adm_ctx.resource_name) { | 193 | |
218 | adm_ctx.resource = drbd_find_resource(adm_ctx.resource_name); | 194 | /* We are protected by the global genl_lock(). |
195 | * But we may explicitly drop it/retake it in drbd_adm_set_role(), | ||
196 | * so make sure this object stays around. */ | ||
197 | if (adm_ctx->device) | ||
198 | kref_get(&adm_ctx->device->kref); | ||
199 | |||
200 | if (adm_ctx->resource_name) { | ||
201 | adm_ctx->resource = drbd_find_resource(adm_ctx->resource_name); | ||
219 | } | 202 | } |
220 | 203 | ||
221 | if (!adm_ctx.device && (flags & DRBD_ADM_NEED_MINOR)) { | 204 | if (!adm_ctx->device && (flags & DRBD_ADM_NEED_MINOR)) { |
222 | drbd_msg_put_info("unknown minor"); | 205 | drbd_msg_put_info(adm_ctx->reply_skb, "unknown minor"); |
223 | return ERR_MINOR_INVALID; | 206 | return ERR_MINOR_INVALID; |
224 | } | 207 | } |
225 | if (!adm_ctx.resource && (flags & DRBD_ADM_NEED_RESOURCE)) { | 208 | if (!adm_ctx->resource && (flags & DRBD_ADM_NEED_RESOURCE)) { |
226 | drbd_msg_put_info("unknown resource"); | 209 | drbd_msg_put_info(adm_ctx->reply_skb, "unknown resource"); |
227 | if (adm_ctx.resource_name) | 210 | if (adm_ctx->resource_name) |
228 | return ERR_RES_NOT_KNOWN; | 211 | return ERR_RES_NOT_KNOWN; |
229 | return ERR_INVALID_REQUEST; | 212 | return ERR_INVALID_REQUEST; |
230 | } | 213 | } |
231 | 214 | ||
232 | if (flags & DRBD_ADM_NEED_CONNECTION) { | 215 | if (flags & DRBD_ADM_NEED_CONNECTION) { |
233 | if (adm_ctx.resource) { | 216 | if (adm_ctx->resource) { |
234 | drbd_msg_put_info("no resource name expected"); | 217 | drbd_msg_put_info(adm_ctx->reply_skb, "no resource name expected"); |
235 | return ERR_INVALID_REQUEST; | 218 | return ERR_INVALID_REQUEST; |
236 | } | 219 | } |
237 | if (adm_ctx.device) { | 220 | if (adm_ctx->device) { |
238 | drbd_msg_put_info("no minor number expected"); | 221 | drbd_msg_put_info(adm_ctx->reply_skb, "no minor number expected"); |
239 | return ERR_INVALID_REQUEST; | 222 | return ERR_INVALID_REQUEST; |
240 | } | 223 | } |
241 | if (adm_ctx.my_addr && adm_ctx.peer_addr) | 224 | if (adm_ctx->my_addr && adm_ctx->peer_addr) |
242 | adm_ctx.connection = conn_get_by_addrs(nla_data(adm_ctx.my_addr), | 225 | adm_ctx->connection = conn_get_by_addrs(nla_data(adm_ctx->my_addr), |
243 | nla_len(adm_ctx.my_addr), | 226 | nla_len(adm_ctx->my_addr), |
244 | nla_data(adm_ctx.peer_addr), | 227 | nla_data(adm_ctx->peer_addr), |
245 | nla_len(adm_ctx.peer_addr)); | 228 | nla_len(adm_ctx->peer_addr)); |
246 | if (!adm_ctx.connection) { | 229 | if (!adm_ctx->connection) { |
247 | drbd_msg_put_info("unknown connection"); | 230 | drbd_msg_put_info(adm_ctx->reply_skb, "unknown connection"); |
248 | return ERR_INVALID_REQUEST; | 231 | return ERR_INVALID_REQUEST; |
249 | } | 232 | } |
250 | } | 233 | } |
251 | 234 | ||
252 | /* some more paranoia, if the request was over-determined */ | 235 | /* some more paranoia, if the request was over-determined */ |
253 | if (adm_ctx.device && adm_ctx.resource && | 236 | if (adm_ctx->device && adm_ctx->resource && |
254 | adm_ctx.device->resource != adm_ctx.resource) { | 237 | adm_ctx->device->resource != adm_ctx->resource) { |
255 | pr_warning("request: minor=%u, resource=%s; but that minor belongs to resource %s\n", | 238 | pr_warning("request: minor=%u, resource=%s; but that minor belongs to resource %s\n", |
256 | adm_ctx.minor, adm_ctx.resource->name, | 239 | adm_ctx->minor, adm_ctx->resource->name, |
257 | adm_ctx.device->resource->name); | 240 | adm_ctx->device->resource->name); |
258 | drbd_msg_put_info("minor exists in different resource"); | 241 | drbd_msg_put_info(adm_ctx->reply_skb, "minor exists in different resource"); |
259 | return ERR_INVALID_REQUEST; | 242 | return ERR_INVALID_REQUEST; |
260 | } | 243 | } |
261 | if (adm_ctx.device && | 244 | if (adm_ctx->device && |
262 | adm_ctx.volume != VOLUME_UNSPECIFIED && | 245 | adm_ctx->volume != VOLUME_UNSPECIFIED && |
263 | adm_ctx.volume != adm_ctx.device->vnr) { | 246 | adm_ctx->volume != adm_ctx->device->vnr) { |
264 | pr_warning("request: minor=%u, volume=%u; but that minor is volume %u in %s\n", | 247 | pr_warning("request: minor=%u, volume=%u; but that minor is volume %u in %s\n", |
265 | adm_ctx.minor, adm_ctx.volume, | 248 | adm_ctx->minor, adm_ctx->volume, |
266 | adm_ctx.device->vnr, | 249 | adm_ctx->device->vnr, |
267 | adm_ctx.device->resource->name); | 250 | adm_ctx->device->resource->name); |
268 | drbd_msg_put_info("minor exists as different volume"); | 251 | drbd_msg_put_info(adm_ctx->reply_skb, "minor exists as different volume"); |
269 | return ERR_INVALID_REQUEST; | 252 | return ERR_INVALID_REQUEST; |
270 | } | 253 | } |
271 | 254 | ||
255 | /* still, provide adm_ctx->resource always, if possible. */ | ||
256 | if (!adm_ctx->resource) { | ||
257 | adm_ctx->resource = adm_ctx->device ? adm_ctx->device->resource | ||
258 | : adm_ctx->connection ? adm_ctx->connection->resource : NULL; | ||
259 | if (adm_ctx->resource) | ||
260 | kref_get(&adm_ctx->resource->kref); | ||
261 | } | ||
262 | |||
272 | return NO_ERROR; | 263 | return NO_ERROR; |
273 | 264 | ||
274 | fail: | 265 | fail: |
275 | nlmsg_free(adm_ctx.reply_skb); | 266 | nlmsg_free(adm_ctx->reply_skb); |
276 | adm_ctx.reply_skb = NULL; | 267 | adm_ctx->reply_skb = NULL; |
277 | return err; | 268 | return err; |
278 | } | 269 | } |
279 | 270 | ||
280 | static int drbd_adm_finish(struct genl_info *info, int retcode) | 271 | static int drbd_adm_finish(struct drbd_config_context *adm_ctx, |
272 | struct genl_info *info, int retcode) | ||
281 | { | 273 | { |
282 | if (adm_ctx.connection) { | 274 | if (adm_ctx->device) { |
283 | kref_put(&adm_ctx.connection->kref, drbd_destroy_connection); | 275 | kref_put(&adm_ctx->device->kref, drbd_destroy_device); |
284 | adm_ctx.connection = NULL; | 276 | adm_ctx->device = NULL; |
285 | } | 277 | } |
286 | if (adm_ctx.resource) { | 278 | if (adm_ctx->connection) { |
287 | kref_put(&adm_ctx.resource->kref, drbd_destroy_resource); | 279 | kref_put(&adm_ctx->connection->kref, &drbd_destroy_connection); |
288 | adm_ctx.resource = NULL; | 280 | adm_ctx->connection = NULL; |
281 | } | ||
282 | if (adm_ctx->resource) { | ||
283 | kref_put(&adm_ctx->resource->kref, drbd_destroy_resource); | ||
284 | adm_ctx->resource = NULL; | ||
289 | } | 285 | } |
290 | 286 | ||
291 | if (!adm_ctx.reply_skb) | 287 | if (!adm_ctx->reply_skb) |
292 | return -ENOMEM; | 288 | return -ENOMEM; |
293 | 289 | ||
294 | adm_ctx.reply_dh->ret_code = retcode; | 290 | adm_ctx->reply_dh->ret_code = retcode; |
295 | drbd_adm_send_reply(adm_ctx.reply_skb, info); | 291 | drbd_adm_send_reply(adm_ctx->reply_skb, info); |
296 | return 0; | 292 | return 0; |
297 | } | 293 | } |
298 | 294 | ||
@@ -426,6 +422,14 @@ static enum drbd_fencing_p highest_fencing_policy(struct drbd_connection *connec | |||
426 | } | 422 | } |
427 | rcu_read_unlock(); | 423 | rcu_read_unlock(); |
428 | 424 | ||
425 | if (fp == FP_NOT_AVAIL) { | ||
426 | /* IO Suspending works on the whole resource. | ||
427 | Do it only for one device. */ | ||
428 | vnr = 0; | ||
429 | peer_device = idr_get_next(&connection->peer_devices, &vnr); | ||
430 | drbd_change_state(peer_device->device, CS_VERBOSE | CS_HARD, NS(susp_fen, 0)); | ||
431 | } | ||
432 | |||
429 | return fp; | 433 | return fp; |
430 | } | 434 | } |
431 | 435 | ||
@@ -438,12 +442,13 @@ bool conn_try_outdate_peer(struct drbd_connection *connection) | |||
438 | char *ex_to_string; | 442 | char *ex_to_string; |
439 | int r; | 443 | int r; |
440 | 444 | ||
445 | spin_lock_irq(&connection->resource->req_lock); | ||
441 | if (connection->cstate >= C_WF_REPORT_PARAMS) { | 446 | if (connection->cstate >= C_WF_REPORT_PARAMS) { |
442 | drbd_err(connection, "Expected cstate < C_WF_REPORT_PARAMS\n"); | 447 | drbd_err(connection, "Expected cstate < C_WF_REPORT_PARAMS\n"); |
448 | spin_unlock_irq(&connection->resource->req_lock); | ||
443 | return false; | 449 | return false; |
444 | } | 450 | } |
445 | 451 | ||
446 | spin_lock_irq(&connection->resource->req_lock); | ||
447 | connect_cnt = connection->connect_cnt; | 452 | connect_cnt = connection->connect_cnt; |
448 | spin_unlock_irq(&connection->resource->req_lock); | 453 | spin_unlock_irq(&connection->resource->req_lock); |
449 | 454 | ||
@@ -654,11 +659,11 @@ drbd_set_role(struct drbd_device *device, enum drbd_role new_role, int force) | |||
654 | put_ldev(device); | 659 | put_ldev(device); |
655 | } | 660 | } |
656 | } else { | 661 | } else { |
657 | mutex_lock(&device->resource->conf_update); | 662 | /* Called from drbd_adm_set_role only. |
663 | * We are still holding the conf_update mutex. */ | ||
658 | nc = first_peer_device(device)->connection->net_conf; | 664 | nc = first_peer_device(device)->connection->net_conf; |
659 | if (nc) | 665 | if (nc) |
660 | nc->discard_my_data = 0; /* without copy; single bit op is atomic */ | 666 | nc->discard_my_data = 0; /* without copy; single bit op is atomic */ |
661 | mutex_unlock(&device->resource->conf_update); | ||
662 | 667 | ||
663 | set_disk_ro(device->vdisk, false); | 668 | set_disk_ro(device->vdisk, false); |
664 | if (get_ldev(device)) { | 669 | if (get_ldev(device)) { |
@@ -700,11 +705,12 @@ static const char *from_attrs_err_to_txt(int err) | |||
700 | 705 | ||
701 | int drbd_adm_set_role(struct sk_buff *skb, struct genl_info *info) | 706 | int drbd_adm_set_role(struct sk_buff *skb, struct genl_info *info) |
702 | { | 707 | { |
708 | struct drbd_config_context adm_ctx; | ||
703 | struct set_role_parms parms; | 709 | struct set_role_parms parms; |
704 | int err; | 710 | int err; |
705 | enum drbd_ret_code retcode; | 711 | enum drbd_ret_code retcode; |
706 | 712 | ||
707 | retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR); | 713 | retcode = drbd_adm_prepare(&adm_ctx, skb, info, DRBD_ADM_NEED_MINOR); |
708 | if (!adm_ctx.reply_skb) | 714 | if (!adm_ctx.reply_skb) |
709 | return retcode; | 715 | return retcode; |
710 | if (retcode != NO_ERROR) | 716 | if (retcode != NO_ERROR) |
@@ -715,17 +721,22 @@ int drbd_adm_set_role(struct sk_buff *skb, struct genl_info *info) | |||
715 | err = set_role_parms_from_attrs(&parms, info); | 721 | err = set_role_parms_from_attrs(&parms, info); |
716 | if (err) { | 722 | if (err) { |
717 | retcode = ERR_MANDATORY_TAG; | 723 | retcode = ERR_MANDATORY_TAG; |
718 | drbd_msg_put_info(from_attrs_err_to_txt(err)); | 724 | drbd_msg_put_info(adm_ctx.reply_skb, from_attrs_err_to_txt(err)); |
719 | goto out; | 725 | goto out; |
720 | } | 726 | } |
721 | } | 727 | } |
728 | genl_unlock(); | ||
729 | mutex_lock(&adm_ctx.resource->adm_mutex); | ||
722 | 730 | ||
723 | if (info->genlhdr->cmd == DRBD_ADM_PRIMARY) | 731 | if (info->genlhdr->cmd == DRBD_ADM_PRIMARY) |
724 | retcode = drbd_set_role(adm_ctx.device, R_PRIMARY, parms.assume_uptodate); | 732 | retcode = drbd_set_role(adm_ctx.device, R_PRIMARY, parms.assume_uptodate); |
725 | else | 733 | else |
726 | retcode = drbd_set_role(adm_ctx.device, R_SECONDARY, 0); | 734 | retcode = drbd_set_role(adm_ctx.device, R_SECONDARY, 0); |
735 | |||
736 | mutex_unlock(&adm_ctx.resource->adm_mutex); | ||
737 | genl_lock(); | ||
727 | out: | 738 | out: |
728 | drbd_adm_finish(info, retcode); | 739 | drbd_adm_finish(&adm_ctx, info, retcode); |
729 | return 0; | 740 | return 0; |
730 | } | 741 | } |
731 | 742 | ||
@@ -1104,15 +1115,18 @@ static void drbd_setup_queue_param(struct drbd_device *device, unsigned int max_ | |||
1104 | struct request_queue * const q = device->rq_queue; | 1115 | struct request_queue * const q = device->rq_queue; |
1105 | unsigned int max_hw_sectors = max_bio_size >> 9; | 1116 | unsigned int max_hw_sectors = max_bio_size >> 9; |
1106 | unsigned int max_segments = 0; | 1117 | unsigned int max_segments = 0; |
1118 | struct request_queue *b = NULL; | ||
1107 | 1119 | ||
1108 | if (get_ldev_if_state(device, D_ATTACHING)) { | 1120 | if (get_ldev_if_state(device, D_ATTACHING)) { |
1109 | struct request_queue * const b = device->ldev->backing_bdev->bd_disk->queue; | 1121 | b = device->ldev->backing_bdev->bd_disk->queue; |
1110 | 1122 | ||
1111 | max_hw_sectors = min(queue_max_hw_sectors(b), max_bio_size >> 9); | 1123 | max_hw_sectors = min(queue_max_hw_sectors(b), max_bio_size >> 9); |
1112 | rcu_read_lock(); | 1124 | rcu_read_lock(); |
1113 | max_segments = rcu_dereference(device->ldev->disk_conf)->max_bio_bvecs; | 1125 | max_segments = rcu_dereference(device->ldev->disk_conf)->max_bio_bvecs; |
1114 | rcu_read_unlock(); | 1126 | rcu_read_unlock(); |
1115 | put_ldev(device); | 1127 | |
1128 | blk_set_stacking_limits(&q->limits); | ||
1129 | blk_queue_max_write_same_sectors(q, 0); | ||
1116 | } | 1130 | } |
1117 | 1131 | ||
1118 | blk_queue_logical_block_size(q, 512); | 1132 | blk_queue_logical_block_size(q, 512); |
@@ -1121,8 +1135,25 @@ static void drbd_setup_queue_param(struct drbd_device *device, unsigned int max_ | |||
1121 | blk_queue_max_segments(q, max_segments ? max_segments : BLK_MAX_SEGMENTS); | 1135 | blk_queue_max_segments(q, max_segments ? max_segments : BLK_MAX_SEGMENTS); |
1122 | blk_queue_segment_boundary(q, PAGE_CACHE_SIZE-1); | 1136 | blk_queue_segment_boundary(q, PAGE_CACHE_SIZE-1); |
1123 | 1137 | ||
1124 | if (get_ldev_if_state(device, D_ATTACHING)) { | 1138 | if (b) { |
1125 | struct request_queue * const b = device->ldev->backing_bdev->bd_disk->queue; | 1139 | struct drbd_connection *connection = first_peer_device(device)->connection; |
1140 | |||
1141 | if (blk_queue_discard(b) && | ||
1142 | (connection->cstate < C_CONNECTED || connection->agreed_features & FF_TRIM)) { | ||
1143 | /* For now, don't allow more than one activity log extent worth of data | ||
1144 | * to be discarded in one go. We may need to rework drbd_al_begin_io() | ||
1145 | * to allow for even larger discard ranges */ | ||
1146 | q->limits.max_discard_sectors = DRBD_MAX_DISCARD_SECTORS; | ||
1147 | |||
1148 | queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q); | ||
1149 | /* REALLY? Is stacking secdiscard "legal"? */ | ||
1150 | if (blk_queue_secdiscard(b)) | ||
1151 | queue_flag_set_unlocked(QUEUE_FLAG_SECDISCARD, q); | ||
1152 | } else { | ||
1153 | q->limits.max_discard_sectors = 0; | ||
1154 | queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, q); | ||
1155 | queue_flag_clear_unlocked(QUEUE_FLAG_SECDISCARD, q); | ||
1156 | } | ||
1126 | 1157 | ||
1127 | blk_queue_stack_limits(q, b); | 1158 | blk_queue_stack_limits(q, b); |
1128 | 1159 | ||
@@ -1164,8 +1195,14 @@ void drbd_reconsider_max_bio_size(struct drbd_device *device) | |||
1164 | peer = DRBD_MAX_BIO_SIZE_P95; /* drbd 8.3.8 onwards, before 8.4.0 */ | 1195 | peer = DRBD_MAX_BIO_SIZE_P95; /* drbd 8.3.8 onwards, before 8.4.0 */ |
1165 | else | 1196 | else |
1166 | peer = DRBD_MAX_BIO_SIZE; | 1197 | peer = DRBD_MAX_BIO_SIZE; |
1167 | } | ||
1168 | 1198 | ||
1199 | /* We may later detach and re-attach on a disconnected Primary. | ||
1200 | * Avoid this setting to jump back in that case. | ||
1201 | * We want to store what we know the peer DRBD can handle, | ||
1202 | * not what the peer IO backend can handle. */ | ||
1203 | if (peer > device->peer_max_bio_size) | ||
1204 | device->peer_max_bio_size = peer; | ||
1205 | } | ||
1169 | new = min(local, peer); | 1206 | new = min(local, peer); |
1170 | 1207 | ||
1171 | if (device->state.role == R_PRIMARY && new < now) | 1208 | if (device->state.role == R_PRIMARY && new < now) |
@@ -1258,19 +1295,21 @@ static unsigned int drbd_al_extents_max(struct drbd_backing_dev *bdev) | |||
1258 | 1295 | ||
1259 | int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info) | 1296 | int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info) |
1260 | { | 1297 | { |
1298 | struct drbd_config_context adm_ctx; | ||
1261 | enum drbd_ret_code retcode; | 1299 | enum drbd_ret_code retcode; |
1262 | struct drbd_device *device; | 1300 | struct drbd_device *device; |
1263 | struct disk_conf *new_disk_conf, *old_disk_conf; | 1301 | struct disk_conf *new_disk_conf, *old_disk_conf; |
1264 | struct fifo_buffer *old_plan = NULL, *new_plan = NULL; | 1302 | struct fifo_buffer *old_plan = NULL, *new_plan = NULL; |
1265 | int err, fifo_size; | 1303 | int err, fifo_size; |
1266 | 1304 | ||
1267 | retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR); | 1305 | retcode = drbd_adm_prepare(&adm_ctx, skb, info, DRBD_ADM_NEED_MINOR); |
1268 | if (!adm_ctx.reply_skb) | 1306 | if (!adm_ctx.reply_skb) |
1269 | return retcode; | 1307 | return retcode; |
1270 | if (retcode != NO_ERROR) | 1308 | if (retcode != NO_ERROR) |
1271 | goto out; | 1309 | goto finish; |
1272 | 1310 | ||
1273 | device = adm_ctx.device; | 1311 | device = adm_ctx.device; |
1312 | mutex_lock(&adm_ctx.resource->adm_mutex); | ||
1274 | 1313 | ||
1275 | /* we also need a disk | 1314 | /* we also need a disk |
1276 | * to change the options on */ | 1315 | * to change the options on */ |
@@ -1294,7 +1333,7 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info) | |||
1294 | err = disk_conf_from_attrs_for_change(new_disk_conf, info); | 1333 | err = disk_conf_from_attrs_for_change(new_disk_conf, info); |
1295 | if (err && err != -ENOMSG) { | 1334 | if (err && err != -ENOMSG) { |
1296 | retcode = ERR_MANDATORY_TAG; | 1335 | retcode = ERR_MANDATORY_TAG; |
1297 | drbd_msg_put_info(from_attrs_err_to_txt(err)); | 1336 | drbd_msg_put_info(adm_ctx.reply_skb, from_attrs_err_to_txt(err)); |
1298 | goto fail_unlock; | 1337 | goto fail_unlock; |
1299 | } | 1338 | } |
1300 | 1339 | ||
@@ -1385,12 +1424,15 @@ fail_unlock: | |||
1385 | success: | 1424 | success: |
1386 | put_ldev(device); | 1425 | put_ldev(device); |
1387 | out: | 1426 | out: |
1388 | drbd_adm_finish(info, retcode); | 1427 | mutex_unlock(&adm_ctx.resource->adm_mutex); |
1428 | finish: | ||
1429 | drbd_adm_finish(&adm_ctx, info, retcode); | ||
1389 | return 0; | 1430 | return 0; |
1390 | } | 1431 | } |
1391 | 1432 | ||
1392 | int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info) | 1433 | int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info) |
1393 | { | 1434 | { |
1435 | struct drbd_config_context adm_ctx; | ||
1394 | struct drbd_device *device; | 1436 | struct drbd_device *device; |
1395 | int err; | 1437 | int err; |
1396 | enum drbd_ret_code retcode; | 1438 | enum drbd_ret_code retcode; |
@@ -1406,13 +1448,14 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info) | |||
1406 | enum drbd_state_rv rv; | 1448 | enum drbd_state_rv rv; |
1407 | struct net_conf *nc; | 1449 | struct net_conf *nc; |
1408 | 1450 | ||
1409 | retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR); | 1451 | retcode = drbd_adm_prepare(&adm_ctx, skb, info, DRBD_ADM_NEED_MINOR); |
1410 | if (!adm_ctx.reply_skb) | 1452 | if (!adm_ctx.reply_skb) |
1411 | return retcode; | 1453 | return retcode; |
1412 | if (retcode != NO_ERROR) | 1454 | if (retcode != NO_ERROR) |
1413 | goto finish; | 1455 | goto finish; |
1414 | 1456 | ||
1415 | device = adm_ctx.device; | 1457 | device = adm_ctx.device; |
1458 | mutex_lock(&adm_ctx.resource->adm_mutex); | ||
1416 | conn_reconfig_start(first_peer_device(device)->connection); | 1459 | conn_reconfig_start(first_peer_device(device)->connection); |
1417 | 1460 | ||
1418 | /* if you want to reconfigure, please tear down first */ | 1461 | /* if you want to reconfigure, please tear down first */ |
@@ -1455,7 +1498,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info) | |||
1455 | err = disk_conf_from_attrs(new_disk_conf, info); | 1498 | err = disk_conf_from_attrs(new_disk_conf, info); |
1456 | if (err) { | 1499 | if (err) { |
1457 | retcode = ERR_MANDATORY_TAG; | 1500 | retcode = ERR_MANDATORY_TAG; |
1458 | drbd_msg_put_info(from_attrs_err_to_txt(err)); | 1501 | drbd_msg_put_info(adm_ctx.reply_skb, from_attrs_err_to_txt(err)); |
1459 | goto fail; | 1502 | goto fail; |
1460 | } | 1503 | } |
1461 | 1504 | ||
@@ -1619,7 +1662,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info) | |||
1619 | } | 1662 | } |
1620 | 1663 | ||
1621 | if (device->state.conn < C_CONNECTED && | 1664 | if (device->state.conn < C_CONNECTED && |
1622 | device->state.role == R_PRIMARY && | 1665 | device->state.role == R_PRIMARY && device->ed_uuid && |
1623 | (device->ed_uuid & ~((u64)1)) != (nbc->md.uuid[UI_CURRENT] & ~((u64)1))) { | 1666 | (device->ed_uuid & ~((u64)1)) != (nbc->md.uuid[UI_CURRENT] & ~((u64)1))) { |
1624 | drbd_err(device, "Can only attach to data with current UUID=%016llX\n", | 1667 | drbd_err(device, "Can only attach to data with current UUID=%016llX\n", |
1625 | (unsigned long long)device->ed_uuid); | 1668 | (unsigned long long)device->ed_uuid); |
@@ -1797,7 +1840,8 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info) | |||
1797 | kobject_uevent(&disk_to_dev(device->vdisk)->kobj, KOBJ_CHANGE); | 1840 | kobject_uevent(&disk_to_dev(device->vdisk)->kobj, KOBJ_CHANGE); |
1798 | put_ldev(device); | 1841 | put_ldev(device); |
1799 | conn_reconfig_done(first_peer_device(device)->connection); | 1842 | conn_reconfig_done(first_peer_device(device)->connection); |
1800 | drbd_adm_finish(info, retcode); | 1843 | mutex_unlock(&adm_ctx.resource->adm_mutex); |
1844 | drbd_adm_finish(&adm_ctx, info, retcode); | ||
1801 | return 0; | 1845 | return 0; |
1802 | 1846 | ||
1803 | force_diskless_dec: | 1847 | force_diskless_dec: |
@@ -1819,9 +1863,9 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info) | |||
1819 | kfree(new_disk_conf); | 1863 | kfree(new_disk_conf); |
1820 | lc_destroy(resync_lru); | 1864 | lc_destroy(resync_lru); |
1821 | kfree(new_plan); | 1865 | kfree(new_plan); |
1822 | 1866 | mutex_unlock(&adm_ctx.resource->adm_mutex); | |
1823 | finish: | 1867 | finish: |
1824 | drbd_adm_finish(info, retcode); | 1868 | drbd_adm_finish(&adm_ctx, info, retcode); |
1825 | return 0; | 1869 | return 0; |
1826 | } | 1870 | } |
1827 | 1871 | ||
@@ -1860,11 +1904,12 @@ out: | |||
1860 | * Only then we have finally detached. */ | 1904 | * Only then we have finally detached. */ |
1861 | int drbd_adm_detach(struct sk_buff *skb, struct genl_info *info) | 1905 | int drbd_adm_detach(struct sk_buff *skb, struct genl_info *info) |
1862 | { | 1906 | { |
1907 | struct drbd_config_context adm_ctx; | ||
1863 | enum drbd_ret_code retcode; | 1908 | enum drbd_ret_code retcode; |
1864 | struct detach_parms parms = { }; | 1909 | struct detach_parms parms = { }; |
1865 | int err; | 1910 | int err; |
1866 | 1911 | ||
1867 | retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR); | 1912 | retcode = drbd_adm_prepare(&adm_ctx, skb, info, DRBD_ADM_NEED_MINOR); |
1868 | if (!adm_ctx.reply_skb) | 1913 | if (!adm_ctx.reply_skb) |
1869 | return retcode; | 1914 | return retcode; |
1870 | if (retcode != NO_ERROR) | 1915 | if (retcode != NO_ERROR) |
@@ -1874,14 +1919,16 @@ int drbd_adm_detach(struct sk_buff *skb, struct genl_info *info) | |||
1874 | err = detach_parms_from_attrs(&parms, info); | 1919 | err = detach_parms_from_attrs(&parms, info); |
1875 | if (err) { | 1920 | if (err) { |
1876 | retcode = ERR_MANDATORY_TAG; | 1921 | retcode = ERR_MANDATORY_TAG; |
1877 | drbd_msg_put_info(from_attrs_err_to_txt(err)); | 1922 | drbd_msg_put_info(adm_ctx.reply_skb, from_attrs_err_to_txt(err)); |
1878 | goto out; | 1923 | goto out; |
1879 | } | 1924 | } |
1880 | } | 1925 | } |
1881 | 1926 | ||
1927 | mutex_lock(&adm_ctx.resource->adm_mutex); | ||
1882 | retcode = adm_detach(adm_ctx.device, parms.force_detach); | 1928 | retcode = adm_detach(adm_ctx.device, parms.force_detach); |
1929 | mutex_unlock(&adm_ctx.resource->adm_mutex); | ||
1883 | out: | 1930 | out: |
1884 | drbd_adm_finish(info, retcode); | 1931 | drbd_adm_finish(&adm_ctx, info, retcode); |
1885 | return 0; | 1932 | return 0; |
1886 | } | 1933 | } |
1887 | 1934 | ||
@@ -2055,6 +2102,7 @@ static void free_crypto(struct crypto *crypto) | |||
2055 | 2102 | ||
2056 | int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info) | 2103 | int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info) |
2057 | { | 2104 | { |
2105 | struct drbd_config_context adm_ctx; | ||
2058 | enum drbd_ret_code retcode; | 2106 | enum drbd_ret_code retcode; |
2059 | struct drbd_connection *connection; | 2107 | struct drbd_connection *connection; |
2060 | struct net_conf *old_net_conf, *new_net_conf = NULL; | 2108 | struct net_conf *old_net_conf, *new_net_conf = NULL; |
@@ -2063,13 +2111,14 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info) | |||
2063 | int rsr; /* re-sync running */ | 2111 | int rsr; /* re-sync running */ |
2064 | struct crypto crypto = { }; | 2112 | struct crypto crypto = { }; |
2065 | 2113 | ||
2066 | retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_CONNECTION); | 2114 | retcode = drbd_adm_prepare(&adm_ctx, skb, info, DRBD_ADM_NEED_CONNECTION); |
2067 | if (!adm_ctx.reply_skb) | 2115 | if (!adm_ctx.reply_skb) |
2068 | return retcode; | 2116 | return retcode; |
2069 | if (retcode != NO_ERROR) | 2117 | if (retcode != NO_ERROR) |
2070 | goto out; | 2118 | goto finish; |
2071 | 2119 | ||
2072 | connection = adm_ctx.connection; | 2120 | connection = adm_ctx.connection; |
2121 | mutex_lock(&adm_ctx.resource->adm_mutex); | ||
2073 | 2122 | ||
2074 | new_net_conf = kzalloc(sizeof(struct net_conf), GFP_KERNEL); | 2123 | new_net_conf = kzalloc(sizeof(struct net_conf), GFP_KERNEL); |
2075 | if (!new_net_conf) { | 2124 | if (!new_net_conf) { |
@@ -2084,7 +2133,7 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info) | |||
2084 | old_net_conf = connection->net_conf; | 2133 | old_net_conf = connection->net_conf; |
2085 | 2134 | ||
2086 | if (!old_net_conf) { | 2135 | if (!old_net_conf) { |
2087 | drbd_msg_put_info("net conf missing, try connect"); | 2136 | drbd_msg_put_info(adm_ctx.reply_skb, "net conf missing, try connect"); |
2088 | retcode = ERR_INVALID_REQUEST; | 2137 | retcode = ERR_INVALID_REQUEST; |
2089 | goto fail; | 2138 | goto fail; |
2090 | } | 2139 | } |
@@ -2096,7 +2145,7 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info) | |||
2096 | err = net_conf_from_attrs_for_change(new_net_conf, info); | 2145 | err = net_conf_from_attrs_for_change(new_net_conf, info); |
2097 | if (err && err != -ENOMSG) { | 2146 | if (err && err != -ENOMSG) { |
2098 | retcode = ERR_MANDATORY_TAG; | 2147 | retcode = ERR_MANDATORY_TAG; |
2099 | drbd_msg_put_info(from_attrs_err_to_txt(err)); | 2148 | drbd_msg_put_info(adm_ctx.reply_skb, from_attrs_err_to_txt(err)); |
2100 | goto fail; | 2149 | goto fail; |
2101 | } | 2150 | } |
2102 | 2151 | ||
@@ -2167,12 +2216,15 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info) | |||
2167 | done: | 2216 | done: |
2168 | conn_reconfig_done(connection); | 2217 | conn_reconfig_done(connection); |
2169 | out: | 2218 | out: |
2170 | drbd_adm_finish(info, retcode); | 2219 | mutex_unlock(&adm_ctx.resource->adm_mutex); |
2220 | finish: | ||
2221 | drbd_adm_finish(&adm_ctx, info, retcode); | ||
2171 | return 0; | 2222 | return 0; |
2172 | } | 2223 | } |
2173 | 2224 | ||
2174 | int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info) | 2225 | int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info) |
2175 | { | 2226 | { |
2227 | struct drbd_config_context adm_ctx; | ||
2176 | struct drbd_peer_device *peer_device; | 2228 | struct drbd_peer_device *peer_device; |
2177 | struct net_conf *old_net_conf, *new_net_conf = NULL; | 2229 | struct net_conf *old_net_conf, *new_net_conf = NULL; |
2178 | struct crypto crypto = { }; | 2230 | struct crypto crypto = { }; |
@@ -2182,14 +2234,14 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info) | |||
2182 | int i; | 2234 | int i; |
2183 | int err; | 2235 | int err; |
2184 | 2236 | ||
2185 | retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_RESOURCE); | 2237 | retcode = drbd_adm_prepare(&adm_ctx, skb, info, DRBD_ADM_NEED_RESOURCE); |
2186 | 2238 | ||
2187 | if (!adm_ctx.reply_skb) | 2239 | if (!adm_ctx.reply_skb) |
2188 | return retcode; | 2240 | return retcode; |
2189 | if (retcode != NO_ERROR) | 2241 | if (retcode != NO_ERROR) |
2190 | goto out; | 2242 | goto out; |
2191 | if (!(adm_ctx.my_addr && adm_ctx.peer_addr)) { | 2243 | if (!(adm_ctx.my_addr && adm_ctx.peer_addr)) { |
2192 | drbd_msg_put_info("connection endpoint(s) missing"); | 2244 | drbd_msg_put_info(adm_ctx.reply_skb, "connection endpoint(s) missing"); |
2193 | retcode = ERR_INVALID_REQUEST; | 2245 | retcode = ERR_INVALID_REQUEST; |
2194 | goto out; | 2246 | goto out; |
2195 | } | 2247 | } |
@@ -2215,6 +2267,7 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info) | |||
2215 | } | 2267 | } |
2216 | } | 2268 | } |
2217 | 2269 | ||
2270 | mutex_lock(&adm_ctx.resource->adm_mutex); | ||
2218 | connection = first_connection(adm_ctx.resource); | 2271 | connection = first_connection(adm_ctx.resource); |
2219 | conn_reconfig_start(connection); | 2272 | conn_reconfig_start(connection); |
2220 | 2273 | ||
@@ -2235,7 +2288,7 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info) | |||
2235 | err = net_conf_from_attrs(new_net_conf, info); | 2288 | err = net_conf_from_attrs(new_net_conf, info); |
2236 | if (err && err != -ENOMSG) { | 2289 | if (err && err != -ENOMSG) { |
2237 | retcode = ERR_MANDATORY_TAG; | 2290 | retcode = ERR_MANDATORY_TAG; |
2238 | drbd_msg_put_info(from_attrs_err_to_txt(err)); | 2291 | drbd_msg_put_info(adm_ctx.reply_skb, from_attrs_err_to_txt(err)); |
2239 | goto fail; | 2292 | goto fail; |
2240 | } | 2293 | } |
2241 | 2294 | ||
@@ -2284,7 +2337,8 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info) | |||
2284 | retcode = conn_request_state(connection, NS(conn, C_UNCONNECTED), CS_VERBOSE); | 2337 | retcode = conn_request_state(connection, NS(conn, C_UNCONNECTED), CS_VERBOSE); |
2285 | 2338 | ||
2286 | conn_reconfig_done(connection); | 2339 | conn_reconfig_done(connection); |
2287 | drbd_adm_finish(info, retcode); | 2340 | mutex_unlock(&adm_ctx.resource->adm_mutex); |
2341 | drbd_adm_finish(&adm_ctx, info, retcode); | ||
2288 | return 0; | 2342 | return 0; |
2289 | 2343 | ||
2290 | fail: | 2344 | fail: |
@@ -2292,8 +2346,9 @@ fail: | |||
2292 | kfree(new_net_conf); | 2346 | kfree(new_net_conf); |
2293 | 2347 | ||
2294 | conn_reconfig_done(connection); | 2348 | conn_reconfig_done(connection); |
2349 | mutex_unlock(&adm_ctx.resource->adm_mutex); | ||
2295 | out: | 2350 | out: |
2296 | drbd_adm_finish(info, retcode); | 2351 | drbd_adm_finish(&adm_ctx, info, retcode); |
2297 | return 0; | 2352 | return 0; |
2298 | } | 2353 | } |
2299 | 2354 | ||
@@ -2356,13 +2411,14 @@ static enum drbd_state_rv conn_try_disconnect(struct drbd_connection *connection | |||
2356 | 2411 | ||
2357 | int drbd_adm_disconnect(struct sk_buff *skb, struct genl_info *info) | 2412 | int drbd_adm_disconnect(struct sk_buff *skb, struct genl_info *info) |
2358 | { | 2413 | { |
2414 | struct drbd_config_context adm_ctx; | ||
2359 | struct disconnect_parms parms; | 2415 | struct disconnect_parms parms; |
2360 | struct drbd_connection *connection; | 2416 | struct drbd_connection *connection; |
2361 | enum drbd_state_rv rv; | 2417 | enum drbd_state_rv rv; |
2362 | enum drbd_ret_code retcode; | 2418 | enum drbd_ret_code retcode; |
2363 | int err; | 2419 | int err; |
2364 | 2420 | ||
2365 | retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_CONNECTION); | 2421 | retcode = drbd_adm_prepare(&adm_ctx, skb, info, DRBD_ADM_NEED_CONNECTION); |
2366 | if (!adm_ctx.reply_skb) | 2422 | if (!adm_ctx.reply_skb) |
2367 | return retcode; | 2423 | return retcode; |
2368 | if (retcode != NO_ERROR) | 2424 | if (retcode != NO_ERROR) |
@@ -2374,18 +2430,20 @@ int drbd_adm_disconnect(struct sk_buff *skb, struct genl_info *info) | |||
2374 | err = disconnect_parms_from_attrs(&parms, info); | 2430 | err = disconnect_parms_from_attrs(&parms, info); |
2375 | if (err) { | 2431 | if (err) { |
2376 | retcode = ERR_MANDATORY_TAG; | 2432 | retcode = ERR_MANDATORY_TAG; |
2377 | drbd_msg_put_info(from_attrs_err_to_txt(err)); | 2433 | drbd_msg_put_info(adm_ctx.reply_skb, from_attrs_err_to_txt(err)); |
2378 | goto fail; | 2434 | goto fail; |
2379 | } | 2435 | } |
2380 | } | 2436 | } |
2381 | 2437 | ||
2438 | mutex_lock(&adm_ctx.resource->adm_mutex); | ||
2382 | rv = conn_try_disconnect(connection, parms.force_disconnect); | 2439 | rv = conn_try_disconnect(connection, parms.force_disconnect); |
2383 | if (rv < SS_SUCCESS) | 2440 | if (rv < SS_SUCCESS) |
2384 | retcode = rv; /* FIXME: Type mismatch. */ | 2441 | retcode = rv; /* FIXME: Type mismatch. */ |
2385 | else | 2442 | else |
2386 | retcode = NO_ERROR; | 2443 | retcode = NO_ERROR; |
2444 | mutex_unlock(&adm_ctx.resource->adm_mutex); | ||
2387 | fail: | 2445 | fail: |
2388 | drbd_adm_finish(info, retcode); | 2446 | drbd_adm_finish(&adm_ctx, info, retcode); |
2389 | return 0; | 2447 | return 0; |
2390 | } | 2448 | } |
2391 | 2449 | ||
@@ -2407,6 +2465,7 @@ void resync_after_online_grow(struct drbd_device *device) | |||
2407 | 2465 | ||
2408 | int drbd_adm_resize(struct sk_buff *skb, struct genl_info *info) | 2466 | int drbd_adm_resize(struct sk_buff *skb, struct genl_info *info) |
2409 | { | 2467 | { |
2468 | struct drbd_config_context adm_ctx; | ||
2410 | struct disk_conf *old_disk_conf, *new_disk_conf = NULL; | 2469 | struct disk_conf *old_disk_conf, *new_disk_conf = NULL; |
2411 | struct resize_parms rs; | 2470 | struct resize_parms rs; |
2412 | struct drbd_device *device; | 2471 | struct drbd_device *device; |
@@ -2417,12 +2476,13 @@ int drbd_adm_resize(struct sk_buff *skb, struct genl_info *info) | |||
2417 | sector_t u_size; | 2476 | sector_t u_size; |
2418 | int err; | 2477 | int err; |
2419 | 2478 | ||
2420 | retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR); | 2479 | retcode = drbd_adm_prepare(&adm_ctx, skb, info, DRBD_ADM_NEED_MINOR); |
2421 | if (!adm_ctx.reply_skb) | 2480 | if (!adm_ctx.reply_skb) |
2422 | return retcode; | 2481 | return retcode; |
2423 | if (retcode != NO_ERROR) | 2482 | if (retcode != NO_ERROR) |
2424 | goto fail; | 2483 | goto finish; |
2425 | 2484 | ||
2485 | mutex_lock(&adm_ctx.resource->adm_mutex); | ||
2426 | device = adm_ctx.device; | 2486 | device = adm_ctx.device; |
2427 | if (!get_ldev(device)) { | 2487 | if (!get_ldev(device)) { |
2428 | retcode = ERR_NO_DISK; | 2488 | retcode = ERR_NO_DISK; |
@@ -2436,7 +2496,7 @@ int drbd_adm_resize(struct sk_buff *skb, struct genl_info *info) | |||
2436 | err = resize_parms_from_attrs(&rs, info); | 2496 | err = resize_parms_from_attrs(&rs, info); |
2437 | if (err) { | 2497 | if (err) { |
2438 | retcode = ERR_MANDATORY_TAG; | 2498 | retcode = ERR_MANDATORY_TAG; |
2439 | drbd_msg_put_info(from_attrs_err_to_txt(err)); | 2499 | drbd_msg_put_info(adm_ctx.reply_skb, from_attrs_err_to_txt(err)); |
2440 | goto fail_ldev; | 2500 | goto fail_ldev; |
2441 | } | 2501 | } |
2442 | } | 2502 | } |
@@ -2482,7 +2542,7 @@ int drbd_adm_resize(struct sk_buff *skb, struct genl_info *info) | |||
2482 | goto fail_ldev; | 2542 | goto fail_ldev; |
2483 | } | 2543 | } |
2484 | 2544 | ||
2485 | if (device->state.conn != C_CONNECTED) { | 2545 | if (device->state.conn != C_CONNECTED && !rs.resize_force) { |
2486 | retcode = ERR_MD_LAYOUT_CONNECTED; | 2546 | retcode = ERR_MD_LAYOUT_CONNECTED; |
2487 | goto fail_ldev; | 2547 | goto fail_ldev; |
2488 | } | 2548 | } |
@@ -2528,7 +2588,9 @@ int drbd_adm_resize(struct sk_buff *skb, struct genl_info *info) | |||
2528 | } | 2588 | } |
2529 | 2589 | ||
2530 | fail: | 2590 | fail: |
2531 | drbd_adm_finish(info, retcode); | 2591 | mutex_unlock(&adm_ctx.resource->adm_mutex); |
2592 | finish: | ||
2593 | drbd_adm_finish(&adm_ctx, info, retcode); | ||
2532 | return 0; | 2594 | return 0; |
2533 | 2595 | ||
2534 | fail_ldev: | 2596 | fail_ldev: |
@@ -2538,11 +2600,12 @@ int drbd_adm_resize(struct sk_buff *skb, struct genl_info *info) | |||
2538 | 2600 | ||
2539 | int drbd_adm_resource_opts(struct sk_buff *skb, struct genl_info *info) | 2601 | int drbd_adm_resource_opts(struct sk_buff *skb, struct genl_info *info) |
2540 | { | 2602 | { |
2603 | struct drbd_config_context adm_ctx; | ||
2541 | enum drbd_ret_code retcode; | 2604 | enum drbd_ret_code retcode; |
2542 | struct res_opts res_opts; | 2605 | struct res_opts res_opts; |
2543 | int err; | 2606 | int err; |
2544 | 2607 | ||
2545 | retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_RESOURCE); | 2608 | retcode = drbd_adm_prepare(&adm_ctx, skb, info, DRBD_ADM_NEED_RESOURCE); |
2546 | if (!adm_ctx.reply_skb) | 2609 | if (!adm_ctx.reply_skb) |
2547 | return retcode; | 2610 | return retcode; |
2548 | if (retcode != NO_ERROR) | 2611 | if (retcode != NO_ERROR) |
@@ -2555,33 +2618,37 @@ int drbd_adm_resource_opts(struct sk_buff *skb, struct genl_info *info) | |||
2555 | err = res_opts_from_attrs(&res_opts, info); | 2618 | err = res_opts_from_attrs(&res_opts, info); |
2556 | if (err && err != -ENOMSG) { | 2619 | if (err && err != -ENOMSG) { |
2557 | retcode = ERR_MANDATORY_TAG; | 2620 | retcode = ERR_MANDATORY_TAG; |
2558 | drbd_msg_put_info(from_attrs_err_to_txt(err)); | 2621 | drbd_msg_put_info(adm_ctx.reply_skb, from_attrs_err_to_txt(err)); |
2559 | goto fail; | 2622 | goto fail; |
2560 | } | 2623 | } |
2561 | 2624 | ||
2625 | mutex_lock(&adm_ctx.resource->adm_mutex); | ||
2562 | err = set_resource_options(adm_ctx.resource, &res_opts); | 2626 | err = set_resource_options(adm_ctx.resource, &res_opts); |
2563 | if (err) { | 2627 | if (err) { |
2564 | retcode = ERR_INVALID_REQUEST; | 2628 | retcode = ERR_INVALID_REQUEST; |
2565 | if (err == -ENOMEM) | 2629 | if (err == -ENOMEM) |
2566 | retcode = ERR_NOMEM; | 2630 | retcode = ERR_NOMEM; |
2567 | } | 2631 | } |
2632 | mutex_unlock(&adm_ctx.resource->adm_mutex); | ||
2568 | 2633 | ||
2569 | fail: | 2634 | fail: |
2570 | drbd_adm_finish(info, retcode); | 2635 | drbd_adm_finish(&adm_ctx, info, retcode); |
2571 | return 0; | 2636 | return 0; |
2572 | } | 2637 | } |
2573 | 2638 | ||
2574 | int drbd_adm_invalidate(struct sk_buff *skb, struct genl_info *info) | 2639 | int drbd_adm_invalidate(struct sk_buff *skb, struct genl_info *info) |
2575 | { | 2640 | { |
2641 | struct drbd_config_context adm_ctx; | ||
2576 | struct drbd_device *device; | 2642 | struct drbd_device *device; |
2577 | int retcode; /* enum drbd_ret_code rsp. enum drbd_state_rv */ | 2643 | int retcode; /* enum drbd_ret_code rsp. enum drbd_state_rv */ |
2578 | 2644 | ||
2579 | retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR); | 2645 | retcode = drbd_adm_prepare(&adm_ctx, skb, info, DRBD_ADM_NEED_MINOR); |
2580 | if (!adm_ctx.reply_skb) | 2646 | if (!adm_ctx.reply_skb) |
2581 | return retcode; | 2647 | return retcode; |
2582 | if (retcode != NO_ERROR) | 2648 | if (retcode != NO_ERROR) |
2583 | goto out; | 2649 | goto out; |
2584 | 2650 | ||
2651 | mutex_lock(&adm_ctx.resource->adm_mutex); | ||
2585 | device = adm_ctx.device; | 2652 | device = adm_ctx.device; |
2586 | 2653 | ||
2587 | /* If there is still bitmap IO pending, probably because of a previous | 2654 | /* If there is still bitmap IO pending, probably because of a previous |
@@ -2605,26 +2672,29 @@ int drbd_adm_invalidate(struct sk_buff *skb, struct genl_info *info) | |||
2605 | } else | 2672 | } else |
2606 | retcode = drbd_request_state(device, NS(conn, C_STARTING_SYNC_T)); | 2673 | retcode = drbd_request_state(device, NS(conn, C_STARTING_SYNC_T)); |
2607 | drbd_resume_io(device); | 2674 | drbd_resume_io(device); |
2608 | 2675 | mutex_unlock(&adm_ctx.resource->adm_mutex); | |
2609 | out: | 2676 | out: |
2610 | drbd_adm_finish(info, retcode); | 2677 | drbd_adm_finish(&adm_ctx, info, retcode); |
2611 | return 0; | 2678 | return 0; |
2612 | } | 2679 | } |
2613 | 2680 | ||
2614 | static int drbd_adm_simple_request_state(struct sk_buff *skb, struct genl_info *info, | 2681 | static int drbd_adm_simple_request_state(struct sk_buff *skb, struct genl_info *info, |
2615 | union drbd_state mask, union drbd_state val) | 2682 | union drbd_state mask, union drbd_state val) |
2616 | { | 2683 | { |
2684 | struct drbd_config_context adm_ctx; | ||
2617 | enum drbd_ret_code retcode; | 2685 | enum drbd_ret_code retcode; |
2618 | 2686 | ||
2619 | retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR); | 2687 | retcode = drbd_adm_prepare(&adm_ctx, skb, info, DRBD_ADM_NEED_MINOR); |
2620 | if (!adm_ctx.reply_skb) | 2688 | if (!adm_ctx.reply_skb) |
2621 | return retcode; | 2689 | return retcode; |
2622 | if (retcode != NO_ERROR) | 2690 | if (retcode != NO_ERROR) |
2623 | goto out; | 2691 | goto out; |
2624 | 2692 | ||
2693 | mutex_lock(&adm_ctx.resource->adm_mutex); | ||
2625 | retcode = drbd_request_state(adm_ctx.device, mask, val); | 2694 | retcode = drbd_request_state(adm_ctx.device, mask, val); |
2695 | mutex_unlock(&adm_ctx.resource->adm_mutex); | ||
2626 | out: | 2696 | out: |
2627 | drbd_adm_finish(info, retcode); | 2697 | drbd_adm_finish(&adm_ctx, info, retcode); |
2628 | return 0; | 2698 | return 0; |
2629 | } | 2699 | } |
2630 | 2700 | ||
@@ -2639,15 +2709,17 @@ static int drbd_bmio_set_susp_al(struct drbd_device *device) | |||
2639 | 2709 | ||
2640 | int drbd_adm_invalidate_peer(struct sk_buff *skb, struct genl_info *info) | 2710 | int drbd_adm_invalidate_peer(struct sk_buff *skb, struct genl_info *info) |
2641 | { | 2711 | { |
2712 | struct drbd_config_context adm_ctx; | ||
2642 | int retcode; /* drbd_ret_code, drbd_state_rv */ | 2713 | int retcode; /* drbd_ret_code, drbd_state_rv */ |
2643 | struct drbd_device *device; | 2714 | struct drbd_device *device; |
2644 | 2715 | ||
2645 | retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR); | 2716 | retcode = drbd_adm_prepare(&adm_ctx, skb, info, DRBD_ADM_NEED_MINOR); |
2646 | if (!adm_ctx.reply_skb) | 2717 | if (!adm_ctx.reply_skb) |
2647 | return retcode; | 2718 | return retcode; |
2648 | if (retcode != NO_ERROR) | 2719 | if (retcode != NO_ERROR) |
2649 | goto out; | 2720 | goto out; |
2650 | 2721 | ||
2722 | mutex_lock(&adm_ctx.resource->adm_mutex); | ||
2651 | device = adm_ctx.device; | 2723 | device = adm_ctx.device; |
2652 | 2724 | ||
2653 | /* If there is still bitmap IO pending, probably because of a previous | 2725 | /* If there is still bitmap IO pending, probably because of a previous |
@@ -2674,40 +2746,45 @@ int drbd_adm_invalidate_peer(struct sk_buff *skb, struct genl_info *info) | |||
2674 | } else | 2746 | } else |
2675 | retcode = drbd_request_state(device, NS(conn, C_STARTING_SYNC_S)); | 2747 | retcode = drbd_request_state(device, NS(conn, C_STARTING_SYNC_S)); |
2676 | drbd_resume_io(device); | 2748 | drbd_resume_io(device); |
2677 | 2749 | mutex_unlock(&adm_ctx.resource->adm_mutex); | |
2678 | out: | 2750 | out: |
2679 | drbd_adm_finish(info, retcode); | 2751 | drbd_adm_finish(&adm_ctx, info, retcode); |
2680 | return 0; | 2752 | return 0; |
2681 | } | 2753 | } |
2682 | 2754 | ||
2683 | int drbd_adm_pause_sync(struct sk_buff *skb, struct genl_info *info) | 2755 | int drbd_adm_pause_sync(struct sk_buff *skb, struct genl_info *info) |
2684 | { | 2756 | { |
2757 | struct drbd_config_context adm_ctx; | ||
2685 | enum drbd_ret_code retcode; | 2758 | enum drbd_ret_code retcode; |
2686 | 2759 | ||
2687 | retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR); | 2760 | retcode = drbd_adm_prepare(&adm_ctx, skb, info, DRBD_ADM_NEED_MINOR); |
2688 | if (!adm_ctx.reply_skb) | 2761 | if (!adm_ctx.reply_skb) |
2689 | return retcode; | 2762 | return retcode; |
2690 | if (retcode != NO_ERROR) | 2763 | if (retcode != NO_ERROR) |
2691 | goto out; | 2764 | goto out; |
2692 | 2765 | ||
2766 | mutex_lock(&adm_ctx.resource->adm_mutex); | ||
2693 | if (drbd_request_state(adm_ctx.device, NS(user_isp, 1)) == SS_NOTHING_TO_DO) | 2767 | if (drbd_request_state(adm_ctx.device, NS(user_isp, 1)) == SS_NOTHING_TO_DO) |
2694 | retcode = ERR_PAUSE_IS_SET; | 2768 | retcode = ERR_PAUSE_IS_SET; |
2769 | mutex_unlock(&adm_ctx.resource->adm_mutex); | ||
2695 | out: | 2770 | out: |
2696 | drbd_adm_finish(info, retcode); | 2771 | drbd_adm_finish(&adm_ctx, info, retcode); |
2697 | return 0; | 2772 | return 0; |
2698 | } | 2773 | } |
2699 | 2774 | ||
2700 | int drbd_adm_resume_sync(struct sk_buff *skb, struct genl_info *info) | 2775 | int drbd_adm_resume_sync(struct sk_buff *skb, struct genl_info *info) |
2701 | { | 2776 | { |
2777 | struct drbd_config_context adm_ctx; | ||
2702 | union drbd_dev_state s; | 2778 | union drbd_dev_state s; |
2703 | enum drbd_ret_code retcode; | 2779 | enum drbd_ret_code retcode; |
2704 | 2780 | ||
2705 | retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR); | 2781 | retcode = drbd_adm_prepare(&adm_ctx, skb, info, DRBD_ADM_NEED_MINOR); |
2706 | if (!adm_ctx.reply_skb) | 2782 | if (!adm_ctx.reply_skb) |
2707 | return retcode; | 2783 | return retcode; |
2708 | if (retcode != NO_ERROR) | 2784 | if (retcode != NO_ERROR) |
2709 | goto out; | 2785 | goto out; |
2710 | 2786 | ||
2787 | mutex_lock(&adm_ctx.resource->adm_mutex); | ||
2711 | if (drbd_request_state(adm_ctx.device, NS(user_isp, 0)) == SS_NOTHING_TO_DO) { | 2788 | if (drbd_request_state(adm_ctx.device, NS(user_isp, 0)) == SS_NOTHING_TO_DO) { |
2712 | s = adm_ctx.device->state; | 2789 | s = adm_ctx.device->state; |
2713 | if (s.conn == C_PAUSED_SYNC_S || s.conn == C_PAUSED_SYNC_T) { | 2790 | if (s.conn == C_PAUSED_SYNC_S || s.conn == C_PAUSED_SYNC_T) { |
@@ -2717,9 +2794,9 @@ int drbd_adm_resume_sync(struct sk_buff *skb, struct genl_info *info) | |||
2717 | retcode = ERR_PAUSE_IS_CLEAR; | 2794 | retcode = ERR_PAUSE_IS_CLEAR; |
2718 | } | 2795 | } |
2719 | } | 2796 | } |
2720 | 2797 | mutex_unlock(&adm_ctx.resource->adm_mutex); | |
2721 | out: | 2798 | out: |
2722 | drbd_adm_finish(info, retcode); | 2799 | drbd_adm_finish(&adm_ctx, info, retcode); |
2723 | return 0; | 2800 | return 0; |
2724 | } | 2801 | } |
2725 | 2802 | ||
@@ -2730,15 +2807,17 @@ int drbd_adm_suspend_io(struct sk_buff *skb, struct genl_info *info) | |||
2730 | 2807 | ||
2731 | int drbd_adm_resume_io(struct sk_buff *skb, struct genl_info *info) | 2808 | int drbd_adm_resume_io(struct sk_buff *skb, struct genl_info *info) |
2732 | { | 2809 | { |
2810 | struct drbd_config_context adm_ctx; | ||
2733 | struct drbd_device *device; | 2811 | struct drbd_device *device; |
2734 | int retcode; /* enum drbd_ret_code rsp. enum drbd_state_rv */ | 2812 | int retcode; /* enum drbd_ret_code rsp. enum drbd_state_rv */ |
2735 | 2813 | ||
2736 | retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR); | 2814 | retcode = drbd_adm_prepare(&adm_ctx, skb, info, DRBD_ADM_NEED_MINOR); |
2737 | if (!adm_ctx.reply_skb) | 2815 | if (!adm_ctx.reply_skb) |
2738 | return retcode; | 2816 | return retcode; |
2739 | if (retcode != NO_ERROR) | 2817 | if (retcode != NO_ERROR) |
2740 | goto out; | 2818 | goto out; |
2741 | 2819 | ||
2820 | mutex_lock(&adm_ctx.resource->adm_mutex); | ||
2742 | device = adm_ctx.device; | 2821 | device = adm_ctx.device; |
2743 | if (test_bit(NEW_CUR_UUID, &device->flags)) { | 2822 | if (test_bit(NEW_CUR_UUID, &device->flags)) { |
2744 | drbd_uuid_new_current(device); | 2823 | drbd_uuid_new_current(device); |
@@ -2753,9 +2832,9 @@ int drbd_adm_resume_io(struct sk_buff *skb, struct genl_info *info) | |||
2753 | tl_restart(first_peer_device(device)->connection, FAIL_FROZEN_DISK_IO); | 2832 | tl_restart(first_peer_device(device)->connection, FAIL_FROZEN_DISK_IO); |
2754 | } | 2833 | } |
2755 | drbd_resume_io(device); | 2834 | drbd_resume_io(device); |
2756 | 2835 | mutex_unlock(&adm_ctx.resource->adm_mutex); | |
2757 | out: | 2836 | out: |
2758 | drbd_adm_finish(info, retcode); | 2837 | drbd_adm_finish(&adm_ctx, info, retcode); |
2759 | return 0; | 2838 | return 0; |
2760 | } | 2839 | } |
2761 | 2840 | ||
@@ -2931,10 +3010,11 @@ nla_put_failure: | |||
2931 | 3010 | ||
2932 | int drbd_adm_get_status(struct sk_buff *skb, struct genl_info *info) | 3011 | int drbd_adm_get_status(struct sk_buff *skb, struct genl_info *info) |
2933 | { | 3012 | { |
3013 | struct drbd_config_context adm_ctx; | ||
2934 | enum drbd_ret_code retcode; | 3014 | enum drbd_ret_code retcode; |
2935 | int err; | 3015 | int err; |
2936 | 3016 | ||
2937 | retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR); | 3017 | retcode = drbd_adm_prepare(&adm_ctx, skb, info, DRBD_ADM_NEED_MINOR); |
2938 | if (!adm_ctx.reply_skb) | 3018 | if (!adm_ctx.reply_skb) |
2939 | return retcode; | 3019 | return retcode; |
2940 | if (retcode != NO_ERROR) | 3020 | if (retcode != NO_ERROR) |
@@ -2946,7 +3026,7 @@ int drbd_adm_get_status(struct sk_buff *skb, struct genl_info *info) | |||
2946 | return err; | 3026 | return err; |
2947 | } | 3027 | } |
2948 | out: | 3028 | out: |
2949 | drbd_adm_finish(info, retcode); | 3029 | drbd_adm_finish(&adm_ctx, info, retcode); |
2950 | return 0; | 3030 | return 0; |
2951 | } | 3031 | } |
2952 | 3032 | ||
@@ -3133,11 +3213,12 @@ dump: | |||
3133 | 3213 | ||
3134 | int drbd_adm_get_timeout_type(struct sk_buff *skb, struct genl_info *info) | 3214 | int drbd_adm_get_timeout_type(struct sk_buff *skb, struct genl_info *info) |
3135 | { | 3215 | { |
3216 | struct drbd_config_context adm_ctx; | ||
3136 | enum drbd_ret_code retcode; | 3217 | enum drbd_ret_code retcode; |
3137 | struct timeout_parms tp; | 3218 | struct timeout_parms tp; |
3138 | int err; | 3219 | int err; |
3139 | 3220 | ||
3140 | retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR); | 3221 | retcode = drbd_adm_prepare(&adm_ctx, skb, info, DRBD_ADM_NEED_MINOR); |
3141 | if (!adm_ctx.reply_skb) | 3222 | if (!adm_ctx.reply_skb) |
3142 | return retcode; | 3223 | return retcode; |
3143 | if (retcode != NO_ERROR) | 3224 | if (retcode != NO_ERROR) |
@@ -3154,17 +3235,18 @@ int drbd_adm_get_timeout_type(struct sk_buff *skb, struct genl_info *info) | |||
3154 | return err; | 3235 | return err; |
3155 | } | 3236 | } |
3156 | out: | 3237 | out: |
3157 | drbd_adm_finish(info, retcode); | 3238 | drbd_adm_finish(&adm_ctx, info, retcode); |
3158 | return 0; | 3239 | return 0; |
3159 | } | 3240 | } |
3160 | 3241 | ||
3161 | int drbd_adm_start_ov(struct sk_buff *skb, struct genl_info *info) | 3242 | int drbd_adm_start_ov(struct sk_buff *skb, struct genl_info *info) |
3162 | { | 3243 | { |
3244 | struct drbd_config_context adm_ctx; | ||
3163 | struct drbd_device *device; | 3245 | struct drbd_device *device; |
3164 | enum drbd_ret_code retcode; | 3246 | enum drbd_ret_code retcode; |
3165 | struct start_ov_parms parms; | 3247 | struct start_ov_parms parms; |
3166 | 3248 | ||
3167 | retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR); | 3249 | retcode = drbd_adm_prepare(&adm_ctx, skb, info, DRBD_ADM_NEED_MINOR); |
3168 | if (!adm_ctx.reply_skb) | 3250 | if (!adm_ctx.reply_skb) |
3169 | return retcode; | 3251 | return retcode; |
3170 | if (retcode != NO_ERROR) | 3252 | if (retcode != NO_ERROR) |
@@ -3179,10 +3261,12 @@ int drbd_adm_start_ov(struct sk_buff *skb, struct genl_info *info) | |||
3179 | int err = start_ov_parms_from_attrs(&parms, info); | 3261 | int err = start_ov_parms_from_attrs(&parms, info); |
3180 | if (err) { | 3262 | if (err) { |
3181 | retcode = ERR_MANDATORY_TAG; | 3263 | retcode = ERR_MANDATORY_TAG; |
3182 | drbd_msg_put_info(from_attrs_err_to_txt(err)); | 3264 | drbd_msg_put_info(adm_ctx.reply_skb, from_attrs_err_to_txt(err)); |
3183 | goto out; | 3265 | goto out; |
3184 | } | 3266 | } |
3185 | } | 3267 | } |
3268 | mutex_lock(&adm_ctx.resource->adm_mutex); | ||
3269 | |||
3186 | /* w_make_ov_request expects position to be aligned */ | 3270 | /* w_make_ov_request expects position to be aligned */ |
3187 | device->ov_start_sector = parms.ov_start_sector & ~(BM_SECT_PER_BIT-1); | 3271 | device->ov_start_sector = parms.ov_start_sector & ~(BM_SECT_PER_BIT-1); |
3188 | device->ov_stop_sector = parms.ov_stop_sector; | 3272 | device->ov_stop_sector = parms.ov_stop_sector; |
@@ -3193,21 +3277,24 @@ int drbd_adm_start_ov(struct sk_buff *skb, struct genl_info *info) | |||
3193 | wait_event(device->misc_wait, !test_bit(BITMAP_IO, &device->flags)); | 3277 | wait_event(device->misc_wait, !test_bit(BITMAP_IO, &device->flags)); |
3194 | retcode = drbd_request_state(device, NS(conn, C_VERIFY_S)); | 3278 | retcode = drbd_request_state(device, NS(conn, C_VERIFY_S)); |
3195 | drbd_resume_io(device); | 3279 | drbd_resume_io(device); |
3280 | |||
3281 | mutex_unlock(&adm_ctx.resource->adm_mutex); | ||
3196 | out: | 3282 | out: |
3197 | drbd_adm_finish(info, retcode); | 3283 | drbd_adm_finish(&adm_ctx, info, retcode); |
3198 | return 0; | 3284 | return 0; |
3199 | } | 3285 | } |
3200 | 3286 | ||
3201 | 3287 | ||
3202 | int drbd_adm_new_c_uuid(struct sk_buff *skb, struct genl_info *info) | 3288 | int drbd_adm_new_c_uuid(struct sk_buff *skb, struct genl_info *info) |
3203 | { | 3289 | { |
3290 | struct drbd_config_context adm_ctx; | ||
3204 | struct drbd_device *device; | 3291 | struct drbd_device *device; |
3205 | enum drbd_ret_code retcode; | 3292 | enum drbd_ret_code retcode; |
3206 | int skip_initial_sync = 0; | 3293 | int skip_initial_sync = 0; |
3207 | int err; | 3294 | int err; |
3208 | struct new_c_uuid_parms args; | 3295 | struct new_c_uuid_parms args; |
3209 | 3296 | ||
3210 | retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR); | 3297 | retcode = drbd_adm_prepare(&adm_ctx, skb, info, DRBD_ADM_NEED_MINOR); |
3211 | if (!adm_ctx.reply_skb) | 3298 | if (!adm_ctx.reply_skb) |
3212 | return retcode; | 3299 | return retcode; |
3213 | if (retcode != NO_ERROR) | 3300 | if (retcode != NO_ERROR) |
@@ -3219,11 +3306,12 @@ int drbd_adm_new_c_uuid(struct sk_buff *skb, struct genl_info *info) | |||
3219 | err = new_c_uuid_parms_from_attrs(&args, info); | 3306 | err = new_c_uuid_parms_from_attrs(&args, info); |
3220 | if (err) { | 3307 | if (err) { |
3221 | retcode = ERR_MANDATORY_TAG; | 3308 | retcode = ERR_MANDATORY_TAG; |
3222 | drbd_msg_put_info(from_attrs_err_to_txt(err)); | 3309 | drbd_msg_put_info(adm_ctx.reply_skb, from_attrs_err_to_txt(err)); |
3223 | goto out_nolock; | 3310 | goto out_nolock; |
3224 | } | 3311 | } |
3225 | } | 3312 | } |
3226 | 3313 | ||
3314 | mutex_lock(&adm_ctx.resource->adm_mutex); | ||
3227 | mutex_lock(device->state_mutex); /* Protects us against serialized state changes. */ | 3315 | mutex_lock(device->state_mutex); /* Protects us against serialized state changes. */ |
3228 | 3316 | ||
3229 | if (!get_ldev(device)) { | 3317 | if (!get_ldev(device)) { |
@@ -3268,22 +3356,24 @@ out_dec: | |||
3268 | put_ldev(device); | 3356 | put_ldev(device); |
3269 | out: | 3357 | out: |
3270 | mutex_unlock(device->state_mutex); | 3358 | mutex_unlock(device->state_mutex); |
3359 | mutex_unlock(&adm_ctx.resource->adm_mutex); | ||
3271 | out_nolock: | 3360 | out_nolock: |
3272 | drbd_adm_finish(info, retcode); | 3361 | drbd_adm_finish(&adm_ctx, info, retcode); |
3273 | return 0; | 3362 | return 0; |
3274 | } | 3363 | } |
3275 | 3364 | ||
3276 | static enum drbd_ret_code | 3365 | static enum drbd_ret_code |
3277 | drbd_check_resource_name(const char *name) | 3366 | drbd_check_resource_name(struct drbd_config_context *adm_ctx) |
3278 | { | 3367 | { |
3368 | const char *name = adm_ctx->resource_name; | ||
3279 | if (!name || !name[0]) { | 3369 | if (!name || !name[0]) { |
3280 | drbd_msg_put_info("resource name missing"); | 3370 | drbd_msg_put_info(adm_ctx->reply_skb, "resource name missing"); |
3281 | return ERR_MANDATORY_TAG; | 3371 | return ERR_MANDATORY_TAG; |
3282 | } | 3372 | } |
3283 | /* if we want to use these in sysfs/configfs/debugfs some day, | 3373 | /* if we want to use these in sysfs/configfs/debugfs some day, |
3284 | * we must not allow slashes */ | 3374 | * we must not allow slashes */ |
3285 | if (strchr(name, '/')) { | 3375 | if (strchr(name, '/')) { |
3286 | drbd_msg_put_info("invalid resource name"); | 3376 | drbd_msg_put_info(adm_ctx->reply_skb, "invalid resource name"); |
3287 | return ERR_INVALID_REQUEST; | 3377 | return ERR_INVALID_REQUEST; |
3288 | } | 3378 | } |
3289 | return NO_ERROR; | 3379 | return NO_ERROR; |
@@ -3291,11 +3381,12 @@ drbd_check_resource_name(const char *name) | |||
3291 | 3381 | ||
3292 | int drbd_adm_new_resource(struct sk_buff *skb, struct genl_info *info) | 3382 | int drbd_adm_new_resource(struct sk_buff *skb, struct genl_info *info) |
3293 | { | 3383 | { |
3384 | struct drbd_config_context adm_ctx; | ||
3294 | enum drbd_ret_code retcode; | 3385 | enum drbd_ret_code retcode; |
3295 | struct res_opts res_opts; | 3386 | struct res_opts res_opts; |
3296 | int err; | 3387 | int err; |
3297 | 3388 | ||
3298 | retcode = drbd_adm_prepare(skb, info, 0); | 3389 | retcode = drbd_adm_prepare(&adm_ctx, skb, info, 0); |
3299 | if (!adm_ctx.reply_skb) | 3390 | if (!adm_ctx.reply_skb) |
3300 | return retcode; | 3391 | return retcode; |
3301 | if (retcode != NO_ERROR) | 3392 | if (retcode != NO_ERROR) |
@@ -3305,48 +3396,50 @@ int drbd_adm_new_resource(struct sk_buff *skb, struct genl_info *info) | |||
3305 | err = res_opts_from_attrs(&res_opts, info); | 3396 | err = res_opts_from_attrs(&res_opts, info); |
3306 | if (err && err != -ENOMSG) { | 3397 | if (err && err != -ENOMSG) { |
3307 | retcode = ERR_MANDATORY_TAG; | 3398 | retcode = ERR_MANDATORY_TAG; |
3308 | drbd_msg_put_info(from_attrs_err_to_txt(err)); | 3399 | drbd_msg_put_info(adm_ctx.reply_skb, from_attrs_err_to_txt(err)); |
3309 | goto out; | 3400 | goto out; |
3310 | } | 3401 | } |
3311 | 3402 | ||
3312 | retcode = drbd_check_resource_name(adm_ctx.resource_name); | 3403 | retcode = drbd_check_resource_name(&adm_ctx); |
3313 | if (retcode != NO_ERROR) | 3404 | if (retcode != NO_ERROR) |
3314 | goto out; | 3405 | goto out; |
3315 | 3406 | ||
3316 | if (adm_ctx.resource) { | 3407 | if (adm_ctx.resource) { |
3317 | if (info->nlhdr->nlmsg_flags & NLM_F_EXCL) { | 3408 | if (info->nlhdr->nlmsg_flags & NLM_F_EXCL) { |
3318 | retcode = ERR_INVALID_REQUEST; | 3409 | retcode = ERR_INVALID_REQUEST; |
3319 | drbd_msg_put_info("resource exists"); | 3410 | drbd_msg_put_info(adm_ctx.reply_skb, "resource exists"); |
3320 | } | 3411 | } |
3321 | /* else: still NO_ERROR */ | 3412 | /* else: still NO_ERROR */ |
3322 | goto out; | 3413 | goto out; |
3323 | } | 3414 | } |
3324 | 3415 | ||
3416 | /* not yet safe for genl_family.parallel_ops */ | ||
3325 | if (!conn_create(adm_ctx.resource_name, &res_opts)) | 3417 | if (!conn_create(adm_ctx.resource_name, &res_opts)) |
3326 | retcode = ERR_NOMEM; | 3418 | retcode = ERR_NOMEM; |
3327 | out: | 3419 | out: |
3328 | drbd_adm_finish(info, retcode); | 3420 | drbd_adm_finish(&adm_ctx, info, retcode); |
3329 | return 0; | 3421 | return 0; |
3330 | } | 3422 | } |
3331 | 3423 | ||
3332 | int drbd_adm_new_minor(struct sk_buff *skb, struct genl_info *info) | 3424 | int drbd_adm_new_minor(struct sk_buff *skb, struct genl_info *info) |
3333 | { | 3425 | { |
3426 | struct drbd_config_context adm_ctx; | ||
3334 | struct drbd_genlmsghdr *dh = info->userhdr; | 3427 | struct drbd_genlmsghdr *dh = info->userhdr; |
3335 | enum drbd_ret_code retcode; | 3428 | enum drbd_ret_code retcode; |
3336 | 3429 | ||
3337 | retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_RESOURCE); | 3430 | retcode = drbd_adm_prepare(&adm_ctx, skb, info, DRBD_ADM_NEED_RESOURCE); |
3338 | if (!adm_ctx.reply_skb) | 3431 | if (!adm_ctx.reply_skb) |
3339 | return retcode; | 3432 | return retcode; |
3340 | if (retcode != NO_ERROR) | 3433 | if (retcode != NO_ERROR) |
3341 | goto out; | 3434 | goto out; |
3342 | 3435 | ||
3343 | if (dh->minor > MINORMASK) { | 3436 | if (dh->minor > MINORMASK) { |
3344 | drbd_msg_put_info("requested minor out of range"); | 3437 | drbd_msg_put_info(adm_ctx.reply_skb, "requested minor out of range"); |
3345 | retcode = ERR_INVALID_REQUEST; | 3438 | retcode = ERR_INVALID_REQUEST; |
3346 | goto out; | 3439 | goto out; |
3347 | } | 3440 | } |
3348 | if (adm_ctx.volume > DRBD_VOLUME_MAX) { | 3441 | if (adm_ctx.volume > DRBD_VOLUME_MAX) { |
3349 | drbd_msg_put_info("requested volume id out of range"); | 3442 | drbd_msg_put_info(adm_ctx.reply_skb, "requested volume id out of range"); |
3350 | retcode = ERR_INVALID_REQUEST; | 3443 | retcode = ERR_INVALID_REQUEST; |
3351 | goto out; | 3444 | goto out; |
3352 | } | 3445 | } |
@@ -3360,9 +3453,11 @@ int drbd_adm_new_minor(struct sk_buff *skb, struct genl_info *info) | |||
3360 | goto out; | 3453 | goto out; |
3361 | } | 3454 | } |
3362 | 3455 | ||
3363 | retcode = drbd_create_device(adm_ctx.resource, dh->minor, adm_ctx.volume); | 3456 | mutex_lock(&adm_ctx.resource->adm_mutex); |
3457 | retcode = drbd_create_device(&adm_ctx, dh->minor); | ||
3458 | mutex_unlock(&adm_ctx.resource->adm_mutex); | ||
3364 | out: | 3459 | out: |
3365 | drbd_adm_finish(info, retcode); | 3460 | drbd_adm_finish(&adm_ctx, info, retcode); |
3366 | return 0; | 3461 | return 0; |
3367 | } | 3462 | } |
3368 | 3463 | ||
@@ -3383,35 +3478,40 @@ static enum drbd_ret_code adm_del_minor(struct drbd_device *device) | |||
3383 | 3478 | ||
3384 | int drbd_adm_del_minor(struct sk_buff *skb, struct genl_info *info) | 3479 | int drbd_adm_del_minor(struct sk_buff *skb, struct genl_info *info) |
3385 | { | 3480 | { |
3481 | struct drbd_config_context adm_ctx; | ||
3386 | enum drbd_ret_code retcode; | 3482 | enum drbd_ret_code retcode; |
3387 | 3483 | ||
3388 | retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR); | 3484 | retcode = drbd_adm_prepare(&adm_ctx, skb, info, DRBD_ADM_NEED_MINOR); |
3389 | if (!adm_ctx.reply_skb) | 3485 | if (!adm_ctx.reply_skb) |
3390 | return retcode; | 3486 | return retcode; |
3391 | if (retcode != NO_ERROR) | 3487 | if (retcode != NO_ERROR) |
3392 | goto out; | 3488 | goto out; |
3393 | 3489 | ||
3490 | mutex_lock(&adm_ctx.resource->adm_mutex); | ||
3394 | retcode = adm_del_minor(adm_ctx.device); | 3491 | retcode = adm_del_minor(adm_ctx.device); |
3492 | mutex_unlock(&adm_ctx.resource->adm_mutex); | ||
3395 | out: | 3493 | out: |
3396 | drbd_adm_finish(info, retcode); | 3494 | drbd_adm_finish(&adm_ctx, info, retcode); |
3397 | return 0; | 3495 | return 0; |
3398 | } | 3496 | } |
3399 | 3497 | ||
3400 | int drbd_adm_down(struct sk_buff *skb, struct genl_info *info) | 3498 | int drbd_adm_down(struct sk_buff *skb, struct genl_info *info) |
3401 | { | 3499 | { |
3500 | struct drbd_config_context adm_ctx; | ||
3402 | struct drbd_resource *resource; | 3501 | struct drbd_resource *resource; |
3403 | struct drbd_connection *connection; | 3502 | struct drbd_connection *connection; |
3404 | struct drbd_device *device; | 3503 | struct drbd_device *device; |
3405 | int retcode; /* enum drbd_ret_code rsp. enum drbd_state_rv */ | 3504 | int retcode; /* enum drbd_ret_code rsp. enum drbd_state_rv */ |
3406 | unsigned i; | 3505 | unsigned i; |
3407 | 3506 | ||
3408 | retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_RESOURCE); | 3507 | retcode = drbd_adm_prepare(&adm_ctx, skb, info, DRBD_ADM_NEED_RESOURCE); |
3409 | if (!adm_ctx.reply_skb) | 3508 | if (!adm_ctx.reply_skb) |
3410 | return retcode; | 3509 | return retcode; |
3411 | if (retcode != NO_ERROR) | 3510 | if (retcode != NO_ERROR) |
3412 | goto out; | 3511 | goto finish; |
3413 | 3512 | ||
3414 | resource = adm_ctx.resource; | 3513 | resource = adm_ctx.resource; |
3514 | mutex_lock(&resource->adm_mutex); | ||
3415 | /* demote */ | 3515 | /* demote */ |
3416 | for_each_connection(connection, resource) { | 3516 | for_each_connection(connection, resource) { |
3417 | struct drbd_peer_device *peer_device; | 3517 | struct drbd_peer_device *peer_device; |
@@ -3419,14 +3519,14 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info) | |||
3419 | idr_for_each_entry(&connection->peer_devices, peer_device, i) { | 3519 | idr_for_each_entry(&connection->peer_devices, peer_device, i) { |
3420 | retcode = drbd_set_role(peer_device->device, R_SECONDARY, 0); | 3520 | retcode = drbd_set_role(peer_device->device, R_SECONDARY, 0); |
3421 | if (retcode < SS_SUCCESS) { | 3521 | if (retcode < SS_SUCCESS) { |
3422 | drbd_msg_put_info("failed to demote"); | 3522 | drbd_msg_put_info(adm_ctx.reply_skb, "failed to demote"); |
3423 | goto out; | 3523 | goto out; |
3424 | } | 3524 | } |
3425 | } | 3525 | } |
3426 | 3526 | ||
3427 | retcode = conn_try_disconnect(connection, 0); | 3527 | retcode = conn_try_disconnect(connection, 0); |
3428 | if (retcode < SS_SUCCESS) { | 3528 | if (retcode < SS_SUCCESS) { |
3429 | drbd_msg_put_info("failed to disconnect"); | 3529 | drbd_msg_put_info(adm_ctx.reply_skb, "failed to disconnect"); |
3430 | goto out; | 3530 | goto out; |
3431 | } | 3531 | } |
3432 | } | 3532 | } |
@@ -3435,7 +3535,7 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info) | |||
3435 | idr_for_each_entry(&resource->devices, device, i) { | 3535 | idr_for_each_entry(&resource->devices, device, i) { |
3436 | retcode = adm_detach(device, 0); | 3536 | retcode = adm_detach(device, 0); |
3437 | if (retcode < SS_SUCCESS || retcode > NO_ERROR) { | 3537 | if (retcode < SS_SUCCESS || retcode > NO_ERROR) { |
3438 | drbd_msg_put_info("failed to detach"); | 3538 | drbd_msg_put_info(adm_ctx.reply_skb, "failed to detach"); |
3439 | goto out; | 3539 | goto out; |
3440 | } | 3540 | } |
3441 | } | 3541 | } |
@@ -3453,7 +3553,7 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info) | |||
3453 | retcode = adm_del_minor(device); | 3553 | retcode = adm_del_minor(device); |
3454 | if (retcode != NO_ERROR) { | 3554 | if (retcode != NO_ERROR) { |
3455 | /* "can not happen" */ | 3555 | /* "can not happen" */ |
3456 | drbd_msg_put_info("failed to delete volume"); | 3556 | drbd_msg_put_info(adm_ctx.reply_skb, "failed to delete volume"); |
3457 | goto out; | 3557 | goto out; |
3458 | } | 3558 | } |
3459 | } | 3559 | } |
@@ -3462,25 +3562,28 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info) | |||
3462 | synchronize_rcu(); | 3562 | synchronize_rcu(); |
3463 | drbd_free_resource(resource); | 3563 | drbd_free_resource(resource); |
3464 | retcode = NO_ERROR; | 3564 | retcode = NO_ERROR; |
3465 | |||
3466 | out: | 3565 | out: |
3467 | drbd_adm_finish(info, retcode); | 3566 | mutex_unlock(&resource->adm_mutex); |
3567 | finish: | ||
3568 | drbd_adm_finish(&adm_ctx, info, retcode); | ||
3468 | return 0; | 3569 | return 0; |
3469 | } | 3570 | } |
3470 | 3571 | ||
3471 | int drbd_adm_del_resource(struct sk_buff *skb, struct genl_info *info) | 3572 | int drbd_adm_del_resource(struct sk_buff *skb, struct genl_info *info) |
3472 | { | 3573 | { |
3574 | struct drbd_config_context adm_ctx; | ||
3473 | struct drbd_resource *resource; | 3575 | struct drbd_resource *resource; |
3474 | struct drbd_connection *connection; | 3576 | struct drbd_connection *connection; |
3475 | enum drbd_ret_code retcode; | 3577 | enum drbd_ret_code retcode; |
3476 | 3578 | ||
3477 | retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_RESOURCE); | 3579 | retcode = drbd_adm_prepare(&adm_ctx, skb, info, DRBD_ADM_NEED_RESOURCE); |
3478 | if (!adm_ctx.reply_skb) | 3580 | if (!adm_ctx.reply_skb) |
3479 | return retcode; | 3581 | return retcode; |
3480 | if (retcode != NO_ERROR) | 3582 | if (retcode != NO_ERROR) |
3481 | goto out; | 3583 | goto finish; |
3482 | 3584 | ||
3483 | resource = adm_ctx.resource; | 3585 | resource = adm_ctx.resource; |
3586 | mutex_lock(&resource->adm_mutex); | ||
3484 | for_each_connection(connection, resource) { | 3587 | for_each_connection(connection, resource) { |
3485 | if (connection->cstate > C_STANDALONE) { | 3588 | if (connection->cstate > C_STANDALONE) { |
3486 | retcode = ERR_NET_CONFIGURED; | 3589 | retcode = ERR_NET_CONFIGURED; |
@@ -3499,7 +3602,9 @@ int drbd_adm_del_resource(struct sk_buff *skb, struct genl_info *info) | |||
3499 | drbd_free_resource(resource); | 3602 | drbd_free_resource(resource); |
3500 | retcode = NO_ERROR; | 3603 | retcode = NO_ERROR; |
3501 | out: | 3604 | out: |
3502 | drbd_adm_finish(info, retcode); | 3605 | mutex_unlock(&resource->adm_mutex); |
3606 | finish: | ||
3607 | drbd_adm_finish(&adm_ctx, info, retcode); | ||
3503 | return 0; | 3608 | return 0; |
3504 | } | 3609 | } |
3505 | 3610 | ||
diff --git a/drivers/block/drbd/drbd_nla.c b/drivers/block/drbd/drbd_nla.c index fa672b6df8d6..b2d4791498a6 100644 --- a/drivers/block/drbd/drbd_nla.c +++ b/drivers/block/drbd/drbd_nla.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #include "drbd_wrappers.h" | ||
2 | #include <linux/kernel.h> | 1 | #include <linux/kernel.h> |
3 | #include <net/netlink.h> | 2 | #include <net/netlink.h> |
4 | #include <linux/drbd_genl_api.h> | 3 | #include <linux/drbd_genl_api.h> |
diff --git a/drivers/block/drbd/drbd_proc.c b/drivers/block/drbd/drbd_proc.c index 2f26e8ffa45b..89736bdbbc70 100644 --- a/drivers/block/drbd/drbd_proc.c +++ b/drivers/block/drbd/drbd_proc.c | |||
@@ -116,7 +116,7 @@ static void drbd_syncer_progress(struct drbd_device *device, struct seq_file *se | |||
116 | /* ------------------------ ~18s average ------------------------ */ | 116 | /* ------------------------ ~18s average ------------------------ */ |
117 | i = (device->rs_last_mark + 2) % DRBD_SYNC_MARKS; | 117 | i = (device->rs_last_mark + 2) % DRBD_SYNC_MARKS; |
118 | dt = (jiffies - device->rs_mark_time[i]) / HZ; | 118 | dt = (jiffies - device->rs_mark_time[i]) / HZ; |
119 | if (dt > (DRBD_SYNC_MARK_STEP * DRBD_SYNC_MARKS)) | 119 | if (dt > 180) |
120 | stalled = 1; | 120 | stalled = 1; |
121 | 121 | ||
122 | if (!dt) | 122 | if (!dt) |
diff --git a/drivers/block/drbd/drbd_protocol.h b/drivers/block/drbd/drbd_protocol.h index 3c04ec0ea333..2da9104a3851 100644 --- a/drivers/block/drbd/drbd_protocol.h +++ b/drivers/block/drbd/drbd_protocol.h | |||
@@ -54,6 +54,11 @@ enum drbd_packet { | |||
54 | P_CONN_ST_CHG_REPLY = 0x2b, /* meta sock: Connection side state req reply */ | 54 | P_CONN_ST_CHG_REPLY = 0x2b, /* meta sock: Connection side state req reply */ |
55 | P_RETRY_WRITE = 0x2c, /* Protocol C: retry conflicting write request */ | 55 | P_RETRY_WRITE = 0x2c, /* Protocol C: retry conflicting write request */ |
56 | P_PROTOCOL_UPDATE = 0x2d, /* data sock: is used in established connections */ | 56 | P_PROTOCOL_UPDATE = 0x2d, /* data sock: is used in established connections */ |
57 | /* 0x2e to 0x30 reserved, used in drbd 9 */ | ||
58 | |||
59 | /* REQ_DISCARD. We used "discard" in different contexts before, | ||
60 | * which is why I chose TRIM here, to disambiguate. */ | ||
61 | P_TRIM = 0x31, | ||
57 | 62 | ||
58 | P_MAY_IGNORE = 0x100, /* Flag to test if (cmd > P_MAY_IGNORE) ... */ | 63 | P_MAY_IGNORE = 0x100, /* Flag to test if (cmd > P_MAY_IGNORE) ... */ |
59 | P_MAX_OPT_CMD = 0x101, | 64 | P_MAX_OPT_CMD = 0x101, |
@@ -119,6 +124,11 @@ struct p_data { | |||
119 | u32 dp_flags; | 124 | u32 dp_flags; |
120 | } __packed; | 125 | } __packed; |
121 | 126 | ||
127 | struct p_trim { | ||
128 | struct p_data p_data; | ||
129 | u32 size; /* == bio->bi_size */ | ||
130 | } __packed; | ||
131 | |||
122 | /* | 132 | /* |
123 | * commands which share a struct: | 133 | * commands which share a struct: |
124 | * p_block_ack: | 134 | * p_block_ack: |
@@ -150,6 +160,8 @@ struct p_block_req { | |||
150 | * ReportParams | 160 | * ReportParams |
151 | */ | 161 | */ |
152 | 162 | ||
163 | #define FF_TRIM 1 | ||
164 | |||
153 | struct p_connection_features { | 165 | struct p_connection_features { |
154 | u32 protocol_min; | 166 | u32 protocol_min; |
155 | u32 feature_flags; | 167 | u32 feature_flags; |
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 68e3992e8838..b6c8aaf4931b 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c | |||
@@ -46,9 +46,10 @@ | |||
46 | #include "drbd_int.h" | 46 | #include "drbd_int.h" |
47 | #include "drbd_protocol.h" | 47 | #include "drbd_protocol.h" |
48 | #include "drbd_req.h" | 48 | #include "drbd_req.h" |
49 | |||
50 | #include "drbd_vli.h" | 49 | #include "drbd_vli.h" |
51 | 50 | ||
51 | #define PRO_FEATURES (FF_TRIM) | ||
52 | |||
52 | struct packet_info { | 53 | struct packet_info { |
53 | enum drbd_packet cmd; | 54 | enum drbd_packet cmd; |
54 | unsigned int size; | 55 | unsigned int size; |
@@ -65,7 +66,7 @@ enum finish_epoch { | |||
65 | static int drbd_do_features(struct drbd_connection *connection); | 66 | static int drbd_do_features(struct drbd_connection *connection); |
66 | static int drbd_do_auth(struct drbd_connection *connection); | 67 | static int drbd_do_auth(struct drbd_connection *connection); |
67 | static int drbd_disconnected(struct drbd_peer_device *); | 68 | static int drbd_disconnected(struct drbd_peer_device *); |
68 | 69 | static void conn_wait_active_ee_empty(struct drbd_connection *connection); | |
69 | static enum finish_epoch drbd_may_finish_epoch(struct drbd_connection *, struct drbd_epoch *, enum epoch_event); | 70 | static enum finish_epoch drbd_may_finish_epoch(struct drbd_connection *, struct drbd_epoch *, enum epoch_event); |
70 | static int e_end_block(struct drbd_work *, int); | 71 | static int e_end_block(struct drbd_work *, int); |
71 | 72 | ||
@@ -234,9 +235,17 @@ static void drbd_kick_lo_and_reclaim_net(struct drbd_device *device) | |||
234 | * @retry: whether to retry, if not enough pages are available right now | 235 | * @retry: whether to retry, if not enough pages are available right now |
235 | * | 236 | * |
236 | * Tries to allocate number pages, first from our own page pool, then from | 237 | * Tries to allocate number pages, first from our own page pool, then from |
237 | * the kernel, unless this allocation would exceed the max_buffers setting. | 238 | * the kernel. |
238 | * Possibly retry until DRBD frees sufficient pages somewhere else. | 239 | * Possibly retry until DRBD frees sufficient pages somewhere else. |
239 | * | 240 | * |
241 | * If this allocation would exceed the max_buffers setting, we throttle | ||
242 | * allocation (schedule_timeout) to give the system some room to breathe. | ||
243 | * | ||
244 | * We do not use max-buffers as hard limit, because it could lead to | ||
245 | * congestion and further to a distributed deadlock during online-verify or | ||
246 | * (checksum based) resync, if the max-buffers, socket buffer sizes and | ||
247 | * resync-rate settings are mis-configured. | ||
248 | * | ||
240 | * Returns a page chain linked via page->private. | 249 | * Returns a page chain linked via page->private. |
241 | */ | 250 | */ |
242 | struct page *drbd_alloc_pages(struct drbd_peer_device *peer_device, unsigned int number, | 251 | struct page *drbd_alloc_pages(struct drbd_peer_device *peer_device, unsigned int number, |
@@ -246,10 +255,8 @@ struct page *drbd_alloc_pages(struct drbd_peer_device *peer_device, unsigned int | |||
246 | struct page *page = NULL; | 255 | struct page *page = NULL; |
247 | struct net_conf *nc; | 256 | struct net_conf *nc; |
248 | DEFINE_WAIT(wait); | 257 | DEFINE_WAIT(wait); |
249 | int mxb; | 258 | unsigned int mxb; |
250 | 259 | ||
251 | /* Yes, we may run up to @number over max_buffers. If we | ||
252 | * follow it strictly, the admin will get it wrong anyways. */ | ||
253 | rcu_read_lock(); | 260 | rcu_read_lock(); |
254 | nc = rcu_dereference(peer_device->connection->net_conf); | 261 | nc = rcu_dereference(peer_device->connection->net_conf); |
255 | mxb = nc ? nc->max_buffers : 1000000; | 262 | mxb = nc ? nc->max_buffers : 1000000; |
@@ -277,7 +284,8 @@ struct page *drbd_alloc_pages(struct drbd_peer_device *peer_device, unsigned int | |||
277 | break; | 284 | break; |
278 | } | 285 | } |
279 | 286 | ||
280 | schedule(); | 287 | if (schedule_timeout(HZ/10) == 0) |
288 | mxb = UINT_MAX; | ||
281 | } | 289 | } |
282 | finish_wait(&drbd_pp_wait, &wait); | 290 | finish_wait(&drbd_pp_wait, &wait); |
283 | 291 | ||
@@ -331,7 +339,7 @@ You must not have the req_lock: | |||
331 | 339 | ||
332 | struct drbd_peer_request * | 340 | struct drbd_peer_request * |
333 | drbd_alloc_peer_req(struct drbd_peer_device *peer_device, u64 id, sector_t sector, | 341 | drbd_alloc_peer_req(struct drbd_peer_device *peer_device, u64 id, sector_t sector, |
334 | unsigned int data_size, gfp_t gfp_mask) __must_hold(local) | 342 | unsigned int data_size, bool has_payload, gfp_t gfp_mask) __must_hold(local) |
335 | { | 343 | { |
336 | struct drbd_device *device = peer_device->device; | 344 | struct drbd_device *device = peer_device->device; |
337 | struct drbd_peer_request *peer_req; | 345 | struct drbd_peer_request *peer_req; |
@@ -348,7 +356,7 @@ drbd_alloc_peer_req(struct drbd_peer_device *peer_device, u64 id, sector_t secto | |||
348 | return NULL; | 356 | return NULL; |
349 | } | 357 | } |
350 | 358 | ||
351 | if (data_size) { | 359 | if (has_payload && data_size) { |
352 | page = drbd_alloc_pages(peer_device, nr_pages, (gfp_mask & __GFP_WAIT)); | 360 | page = drbd_alloc_pages(peer_device, nr_pages, (gfp_mask & __GFP_WAIT)); |
353 | if (!page) | 361 | if (!page) |
354 | goto fail; | 362 | goto fail; |
@@ -1026,24 +1034,27 @@ randomize: | |||
1026 | if (drbd_send_protocol(connection) == -EOPNOTSUPP) | 1034 | if (drbd_send_protocol(connection) == -EOPNOTSUPP) |
1027 | return -1; | 1035 | return -1; |
1028 | 1036 | ||
1037 | /* Prevent a race between resync-handshake and | ||
1038 | * being promoted to Primary. | ||
1039 | * | ||
1040 | * Grab and release the state mutex, so we know that any current | ||
1041 | * drbd_set_role() is finished, and any incoming drbd_set_role | ||
1042 | * will see the STATE_SENT flag, and wait for it to be cleared. | ||
1043 | */ | ||
1044 | idr_for_each_entry(&connection->peer_devices, peer_device, vnr) | ||
1045 | mutex_lock(peer_device->device->state_mutex); | ||
1046 | |||
1029 | set_bit(STATE_SENT, &connection->flags); | 1047 | set_bit(STATE_SENT, &connection->flags); |
1030 | 1048 | ||
1049 | idr_for_each_entry(&connection->peer_devices, peer_device, vnr) | ||
1050 | mutex_unlock(peer_device->device->state_mutex); | ||
1051 | |||
1031 | rcu_read_lock(); | 1052 | rcu_read_lock(); |
1032 | idr_for_each_entry(&connection->peer_devices, peer_device, vnr) { | 1053 | idr_for_each_entry(&connection->peer_devices, peer_device, vnr) { |
1033 | struct drbd_device *device = peer_device->device; | 1054 | struct drbd_device *device = peer_device->device; |
1034 | kref_get(&device->kref); | 1055 | kref_get(&device->kref); |
1035 | rcu_read_unlock(); | 1056 | rcu_read_unlock(); |
1036 | 1057 | ||
1037 | /* Prevent a race between resync-handshake and | ||
1038 | * being promoted to Primary. | ||
1039 | * | ||
1040 | * Grab and release the state mutex, so we know that any current | ||
1041 | * drbd_set_role() is finished, and any incoming drbd_set_role | ||
1042 | * will see the STATE_SENT flag, and wait for it to be cleared. | ||
1043 | */ | ||
1044 | mutex_lock(device->state_mutex); | ||
1045 | mutex_unlock(device->state_mutex); | ||
1046 | |||
1047 | if (discard_my_data) | 1058 | if (discard_my_data) |
1048 | set_bit(DISCARD_MY_DATA, &device->flags); | 1059 | set_bit(DISCARD_MY_DATA, &device->flags); |
1049 | else | 1060 | else |
@@ -1315,6 +1326,20 @@ int drbd_submit_peer_request(struct drbd_device *device, | |||
1315 | unsigned nr_pages = (ds + PAGE_SIZE -1) >> PAGE_SHIFT; | 1326 | unsigned nr_pages = (ds + PAGE_SIZE -1) >> PAGE_SHIFT; |
1316 | int err = -ENOMEM; | 1327 | int err = -ENOMEM; |
1317 | 1328 | ||
1329 | if (peer_req->flags & EE_IS_TRIM_USE_ZEROOUT) { | ||
1330 | /* wait for all pending IO completions, before we start | ||
1331 | * zeroing things out. */ | ||
1332 | conn_wait_active_ee_empty(first_peer_device(device)->connection); | ||
1333 | if (blkdev_issue_zeroout(device->ldev->backing_bdev, | ||
1334 | sector, ds >> 9, GFP_NOIO)) | ||
1335 | peer_req->flags |= EE_WAS_ERROR; | ||
1336 | drbd_endio_write_sec_final(peer_req); | ||
1337 | return 0; | ||
1338 | } | ||
1339 | |||
1340 | if (peer_req->flags & EE_IS_TRIM) | ||
1341 | nr_pages = 0; /* discards don't have any payload. */ | ||
1342 | |||
1318 | /* In most cases, we will only need one bio. But in case the lower | 1343 | /* In most cases, we will only need one bio. But in case the lower |
1319 | * level restrictions happen to be different at this offset on this | 1344 | * level restrictions happen to be different at this offset on this |
1320 | * side than those of the sending peer, we may need to submit the | 1345 | * side than those of the sending peer, we may need to submit the |
@@ -1326,7 +1351,7 @@ int drbd_submit_peer_request(struct drbd_device *device, | |||
1326 | next_bio: | 1351 | next_bio: |
1327 | bio = bio_alloc(GFP_NOIO, nr_pages); | 1352 | bio = bio_alloc(GFP_NOIO, nr_pages); |
1328 | if (!bio) { | 1353 | if (!bio) { |
1329 | drbd_err(device, "submit_ee: Allocation of a bio failed\n"); | 1354 | drbd_err(device, "submit_ee: Allocation of a bio failed (nr_pages=%u)\n", nr_pages); |
1330 | goto fail; | 1355 | goto fail; |
1331 | } | 1356 | } |
1332 | /* > peer_req->i.sector, unless this is the first bio */ | 1357 | /* > peer_req->i.sector, unless this is the first bio */ |
@@ -1340,6 +1365,11 @@ next_bio: | |||
1340 | bios = bio; | 1365 | bios = bio; |
1341 | ++n_bios; | 1366 | ++n_bios; |
1342 | 1367 | ||
1368 | if (rw & REQ_DISCARD) { | ||
1369 | bio->bi_iter.bi_size = ds; | ||
1370 | goto submit; | ||
1371 | } | ||
1372 | |||
1343 | page_chain_for_each(page) { | 1373 | page_chain_for_each(page) { |
1344 | unsigned len = min_t(unsigned, ds, PAGE_SIZE); | 1374 | unsigned len = min_t(unsigned, ds, PAGE_SIZE); |
1345 | if (!bio_add_page(bio, page, len, 0)) { | 1375 | if (!bio_add_page(bio, page, len, 0)) { |
@@ -1360,8 +1390,9 @@ next_bio: | |||
1360 | sector += len >> 9; | 1390 | sector += len >> 9; |
1361 | --nr_pages; | 1391 | --nr_pages; |
1362 | } | 1392 | } |
1363 | D_ASSERT(device, page == NULL); | ||
1364 | D_ASSERT(device, ds == 0); | 1393 | D_ASSERT(device, ds == 0); |
1394 | submit: | ||
1395 | D_ASSERT(device, page == NULL); | ||
1365 | 1396 | ||
1366 | atomic_set(&peer_req->pending_bios, n_bios); | 1397 | atomic_set(&peer_req->pending_bios, n_bios); |
1367 | do { | 1398 | do { |
@@ -1490,19 +1521,21 @@ static int receive_Barrier(struct drbd_connection *connection, struct packet_inf | |||
1490 | * and from receive_Data */ | 1521 | * and from receive_Data */ |
1491 | static struct drbd_peer_request * | 1522 | static struct drbd_peer_request * |
1492 | read_in_block(struct drbd_peer_device *peer_device, u64 id, sector_t sector, | 1523 | read_in_block(struct drbd_peer_device *peer_device, u64 id, sector_t sector, |
1493 | int data_size) __must_hold(local) | 1524 | struct packet_info *pi) __must_hold(local) |
1494 | { | 1525 | { |
1495 | struct drbd_device *device = peer_device->device; | 1526 | struct drbd_device *device = peer_device->device; |
1496 | const sector_t capacity = drbd_get_capacity(device->this_bdev); | 1527 | const sector_t capacity = drbd_get_capacity(device->this_bdev); |
1497 | struct drbd_peer_request *peer_req; | 1528 | struct drbd_peer_request *peer_req; |
1498 | struct page *page; | 1529 | struct page *page; |
1499 | int dgs, ds, err; | 1530 | int dgs, ds, err; |
1531 | int data_size = pi->size; | ||
1500 | void *dig_in = peer_device->connection->int_dig_in; | 1532 | void *dig_in = peer_device->connection->int_dig_in; |
1501 | void *dig_vv = peer_device->connection->int_dig_vv; | 1533 | void *dig_vv = peer_device->connection->int_dig_vv; |
1502 | unsigned long *data; | 1534 | unsigned long *data; |
1535 | struct p_trim *trim = (pi->cmd == P_TRIM) ? pi->data : NULL; | ||
1503 | 1536 | ||
1504 | dgs = 0; | 1537 | dgs = 0; |
1505 | if (peer_device->connection->peer_integrity_tfm) { | 1538 | if (!trim && peer_device->connection->peer_integrity_tfm) { |
1506 | dgs = crypto_hash_digestsize(peer_device->connection->peer_integrity_tfm); | 1539 | dgs = crypto_hash_digestsize(peer_device->connection->peer_integrity_tfm); |
1507 | /* | 1540 | /* |
1508 | * FIXME: Receive the incoming digest into the receive buffer | 1541 | * FIXME: Receive the incoming digest into the receive buffer |
@@ -1514,9 +1547,15 @@ read_in_block(struct drbd_peer_device *peer_device, u64 id, sector_t sector, | |||
1514 | data_size -= dgs; | 1547 | data_size -= dgs; |
1515 | } | 1548 | } |
1516 | 1549 | ||
1550 | if (trim) { | ||
1551 | D_ASSERT(peer_device, data_size == 0); | ||
1552 | data_size = be32_to_cpu(trim->size); | ||
1553 | } | ||
1554 | |||
1517 | if (!expect(IS_ALIGNED(data_size, 512))) | 1555 | if (!expect(IS_ALIGNED(data_size, 512))) |
1518 | return NULL; | 1556 | return NULL; |
1519 | if (!expect(data_size <= DRBD_MAX_BIO_SIZE)) | 1557 | /* prepare for larger trim requests. */ |
1558 | if (!trim && !expect(data_size <= DRBD_MAX_BIO_SIZE)) | ||
1520 | return NULL; | 1559 | return NULL; |
1521 | 1560 | ||
1522 | /* even though we trust out peer, | 1561 | /* even though we trust out peer, |
@@ -1532,11 +1571,11 @@ read_in_block(struct drbd_peer_device *peer_device, u64 id, sector_t sector, | |||
1532 | /* GFP_NOIO, because we must not cause arbitrary write-out: in a DRBD | 1571 | /* GFP_NOIO, because we must not cause arbitrary write-out: in a DRBD |
1533 | * "criss-cross" setup, that might cause write-out on some other DRBD, | 1572 | * "criss-cross" setup, that might cause write-out on some other DRBD, |
1534 | * which in turn might block on the other node at this very place. */ | 1573 | * which in turn might block on the other node at this very place. */ |
1535 | peer_req = drbd_alloc_peer_req(peer_device, id, sector, data_size, GFP_NOIO); | 1574 | peer_req = drbd_alloc_peer_req(peer_device, id, sector, data_size, trim == NULL, GFP_NOIO); |
1536 | if (!peer_req) | 1575 | if (!peer_req) |
1537 | return NULL; | 1576 | return NULL; |
1538 | 1577 | ||
1539 | if (!data_size) | 1578 | if (trim) |
1540 | return peer_req; | 1579 | return peer_req; |
1541 | 1580 | ||
1542 | ds = data_size; | 1581 | ds = data_size; |
@@ -1676,12 +1715,12 @@ static int e_end_resync_block(struct drbd_work *w, int unused) | |||
1676 | } | 1715 | } |
1677 | 1716 | ||
1678 | static int recv_resync_read(struct drbd_peer_device *peer_device, sector_t sector, | 1717 | static int recv_resync_read(struct drbd_peer_device *peer_device, sector_t sector, |
1679 | int data_size) __releases(local) | 1718 | struct packet_info *pi) __releases(local) |
1680 | { | 1719 | { |
1681 | struct drbd_device *device = peer_device->device; | 1720 | struct drbd_device *device = peer_device->device; |
1682 | struct drbd_peer_request *peer_req; | 1721 | struct drbd_peer_request *peer_req; |
1683 | 1722 | ||
1684 | peer_req = read_in_block(peer_device, ID_SYNCER, sector, data_size); | 1723 | peer_req = read_in_block(peer_device, ID_SYNCER, sector, pi); |
1685 | if (!peer_req) | 1724 | if (!peer_req) |
1686 | goto fail; | 1725 | goto fail; |
1687 | 1726 | ||
@@ -1697,7 +1736,7 @@ static int recv_resync_read(struct drbd_peer_device *peer_device, sector_t secto | |||
1697 | list_add(&peer_req->w.list, &device->sync_ee); | 1736 | list_add(&peer_req->w.list, &device->sync_ee); |
1698 | spin_unlock_irq(&device->resource->req_lock); | 1737 | spin_unlock_irq(&device->resource->req_lock); |
1699 | 1738 | ||
1700 | atomic_add(data_size >> 9, &device->rs_sect_ev); | 1739 | atomic_add(pi->size >> 9, &device->rs_sect_ev); |
1701 | if (drbd_submit_peer_request(device, peer_req, WRITE, DRBD_FAULT_RS_WR) == 0) | 1740 | if (drbd_submit_peer_request(device, peer_req, WRITE, DRBD_FAULT_RS_WR) == 0) |
1702 | return 0; | 1741 | return 0; |
1703 | 1742 | ||
@@ -1785,7 +1824,7 @@ static int receive_RSDataReply(struct drbd_connection *connection, struct packet | |||
1785 | /* data is submitted to disk within recv_resync_read. | 1824 | /* data is submitted to disk within recv_resync_read. |
1786 | * corresponding put_ldev done below on error, | 1825 | * corresponding put_ldev done below on error, |
1787 | * or in drbd_peer_request_endio. */ | 1826 | * or in drbd_peer_request_endio. */ |
1788 | err = recv_resync_read(peer_device, sector, pi->size); | 1827 | err = recv_resync_read(peer_device, sector, pi); |
1789 | } else { | 1828 | } else { |
1790 | if (__ratelimit(&drbd_ratelimit_state)) | 1829 | if (__ratelimit(&drbd_ratelimit_state)) |
1791 | drbd_err(device, "Can not write resync data to local disk.\n"); | 1830 | drbd_err(device, "Can not write resync data to local disk.\n"); |
@@ -2196,7 +2235,7 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info * | |||
2196 | */ | 2235 | */ |
2197 | 2236 | ||
2198 | sector = be64_to_cpu(p->sector); | 2237 | sector = be64_to_cpu(p->sector); |
2199 | peer_req = read_in_block(peer_device, p->block_id, sector, pi->size); | 2238 | peer_req = read_in_block(peer_device, p->block_id, sector, pi); |
2200 | if (!peer_req) { | 2239 | if (!peer_req) { |
2201 | put_ldev(device); | 2240 | put_ldev(device); |
2202 | return -EIO; | 2241 | return -EIO; |
@@ -2206,7 +2245,15 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info * | |||
2206 | 2245 | ||
2207 | dp_flags = be32_to_cpu(p->dp_flags); | 2246 | dp_flags = be32_to_cpu(p->dp_flags); |
2208 | rw |= wire_flags_to_bio(dp_flags); | 2247 | rw |= wire_flags_to_bio(dp_flags); |
2209 | if (peer_req->pages == NULL) { | 2248 | if (pi->cmd == P_TRIM) { |
2249 | struct request_queue *q = bdev_get_queue(device->ldev->backing_bdev); | ||
2250 | peer_req->flags |= EE_IS_TRIM; | ||
2251 | if (!blk_queue_discard(q)) | ||
2252 | peer_req->flags |= EE_IS_TRIM_USE_ZEROOUT; | ||
2253 | D_ASSERT(peer_device, peer_req->i.size > 0); | ||
2254 | D_ASSERT(peer_device, rw & REQ_DISCARD); | ||
2255 | D_ASSERT(peer_device, peer_req->pages == NULL); | ||
2256 | } else if (peer_req->pages == NULL) { | ||
2210 | D_ASSERT(device, peer_req->i.size == 0); | 2257 | D_ASSERT(device, peer_req->i.size == 0); |
2211 | D_ASSERT(device, dp_flags & DP_FLUSH); | 2258 | D_ASSERT(device, dp_flags & DP_FLUSH); |
2212 | } | 2259 | } |
@@ -2242,7 +2289,12 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info * | |||
2242 | update_peer_seq(peer_device, peer_seq); | 2289 | update_peer_seq(peer_device, peer_seq); |
2243 | spin_lock_irq(&device->resource->req_lock); | 2290 | spin_lock_irq(&device->resource->req_lock); |
2244 | } | 2291 | } |
2245 | list_add(&peer_req->w.list, &device->active_ee); | 2292 | /* if we use the zeroout fallback code, we process synchronously |
2293 | * and we wait for all pending requests, respectively wait for | ||
2294 | * active_ee to become empty in drbd_submit_peer_request(); | ||
2295 | * better not add ourselves here. */ | ||
2296 | if ((peer_req->flags & EE_IS_TRIM_USE_ZEROOUT) == 0) | ||
2297 | list_add(&peer_req->w.list, &device->active_ee); | ||
2246 | spin_unlock_irq(&device->resource->req_lock); | 2298 | spin_unlock_irq(&device->resource->req_lock); |
2247 | 2299 | ||
2248 | if (device->state.conn == C_SYNC_TARGET) | 2300 | if (device->state.conn == C_SYNC_TARGET) |
@@ -2313,39 +2365,45 @@ out_interrupted: | |||
2313 | * The current sync rate used here uses only the most recent two step marks, | 2365 | * The current sync rate used here uses only the most recent two step marks, |
2314 | * to have a short time average so we can react faster. | 2366 | * to have a short time average so we can react faster. |
2315 | */ | 2367 | */ |
2316 | int drbd_rs_should_slow_down(struct drbd_device *device, sector_t sector) | 2368 | bool drbd_rs_should_slow_down(struct drbd_device *device, sector_t sector) |
2317 | { | 2369 | { |
2318 | struct gendisk *disk = device->ldev->backing_bdev->bd_contains->bd_disk; | ||
2319 | unsigned long db, dt, dbdt; | ||
2320 | struct lc_element *tmp; | 2370 | struct lc_element *tmp; |
2321 | int curr_events; | 2371 | bool throttle = true; |
2322 | int throttle = 0; | ||
2323 | unsigned int c_min_rate; | ||
2324 | |||
2325 | rcu_read_lock(); | ||
2326 | c_min_rate = rcu_dereference(device->ldev->disk_conf)->c_min_rate; | ||
2327 | rcu_read_unlock(); | ||
2328 | 2372 | ||
2329 | /* feature disabled? */ | 2373 | if (!drbd_rs_c_min_rate_throttle(device)) |
2330 | if (c_min_rate == 0) | 2374 | return false; |
2331 | return 0; | ||
2332 | 2375 | ||
2333 | spin_lock_irq(&device->al_lock); | 2376 | spin_lock_irq(&device->al_lock); |
2334 | tmp = lc_find(device->resync, BM_SECT_TO_EXT(sector)); | 2377 | tmp = lc_find(device->resync, BM_SECT_TO_EXT(sector)); |
2335 | if (tmp) { | 2378 | if (tmp) { |
2336 | struct bm_extent *bm_ext = lc_entry(tmp, struct bm_extent, lce); | 2379 | struct bm_extent *bm_ext = lc_entry(tmp, struct bm_extent, lce); |
2337 | if (test_bit(BME_PRIORITY, &bm_ext->flags)) { | 2380 | if (test_bit(BME_PRIORITY, &bm_ext->flags)) |
2338 | spin_unlock_irq(&device->al_lock); | 2381 | throttle = false; |
2339 | return 0; | ||
2340 | } | ||
2341 | /* Do not slow down if app IO is already waiting for this extent */ | 2382 | /* Do not slow down if app IO is already waiting for this extent */ |
2342 | } | 2383 | } |
2343 | spin_unlock_irq(&device->al_lock); | 2384 | spin_unlock_irq(&device->al_lock); |
2344 | 2385 | ||
2386 | return throttle; | ||
2387 | } | ||
2388 | |||
2389 | bool drbd_rs_c_min_rate_throttle(struct drbd_device *device) | ||
2390 | { | ||
2391 | struct gendisk *disk = device->ldev->backing_bdev->bd_contains->bd_disk; | ||
2392 | unsigned long db, dt, dbdt; | ||
2393 | unsigned int c_min_rate; | ||
2394 | int curr_events; | ||
2395 | |||
2396 | rcu_read_lock(); | ||
2397 | c_min_rate = rcu_dereference(device->ldev->disk_conf)->c_min_rate; | ||
2398 | rcu_read_unlock(); | ||
2399 | |||
2400 | /* feature disabled? */ | ||
2401 | if (c_min_rate == 0) | ||
2402 | return false; | ||
2403 | |||
2345 | curr_events = (int)part_stat_read(&disk->part0, sectors[0]) + | 2404 | curr_events = (int)part_stat_read(&disk->part0, sectors[0]) + |
2346 | (int)part_stat_read(&disk->part0, sectors[1]) - | 2405 | (int)part_stat_read(&disk->part0, sectors[1]) - |
2347 | atomic_read(&device->rs_sect_ev); | 2406 | atomic_read(&device->rs_sect_ev); |
2348 | |||
2349 | if (!device->rs_last_events || curr_events - device->rs_last_events > 64) { | 2407 | if (!device->rs_last_events || curr_events - device->rs_last_events > 64) { |
2350 | unsigned long rs_left; | 2408 | unsigned long rs_left; |
2351 | int i; | 2409 | int i; |
@@ -2368,12 +2426,11 @@ int drbd_rs_should_slow_down(struct drbd_device *device, sector_t sector) | |||
2368 | dbdt = Bit2KB(db/dt); | 2426 | dbdt = Bit2KB(db/dt); |
2369 | 2427 | ||
2370 | if (dbdt > c_min_rate) | 2428 | if (dbdt > c_min_rate) |
2371 | throttle = 1; | 2429 | return true; |
2372 | } | 2430 | } |
2373 | return throttle; | 2431 | return false; |
2374 | } | 2432 | } |
2375 | 2433 | ||
2376 | |||
2377 | static int receive_DataRequest(struct drbd_connection *connection, struct packet_info *pi) | 2434 | static int receive_DataRequest(struct drbd_connection *connection, struct packet_info *pi) |
2378 | { | 2435 | { |
2379 | struct drbd_peer_device *peer_device; | 2436 | struct drbd_peer_device *peer_device; |
@@ -2436,7 +2493,8 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet | |||
2436 | /* GFP_NOIO, because we must not cause arbitrary write-out: in a DRBD | 2493 | /* GFP_NOIO, because we must not cause arbitrary write-out: in a DRBD |
2437 | * "criss-cross" setup, that might cause write-out on some other DRBD, | 2494 | * "criss-cross" setup, that might cause write-out on some other DRBD, |
2438 | * which in turn might block on the other node at this very place. */ | 2495 | * which in turn might block on the other node at this very place. */ |
2439 | peer_req = drbd_alloc_peer_req(peer_device, p->block_id, sector, size, GFP_NOIO); | 2496 | peer_req = drbd_alloc_peer_req(peer_device, p->block_id, sector, size, |
2497 | true /* has real payload */, GFP_NOIO); | ||
2440 | if (!peer_req) { | 2498 | if (!peer_req) { |
2441 | put_ldev(device); | 2499 | put_ldev(device); |
2442 | return -ENOMEM; | 2500 | return -ENOMEM; |
@@ -3648,6 +3706,13 @@ static int receive_sizes(struct drbd_connection *connection, struct packet_info | |||
3648 | put_ldev(device); | 3706 | put_ldev(device); |
3649 | } | 3707 | } |
3650 | 3708 | ||
3709 | device->peer_max_bio_size = be32_to_cpu(p->max_bio_size); | ||
3710 | drbd_reconsider_max_bio_size(device); | ||
3711 | /* Leave drbd_reconsider_max_bio_size() before drbd_determine_dev_size(). | ||
3712 | In case we cleared the QUEUE_FLAG_DISCARD from our queue in | ||
3713 | drbd_reconsider_max_bio_size(), we can be sure that after | ||
3714 | drbd_determine_dev_size() no REQ_DISCARDs are in the queue. */ | ||
3715 | |||
3651 | ddsf = be16_to_cpu(p->dds_flags); | 3716 | ddsf = be16_to_cpu(p->dds_flags); |
3652 | if (get_ldev(device)) { | 3717 | if (get_ldev(device)) { |
3653 | dd = drbd_determine_dev_size(device, ddsf, NULL); | 3718 | dd = drbd_determine_dev_size(device, ddsf, NULL); |
@@ -3660,9 +3725,6 @@ static int receive_sizes(struct drbd_connection *connection, struct packet_info | |||
3660 | drbd_set_my_capacity(device, p_size); | 3725 | drbd_set_my_capacity(device, p_size); |
3661 | } | 3726 | } |
3662 | 3727 | ||
3663 | device->peer_max_bio_size = be32_to_cpu(p->max_bio_size); | ||
3664 | drbd_reconsider_max_bio_size(device); | ||
3665 | |||
3666 | if (get_ldev(device)) { | 3728 | if (get_ldev(device)) { |
3667 | if (device->ldev->known_size != drbd_get_capacity(device->ldev->backing_bdev)) { | 3729 | if (device->ldev->known_size != drbd_get_capacity(device->ldev->backing_bdev)) { |
3668 | device->ldev->known_size = drbd_get_capacity(device->ldev->backing_bdev); | 3730 | device->ldev->known_size = drbd_get_capacity(device->ldev->backing_bdev); |
@@ -4423,6 +4485,7 @@ static struct data_cmd drbd_cmd_handler[] = { | |||
4423 | [P_OUT_OF_SYNC] = { 0, sizeof(struct p_block_desc), receive_out_of_sync }, | 4485 | [P_OUT_OF_SYNC] = { 0, sizeof(struct p_block_desc), receive_out_of_sync }, |
4424 | [P_CONN_ST_CHG_REQ] = { 0, sizeof(struct p_req_state), receive_req_conn_state }, | 4486 | [P_CONN_ST_CHG_REQ] = { 0, sizeof(struct p_req_state), receive_req_conn_state }, |
4425 | [P_PROTOCOL_UPDATE] = { 1, sizeof(struct p_protocol), receive_protocol }, | 4487 | [P_PROTOCOL_UPDATE] = { 1, sizeof(struct p_protocol), receive_protocol }, |
4488 | [P_TRIM] = { 0, sizeof(struct p_trim), receive_Data }, | ||
4426 | }; | 4489 | }; |
4427 | 4490 | ||
4428 | static void drbdd(struct drbd_connection *connection) | 4491 | static void drbdd(struct drbd_connection *connection) |
@@ -4630,6 +4693,7 @@ static int drbd_send_features(struct drbd_connection *connection) | |||
4630 | memset(p, 0, sizeof(*p)); | 4693 | memset(p, 0, sizeof(*p)); |
4631 | p->protocol_min = cpu_to_be32(PRO_VERSION_MIN); | 4694 | p->protocol_min = cpu_to_be32(PRO_VERSION_MIN); |
4632 | p->protocol_max = cpu_to_be32(PRO_VERSION_MAX); | 4695 | p->protocol_max = cpu_to_be32(PRO_VERSION_MAX); |
4696 | p->feature_flags = cpu_to_be32(PRO_FEATURES); | ||
4633 | return conn_send_command(connection, sock, P_CONNECTION_FEATURES, sizeof(*p), NULL, 0); | 4697 | return conn_send_command(connection, sock, P_CONNECTION_FEATURES, sizeof(*p), NULL, 0); |
4634 | } | 4698 | } |
4635 | 4699 | ||
@@ -4683,10 +4747,14 @@ static int drbd_do_features(struct drbd_connection *connection) | |||
4683 | goto incompat; | 4747 | goto incompat; |
4684 | 4748 | ||
4685 | connection->agreed_pro_version = min_t(int, PRO_VERSION_MAX, p->protocol_max); | 4749 | connection->agreed_pro_version = min_t(int, PRO_VERSION_MAX, p->protocol_max); |
4750 | connection->agreed_features = PRO_FEATURES & be32_to_cpu(p->feature_flags); | ||
4686 | 4751 | ||
4687 | drbd_info(connection, "Handshake successful: " | 4752 | drbd_info(connection, "Handshake successful: " |
4688 | "Agreed network protocol version %d\n", connection->agreed_pro_version); | 4753 | "Agreed network protocol version %d\n", connection->agreed_pro_version); |
4689 | 4754 | ||
4755 | drbd_info(connection, "Agreed to%ssupport TRIM on protocol level\n", | ||
4756 | connection->agreed_features & FF_TRIM ? " " : " not "); | ||
4757 | |||
4690 | return 1; | 4758 | return 1; |
4691 | 4759 | ||
4692 | incompat: | 4760 | incompat: |
@@ -4778,6 +4846,12 @@ static int drbd_do_auth(struct drbd_connection *connection) | |||
4778 | goto fail; | 4846 | goto fail; |
4779 | } | 4847 | } |
4780 | 4848 | ||
4849 | if (pi.size < CHALLENGE_LEN) { | ||
4850 | drbd_err(connection, "AuthChallenge payload too small.\n"); | ||
4851 | rv = -1; | ||
4852 | goto fail; | ||
4853 | } | ||
4854 | |||
4781 | peers_ch = kmalloc(pi.size, GFP_NOIO); | 4855 | peers_ch = kmalloc(pi.size, GFP_NOIO); |
4782 | if (peers_ch == NULL) { | 4856 | if (peers_ch == NULL) { |
4783 | drbd_err(connection, "kmalloc of peers_ch failed\n"); | 4857 | drbd_err(connection, "kmalloc of peers_ch failed\n"); |
@@ -4791,6 +4865,12 @@ static int drbd_do_auth(struct drbd_connection *connection) | |||
4791 | goto fail; | 4865 | goto fail; |
4792 | } | 4866 | } |
4793 | 4867 | ||
4868 | if (!memcmp(my_challenge, peers_ch, CHALLENGE_LEN)) { | ||
4869 | drbd_err(connection, "Peer presented the same challenge!\n"); | ||
4870 | rv = -1; | ||
4871 | goto fail; | ||
4872 | } | ||
4873 | |||
4794 | resp_size = crypto_hash_digestsize(connection->cram_hmac_tfm); | 4874 | resp_size = crypto_hash_digestsize(connection->cram_hmac_tfm); |
4795 | response = kmalloc(resp_size, GFP_NOIO); | 4875 | response = kmalloc(resp_size, GFP_NOIO); |
4796 | if (response == NULL) { | 4876 | if (response == NULL) { |
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 3779c8d2875b..09803d0d5207 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c | |||
@@ -522,6 +522,13 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, | |||
522 | mod_rq_state(req, m, RQ_LOCAL_PENDING, RQ_LOCAL_COMPLETED); | 522 | mod_rq_state(req, m, RQ_LOCAL_PENDING, RQ_LOCAL_COMPLETED); |
523 | break; | 523 | break; |
524 | 524 | ||
525 | case DISCARD_COMPLETED_NOTSUPP: | ||
526 | case DISCARD_COMPLETED_WITH_ERROR: | ||
527 | /* I'd rather not detach from local disk just because it | ||
528 | * failed a REQ_DISCARD. */ | ||
529 | mod_rq_state(req, m, RQ_LOCAL_PENDING, RQ_LOCAL_COMPLETED); | ||
530 | break; | ||
531 | |||
525 | case QUEUE_FOR_NET_READ: | 532 | case QUEUE_FOR_NET_READ: |
526 | /* READ or READA, and | 533 | /* READ or READA, and |
527 | * no local disk, | 534 | * no local disk, |
@@ -1235,6 +1242,7 @@ void do_submit(struct work_struct *ws) | |||
1235 | if (list_empty(&incoming)) | 1242 | if (list_empty(&incoming)) |
1236 | break; | 1243 | break; |
1237 | 1244 | ||
1245 | skip_fast_path: | ||
1238 | wait_event(device->al_wait, prepare_al_transaction_nonblock(device, &incoming, &pending)); | 1246 | wait_event(device->al_wait, prepare_al_transaction_nonblock(device, &incoming, &pending)); |
1239 | /* Maybe more was queued, while we prepared the transaction? | 1247 | /* Maybe more was queued, while we prepared the transaction? |
1240 | * Try to stuff them into this transaction as well. | 1248 | * Try to stuff them into this transaction as well. |
@@ -1273,6 +1281,25 @@ void do_submit(struct work_struct *ws) | |||
1273 | list_del_init(&req->tl_requests); | 1281 | list_del_init(&req->tl_requests); |
1274 | drbd_send_and_submit(device, req); | 1282 | drbd_send_and_submit(device, req); |
1275 | } | 1283 | } |
1284 | |||
1285 | /* If all currently hot activity log extents are kept busy by | ||
1286 | * incoming requests, we still must not totally starve new | ||
1287 | * requests to cold extents. In that case, prepare one request | ||
1288 | * in blocking mode. */ | ||
1289 | list_for_each_entry_safe(req, tmp, &incoming, tl_requests) { | ||
1290 | list_del_init(&req->tl_requests); | ||
1291 | req->rq_state |= RQ_IN_ACT_LOG; | ||
1292 | if (!drbd_al_begin_io_prepare(device, &req->i)) { | ||
1293 | /* Corresponding extent was hot after all? */ | ||
1294 | drbd_send_and_submit(device, req); | ||
1295 | } else { | ||
1296 | /* Found a request to a cold extent. | ||
1297 | * Put on "pending" list, | ||
1298 | * and try to cumulate with more. */ | ||
1299 | list_add(&req->tl_requests, &pending); | ||
1300 | goto skip_fast_path; | ||
1301 | } | ||
1302 | } | ||
1276 | } | 1303 | } |
1277 | } | 1304 | } |
1278 | 1305 | ||
@@ -1326,23 +1353,35 @@ int drbd_merge_bvec(struct request_queue *q, struct bvec_merge_data *bvm, struct | |||
1326 | return limit; | 1353 | return limit; |
1327 | } | 1354 | } |
1328 | 1355 | ||
1329 | static struct drbd_request *find_oldest_request(struct drbd_connection *connection) | 1356 | static void find_oldest_requests( |
1357 | struct drbd_connection *connection, | ||
1358 | struct drbd_device *device, | ||
1359 | struct drbd_request **oldest_req_waiting_for_peer, | ||
1360 | struct drbd_request **oldest_req_waiting_for_disk) | ||
1330 | { | 1361 | { |
1331 | /* Walk the transfer log, | ||
1332 | * and find the oldest not yet completed request */ | ||
1333 | struct drbd_request *r; | 1362 | struct drbd_request *r; |
1363 | *oldest_req_waiting_for_peer = NULL; | ||
1364 | *oldest_req_waiting_for_disk = NULL; | ||
1334 | list_for_each_entry(r, &connection->transfer_log, tl_requests) { | 1365 | list_for_each_entry(r, &connection->transfer_log, tl_requests) { |
1335 | if (atomic_read(&r->completion_ref)) | 1366 | const unsigned s = r->rq_state; |
1336 | return r; | 1367 | if (!*oldest_req_waiting_for_peer |
1368 | && ((s & RQ_NET_MASK) && !(s & RQ_NET_DONE))) | ||
1369 | *oldest_req_waiting_for_peer = r; | ||
1370 | |||
1371 | if (!*oldest_req_waiting_for_disk | ||
1372 | && (s & RQ_LOCAL_PENDING) && r->device == device) | ||
1373 | *oldest_req_waiting_for_disk = r; | ||
1374 | |||
1375 | if (*oldest_req_waiting_for_peer && *oldest_req_waiting_for_disk) | ||
1376 | break; | ||
1337 | } | 1377 | } |
1338 | return NULL; | ||
1339 | } | 1378 | } |
1340 | 1379 | ||
1341 | void request_timer_fn(unsigned long data) | 1380 | void request_timer_fn(unsigned long data) |
1342 | { | 1381 | { |
1343 | struct drbd_device *device = (struct drbd_device *) data; | 1382 | struct drbd_device *device = (struct drbd_device *) data; |
1344 | struct drbd_connection *connection = first_peer_device(device)->connection; | 1383 | struct drbd_connection *connection = first_peer_device(device)->connection; |
1345 | struct drbd_request *req; /* oldest request */ | 1384 | struct drbd_request *req_disk, *req_peer; /* oldest request */ |
1346 | struct net_conf *nc; | 1385 | struct net_conf *nc; |
1347 | unsigned long ent = 0, dt = 0, et, nt; /* effective timeout = ko_count * timeout */ | 1386 | unsigned long ent = 0, dt = 0, et, nt; /* effective timeout = ko_count * timeout */ |
1348 | unsigned long now; | 1387 | unsigned long now; |
@@ -1366,8 +1405,8 @@ void request_timer_fn(unsigned long data) | |||
1366 | now = jiffies; | 1405 | now = jiffies; |
1367 | 1406 | ||
1368 | spin_lock_irq(&device->resource->req_lock); | 1407 | spin_lock_irq(&device->resource->req_lock); |
1369 | req = find_oldest_request(connection); | 1408 | find_oldest_requests(connection, device, &req_peer, &req_disk); |
1370 | if (!req) { | 1409 | if (req_peer == NULL && req_disk == NULL) { |
1371 | spin_unlock_irq(&device->resource->req_lock); | 1410 | spin_unlock_irq(&device->resource->req_lock); |
1372 | mod_timer(&device->request_timer, now + et); | 1411 | mod_timer(&device->request_timer, now + et); |
1373 | return; | 1412 | return; |
@@ -1389,19 +1428,26 @@ void request_timer_fn(unsigned long data) | |||
1389 | * ~198 days with 250 HZ, we have a window where the timeout would need | 1428 | * ~198 days with 250 HZ, we have a window where the timeout would need |
1390 | * to expire twice (worst case) to become effective. Good enough. | 1429 | * to expire twice (worst case) to become effective. Good enough. |
1391 | */ | 1430 | */ |
1392 | if (ent && req->rq_state & RQ_NET_PENDING && | 1431 | if (ent && req_peer && |
1393 | time_after(now, req->start_time + ent) && | 1432 | time_after(now, req_peer->start_time + ent) && |
1394 | !time_in_range(now, connection->last_reconnect_jif, connection->last_reconnect_jif + ent)) { | 1433 | !time_in_range(now, connection->last_reconnect_jif, connection->last_reconnect_jif + ent)) { |
1395 | drbd_warn(device, "Remote failed to finish a request within ko-count * timeout\n"); | 1434 | drbd_warn(device, "Remote failed to finish a request within ko-count * timeout\n"); |
1396 | _drbd_set_state(_NS(device, conn, C_TIMEOUT), CS_VERBOSE | CS_HARD, NULL); | 1435 | _drbd_set_state(_NS(device, conn, C_TIMEOUT), CS_VERBOSE | CS_HARD, NULL); |
1397 | } | 1436 | } |
1398 | if (dt && req->rq_state & RQ_LOCAL_PENDING && req->device == device && | 1437 | if (dt && req_disk && |
1399 | time_after(now, req->start_time + dt) && | 1438 | time_after(now, req_disk->start_time + dt) && |
1400 | !time_in_range(now, device->last_reattach_jif, device->last_reattach_jif + dt)) { | 1439 | !time_in_range(now, device->last_reattach_jif, device->last_reattach_jif + dt)) { |
1401 | drbd_warn(device, "Local backing device failed to meet the disk-timeout\n"); | 1440 | drbd_warn(device, "Local backing device failed to meet the disk-timeout\n"); |
1402 | __drbd_chk_io_error(device, DRBD_FORCE_DETACH); | 1441 | __drbd_chk_io_error(device, DRBD_FORCE_DETACH); |
1403 | } | 1442 | } |
1404 | nt = (time_after(now, req->start_time + et) ? now : req->start_time) + et; | 1443 | |
1444 | /* Reschedule timer for the nearest not already expired timeout. | ||
1445 | * Fallback to now + min(effective network timeout, disk timeout). */ | ||
1446 | ent = (ent && req_peer && time_before(now, req_peer->start_time + ent)) | ||
1447 | ? req_peer->start_time + ent : now + et; | ||
1448 | dt = (dt && req_disk && time_before(now, req_disk->start_time + dt)) | ||
1449 | ? req_disk->start_time + dt : now + et; | ||
1450 | nt = time_before(ent, dt) ? ent : dt; | ||
1405 | spin_unlock_irq(&connection->resource->req_lock); | 1451 | spin_unlock_irq(&connection->resource->req_lock); |
1406 | mod_timer(&device->request_timer, nt); | 1452 | mod_timer(&device->request_timer, nt); |
1407 | } | 1453 | } |
diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h index c684c963538e..8566cd5866b4 100644 --- a/drivers/block/drbd/drbd_req.h +++ b/drivers/block/drbd/drbd_req.h | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <linux/drbd.h> | 31 | #include <linux/drbd.h> |
32 | #include "drbd_int.h" | 32 | #include "drbd_int.h" |
33 | #include "drbd_wrappers.h" | ||
34 | 33 | ||
35 | /* The request callbacks will be called in irq context by the IDE drivers, | 34 | /* The request callbacks will be called in irq context by the IDE drivers, |
36 | and in Softirqs/Tasklets/BH context by the SCSI drivers, | 35 | and in Softirqs/Tasklets/BH context by the SCSI drivers, |
@@ -111,11 +110,14 @@ enum drbd_req_event { | |||
111 | BARRIER_ACKED, /* in protocol A and B */ | 110 | BARRIER_ACKED, /* in protocol A and B */ |
112 | DATA_RECEIVED, /* (remote read) */ | 111 | DATA_RECEIVED, /* (remote read) */ |
113 | 112 | ||
113 | COMPLETED_OK, | ||
114 | READ_COMPLETED_WITH_ERROR, | 114 | READ_COMPLETED_WITH_ERROR, |
115 | READ_AHEAD_COMPLETED_WITH_ERROR, | 115 | READ_AHEAD_COMPLETED_WITH_ERROR, |
116 | WRITE_COMPLETED_WITH_ERROR, | 116 | WRITE_COMPLETED_WITH_ERROR, |
117 | DISCARD_COMPLETED_NOTSUPP, | ||
118 | DISCARD_COMPLETED_WITH_ERROR, | ||
119 | |||
117 | ABORT_DISK_IO, | 120 | ABORT_DISK_IO, |
118 | COMPLETED_OK, | ||
119 | RESEND, | 121 | RESEND, |
120 | FAIL_FROZEN_DISK_IO, | 122 | FAIL_FROZEN_DISK_IO, |
121 | RESTART_FROZEN_DISK_IO, | 123 | RESTART_FROZEN_DISK_IO, |
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c index 1a84345a3868..a5d8aae00e04 100644 --- a/drivers/block/drbd/drbd_state.c +++ b/drivers/block/drbd/drbd_state.c | |||
@@ -54,8 +54,8 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os, | |||
54 | static enum drbd_state_rv is_valid_state(struct drbd_device *, union drbd_state); | 54 | static enum drbd_state_rv is_valid_state(struct drbd_device *, union drbd_state); |
55 | static enum drbd_state_rv is_valid_soft_transition(union drbd_state, union drbd_state, struct drbd_connection *); | 55 | static enum drbd_state_rv is_valid_soft_transition(union drbd_state, union drbd_state, struct drbd_connection *); |
56 | static enum drbd_state_rv is_valid_transition(union drbd_state os, union drbd_state ns); | 56 | static enum drbd_state_rv is_valid_transition(union drbd_state os, union drbd_state ns); |
57 | static union drbd_state sanitize_state(struct drbd_device *device, union drbd_state ns, | 57 | static union drbd_state sanitize_state(struct drbd_device *device, union drbd_state os, |
58 | enum sanitize_state_warnings *warn); | 58 | union drbd_state ns, enum sanitize_state_warnings *warn); |
59 | 59 | ||
60 | static inline bool is_susp(union drbd_state s) | 60 | static inline bool is_susp(union drbd_state s) |
61 | { | 61 | { |
@@ -287,7 +287,7 @@ _req_st_cond(struct drbd_device *device, union drbd_state mask, | |||
287 | 287 | ||
288 | spin_lock_irqsave(&device->resource->req_lock, flags); | 288 | spin_lock_irqsave(&device->resource->req_lock, flags); |
289 | os = drbd_read_state(device); | 289 | os = drbd_read_state(device); |
290 | ns = sanitize_state(device, apply_mask_val(os, mask, val), NULL); | 290 | ns = sanitize_state(device, os, apply_mask_val(os, mask, val), NULL); |
291 | rv = is_valid_transition(os, ns); | 291 | rv = is_valid_transition(os, ns); |
292 | if (rv >= SS_SUCCESS) | 292 | if (rv >= SS_SUCCESS) |
293 | rv = SS_UNKNOWN_ERROR; /* cont waiting, otherwise fail. */ | 293 | rv = SS_UNKNOWN_ERROR; /* cont waiting, otherwise fail. */ |
@@ -333,7 +333,7 @@ drbd_req_state(struct drbd_device *device, union drbd_state mask, | |||
333 | 333 | ||
334 | spin_lock_irqsave(&device->resource->req_lock, flags); | 334 | spin_lock_irqsave(&device->resource->req_lock, flags); |
335 | os = drbd_read_state(device); | 335 | os = drbd_read_state(device); |
336 | ns = sanitize_state(device, apply_mask_val(os, mask, val), NULL); | 336 | ns = sanitize_state(device, os, apply_mask_val(os, mask, val), NULL); |
337 | rv = is_valid_transition(os, ns); | 337 | rv = is_valid_transition(os, ns); |
338 | if (rv < SS_SUCCESS) { | 338 | if (rv < SS_SUCCESS) { |
339 | spin_unlock_irqrestore(&device->resource->req_lock, flags); | 339 | spin_unlock_irqrestore(&device->resource->req_lock, flags); |
@@ -740,8 +740,8 @@ static void print_sanitize_warnings(struct drbd_device *device, enum sanitize_st | |||
740 | * When we loose connection, we have to set the state of the peers disk (pdsk) | 740 | * When we loose connection, we have to set the state of the peers disk (pdsk) |
741 | * to D_UNKNOWN. This rule and many more along those lines are in this function. | 741 | * to D_UNKNOWN. This rule and many more along those lines are in this function. |
742 | */ | 742 | */ |
743 | static union drbd_state sanitize_state(struct drbd_device *device, union drbd_state ns, | 743 | static union drbd_state sanitize_state(struct drbd_device *device, union drbd_state os, |
744 | enum sanitize_state_warnings *warn) | 744 | union drbd_state ns, enum sanitize_state_warnings *warn) |
745 | { | 745 | { |
746 | enum drbd_fencing_p fp; | 746 | enum drbd_fencing_p fp; |
747 | enum drbd_disk_state disk_min, disk_max, pdsk_min, pdsk_max; | 747 | enum drbd_disk_state disk_min, disk_max, pdsk_min, pdsk_max; |
@@ -882,11 +882,13 @@ static union drbd_state sanitize_state(struct drbd_device *device, union drbd_st | |||
882 | } | 882 | } |
883 | 883 | ||
884 | if (fp == FP_STONITH && | 884 | if (fp == FP_STONITH && |
885 | (ns.role == R_PRIMARY && ns.conn < C_CONNECTED && ns.pdsk > D_OUTDATED)) | 885 | (ns.role == R_PRIMARY && ns.conn < C_CONNECTED && ns.pdsk > D_OUTDATED) && |
886 | !(os.role == R_PRIMARY && os.conn < C_CONNECTED && os.pdsk > D_OUTDATED)) | ||
886 | ns.susp_fen = 1; /* Suspend IO while fence-peer handler runs (peer lost) */ | 887 | ns.susp_fen = 1; /* Suspend IO while fence-peer handler runs (peer lost) */ |
887 | 888 | ||
888 | if (device->resource->res_opts.on_no_data == OND_SUSPEND_IO && | 889 | if (device->resource->res_opts.on_no_data == OND_SUSPEND_IO && |
889 | (ns.role == R_PRIMARY && ns.disk < D_UP_TO_DATE && ns.pdsk < D_UP_TO_DATE)) | 890 | (ns.role == R_PRIMARY && ns.disk < D_UP_TO_DATE && ns.pdsk < D_UP_TO_DATE) && |
891 | !(os.role == R_PRIMARY && os.disk < D_UP_TO_DATE && os.pdsk < D_UP_TO_DATE)) | ||
890 | ns.susp_nod = 1; /* Suspend IO while no data available (no accessible data available) */ | 892 | ns.susp_nod = 1; /* Suspend IO while no data available (no accessible data available) */ |
891 | 893 | ||
892 | if (ns.aftr_isp || ns.peer_isp || ns.user_isp) { | 894 | if (ns.aftr_isp || ns.peer_isp || ns.user_isp) { |
@@ -958,7 +960,7 @@ __drbd_set_state(struct drbd_device *device, union drbd_state ns, | |||
958 | 960 | ||
959 | os = drbd_read_state(device); | 961 | os = drbd_read_state(device); |
960 | 962 | ||
961 | ns = sanitize_state(device, ns, &ssw); | 963 | ns = sanitize_state(device, os, ns, &ssw); |
962 | if (ns.i == os.i) | 964 | if (ns.i == os.i) |
963 | return SS_NOTHING_TO_DO; | 965 | return SS_NOTHING_TO_DO; |
964 | 966 | ||
@@ -1656,7 +1658,7 @@ conn_is_valid_transition(struct drbd_connection *connection, union drbd_state ma | |||
1656 | idr_for_each_entry(&connection->peer_devices, peer_device, vnr) { | 1658 | idr_for_each_entry(&connection->peer_devices, peer_device, vnr) { |
1657 | struct drbd_device *device = peer_device->device; | 1659 | struct drbd_device *device = peer_device->device; |
1658 | os = drbd_read_state(device); | 1660 | os = drbd_read_state(device); |
1659 | ns = sanitize_state(device, apply_mask_val(os, mask, val), NULL); | 1661 | ns = sanitize_state(device, os, apply_mask_val(os, mask, val), NULL); |
1660 | 1662 | ||
1661 | if (flags & CS_IGN_OUTD_FAIL && ns.disk == D_OUTDATED && os.disk < D_OUTDATED) | 1663 | if (flags & CS_IGN_OUTD_FAIL && ns.disk == D_OUTDATED && os.disk < D_OUTDATED) |
1662 | ns.disk = os.disk; | 1664 | ns.disk = os.disk; |
@@ -1718,7 +1720,7 @@ conn_set_state(struct drbd_connection *connection, union drbd_state mask, union | |||
1718 | number_of_volumes++; | 1720 | number_of_volumes++; |
1719 | os = drbd_read_state(device); | 1721 | os = drbd_read_state(device); |
1720 | ns = apply_mask_val(os, mask, val); | 1722 | ns = apply_mask_val(os, mask, val); |
1721 | ns = sanitize_state(device, ns, NULL); | 1723 | ns = sanitize_state(device, os, ns, NULL); |
1722 | 1724 | ||
1723 | if (flags & CS_IGN_OUTD_FAIL && ns.disk == D_OUTDATED && os.disk < D_OUTDATED) | 1725 | if (flags & CS_IGN_OUTD_FAIL && ns.disk == D_OUTDATED && os.disk < D_OUTDATED) |
1724 | ns.disk = os.disk; | 1726 | ns.disk = os.disk; |
@@ -1763,19 +1765,19 @@ conn_set_state(struct drbd_connection *connection, union drbd_state mask, union | |||
1763 | static enum drbd_state_rv | 1765 | static enum drbd_state_rv |
1764 | _conn_rq_cond(struct drbd_connection *connection, union drbd_state mask, union drbd_state val) | 1766 | _conn_rq_cond(struct drbd_connection *connection, union drbd_state mask, union drbd_state val) |
1765 | { | 1767 | { |
1766 | enum drbd_state_rv rv; | 1768 | enum drbd_state_rv err, rv = SS_UNKNOWN_ERROR; /* continue waiting */; |
1767 | 1769 | ||
1768 | if (test_and_clear_bit(CONN_WD_ST_CHG_OKAY, &connection->flags)) | 1770 | if (test_and_clear_bit(CONN_WD_ST_CHG_OKAY, &connection->flags)) |
1769 | return SS_CW_SUCCESS; | 1771 | rv = SS_CW_SUCCESS; |
1770 | 1772 | ||
1771 | if (test_and_clear_bit(CONN_WD_ST_CHG_FAIL, &connection->flags)) | 1773 | if (test_and_clear_bit(CONN_WD_ST_CHG_FAIL, &connection->flags)) |
1772 | return SS_CW_FAILED_BY_PEER; | 1774 | rv = SS_CW_FAILED_BY_PEER; |
1773 | 1775 | ||
1774 | rv = conn_is_valid_transition(connection, mask, val, 0); | 1776 | err = conn_is_valid_transition(connection, mask, val, 0); |
1775 | if (rv == SS_SUCCESS && connection->cstate == C_WF_REPORT_PARAMS) | 1777 | if (err == SS_SUCCESS && connection->cstate == C_WF_REPORT_PARAMS) |
1776 | rv = SS_UNKNOWN_ERROR; /* continue waiting */ | 1778 | return rv; |
1777 | 1779 | ||
1778 | return rv; | 1780 | return err; |
1779 | } | 1781 | } |
1780 | 1782 | ||
1781 | enum drbd_state_rv | 1783 | enum drbd_state_rv |
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index 2c4ce42c3657..d8f57b6305cd 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c | |||
@@ -118,7 +118,7 @@ static void drbd_endio_read_sec_final(struct drbd_peer_request *peer_req) __rele | |||
118 | 118 | ||
119 | /* writes on behalf of the partner, or resync writes, | 119 | /* writes on behalf of the partner, or resync writes, |
120 | * "submitted" by the receiver, final stage. */ | 120 | * "submitted" by the receiver, final stage. */ |
121 | static void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req) __releases(local) | 121 | void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req) __releases(local) |
122 | { | 122 | { |
123 | unsigned long flags = 0; | 123 | unsigned long flags = 0; |
124 | struct drbd_peer_device *peer_device = peer_req->peer_device; | 124 | struct drbd_peer_device *peer_device = peer_req->peer_device; |
@@ -150,7 +150,9 @@ static void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req) __rel | |||
150 | 150 | ||
151 | do_wake = list_empty(block_id == ID_SYNCER ? &device->sync_ee : &device->active_ee); | 151 | do_wake = list_empty(block_id == ID_SYNCER ? &device->sync_ee : &device->active_ee); |
152 | 152 | ||
153 | if (test_bit(__EE_WAS_ERROR, &peer_req->flags)) | 153 | /* FIXME do we want to detach for failed REQ_DISCARD? |
154 | * ((peer_req->flags & (EE_WAS_ERROR|EE_IS_TRIM)) == EE_WAS_ERROR) */ | ||
155 | if (peer_req->flags & EE_WAS_ERROR) | ||
154 | __drbd_chk_io_error(device, DRBD_WRITE_ERROR); | 156 | __drbd_chk_io_error(device, DRBD_WRITE_ERROR); |
155 | spin_unlock_irqrestore(&device->resource->req_lock, flags); | 157 | spin_unlock_irqrestore(&device->resource->req_lock, flags); |
156 | 158 | ||
@@ -176,10 +178,12 @@ void drbd_peer_request_endio(struct bio *bio, int error) | |||
176 | struct drbd_device *device = peer_req->peer_device->device; | 178 | struct drbd_device *device = peer_req->peer_device->device; |
177 | int uptodate = bio_flagged(bio, BIO_UPTODATE); | 179 | int uptodate = bio_flagged(bio, BIO_UPTODATE); |
178 | int is_write = bio_data_dir(bio) == WRITE; | 180 | int is_write = bio_data_dir(bio) == WRITE; |
181 | int is_discard = !!(bio->bi_rw & REQ_DISCARD); | ||
179 | 182 | ||
180 | if (error && __ratelimit(&drbd_ratelimit_state)) | 183 | if (error && __ratelimit(&drbd_ratelimit_state)) |
181 | drbd_warn(device, "%s: error=%d s=%llus\n", | 184 | drbd_warn(device, "%s: error=%d s=%llus\n", |
182 | is_write ? "write" : "read", error, | 185 | is_write ? (is_discard ? "discard" : "write") |
186 | : "read", error, | ||
183 | (unsigned long long)peer_req->i.sector); | 187 | (unsigned long long)peer_req->i.sector); |
184 | if (!error && !uptodate) { | 188 | if (!error && !uptodate) { |
185 | if (__ratelimit(&drbd_ratelimit_state)) | 189 | if (__ratelimit(&drbd_ratelimit_state)) |
@@ -263,7 +267,12 @@ void drbd_request_endio(struct bio *bio, int error) | |||
263 | 267 | ||
264 | /* to avoid recursion in __req_mod */ | 268 | /* to avoid recursion in __req_mod */ |
265 | if (unlikely(error)) { | 269 | if (unlikely(error)) { |
266 | what = (bio_data_dir(bio) == WRITE) | 270 | if (bio->bi_rw & REQ_DISCARD) |
271 | what = (error == -EOPNOTSUPP) | ||
272 | ? DISCARD_COMPLETED_NOTSUPP | ||
273 | : DISCARD_COMPLETED_WITH_ERROR; | ||
274 | else | ||
275 | what = (bio_data_dir(bio) == WRITE) | ||
267 | ? WRITE_COMPLETED_WITH_ERROR | 276 | ? WRITE_COMPLETED_WITH_ERROR |
268 | : (bio_rw(bio) == READ) | 277 | : (bio_rw(bio) == READ) |
269 | ? READ_COMPLETED_WITH_ERROR | 278 | ? READ_COMPLETED_WITH_ERROR |
@@ -395,7 +404,7 @@ static int read_for_csum(struct drbd_peer_device *peer_device, sector_t sector, | |||
395 | /* GFP_TRY, because if there is no memory available right now, this may | 404 | /* GFP_TRY, because if there is no memory available right now, this may |
396 | * be rescheduled for later. It is "only" background resync, after all. */ | 405 | * be rescheduled for later. It is "only" background resync, after all. */ |
397 | peer_req = drbd_alloc_peer_req(peer_device, ID_SYNCER /* unused */, sector, | 406 | peer_req = drbd_alloc_peer_req(peer_device, ID_SYNCER /* unused */, sector, |
398 | size, GFP_TRY); | 407 | size, true /* has real payload */, GFP_TRY); |
399 | if (!peer_req) | 408 | if (!peer_req) |
400 | goto defer; | 409 | goto defer; |
401 | 410 | ||
@@ -492,10 +501,9 @@ struct fifo_buffer *fifo_alloc(int fifo_size) | |||
492 | return fb; | 501 | return fb; |
493 | } | 502 | } |
494 | 503 | ||
495 | static int drbd_rs_controller(struct drbd_device *device) | 504 | static int drbd_rs_controller(struct drbd_device *device, unsigned int sect_in) |
496 | { | 505 | { |
497 | struct disk_conf *dc; | 506 | struct disk_conf *dc; |
498 | unsigned int sect_in; /* Number of sectors that came in since the last turn */ | ||
499 | unsigned int want; /* The number of sectors we want in the proxy */ | 507 | unsigned int want; /* The number of sectors we want in the proxy */ |
500 | int req_sect; /* Number of sectors to request in this turn */ | 508 | int req_sect; /* Number of sectors to request in this turn */ |
501 | int correction; /* Number of sectors more we need in the proxy*/ | 509 | int correction; /* Number of sectors more we need in the proxy*/ |
@@ -505,9 +513,6 @@ static int drbd_rs_controller(struct drbd_device *device) | |||
505 | int max_sect; | 513 | int max_sect; |
506 | struct fifo_buffer *plan; | 514 | struct fifo_buffer *plan; |
507 | 515 | ||
508 | sect_in = atomic_xchg(&device->rs_sect_in, 0); /* Number of sectors that came in */ | ||
509 | device->rs_in_flight -= sect_in; | ||
510 | |||
511 | dc = rcu_dereference(device->ldev->disk_conf); | 516 | dc = rcu_dereference(device->ldev->disk_conf); |
512 | plan = rcu_dereference(device->rs_plan_s); | 517 | plan = rcu_dereference(device->rs_plan_s); |
513 | 518 | ||
@@ -550,11 +555,16 @@ static int drbd_rs_controller(struct drbd_device *device) | |||
550 | 555 | ||
551 | static int drbd_rs_number_requests(struct drbd_device *device) | 556 | static int drbd_rs_number_requests(struct drbd_device *device) |
552 | { | 557 | { |
553 | int number; | 558 | unsigned int sect_in; /* Number of sectors that came in since the last turn */ |
559 | int number, mxb; | ||
560 | |||
561 | sect_in = atomic_xchg(&device->rs_sect_in, 0); | ||
562 | device->rs_in_flight -= sect_in; | ||
554 | 563 | ||
555 | rcu_read_lock(); | 564 | rcu_read_lock(); |
565 | mxb = drbd_get_max_buffers(device) / 2; | ||
556 | if (rcu_dereference(device->rs_plan_s)->size) { | 566 | if (rcu_dereference(device->rs_plan_s)->size) { |
557 | number = drbd_rs_controller(device) >> (BM_BLOCK_SHIFT - 9); | 567 | number = drbd_rs_controller(device, sect_in) >> (BM_BLOCK_SHIFT - 9); |
558 | device->c_sync_rate = number * HZ * (BM_BLOCK_SIZE / 1024) / SLEEP_TIME; | 568 | device->c_sync_rate = number * HZ * (BM_BLOCK_SIZE / 1024) / SLEEP_TIME; |
559 | } else { | 569 | } else { |
560 | device->c_sync_rate = rcu_dereference(device->ldev->disk_conf)->resync_rate; | 570 | device->c_sync_rate = rcu_dereference(device->ldev->disk_conf)->resync_rate; |
@@ -562,8 +572,14 @@ static int drbd_rs_number_requests(struct drbd_device *device) | |||
562 | } | 572 | } |
563 | rcu_read_unlock(); | 573 | rcu_read_unlock(); |
564 | 574 | ||
565 | /* ignore the amount of pending requests, the resync controller should | 575 | /* Don't have more than "max-buffers"/2 in-flight. |
566 | * throttle down to incoming reply rate soon enough anyways. */ | 576 | * Otherwise we may cause the remote site to stall on drbd_alloc_pages(), |
577 | * potentially causing a distributed deadlock on congestion during | ||
578 | * online-verify or (checksum-based) resync, if max-buffers, | ||
579 | * socket buffer sizes and resync rate settings are mis-configured. */ | ||
580 | if (mxb - device->rs_in_flight < number) | ||
581 | number = mxb - device->rs_in_flight; | ||
582 | |||
567 | return number; | 583 | return number; |
568 | } | 584 | } |
569 | 585 | ||
@@ -597,7 +613,7 @@ static int make_resync_request(struct drbd_device *device, int cancel) | |||
597 | 613 | ||
598 | max_bio_size = queue_max_hw_sectors(device->rq_queue) << 9; | 614 | max_bio_size = queue_max_hw_sectors(device->rq_queue) << 9; |
599 | number = drbd_rs_number_requests(device); | 615 | number = drbd_rs_number_requests(device); |
600 | if (number == 0) | 616 | if (number <= 0) |
601 | goto requeue; | 617 | goto requeue; |
602 | 618 | ||
603 | for (i = 0; i < number; i++) { | 619 | for (i = 0; i < number; i++) { |
@@ -647,7 +663,7 @@ next_sector: | |||
647 | */ | 663 | */ |
648 | align = 1; | 664 | align = 1; |
649 | rollback_i = i; | 665 | rollback_i = i; |
650 | for (;;) { | 666 | while (i < number) { |
651 | if (size + BM_BLOCK_SIZE > max_bio_size) | 667 | if (size + BM_BLOCK_SIZE > max_bio_size) |
652 | break; | 668 | break; |
653 | 669 | ||
@@ -1670,11 +1686,15 @@ void drbd_start_resync(struct drbd_device *device, enum drbd_conns side) | |||
1670 | } | 1686 | } |
1671 | clear_bit(B_RS_H_DONE, &device->flags); | 1687 | clear_bit(B_RS_H_DONE, &device->flags); |
1672 | 1688 | ||
1673 | write_lock_irq(&global_state_lock); | 1689 | /* req_lock: serialize with drbd_send_and_submit() and others |
1690 | * global_state_lock: for stable sync-after dependencies */ | ||
1691 | spin_lock_irq(&device->resource->req_lock); | ||
1692 | write_lock(&global_state_lock); | ||
1674 | /* Did some connection breakage or IO error race with us? */ | 1693 | /* Did some connection breakage or IO error race with us? */ |
1675 | if (device->state.conn < C_CONNECTED | 1694 | if (device->state.conn < C_CONNECTED |
1676 | || !get_ldev_if_state(device, D_NEGOTIATING)) { | 1695 | || !get_ldev_if_state(device, D_NEGOTIATING)) { |
1677 | write_unlock_irq(&global_state_lock); | 1696 | write_unlock(&global_state_lock); |
1697 | spin_unlock_irq(&device->resource->req_lock); | ||
1678 | mutex_unlock(device->state_mutex); | 1698 | mutex_unlock(device->state_mutex); |
1679 | return; | 1699 | return; |
1680 | } | 1700 | } |
@@ -1714,7 +1734,8 @@ void drbd_start_resync(struct drbd_device *device, enum drbd_conns side) | |||
1714 | } | 1734 | } |
1715 | _drbd_pause_after(device); | 1735 | _drbd_pause_after(device); |
1716 | } | 1736 | } |
1717 | write_unlock_irq(&global_state_lock); | 1737 | write_unlock(&global_state_lock); |
1738 | spin_unlock_irq(&device->resource->req_lock); | ||
1718 | 1739 | ||
1719 | if (r == SS_SUCCESS) { | 1740 | if (r == SS_SUCCESS) { |
1720 | /* reset rs_last_bcast when a resync or verify is started, | 1741 | /* reset rs_last_bcast when a resync or verify is started, |
@@ -1778,34 +1799,6 @@ void drbd_start_resync(struct drbd_device *device, enum drbd_conns side) | |||
1778 | mutex_unlock(device->state_mutex); | 1799 | mutex_unlock(device->state_mutex); |
1779 | } | 1800 | } |
1780 | 1801 | ||
1781 | /* If the resource already closed the current epoch, but we did not | ||
1782 | * (because we have not yet seen new requests), we should send the | ||
1783 | * corresponding barrier now. Must be checked within the same spinlock | ||
1784 | * that is used to check for new requests. */ | ||
1785 | static bool need_to_send_barrier(struct drbd_connection *connection) | ||
1786 | { | ||
1787 | if (!connection->send.seen_any_write_yet) | ||
1788 | return false; | ||
1789 | |||
1790 | /* Skip barriers that do not contain any writes. | ||
1791 | * This may happen during AHEAD mode. */ | ||
1792 | if (!connection->send.current_epoch_writes) | ||
1793 | return false; | ||
1794 | |||
1795 | /* ->req_lock is held when requests are queued on | ||
1796 | * connection->sender_work, and put into ->transfer_log. | ||
1797 | * It is also held when ->current_tle_nr is increased. | ||
1798 | * So either there are already new requests queued, | ||
1799 | * and corresponding barriers will be send there. | ||
1800 | * Or nothing new is queued yet, so the difference will be 1. | ||
1801 | */ | ||
1802 | if (atomic_read(&connection->current_tle_nr) != | ||
1803 | connection->send.current_epoch_nr + 1) | ||
1804 | return false; | ||
1805 | |||
1806 | return true; | ||
1807 | } | ||
1808 | |||
1809 | static bool dequeue_work_batch(struct drbd_work_queue *queue, struct list_head *work_list) | 1802 | static bool dequeue_work_batch(struct drbd_work_queue *queue, struct list_head *work_list) |
1810 | { | 1803 | { |
1811 | spin_lock_irq(&queue->q_lock); | 1804 | spin_lock_irq(&queue->q_lock); |
@@ -1864,12 +1857,22 @@ static void wait_for_work(struct drbd_connection *connection, struct list_head * | |||
1864 | spin_unlock_irq(&connection->resource->req_lock); | 1857 | spin_unlock_irq(&connection->resource->req_lock); |
1865 | break; | 1858 | break; |
1866 | } | 1859 | } |
1867 | send_barrier = need_to_send_barrier(connection); | 1860 | |
1861 | /* We found nothing new to do, no to-be-communicated request, | ||
1862 | * no other work item. We may still need to close the last | ||
1863 | * epoch. Next incoming request epoch will be connection -> | ||
1864 | * current transfer log epoch number. If that is different | ||
1865 | * from the epoch of the last request we communicated, it is | ||
1866 | * safe to send the epoch separating barrier now. | ||
1867 | */ | ||
1868 | send_barrier = | ||
1869 | atomic_read(&connection->current_tle_nr) != | ||
1870 | connection->send.current_epoch_nr; | ||
1868 | spin_unlock_irq(&connection->resource->req_lock); | 1871 | spin_unlock_irq(&connection->resource->req_lock); |
1869 | if (send_barrier) { | 1872 | |
1870 | drbd_send_barrier(connection); | 1873 | if (send_barrier) |
1871 | connection->send.current_epoch_nr++; | 1874 | maybe_send_barrier(connection, |
1872 | } | 1875 | connection->send.current_epoch_nr + 1); |
1873 | schedule(); | 1876 | schedule(); |
1874 | /* may be woken up for other things but new work, too, | 1877 | /* may be woken up for other things but new work, too, |
1875 | * e.g. if the current epoch got closed. | 1878 | * e.g. if the current epoch got closed. |
diff --git a/drivers/block/drbd/drbd_wrappers.h b/drivers/block/drbd/drbd_wrappers.h deleted file mode 100644 index 3db9ebaf64f6..000000000000 --- a/drivers/block/drbd/drbd_wrappers.h +++ /dev/null | |||
@@ -1,54 +0,0 @@ | |||
1 | #ifndef _DRBD_WRAPPERS_H | ||
2 | #define _DRBD_WRAPPERS_H | ||
3 | |||
4 | #include <linux/ctype.h> | ||
5 | #include <linux/mm.h> | ||
6 | #include "drbd_int.h" | ||
7 | |||
8 | /* see get_sb_bdev and bd_claim */ | ||
9 | extern char *drbd_sec_holder; | ||
10 | |||
11 | /* sets the number of 512 byte sectors of our virtual device */ | ||
12 | static inline void drbd_set_my_capacity(struct drbd_device *device, | ||
13 | sector_t size) | ||
14 | { | ||
15 | /* set_capacity(device->this_bdev->bd_disk, size); */ | ||
16 | set_capacity(device->vdisk, size); | ||
17 | device->this_bdev->bd_inode->i_size = (loff_t)size << 9; | ||
18 | } | ||
19 | |||
20 | #define drbd_bio_uptodate(bio) bio_flagged(bio, BIO_UPTODATE) | ||
21 | |||
22 | /* bi_end_io handlers */ | ||
23 | extern void drbd_md_io_complete(struct bio *bio, int error); | ||
24 | extern void drbd_peer_request_endio(struct bio *bio, int error); | ||
25 | extern void drbd_request_endio(struct bio *bio, int error); | ||
26 | |||
27 | /* | ||
28 | * used to submit our private bio | ||
29 | */ | ||
30 | static inline void drbd_generic_make_request(struct drbd_device *device, | ||
31 | int fault_type, struct bio *bio) | ||
32 | { | ||
33 | __release(local); | ||
34 | if (!bio->bi_bdev) { | ||
35 | printk(KERN_ERR "drbd%d: drbd_generic_make_request: " | ||
36 | "bio->bi_bdev == NULL\n", | ||
37 | device_to_minor(device)); | ||
38 | dump_stack(); | ||
39 | bio_endio(bio, -ENODEV); | ||
40 | return; | ||
41 | } | ||
42 | |||
43 | if (drbd_insert_fault(device, fault_type)) | ||
44 | bio_endio(bio, -EIO); | ||
45 | else | ||
46 | generic_make_request(bio); | ||
47 | } | ||
48 | |||
49 | #ifndef __CHECKER__ | ||
50 | # undef __cond_lock | ||
51 | # define __cond_lock(x,c) (c) | ||
52 | #endif | ||
53 | |||
54 | #endif | ||
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index dc3a41c82b38..677db049f55a 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c | |||
@@ -3812,7 +3812,7 @@ static int __floppy_read_block_0(struct block_device *bdev, int drive) | |||
3812 | bio.bi_iter.bi_size = size; | 3812 | bio.bi_iter.bi_size = size; |
3813 | bio.bi_bdev = bdev; | 3813 | bio.bi_bdev = bdev; |
3814 | bio.bi_iter.bi_sector = 0; | 3814 | bio.bi_iter.bi_sector = 0; |
3815 | bio.bi_flags = (1 << BIO_QUIET); | 3815 | bio.bi_flags |= (1 << BIO_QUIET); |
3816 | bio.bi_private = &cbdata; | 3816 | bio.bi_private = &cbdata; |
3817 | bio.bi_end_io = floppy_rb0_cb; | 3817 | bio.bi_end_io = floppy_rb0_cb; |
3818 | 3818 | ||
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 59c5abe32f06..abc858b3528b 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/genhd.h> | 32 | #include <linux/genhd.h> |
33 | #include <linux/blkdev.h> | 33 | #include <linux/blkdev.h> |
34 | #include <linux/blk-mq.h> | ||
34 | #include <linux/bio.h> | 35 | #include <linux/bio.h> |
35 | #include <linux/dma-mapping.h> | 36 | #include <linux/dma-mapping.h> |
36 | #include <linux/idr.h> | 37 | #include <linux/idr.h> |
@@ -173,60 +174,34 @@ static bool mtip_check_surprise_removal(struct pci_dev *pdev) | |||
173 | return false; /* device present */ | 174 | return false; /* device present */ |
174 | } | 175 | } |
175 | 176 | ||
176 | /* | 177 | static struct mtip_cmd *mtip_get_int_command(struct driver_data *dd) |
177 | * Obtain an empty command slot. | ||
178 | * | ||
179 | * This function needs to be reentrant since it could be called | ||
180 | * at the same time on multiple CPUs. The allocation of the | ||
181 | * command slot must be atomic. | ||
182 | * | ||
183 | * @port Pointer to the port data structure. | ||
184 | * | ||
185 | * return value | ||
186 | * >= 0 Index of command slot obtained. | ||
187 | * -1 No command slots available. | ||
188 | */ | ||
189 | static int get_slot(struct mtip_port *port) | ||
190 | { | 178 | { |
191 | int slot, i; | 179 | struct request *rq; |
192 | unsigned int num_command_slots = port->dd->slot_groups * 32; | ||
193 | 180 | ||
194 | /* | 181 | rq = blk_mq_alloc_request(dd->queue, 0, __GFP_WAIT, true); |
195 | * Try 10 times, because there is a small race here. | 182 | return blk_mq_rq_to_pdu(rq); |
196 | * that's ok, because it's still cheaper than a lock. | 183 | } |
197 | * | ||
198 | * Race: Since this section is not protected by lock, same bit | ||
199 | * could be chosen by different process contexts running in | ||
200 | * different processor. So instead of costly lock, we are going | ||
201 | * with loop. | ||
202 | */ | ||
203 | for (i = 0; i < 10; i++) { | ||
204 | slot = find_next_zero_bit(port->allocated, | ||
205 | num_command_slots, 1); | ||
206 | if ((slot < num_command_slots) && | ||
207 | (!test_and_set_bit(slot, port->allocated))) | ||
208 | return slot; | ||
209 | } | ||
210 | dev_warn(&port->dd->pdev->dev, "Failed to get a tag.\n"); | ||
211 | 184 | ||
212 | mtip_check_surprise_removal(port->dd->pdev); | 185 | static void mtip_put_int_command(struct driver_data *dd, struct mtip_cmd *cmd) |
213 | return -1; | 186 | { |
187 | blk_put_request(blk_mq_rq_from_pdu(cmd)); | ||
214 | } | 188 | } |
215 | 189 | ||
216 | /* | 190 | /* |
217 | * Release a command slot. | 191 | * Once we add support for one hctx per mtip group, this will change a bit |
218 | * | ||
219 | * @port Pointer to the port data structure. | ||
220 | * @tag Tag of command to release | ||
221 | * | ||
222 | * return value | ||
223 | * None | ||
224 | */ | 192 | */ |
225 | static inline void release_slot(struct mtip_port *port, int tag) | 193 | static struct request *mtip_rq_from_tag(struct driver_data *dd, |
194 | unsigned int tag) | ||
195 | { | ||
196 | return blk_mq_tag_to_rq(dd->queue->queue_hw_ctx[0], tag); | ||
197 | } | ||
198 | |||
199 | static struct mtip_cmd *mtip_cmd_from_tag(struct driver_data *dd, | ||
200 | unsigned int tag) | ||
226 | { | 201 | { |
227 | smp_mb__before_clear_bit(); | 202 | struct request *rq = mtip_rq_from_tag(dd, tag); |
228 | clear_bit(tag, port->allocated); | 203 | |
229 | smp_mb__after_clear_bit(); | 204 | return blk_mq_rq_to_pdu(rq); |
230 | } | 205 | } |
231 | 206 | ||
232 | /* | 207 | /* |
@@ -248,93 +223,28 @@ static inline void release_slot(struct mtip_port *port, int tag) | |||
248 | * None | 223 | * None |
249 | */ | 224 | */ |
250 | static void mtip_async_complete(struct mtip_port *port, | 225 | static void mtip_async_complete(struct mtip_port *port, |
251 | int tag, | 226 | int tag, struct mtip_cmd *cmd, int status) |
252 | void *data, | ||
253 | int status) | ||
254 | { | 227 | { |
255 | struct mtip_cmd *cmd; | 228 | struct driver_data *dd = port->dd; |
256 | struct driver_data *dd = data; | 229 | struct request *rq; |
257 | int unaligned, cb_status = status ? -EIO : 0; | ||
258 | void (*func)(void *, int); | ||
259 | 230 | ||
260 | if (unlikely(!dd) || unlikely(!port)) | 231 | if (unlikely(!dd) || unlikely(!port)) |
261 | return; | 232 | return; |
262 | 233 | ||
263 | cmd = &port->commands[tag]; | ||
264 | |||
265 | if (unlikely(status == PORT_IRQ_TF_ERR)) { | 234 | if (unlikely(status == PORT_IRQ_TF_ERR)) { |
266 | dev_warn(&port->dd->pdev->dev, | 235 | dev_warn(&port->dd->pdev->dev, |
267 | "Command tag %d failed due to TFE\n", tag); | 236 | "Command tag %d failed due to TFE\n", tag); |
268 | } | 237 | } |
269 | 238 | ||
270 | /* Clear the active flag */ | 239 | /* Unmap the DMA scatter list entries */ |
271 | atomic_set(&port->commands[tag].active, 0); | 240 | dma_unmap_sg(&dd->pdev->dev, cmd->sg, cmd->scatter_ents, cmd->direction); |
272 | 241 | ||
273 | /* Upper layer callback */ | 242 | rq = mtip_rq_from_tag(dd, tag); |
274 | func = cmd->async_callback; | ||
275 | if (likely(func && cmpxchg(&cmd->async_callback, func, 0) == func)) { | ||
276 | 243 | ||
277 | /* Unmap the DMA scatter list entries */ | 244 | if (unlikely(cmd->unaligned)) |
278 | dma_unmap_sg(&dd->pdev->dev, | 245 | up(&port->cmd_slot_unal); |
279 | cmd->sg, | ||
280 | cmd->scatter_ents, | ||
281 | cmd->direction); | ||
282 | 246 | ||
283 | func(cmd->async_data, cb_status); | 247 | blk_mq_end_io(rq, status ? -EIO : 0); |
284 | unaligned = cmd->unaligned; | ||
285 | |||
286 | /* Clear the allocated bit for the command */ | ||
287 | release_slot(port, tag); | ||
288 | |||
289 | if (unlikely(unaligned)) | ||
290 | up(&port->cmd_slot_unal); | ||
291 | else | ||
292 | up(&port->cmd_slot); | ||
293 | } | ||
294 | } | ||
295 | |||
296 | /* | ||
297 | * This function is called for clean the pending command in the | ||
298 | * command slot during the surprise removal of device and return | ||
299 | * error to the upper layer. | ||
300 | * | ||
301 | * @dd Pointer to the DRIVER_DATA structure. | ||
302 | * | ||
303 | * return value | ||
304 | * None | ||
305 | */ | ||
306 | static void mtip_command_cleanup(struct driver_data *dd) | ||
307 | { | ||
308 | int tag = 0; | ||
309 | struct mtip_cmd *cmd; | ||
310 | struct mtip_port *port = dd->port; | ||
311 | unsigned int num_cmd_slots = dd->slot_groups * 32; | ||
312 | |||
313 | if (!test_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag)) | ||
314 | return; | ||
315 | |||
316 | if (!port) | ||
317 | return; | ||
318 | |||
319 | cmd = &port->commands[MTIP_TAG_INTERNAL]; | ||
320 | if (atomic_read(&cmd->active)) | ||
321 | if (readl(port->cmd_issue[MTIP_TAG_INTERNAL]) & | ||
322 | (1 << MTIP_TAG_INTERNAL)) | ||
323 | if (cmd->comp_func) | ||
324 | cmd->comp_func(port, MTIP_TAG_INTERNAL, | ||
325 | cmd->comp_data, -ENODEV); | ||
326 | |||
327 | while (1) { | ||
328 | tag = find_next_bit(port->allocated, num_cmd_slots, tag); | ||
329 | if (tag >= num_cmd_slots) | ||
330 | break; | ||
331 | |||
332 | cmd = &port->commands[tag]; | ||
333 | if (atomic_read(&cmd->active)) | ||
334 | mtip_async_complete(port, tag, dd, -ENODEV); | ||
335 | } | ||
336 | |||
337 | set_bit(MTIP_DDF_CLEANUP_BIT, &dd->dd_flag); | ||
338 | } | 248 | } |
339 | 249 | ||
340 | /* | 250 | /* |
@@ -388,8 +298,6 @@ static inline void mtip_issue_ncq_command(struct mtip_port *port, int tag) | |||
388 | { | 298 | { |
389 | int group = tag >> 5; | 299 | int group = tag >> 5; |
390 | 300 | ||
391 | atomic_set(&port->commands[tag].active, 1); | ||
392 | |||
393 | /* guard SACT and CI registers */ | 301 | /* guard SACT and CI registers */ |
394 | spin_lock(&port->cmd_issue_lock[group]); | 302 | spin_lock(&port->cmd_issue_lock[group]); |
395 | writel((1 << MTIP_TAG_BIT(tag)), | 303 | writel((1 << MTIP_TAG_BIT(tag)), |
@@ -397,10 +305,6 @@ static inline void mtip_issue_ncq_command(struct mtip_port *port, int tag) | |||
397 | writel((1 << MTIP_TAG_BIT(tag)), | 305 | writel((1 << MTIP_TAG_BIT(tag)), |
398 | port->cmd_issue[MTIP_TAG_INDEX(tag)]); | 306 | port->cmd_issue[MTIP_TAG_INDEX(tag)]); |
399 | spin_unlock(&port->cmd_issue_lock[group]); | 307 | spin_unlock(&port->cmd_issue_lock[group]); |
400 | |||
401 | /* Set the command's timeout value.*/ | ||
402 | port->commands[tag].comp_time = jiffies + msecs_to_jiffies( | ||
403 | MTIP_NCQ_COMMAND_TIMEOUT_MS); | ||
404 | } | 308 | } |
405 | 309 | ||
406 | /* | 310 | /* |
@@ -648,132 +552,13 @@ static void print_tags(struct driver_data *dd, | |||
648 | 552 | ||
649 | memset(tagmap, 0, sizeof(tagmap)); | 553 | memset(tagmap, 0, sizeof(tagmap)); |
650 | for (group = SLOTBITS_IN_LONGS; group > 0; group--) | 554 | for (group = SLOTBITS_IN_LONGS; group > 0; group--) |
651 | tagmap_len = sprintf(tagmap + tagmap_len, "%016lX ", | 555 | tagmap_len += sprintf(tagmap + tagmap_len, "%016lX ", |
652 | tagbits[group-1]); | 556 | tagbits[group-1]); |
653 | dev_warn(&dd->pdev->dev, | 557 | dev_warn(&dd->pdev->dev, |
654 | "%d command(s) %s: tagmap [%s]", cnt, msg, tagmap); | 558 | "%d command(s) %s: tagmap [%s]", cnt, msg, tagmap); |
655 | } | 559 | } |
656 | 560 | ||
657 | /* | 561 | /* |
658 | * Called periodically to see if any read/write commands are | ||
659 | * taking too long to complete. | ||
660 | * | ||
661 | * @data Pointer to the PORT data structure. | ||
662 | * | ||
663 | * return value | ||
664 | * None | ||
665 | */ | ||
666 | static void mtip_timeout_function(unsigned long int data) | ||
667 | { | ||
668 | struct mtip_port *port = (struct mtip_port *) data; | ||
669 | struct host_to_dev_fis *fis; | ||
670 | struct mtip_cmd *cmd; | ||
671 | int unaligned, tag, cmdto_cnt = 0; | ||
672 | unsigned int bit, group; | ||
673 | unsigned int num_command_slots; | ||
674 | unsigned long to, tagaccum[SLOTBITS_IN_LONGS]; | ||
675 | void (*func)(void *, int); | ||
676 | |||
677 | if (unlikely(!port)) | ||
678 | return; | ||
679 | |||
680 | if (unlikely(port->dd->sr)) | ||
681 | return; | ||
682 | |||
683 | if (test_bit(MTIP_DDF_RESUME_BIT, &port->dd->dd_flag)) { | ||
684 | mod_timer(&port->cmd_timer, | ||
685 | jiffies + msecs_to_jiffies(30000)); | ||
686 | return; | ||
687 | } | ||
688 | /* clear the tag accumulator */ | ||
689 | memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long)); | ||
690 | num_command_slots = port->dd->slot_groups * 32; | ||
691 | |||
692 | for (tag = 0; tag < num_command_slots; tag++) { | ||
693 | /* | ||
694 | * Skip internal command slot as it has | ||
695 | * its own timeout mechanism | ||
696 | */ | ||
697 | if (tag == MTIP_TAG_INTERNAL) | ||
698 | continue; | ||
699 | |||
700 | if (atomic_read(&port->commands[tag].active) && | ||
701 | (time_after(jiffies, port->commands[tag].comp_time))) { | ||
702 | group = tag >> 5; | ||
703 | bit = tag & 0x1F; | ||
704 | |||
705 | cmd = &port->commands[tag]; | ||
706 | fis = (struct host_to_dev_fis *) cmd->command; | ||
707 | |||
708 | set_bit(tag, tagaccum); | ||
709 | cmdto_cnt++; | ||
710 | if (cmdto_cnt == 1) | ||
711 | set_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); | ||
712 | |||
713 | /* | ||
714 | * Clear the completed bit. This should prevent | ||
715 | * any interrupt handlers from trying to retire | ||
716 | * the command. | ||
717 | */ | ||
718 | writel(1 << bit, port->completed[group]); | ||
719 | |||
720 | /* Clear the active flag for the command */ | ||
721 | atomic_set(&port->commands[tag].active, 0); | ||
722 | |||
723 | func = cmd->async_callback; | ||
724 | if (func && | ||
725 | cmpxchg(&cmd->async_callback, func, 0) == func) { | ||
726 | |||
727 | /* Unmap the DMA scatter list entries */ | ||
728 | dma_unmap_sg(&port->dd->pdev->dev, | ||
729 | cmd->sg, | ||
730 | cmd->scatter_ents, | ||
731 | cmd->direction); | ||
732 | |||
733 | func(cmd->async_data, -EIO); | ||
734 | unaligned = cmd->unaligned; | ||
735 | |||
736 | /* Clear the allocated bit for the command. */ | ||
737 | release_slot(port, tag); | ||
738 | |||
739 | if (unaligned) | ||
740 | up(&port->cmd_slot_unal); | ||
741 | else | ||
742 | up(&port->cmd_slot); | ||
743 | } | ||
744 | } | ||
745 | } | ||
746 | |||
747 | if (cmdto_cnt) { | ||
748 | print_tags(port->dd, "timed out", tagaccum, cmdto_cnt); | ||
749 | if (!test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags)) { | ||
750 | mtip_device_reset(port->dd); | ||
751 | wake_up_interruptible(&port->svc_wait); | ||
752 | } | ||
753 | clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); | ||
754 | } | ||
755 | |||
756 | if (port->ic_pause_timer) { | ||
757 | to = port->ic_pause_timer + msecs_to_jiffies(1000); | ||
758 | if (time_after(jiffies, to)) { | ||
759 | if (!test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags)) { | ||
760 | port->ic_pause_timer = 0; | ||
761 | clear_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags); | ||
762 | clear_bit(MTIP_PF_DM_ACTIVE_BIT, &port->flags); | ||
763 | clear_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags); | ||
764 | wake_up_interruptible(&port->svc_wait); | ||
765 | } | ||
766 | |||
767 | |||
768 | } | ||
769 | } | ||
770 | |||
771 | /* Restart the timer */ | ||
772 | mod_timer(&port->cmd_timer, | ||
773 | jiffies + msecs_to_jiffies(MTIP_TIMEOUT_CHECK_PERIOD)); | ||
774 | } | ||
775 | |||
776 | /* | ||
777 | * Internal command completion callback function. | 562 | * Internal command completion callback function. |
778 | * | 563 | * |
779 | * This function is normally called by the driver ISR when an internal | 564 | * This function is normally called by the driver ISR when an internal |
@@ -789,28 +574,19 @@ static void mtip_timeout_function(unsigned long int data) | |||
789 | * None | 574 | * None |
790 | */ | 575 | */ |
791 | static void mtip_completion(struct mtip_port *port, | 576 | static void mtip_completion(struct mtip_port *port, |
792 | int tag, | 577 | int tag, struct mtip_cmd *command, int status) |
793 | void *data, | ||
794 | int status) | ||
795 | { | 578 | { |
796 | struct mtip_cmd *command = &port->commands[tag]; | 579 | struct completion *waiting = command->comp_data; |
797 | struct completion *waiting = data; | ||
798 | if (unlikely(status == PORT_IRQ_TF_ERR)) | 580 | if (unlikely(status == PORT_IRQ_TF_ERR)) |
799 | dev_warn(&port->dd->pdev->dev, | 581 | dev_warn(&port->dd->pdev->dev, |
800 | "Internal command %d completed with TFE\n", tag); | 582 | "Internal command %d completed with TFE\n", tag); |
801 | 583 | ||
802 | command->async_callback = NULL; | ||
803 | command->comp_func = NULL; | ||
804 | |||
805 | complete(waiting); | 584 | complete(waiting); |
806 | } | 585 | } |
807 | 586 | ||
808 | static void mtip_null_completion(struct mtip_port *port, | 587 | static void mtip_null_completion(struct mtip_port *port, |
809 | int tag, | 588 | int tag, struct mtip_cmd *command, int status) |
810 | void *data, | ||
811 | int status) | ||
812 | { | 589 | { |
813 | return; | ||
814 | } | 590 | } |
815 | 591 | ||
816 | static int mtip_read_log_page(struct mtip_port *port, u8 page, u16 *buffer, | 592 | static int mtip_read_log_page(struct mtip_port *port, u8 page, u16 *buffer, |
@@ -842,19 +618,16 @@ static void mtip_handle_tfe(struct driver_data *dd) | |||
842 | 618 | ||
843 | port = dd->port; | 619 | port = dd->port; |
844 | 620 | ||
845 | /* Stop the timer to prevent command timeouts. */ | ||
846 | del_timer(&port->cmd_timer); | ||
847 | set_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); | 621 | set_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); |
848 | 622 | ||
849 | if (test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags) && | 623 | if (test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags) && |
850 | test_bit(MTIP_TAG_INTERNAL, port->allocated)) { | 624 | test_bit(MTIP_TAG_INTERNAL, port->allocated)) { |
851 | cmd = &port->commands[MTIP_TAG_INTERNAL]; | 625 | cmd = mtip_cmd_from_tag(dd, MTIP_TAG_INTERNAL); |
852 | dbg_printk(MTIP_DRV_NAME " TFE for the internal command\n"); | 626 | dbg_printk(MTIP_DRV_NAME " TFE for the internal command\n"); |
853 | 627 | ||
854 | atomic_inc(&cmd->active); /* active > 1 indicates error */ | ||
855 | if (cmd->comp_data && cmd->comp_func) { | 628 | if (cmd->comp_data && cmd->comp_func) { |
856 | cmd->comp_func(port, MTIP_TAG_INTERNAL, | 629 | cmd->comp_func(port, MTIP_TAG_INTERNAL, |
857 | cmd->comp_data, PORT_IRQ_TF_ERR); | 630 | cmd, PORT_IRQ_TF_ERR); |
858 | } | 631 | } |
859 | goto handle_tfe_exit; | 632 | goto handle_tfe_exit; |
860 | } | 633 | } |
@@ -866,6 +639,8 @@ static void mtip_handle_tfe(struct driver_data *dd) | |||
866 | for (group = 0; group < dd->slot_groups; group++) { | 639 | for (group = 0; group < dd->slot_groups; group++) { |
867 | completed = readl(port->completed[group]); | 640 | completed = readl(port->completed[group]); |
868 | 641 | ||
642 | dev_warn(&dd->pdev->dev, "g=%u, comp=%x\n", group, completed); | ||
643 | |||
869 | /* clear completed status register in the hardware.*/ | 644 | /* clear completed status register in the hardware.*/ |
870 | writel(completed, port->completed[group]); | 645 | writel(completed, port->completed[group]); |
871 | 646 | ||
@@ -879,15 +654,11 @@ static void mtip_handle_tfe(struct driver_data *dd) | |||
879 | if (tag == MTIP_TAG_INTERNAL) | 654 | if (tag == MTIP_TAG_INTERNAL) |
880 | continue; | 655 | continue; |
881 | 656 | ||
882 | cmd = &port->commands[tag]; | 657 | cmd = mtip_cmd_from_tag(dd, tag); |
883 | if (likely(cmd->comp_func)) { | 658 | if (likely(cmd->comp_func)) { |
884 | set_bit(tag, tagaccum); | 659 | set_bit(tag, tagaccum); |
885 | cmd_cnt++; | 660 | cmd_cnt++; |
886 | atomic_set(&cmd->active, 0); | 661 | cmd->comp_func(port, tag, cmd, 0); |
887 | cmd->comp_func(port, | ||
888 | tag, | ||
889 | cmd->comp_data, | ||
890 | 0); | ||
891 | } else { | 662 | } else { |
892 | dev_err(&port->dd->pdev->dev, | 663 | dev_err(&port->dd->pdev->dev, |
893 | "Missing completion func for tag %d", | 664 | "Missing completion func for tag %d", |
@@ -947,11 +718,7 @@ static void mtip_handle_tfe(struct driver_data *dd) | |||
947 | for (bit = 0; bit < 32; bit++) { | 718 | for (bit = 0; bit < 32; bit++) { |
948 | reissue = 1; | 719 | reissue = 1; |
949 | tag = (group << 5) + bit; | 720 | tag = (group << 5) + bit; |
950 | cmd = &port->commands[tag]; | 721 | cmd = mtip_cmd_from_tag(dd, tag); |
951 | |||
952 | /* If the active bit is set re-issue the command */ | ||
953 | if (atomic_read(&cmd->active) == 0) | ||
954 | continue; | ||
955 | 722 | ||
956 | fis = (struct host_to_dev_fis *)cmd->command; | 723 | fis = (struct host_to_dev_fis *)cmd->command; |
957 | 724 | ||
@@ -970,11 +737,9 @@ static void mtip_handle_tfe(struct driver_data *dd) | |||
970 | tag, | 737 | tag, |
971 | fail_reason != NULL ? | 738 | fail_reason != NULL ? |
972 | fail_reason : "unknown"); | 739 | fail_reason : "unknown"); |
973 | atomic_set(&cmd->active, 0); | ||
974 | if (cmd->comp_func) { | 740 | if (cmd->comp_func) { |
975 | cmd->comp_func(port, tag, | 741 | cmd->comp_func(port, tag, |
976 | cmd->comp_data, | 742 | cmd, -ENODATA); |
977 | -ENODATA); | ||
978 | } | 743 | } |
979 | continue; | 744 | continue; |
980 | } | 745 | } |
@@ -997,14 +762,9 @@ static void mtip_handle_tfe(struct driver_data *dd) | |||
997 | /* Retire a command that will not be reissued */ | 762 | /* Retire a command that will not be reissued */ |
998 | dev_warn(&port->dd->pdev->dev, | 763 | dev_warn(&port->dd->pdev->dev, |
999 | "retiring tag %d\n", tag); | 764 | "retiring tag %d\n", tag); |
1000 | atomic_set(&cmd->active, 0); | ||
1001 | 765 | ||
1002 | if (cmd->comp_func) | 766 | if (cmd->comp_func) |
1003 | cmd->comp_func( | 767 | cmd->comp_func(port, tag, cmd, PORT_IRQ_TF_ERR); |
1004 | port, | ||
1005 | tag, | ||
1006 | cmd->comp_data, | ||
1007 | PORT_IRQ_TF_ERR); | ||
1008 | else | 768 | else |
1009 | dev_warn(&port->dd->pdev->dev, | 769 | dev_warn(&port->dd->pdev->dev, |
1010 | "Bad completion for tag %d\n", | 770 | "Bad completion for tag %d\n", |
@@ -1017,9 +777,6 @@ handle_tfe_exit: | |||
1017 | /* clear eh_active */ | 777 | /* clear eh_active */ |
1018 | clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); | 778 | clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); |
1019 | wake_up_interruptible(&port->svc_wait); | 779 | wake_up_interruptible(&port->svc_wait); |
1020 | |||
1021 | mod_timer(&port->cmd_timer, | ||
1022 | jiffies + msecs_to_jiffies(MTIP_TIMEOUT_CHECK_PERIOD)); | ||
1023 | } | 780 | } |
1024 | 781 | ||
1025 | /* | 782 | /* |
@@ -1048,15 +805,10 @@ static inline void mtip_workq_sdbfx(struct mtip_port *port, int group, | |||
1048 | if (unlikely(tag == MTIP_TAG_INTERNAL)) | 805 | if (unlikely(tag == MTIP_TAG_INTERNAL)) |
1049 | continue; | 806 | continue; |
1050 | 807 | ||
1051 | command = &port->commands[tag]; | 808 | command = mtip_cmd_from_tag(dd, tag); |
1052 | /* make internal callback */ | 809 | if (likely(command->comp_func)) |
1053 | if (likely(command->comp_func)) { | 810 | command->comp_func(port, tag, command, 0); |
1054 | command->comp_func( | 811 | else { |
1055 | port, | ||
1056 | tag, | ||
1057 | command->comp_data, | ||
1058 | 0); | ||
1059 | } else { | ||
1060 | dev_dbg(&dd->pdev->dev, | 812 | dev_dbg(&dd->pdev->dev, |
1061 | "Null completion for tag %d", | 813 | "Null completion for tag %d", |
1062 | tag); | 814 | tag); |
@@ -1081,16 +833,13 @@ static inline void mtip_workq_sdbfx(struct mtip_port *port, int group, | |||
1081 | static inline void mtip_process_legacy(struct driver_data *dd, u32 port_stat) | 833 | static inline void mtip_process_legacy(struct driver_data *dd, u32 port_stat) |
1082 | { | 834 | { |
1083 | struct mtip_port *port = dd->port; | 835 | struct mtip_port *port = dd->port; |
1084 | struct mtip_cmd *cmd = &port->commands[MTIP_TAG_INTERNAL]; | 836 | struct mtip_cmd *cmd = mtip_cmd_from_tag(dd, MTIP_TAG_INTERNAL); |
1085 | 837 | ||
1086 | if (test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags) && | 838 | if (test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags) && |
1087 | (cmd != NULL) && !(readl(port->cmd_issue[MTIP_TAG_INTERNAL]) | 839 | (cmd != NULL) && !(readl(port->cmd_issue[MTIP_TAG_INTERNAL]) |
1088 | & (1 << MTIP_TAG_INTERNAL))) { | 840 | & (1 << MTIP_TAG_INTERNAL))) { |
1089 | if (cmd->comp_func) { | 841 | if (cmd->comp_func) { |
1090 | cmd->comp_func(port, | 842 | cmd->comp_func(port, MTIP_TAG_INTERNAL, cmd, 0); |
1091 | MTIP_TAG_INTERNAL, | ||
1092 | cmd->comp_data, | ||
1093 | 0); | ||
1094 | return; | 843 | return; |
1095 | } | 844 | } |
1096 | } | 845 | } |
@@ -1103,8 +852,6 @@ static inline void mtip_process_legacy(struct driver_data *dd, u32 port_stat) | |||
1103 | */ | 852 | */ |
1104 | static inline void mtip_process_errors(struct driver_data *dd, u32 port_stat) | 853 | static inline void mtip_process_errors(struct driver_data *dd, u32 port_stat) |
1105 | { | 854 | { |
1106 | if (likely(port_stat & (PORT_IRQ_TF_ERR | PORT_IRQ_IF_ERR))) | ||
1107 | mtip_handle_tfe(dd); | ||
1108 | 855 | ||
1109 | if (unlikely(port_stat & PORT_IRQ_CONNECT)) { | 856 | if (unlikely(port_stat & PORT_IRQ_CONNECT)) { |
1110 | dev_warn(&dd->pdev->dev, | 857 | dev_warn(&dd->pdev->dev, |
@@ -1122,6 +869,12 @@ static inline void mtip_process_errors(struct driver_data *dd, u32 port_stat) | |||
1122 | dev_warn(&dd->pdev->dev, | 869 | dev_warn(&dd->pdev->dev, |
1123 | "Port stat errors %x unhandled\n", | 870 | "Port stat errors %x unhandled\n", |
1124 | (port_stat & ~PORT_IRQ_HANDLED)); | 871 | (port_stat & ~PORT_IRQ_HANDLED)); |
872 | if (mtip_check_surprise_removal(dd->pdev)) | ||
873 | return; | ||
874 | } | ||
875 | if (likely(port_stat & (PORT_IRQ_TF_ERR | PORT_IRQ_IF_ERR))) { | ||
876 | set_bit(MTIP_PF_EH_ACTIVE_BIT, &dd->port->flags); | ||
877 | wake_up_interruptible(&dd->port->svc_wait); | ||
1125 | } | 878 | } |
1126 | } | 879 | } |
1127 | 880 | ||
@@ -1222,7 +975,6 @@ static irqreturn_t mtip_irq_handler(int irq, void *instance) | |||
1222 | 975 | ||
1223 | static void mtip_issue_non_ncq_command(struct mtip_port *port, int tag) | 976 | static void mtip_issue_non_ncq_command(struct mtip_port *port, int tag) |
1224 | { | 977 | { |
1225 | atomic_set(&port->commands[tag].active, 1); | ||
1226 | writel(1 << MTIP_TAG_BIT(tag), | 978 | writel(1 << MTIP_TAG_BIT(tag), |
1227 | port->cmd_issue[MTIP_TAG_INDEX(tag)]); | 979 | port->cmd_issue[MTIP_TAG_INDEX(tag)]); |
1228 | } | 980 | } |
@@ -1280,6 +1032,8 @@ static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout) | |||
1280 | unsigned int n; | 1032 | unsigned int n; |
1281 | unsigned int active = 1; | 1033 | unsigned int active = 1; |
1282 | 1034 | ||
1035 | blk_mq_stop_hw_queues(port->dd->queue); | ||
1036 | |||
1283 | to = jiffies + msecs_to_jiffies(timeout); | 1037 | to = jiffies + msecs_to_jiffies(timeout); |
1284 | do { | 1038 | do { |
1285 | if (test_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags) && | 1039 | if (test_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags) && |
@@ -1287,8 +1041,13 @@ static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout) | |||
1287 | msleep(20); | 1041 | msleep(20); |
1288 | continue; /* svc thd is actively issuing commands */ | 1042 | continue; /* svc thd is actively issuing commands */ |
1289 | } | 1043 | } |
1044 | |||
1045 | msleep(100); | ||
1046 | if (mtip_check_surprise_removal(port->dd->pdev)) | ||
1047 | goto err_fault; | ||
1290 | if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag)) | 1048 | if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag)) |
1291 | return -EFAULT; | 1049 | goto err_fault; |
1050 | |||
1292 | /* | 1051 | /* |
1293 | * Ignore s_active bit 0 of array element 0. | 1052 | * Ignore s_active bit 0 of array element 0. |
1294 | * This bit will always be set | 1053 | * This bit will always be set |
@@ -1299,11 +1058,13 @@ static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout) | |||
1299 | 1058 | ||
1300 | if (!active) | 1059 | if (!active) |
1301 | break; | 1060 | break; |
1302 | |||
1303 | msleep(20); | ||
1304 | } while (time_before(jiffies, to)); | 1061 | } while (time_before(jiffies, to)); |
1305 | 1062 | ||
1063 | blk_mq_start_stopped_hw_queues(port->dd->queue, true); | ||
1306 | return active ? -EBUSY : 0; | 1064 | return active ? -EBUSY : 0; |
1065 | err_fault: | ||
1066 | blk_mq_start_stopped_hw_queues(port->dd->queue, true); | ||
1067 | return -EFAULT; | ||
1307 | } | 1068 | } |
1308 | 1069 | ||
1309 | /* | 1070 | /* |
@@ -1335,10 +1096,9 @@ static int mtip_exec_internal_command(struct mtip_port *port, | |||
1335 | { | 1096 | { |
1336 | struct mtip_cmd_sg *command_sg; | 1097 | struct mtip_cmd_sg *command_sg; |
1337 | DECLARE_COMPLETION_ONSTACK(wait); | 1098 | DECLARE_COMPLETION_ONSTACK(wait); |
1338 | int rv = 0, ready2go = 1; | 1099 | struct mtip_cmd *int_cmd; |
1339 | struct mtip_cmd *int_cmd = &port->commands[MTIP_TAG_INTERNAL]; | ||
1340 | unsigned long to; | ||
1341 | struct driver_data *dd = port->dd; | 1100 | struct driver_data *dd = port->dd; |
1101 | int rv = 0; | ||
1342 | 1102 | ||
1343 | /* Make sure the buffer is 8 byte aligned. This is asic specific. */ | 1103 | /* Make sure the buffer is 8 byte aligned. This is asic specific. */ |
1344 | if (buffer & 0x00000007) { | 1104 | if (buffer & 0x00000007) { |
@@ -1346,19 +1106,8 @@ static int mtip_exec_internal_command(struct mtip_port *port, | |||
1346 | return -EFAULT; | 1106 | return -EFAULT; |
1347 | } | 1107 | } |
1348 | 1108 | ||
1349 | to = jiffies + msecs_to_jiffies(timeout); | 1109 | int_cmd = mtip_get_int_command(dd); |
1350 | do { | 1110 | |
1351 | ready2go = !test_and_set_bit(MTIP_TAG_INTERNAL, | ||
1352 | port->allocated); | ||
1353 | if (ready2go) | ||
1354 | break; | ||
1355 | mdelay(100); | ||
1356 | } while (time_before(jiffies, to)); | ||
1357 | if (!ready2go) { | ||
1358 | dev_warn(&dd->pdev->dev, | ||
1359 | "Internal cmd active. new cmd [%02X]\n", fis->command); | ||
1360 | return -EBUSY; | ||
1361 | } | ||
1362 | set_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags); | 1111 | set_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags); |
1363 | port->ic_pause_timer = 0; | 1112 | port->ic_pause_timer = 0; |
1364 | 1113 | ||
@@ -1368,10 +1117,11 @@ static int mtip_exec_internal_command(struct mtip_port *port, | |||
1368 | if (atomic == GFP_KERNEL) { | 1117 | if (atomic == GFP_KERNEL) { |
1369 | if (fis->command != ATA_CMD_STANDBYNOW1) { | 1118 | if (fis->command != ATA_CMD_STANDBYNOW1) { |
1370 | /* wait for io to complete if non atomic */ | 1119 | /* wait for io to complete if non atomic */ |
1371 | if (mtip_quiesce_io(port, 5000) < 0) { | 1120 | if (mtip_quiesce_io(port, |
1121 | MTIP_QUIESCE_IO_TIMEOUT_MS) < 0) { | ||
1372 | dev_warn(&dd->pdev->dev, | 1122 | dev_warn(&dd->pdev->dev, |
1373 | "Failed to quiesce IO\n"); | 1123 | "Failed to quiesce IO\n"); |
1374 | release_slot(port, MTIP_TAG_INTERNAL); | 1124 | mtip_put_int_command(dd, int_cmd); |
1375 | clear_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags); | 1125 | clear_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags); |
1376 | wake_up_interruptible(&port->svc_wait); | 1126 | wake_up_interruptible(&port->svc_wait); |
1377 | return -EBUSY; | 1127 | return -EBUSY; |
@@ -1416,9 +1166,9 @@ static int mtip_exec_internal_command(struct mtip_port *port, | |||
1416 | 1166 | ||
1417 | if (atomic == GFP_KERNEL) { | 1167 | if (atomic == GFP_KERNEL) { |
1418 | /* Wait for the command to complete or timeout. */ | 1168 | /* Wait for the command to complete or timeout. */ |
1419 | if (wait_for_completion_interruptible_timeout( | 1169 | if ((rv = wait_for_completion_interruptible_timeout( |
1420 | &wait, | 1170 | &wait, |
1421 | msecs_to_jiffies(timeout)) <= 0) { | 1171 | msecs_to_jiffies(timeout))) <= 0) { |
1422 | if (rv == -ERESTARTSYS) { /* interrupted */ | 1172 | if (rv == -ERESTARTSYS) { /* interrupted */ |
1423 | dev_err(&dd->pdev->dev, | 1173 | dev_err(&dd->pdev->dev, |
1424 | "Internal command [%02X] was interrupted after %lu ms\n", | 1174 | "Internal command [%02X] was interrupted after %lu ms\n", |
@@ -1497,8 +1247,7 @@ static int mtip_exec_internal_command(struct mtip_port *port, | |||
1497 | } | 1247 | } |
1498 | exec_ic_exit: | 1248 | exec_ic_exit: |
1499 | /* Clear the allocated and active bits for the internal command. */ | 1249 | /* Clear the allocated and active bits for the internal command. */ |
1500 | atomic_set(&int_cmd->active, 0); | 1250 | mtip_put_int_command(dd, int_cmd); |
1501 | release_slot(port, MTIP_TAG_INTERNAL); | ||
1502 | if (rv >= 0 && mtip_pause_ncq(port, fis)) { | 1251 | if (rv >= 0 && mtip_pause_ncq(port, fis)) { |
1503 | /* NCQ paused */ | 1252 | /* NCQ paused */ |
1504 | return rv; | 1253 | return rv; |
@@ -1529,6 +1278,37 @@ static inline void ata_swap_string(u16 *buf, unsigned int len) | |||
1529 | be16_to_cpus(&buf[i]); | 1278 | be16_to_cpus(&buf[i]); |
1530 | } | 1279 | } |
1531 | 1280 | ||
1281 | static void mtip_set_timeout(struct driver_data *dd, | ||
1282 | struct host_to_dev_fis *fis, | ||
1283 | unsigned int *timeout, u8 erasemode) | ||
1284 | { | ||
1285 | switch (fis->command) { | ||
1286 | case ATA_CMD_DOWNLOAD_MICRO: | ||
1287 | *timeout = 120000; /* 2 minutes */ | ||
1288 | break; | ||
1289 | case ATA_CMD_SEC_ERASE_UNIT: | ||
1290 | case 0xFC: | ||
1291 | if (erasemode) | ||
1292 | *timeout = ((*(dd->port->identify + 90) * 2) * 60000); | ||
1293 | else | ||
1294 | *timeout = ((*(dd->port->identify + 89) * 2) * 60000); | ||
1295 | break; | ||
1296 | case ATA_CMD_STANDBYNOW1: | ||
1297 | *timeout = 120000; /* 2 minutes */ | ||
1298 | break; | ||
1299 | case 0xF7: | ||
1300 | case 0xFA: | ||
1301 | *timeout = 60000; /* 60 seconds */ | ||
1302 | break; | ||
1303 | case ATA_CMD_SMART: | ||
1304 | *timeout = 15000; /* 15 seconds */ | ||
1305 | break; | ||
1306 | default: | ||
1307 | *timeout = MTIP_IOCTL_CMD_TIMEOUT_MS; | ||
1308 | break; | ||
1309 | } | ||
1310 | } | ||
1311 | |||
1532 | /* | 1312 | /* |
1533 | * Request the device identity information. | 1313 | * Request the device identity information. |
1534 | * | 1314 | * |
@@ -1576,7 +1356,7 @@ static int mtip_get_identify(struct mtip_port *port, void __user *user_buffer) | |||
1576 | sizeof(u16) * ATA_ID_WORDS, | 1356 | sizeof(u16) * ATA_ID_WORDS, |
1577 | 0, | 1357 | 0, |
1578 | GFP_KERNEL, | 1358 | GFP_KERNEL, |
1579 | MTIP_INTERNAL_COMMAND_TIMEOUT_MS) | 1359 | MTIP_INT_CMD_TIMEOUT_MS) |
1580 | < 0) { | 1360 | < 0) { |
1581 | rv = -1; | 1361 | rv = -1; |
1582 | goto out; | 1362 | goto out; |
@@ -1644,6 +1424,7 @@ static int mtip_standby_immediate(struct mtip_port *port) | |||
1644 | int rv; | 1424 | int rv; |
1645 | struct host_to_dev_fis fis; | 1425 | struct host_to_dev_fis fis; |
1646 | unsigned long start; | 1426 | unsigned long start; |
1427 | unsigned int timeout; | ||
1647 | 1428 | ||
1648 | /* Build the FIS. */ | 1429 | /* Build the FIS. */ |
1649 | memset(&fis, 0, sizeof(struct host_to_dev_fis)); | 1430 | memset(&fis, 0, sizeof(struct host_to_dev_fis)); |
@@ -1651,6 +1432,8 @@ static int mtip_standby_immediate(struct mtip_port *port) | |||
1651 | fis.opts = 1 << 7; | 1432 | fis.opts = 1 << 7; |
1652 | fis.command = ATA_CMD_STANDBYNOW1; | 1433 | fis.command = ATA_CMD_STANDBYNOW1; |
1653 | 1434 | ||
1435 | mtip_set_timeout(port->dd, &fis, &timeout, 0); | ||
1436 | |||
1654 | start = jiffies; | 1437 | start = jiffies; |
1655 | rv = mtip_exec_internal_command(port, | 1438 | rv = mtip_exec_internal_command(port, |
1656 | &fis, | 1439 | &fis, |
@@ -1659,7 +1442,7 @@ static int mtip_standby_immediate(struct mtip_port *port) | |||
1659 | 0, | 1442 | 0, |
1660 | 0, | 1443 | 0, |
1661 | GFP_ATOMIC, | 1444 | GFP_ATOMIC, |
1662 | 15000); | 1445 | timeout); |
1663 | dbg_printk(MTIP_DRV_NAME "Time taken to complete standby cmd: %d ms\n", | 1446 | dbg_printk(MTIP_DRV_NAME "Time taken to complete standby cmd: %d ms\n", |
1664 | jiffies_to_msecs(jiffies - start)); | 1447 | jiffies_to_msecs(jiffies - start)); |
1665 | if (rv) | 1448 | if (rv) |
@@ -1705,7 +1488,7 @@ static int mtip_read_log_page(struct mtip_port *port, u8 page, u16 *buffer, | |||
1705 | sectors * ATA_SECT_SIZE, | 1488 | sectors * ATA_SECT_SIZE, |
1706 | 0, | 1489 | 0, |
1707 | GFP_ATOMIC, | 1490 | GFP_ATOMIC, |
1708 | MTIP_INTERNAL_COMMAND_TIMEOUT_MS); | 1491 | MTIP_INT_CMD_TIMEOUT_MS); |
1709 | } | 1492 | } |
1710 | 1493 | ||
1711 | /* | 1494 | /* |
@@ -1998,6 +1781,7 @@ static int exec_drive_task(struct mtip_port *port, u8 *command) | |||
1998 | { | 1781 | { |
1999 | struct host_to_dev_fis fis; | 1782 | struct host_to_dev_fis fis; |
2000 | struct host_to_dev_fis *reply = (port->rxfis + RX_FIS_D2H_REG); | 1783 | struct host_to_dev_fis *reply = (port->rxfis + RX_FIS_D2H_REG); |
1784 | unsigned int to; | ||
2001 | 1785 | ||
2002 | /* Build the FIS. */ | 1786 | /* Build the FIS. */ |
2003 | memset(&fis, 0, sizeof(struct host_to_dev_fis)); | 1787 | memset(&fis, 0, sizeof(struct host_to_dev_fis)); |
@@ -2011,6 +1795,8 @@ static int exec_drive_task(struct mtip_port *port, u8 *command) | |||
2011 | fis.cyl_hi = command[5]; | 1795 | fis.cyl_hi = command[5]; |
2012 | fis.device = command[6] & ~0x10; /* Clear the dev bit*/ | 1796 | fis.device = command[6] & ~0x10; /* Clear the dev bit*/ |
2013 | 1797 | ||
1798 | mtip_set_timeout(port->dd, &fis, &to, 0); | ||
1799 | |||
2014 | dbg_printk(MTIP_DRV_NAME " %s: User Command: cmd %x, feat %x, nsect %x, sect %x, lcyl %x, hcyl %x, sel %x\n", | 1800 | dbg_printk(MTIP_DRV_NAME " %s: User Command: cmd %x, feat %x, nsect %x, sect %x, lcyl %x, hcyl %x, sel %x\n", |
2015 | __func__, | 1801 | __func__, |
2016 | command[0], | 1802 | command[0], |
@@ -2029,7 +1815,7 @@ static int exec_drive_task(struct mtip_port *port, u8 *command) | |||
2029 | 0, | 1815 | 0, |
2030 | 0, | 1816 | 0, |
2031 | GFP_KERNEL, | 1817 | GFP_KERNEL, |
2032 | MTIP_IOCTL_COMMAND_TIMEOUT_MS) < 0) { | 1818 | to) < 0) { |
2033 | return -1; | 1819 | return -1; |
2034 | } | 1820 | } |
2035 | 1821 | ||
@@ -2069,6 +1855,7 @@ static int exec_drive_command(struct mtip_port *port, u8 *command, | |||
2069 | u8 *buf = NULL; | 1855 | u8 *buf = NULL; |
2070 | dma_addr_t dma_addr = 0; | 1856 | dma_addr_t dma_addr = 0; |
2071 | int rv = 0, xfer_sz = command[3]; | 1857 | int rv = 0, xfer_sz = command[3]; |
1858 | unsigned int to; | ||
2072 | 1859 | ||
2073 | if (xfer_sz) { | 1860 | if (xfer_sz) { |
2074 | if (!user_buffer) | 1861 | if (!user_buffer) |
@@ -2100,6 +1887,8 @@ static int exec_drive_command(struct mtip_port *port, u8 *command, | |||
2100 | fis.cyl_hi = 0xC2; | 1887 | fis.cyl_hi = 0xC2; |
2101 | } | 1888 | } |
2102 | 1889 | ||
1890 | mtip_set_timeout(port->dd, &fis, &to, 0); | ||
1891 | |||
2103 | if (xfer_sz) | 1892 | if (xfer_sz) |
2104 | reply = (port->rxfis + RX_FIS_PIO_SETUP); | 1893 | reply = (port->rxfis + RX_FIS_PIO_SETUP); |
2105 | else | 1894 | else |
@@ -2122,7 +1911,7 @@ static int exec_drive_command(struct mtip_port *port, u8 *command, | |||
2122 | (xfer_sz ? ATA_SECT_SIZE * xfer_sz : 0), | 1911 | (xfer_sz ? ATA_SECT_SIZE * xfer_sz : 0), |
2123 | 0, | 1912 | 0, |
2124 | GFP_KERNEL, | 1913 | GFP_KERNEL, |
2125 | MTIP_IOCTL_COMMAND_TIMEOUT_MS) | 1914 | to) |
2126 | < 0) { | 1915 | < 0) { |
2127 | rv = -EFAULT; | 1916 | rv = -EFAULT; |
2128 | goto exit_drive_command; | 1917 | goto exit_drive_command; |
@@ -2202,36 +1991,6 @@ static unsigned int implicit_sector(unsigned char command, | |||
2202 | } | 1991 | } |
2203 | return rv; | 1992 | return rv; |
2204 | } | 1993 | } |
2205 | static void mtip_set_timeout(struct driver_data *dd, | ||
2206 | struct host_to_dev_fis *fis, | ||
2207 | unsigned int *timeout, u8 erasemode) | ||
2208 | { | ||
2209 | switch (fis->command) { | ||
2210 | case ATA_CMD_DOWNLOAD_MICRO: | ||
2211 | *timeout = 120000; /* 2 minutes */ | ||
2212 | break; | ||
2213 | case ATA_CMD_SEC_ERASE_UNIT: | ||
2214 | case 0xFC: | ||
2215 | if (erasemode) | ||
2216 | *timeout = ((*(dd->port->identify + 90) * 2) * 60000); | ||
2217 | else | ||
2218 | *timeout = ((*(dd->port->identify + 89) * 2) * 60000); | ||
2219 | break; | ||
2220 | case ATA_CMD_STANDBYNOW1: | ||
2221 | *timeout = 120000; /* 2 minutes */ | ||
2222 | break; | ||
2223 | case 0xF7: | ||
2224 | case 0xFA: | ||
2225 | *timeout = 60000; /* 60 seconds */ | ||
2226 | break; | ||
2227 | case ATA_CMD_SMART: | ||
2228 | *timeout = 15000; /* 15 seconds */ | ||
2229 | break; | ||
2230 | default: | ||
2231 | *timeout = MTIP_IOCTL_COMMAND_TIMEOUT_MS; | ||
2232 | break; | ||
2233 | } | ||
2234 | } | ||
2235 | 1994 | ||
2236 | /* | 1995 | /* |
2237 | * Executes a taskfile | 1996 | * Executes a taskfile |
@@ -2606,22 +2365,21 @@ static int mtip_hw_ioctl(struct driver_data *dd, unsigned int cmd, | |||
2606 | * return value | 2365 | * return value |
2607 | * None | 2366 | * None |
2608 | */ | 2367 | */ |
2609 | static void mtip_hw_submit_io(struct driver_data *dd, sector_t sector, | 2368 | static void mtip_hw_submit_io(struct driver_data *dd, struct request *rq, |
2610 | int nsect, int nents, int tag, void *callback, | 2369 | struct mtip_cmd *command, int nents, |
2611 | void *data, int dir, int unaligned) | 2370 | struct blk_mq_hw_ctx *hctx) |
2612 | { | 2371 | { |
2613 | struct host_to_dev_fis *fis; | 2372 | struct host_to_dev_fis *fis; |
2614 | struct mtip_port *port = dd->port; | 2373 | struct mtip_port *port = dd->port; |
2615 | struct mtip_cmd *command = &port->commands[tag]; | 2374 | int dma_dir = rq_data_dir(rq) == READ ? DMA_FROM_DEVICE : DMA_TO_DEVICE; |
2616 | int dma_dir = (dir == READ) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; | 2375 | u64 start = blk_rq_pos(rq); |
2617 | u64 start = sector; | 2376 | unsigned int nsect = blk_rq_sectors(rq); |
2618 | 2377 | ||
2619 | /* Map the scatter list for DMA access */ | 2378 | /* Map the scatter list for DMA access */ |
2620 | nents = dma_map_sg(&dd->pdev->dev, command->sg, nents, dma_dir); | 2379 | nents = dma_map_sg(&dd->pdev->dev, command->sg, nents, dma_dir); |
2621 | 2380 | ||
2622 | command->scatter_ents = nents; | 2381 | command->scatter_ents = nents; |
2623 | 2382 | ||
2624 | command->unaligned = unaligned; | ||
2625 | /* | 2383 | /* |
2626 | * The number of retries for this command before it is | 2384 | * The number of retries for this command before it is |
2627 | * reported as a failure to the upper layers. | 2385 | * reported as a failure to the upper layers. |
@@ -2632,8 +2390,10 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t sector, | |||
2632 | fis = command->command; | 2390 | fis = command->command; |
2633 | fis->type = 0x27; | 2391 | fis->type = 0x27; |
2634 | fis->opts = 1 << 7; | 2392 | fis->opts = 1 << 7; |
2635 | fis->command = | 2393 | if (rq_data_dir(rq) == READ) |
2636 | (dir == READ ? ATA_CMD_FPDMA_READ : ATA_CMD_FPDMA_WRITE); | 2394 | fis->command = ATA_CMD_FPDMA_READ; |
2395 | else | ||
2396 | fis->command = ATA_CMD_FPDMA_WRITE; | ||
2637 | fis->lba_low = start & 0xFF; | 2397 | fis->lba_low = start & 0xFF; |
2638 | fis->lba_mid = (start >> 8) & 0xFF; | 2398 | fis->lba_mid = (start >> 8) & 0xFF; |
2639 | fis->lba_hi = (start >> 16) & 0xFF; | 2399 | fis->lba_hi = (start >> 16) & 0xFF; |
@@ -2643,14 +2403,14 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t sector, | |||
2643 | fis->device = 1 << 6; | 2403 | fis->device = 1 << 6; |
2644 | fis->features = nsect & 0xFF; | 2404 | fis->features = nsect & 0xFF; |
2645 | fis->features_ex = (nsect >> 8) & 0xFF; | 2405 | fis->features_ex = (nsect >> 8) & 0xFF; |
2646 | fis->sect_count = ((tag << 3) | (tag >> 5)); | 2406 | fis->sect_count = ((rq->tag << 3) | (rq->tag >> 5)); |
2647 | fis->sect_cnt_ex = 0; | 2407 | fis->sect_cnt_ex = 0; |
2648 | fis->control = 0; | 2408 | fis->control = 0; |
2649 | fis->res2 = 0; | 2409 | fis->res2 = 0; |
2650 | fis->res3 = 0; | 2410 | fis->res3 = 0; |
2651 | fill_command_sg(dd, command, nents); | 2411 | fill_command_sg(dd, command, nents); |
2652 | 2412 | ||
2653 | if (unaligned) | 2413 | if (command->unaligned) |
2654 | fis->device |= 1 << 7; | 2414 | fis->device |= 1 << 7; |
2655 | 2415 | ||
2656 | /* Populate the command header */ | 2416 | /* Populate the command header */ |
@@ -2668,81 +2428,17 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t sector, | |||
2668 | command->direction = dma_dir; | 2428 | command->direction = dma_dir; |
2669 | 2429 | ||
2670 | /* | 2430 | /* |
2671 | * Set the completion function and data for the command passed | ||
2672 | * from the upper layer. | ||
2673 | */ | ||
2674 | command->async_data = data; | ||
2675 | command->async_callback = callback; | ||
2676 | |||
2677 | /* | ||
2678 | * To prevent this command from being issued | 2431 | * To prevent this command from being issued |
2679 | * if an internal command is in progress or error handling is active. | 2432 | * if an internal command is in progress or error handling is active. |
2680 | */ | 2433 | */ |
2681 | if (port->flags & MTIP_PF_PAUSE_IO) { | 2434 | if (port->flags & MTIP_PF_PAUSE_IO) { |
2682 | set_bit(tag, port->cmds_to_issue); | 2435 | set_bit(rq->tag, port->cmds_to_issue); |
2683 | set_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags); | 2436 | set_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags); |
2684 | return; | 2437 | return; |
2685 | } | 2438 | } |
2686 | 2439 | ||
2687 | /* Issue the command to the hardware */ | 2440 | /* Issue the command to the hardware */ |
2688 | mtip_issue_ncq_command(port, tag); | 2441 | mtip_issue_ncq_command(port, rq->tag); |
2689 | |||
2690 | return; | ||
2691 | } | ||
2692 | |||
2693 | /* | ||
2694 | * Release a command slot. | ||
2695 | * | ||
2696 | * @dd Pointer to the driver data structure. | ||
2697 | * @tag Slot tag | ||
2698 | * | ||
2699 | * return value | ||
2700 | * None | ||
2701 | */ | ||
2702 | static void mtip_hw_release_scatterlist(struct driver_data *dd, int tag, | ||
2703 | int unaligned) | ||
2704 | { | ||
2705 | struct semaphore *sem = unaligned ? &dd->port->cmd_slot_unal : | ||
2706 | &dd->port->cmd_slot; | ||
2707 | release_slot(dd->port, tag); | ||
2708 | up(sem); | ||
2709 | } | ||
2710 | |||
2711 | /* | ||
2712 | * Obtain a command slot and return its associated scatter list. | ||
2713 | * | ||
2714 | * @dd Pointer to the driver data structure. | ||
2715 | * @tag Pointer to an int that will receive the allocated command | ||
2716 | * slot tag. | ||
2717 | * | ||
2718 | * return value | ||
2719 | * Pointer to the scatter list for the allocated command slot | ||
2720 | * or NULL if no command slots are available. | ||
2721 | */ | ||
2722 | static struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd, | ||
2723 | int *tag, int unaligned) | ||
2724 | { | ||
2725 | struct semaphore *sem = unaligned ? &dd->port->cmd_slot_unal : | ||
2726 | &dd->port->cmd_slot; | ||
2727 | |||
2728 | /* | ||
2729 | * It is possible that, even with this semaphore, a thread | ||
2730 | * may think that no command slots are available. Therefore, we | ||
2731 | * need to make an attempt to get_slot(). | ||
2732 | */ | ||
2733 | down(sem); | ||
2734 | *tag = get_slot(dd->port); | ||
2735 | |||
2736 | if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))) { | ||
2737 | up(sem); | ||
2738 | return NULL; | ||
2739 | } | ||
2740 | if (unlikely(*tag < 0)) { | ||
2741 | up(sem); | ||
2742 | return NULL; | ||
2743 | } | ||
2744 | |||
2745 | return dd->port->commands[*tag].sg; | ||
2746 | } | 2442 | } |
2747 | 2443 | ||
2748 | /* | 2444 | /* |
@@ -3113,6 +2809,7 @@ static int mtip_free_orphan(struct driver_data *dd) | |||
3113 | if (dd->queue) { | 2809 | if (dd->queue) { |
3114 | dd->queue->queuedata = NULL; | 2810 | dd->queue->queuedata = NULL; |
3115 | blk_cleanup_queue(dd->queue); | 2811 | blk_cleanup_queue(dd->queue); |
2812 | blk_mq_free_tag_set(&dd->tags); | ||
3116 | dd->queue = NULL; | 2813 | dd->queue = NULL; |
3117 | } | 2814 | } |
3118 | } | 2815 | } |
@@ -3270,6 +2967,11 @@ static int mtip_service_thread(void *data) | |||
3270 | int ret; | 2967 | int ret; |
3271 | 2968 | ||
3272 | while (1) { | 2969 | while (1) { |
2970 | if (kthread_should_stop() || | ||
2971 | test_bit(MTIP_PF_SVC_THD_STOP_BIT, &port->flags)) | ||
2972 | goto st_out; | ||
2973 | clear_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags); | ||
2974 | |||
3273 | /* | 2975 | /* |
3274 | * the condition is to check neither an internal command is | 2976 | * the condition is to check neither an internal command is |
3275 | * is in progress nor error handling is active | 2977 | * is in progress nor error handling is active |
@@ -3277,11 +2979,12 @@ static int mtip_service_thread(void *data) | |||
3277 | wait_event_interruptible(port->svc_wait, (port->flags) && | 2979 | wait_event_interruptible(port->svc_wait, (port->flags) && |
3278 | !(port->flags & MTIP_PF_PAUSE_IO)); | 2980 | !(port->flags & MTIP_PF_PAUSE_IO)); |
3279 | 2981 | ||
3280 | if (kthread_should_stop()) | ||
3281 | goto st_out; | ||
3282 | |||
3283 | set_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags); | 2982 | set_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags); |
3284 | 2983 | ||
2984 | if (kthread_should_stop() || | ||
2985 | test_bit(MTIP_PF_SVC_THD_STOP_BIT, &port->flags)) | ||
2986 | goto st_out; | ||
2987 | |||
3285 | /* If I am an orphan, start self cleanup */ | 2988 | /* If I am an orphan, start self cleanup */ |
3286 | if (test_bit(MTIP_PF_SR_CLEANUP_BIT, &port->flags)) | 2989 | if (test_bit(MTIP_PF_SR_CLEANUP_BIT, &port->flags)) |
3287 | break; | 2990 | break; |
@@ -3290,6 +2993,16 @@ static int mtip_service_thread(void *data) | |||
3290 | &dd->dd_flag))) | 2993 | &dd->dd_flag))) |
3291 | goto st_out; | 2994 | goto st_out; |
3292 | 2995 | ||
2996 | restart_eh: | ||
2997 | /* Demux bits: start with error handling */ | ||
2998 | if (test_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags)) { | ||
2999 | mtip_handle_tfe(dd); | ||
3000 | clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); | ||
3001 | } | ||
3002 | |||
3003 | if (test_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags)) | ||
3004 | goto restart_eh; | ||
3005 | |||
3293 | if (test_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags)) { | 3006 | if (test_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags)) { |
3294 | slot = 1; | 3007 | slot = 1; |
3295 | /* used to restrict the loop to one iteration */ | 3008 | /* used to restrict the loop to one iteration */ |
@@ -3319,16 +3032,14 @@ static int mtip_service_thread(void *data) | |||
3319 | } | 3032 | } |
3320 | 3033 | ||
3321 | clear_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags); | 3034 | clear_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags); |
3322 | } else if (test_bit(MTIP_PF_REBUILD_BIT, &port->flags)) { | 3035 | } |
3036 | |||
3037 | if (test_bit(MTIP_PF_REBUILD_BIT, &port->flags)) { | ||
3323 | if (mtip_ftl_rebuild_poll(dd) < 0) | 3038 | if (mtip_ftl_rebuild_poll(dd) < 0) |
3324 | set_bit(MTIP_DDF_REBUILD_FAILED_BIT, | 3039 | set_bit(MTIP_DDF_REBUILD_FAILED_BIT, |
3325 | &dd->dd_flag); | 3040 | &dd->dd_flag); |
3326 | clear_bit(MTIP_PF_REBUILD_BIT, &port->flags); | 3041 | clear_bit(MTIP_PF_REBUILD_BIT, &port->flags); |
3327 | } | 3042 | } |
3328 | clear_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags); | ||
3329 | |||
3330 | if (test_bit(MTIP_PF_SVC_THD_STOP_BIT, &port->flags)) | ||
3331 | goto st_out; | ||
3332 | } | 3043 | } |
3333 | 3044 | ||
3334 | /* wait for pci remove to exit */ | 3045 | /* wait for pci remove to exit */ |
@@ -3365,7 +3076,6 @@ st_out: | |||
3365 | */ | 3076 | */ |
3366 | static void mtip_dma_free(struct driver_data *dd) | 3077 | static void mtip_dma_free(struct driver_data *dd) |
3367 | { | 3078 | { |
3368 | int i; | ||
3369 | struct mtip_port *port = dd->port; | 3079 | struct mtip_port *port = dd->port; |
3370 | 3080 | ||
3371 | if (port->block1) | 3081 | if (port->block1) |
@@ -3376,13 +3086,6 @@ static void mtip_dma_free(struct driver_data *dd) | |||
3376 | dmam_free_coherent(&dd->pdev->dev, AHCI_CMD_TBL_SZ, | 3086 | dmam_free_coherent(&dd->pdev->dev, AHCI_CMD_TBL_SZ, |
3377 | port->command_list, port->command_list_dma); | 3087 | port->command_list, port->command_list_dma); |
3378 | } | 3088 | } |
3379 | |||
3380 | for (i = 0; i < MTIP_MAX_COMMAND_SLOTS; i++) { | ||
3381 | if (port->commands[i].command) | ||
3382 | dmam_free_coherent(&dd->pdev->dev, CMD_DMA_ALLOC_SZ, | ||
3383 | port->commands[i].command, | ||
3384 | port->commands[i].command_dma); | ||
3385 | } | ||
3386 | } | 3089 | } |
3387 | 3090 | ||
3388 | /* | 3091 | /* |
@@ -3396,8 +3099,6 @@ static void mtip_dma_free(struct driver_data *dd) | |||
3396 | static int mtip_dma_alloc(struct driver_data *dd) | 3099 | static int mtip_dma_alloc(struct driver_data *dd) |
3397 | { | 3100 | { |
3398 | struct mtip_port *port = dd->port; | 3101 | struct mtip_port *port = dd->port; |
3399 | int i, rv = 0; | ||
3400 | u32 host_cap_64 = readl(dd->mmio + HOST_CAP) & HOST_CAP_64; | ||
3401 | 3102 | ||
3402 | /* Allocate dma memory for RX Fis, Identify, and Sector Bufffer */ | 3103 | /* Allocate dma memory for RX Fis, Identify, and Sector Bufffer */ |
3403 | port->block1 = | 3104 | port->block1 = |
@@ -3430,41 +3131,63 @@ static int mtip_dma_alloc(struct driver_data *dd) | |||
3430 | port->smart_buf = port->block1 + AHCI_SMARTBUF_OFFSET; | 3131 | port->smart_buf = port->block1 + AHCI_SMARTBUF_OFFSET; |
3431 | port->smart_buf_dma = port->block1_dma + AHCI_SMARTBUF_OFFSET; | 3132 | port->smart_buf_dma = port->block1_dma + AHCI_SMARTBUF_OFFSET; |
3432 | 3133 | ||
3433 | /* Setup per command SGL DMA region */ | 3134 | return 0; |
3434 | 3135 | } | |
3435 | /* Point the command headers at the command tables */ | ||
3436 | for (i = 0; i < MTIP_MAX_COMMAND_SLOTS; i++) { | ||
3437 | port->commands[i].command = | ||
3438 | dmam_alloc_coherent(&dd->pdev->dev, CMD_DMA_ALLOC_SZ, | ||
3439 | &port->commands[i].command_dma, GFP_KERNEL); | ||
3440 | if (!port->commands[i].command) { | ||
3441 | rv = -ENOMEM; | ||
3442 | mtip_dma_free(dd); | ||
3443 | return rv; | ||
3444 | } | ||
3445 | memset(port->commands[i].command, 0, CMD_DMA_ALLOC_SZ); | ||
3446 | |||
3447 | port->commands[i].command_header = port->command_list + | ||
3448 | (sizeof(struct mtip_cmd_hdr) * i); | ||
3449 | port->commands[i].command_header_dma = | ||
3450 | dd->port->command_list_dma + | ||
3451 | (sizeof(struct mtip_cmd_hdr) * i); | ||
3452 | 3136 | ||
3453 | if (host_cap_64) | 3137 | static int mtip_hw_get_identify(struct driver_data *dd) |
3454 | port->commands[i].command_header->ctbau = | 3138 | { |
3455 | __force_bit2int cpu_to_le32( | 3139 | struct smart_attr attr242; |
3456 | (port->commands[i].command_dma >> 16) >> 16); | 3140 | unsigned char *buf; |
3141 | int rv; | ||
3457 | 3142 | ||
3458 | port->commands[i].command_header->ctba = | 3143 | if (mtip_get_identify(dd->port, NULL) < 0) |
3459 | __force_bit2int cpu_to_le32( | 3144 | return -EFAULT; |
3460 | port->commands[i].command_dma & 0xFFFFFFFF); | ||
3461 | 3145 | ||
3462 | sg_init_table(port->commands[i].sg, MTIP_MAX_SG); | 3146 | if (*(dd->port->identify + MTIP_FTL_REBUILD_OFFSET) == |
3147 | MTIP_FTL_REBUILD_MAGIC) { | ||
3148 | set_bit(MTIP_PF_REBUILD_BIT, &dd->port->flags); | ||
3149 | return MTIP_FTL_REBUILD_MAGIC; | ||
3150 | } | ||
3151 | mtip_dump_identify(dd->port); | ||
3463 | 3152 | ||
3464 | /* Mark command as currently inactive */ | 3153 | /* check write protect, over temp and rebuild statuses */ |
3465 | atomic_set(&dd->port->commands[i].active, 0); | 3154 | rv = mtip_read_log_page(dd->port, ATA_LOG_SATA_NCQ, |
3155 | dd->port->log_buf, | ||
3156 | dd->port->log_buf_dma, 1); | ||
3157 | if (rv) { | ||
3158 | dev_warn(&dd->pdev->dev, | ||
3159 | "Error in READ LOG EXT (10h) command\n"); | ||
3160 | /* non-critical error, don't fail the load */ | ||
3161 | } else { | ||
3162 | buf = (unsigned char *)dd->port->log_buf; | ||
3163 | if (buf[259] & 0x1) { | ||
3164 | dev_info(&dd->pdev->dev, | ||
3165 | "Write protect bit is set.\n"); | ||
3166 | set_bit(MTIP_DDF_WRITE_PROTECT_BIT, &dd->dd_flag); | ||
3167 | } | ||
3168 | if (buf[288] == 0xF7) { | ||
3169 | dev_info(&dd->pdev->dev, | ||
3170 | "Exceeded Tmax, drive in thermal shutdown.\n"); | ||
3171 | set_bit(MTIP_DDF_OVER_TEMP_BIT, &dd->dd_flag); | ||
3172 | } | ||
3173 | if (buf[288] == 0xBF) { | ||
3174 | dev_info(&dd->pdev->dev, | ||
3175 | "Drive indicates rebuild has failed.\n"); | ||
3176 | /* TODO */ | ||
3177 | } | ||
3466 | } | 3178 | } |
3467 | return 0; | 3179 | |
3180 | /* get write protect progess */ | ||
3181 | memset(&attr242, 0, sizeof(struct smart_attr)); | ||
3182 | if (mtip_get_smart_attr(dd->port, 242, &attr242)) | ||
3183 | dev_warn(&dd->pdev->dev, | ||
3184 | "Unable to check write protect progress\n"); | ||
3185 | else | ||
3186 | dev_info(&dd->pdev->dev, | ||
3187 | "Write protect progress: %u%% (%u blocks)\n", | ||
3188 | attr242.cur, le32_to_cpu(attr242.data)); | ||
3189 | |||
3190 | return rv; | ||
3468 | } | 3191 | } |
3469 | 3192 | ||
3470 | /* | 3193 | /* |
@@ -3481,8 +3204,6 @@ static int mtip_hw_init(struct driver_data *dd) | |||
3481 | int rv; | 3204 | int rv; |
3482 | unsigned int num_command_slots; | 3205 | unsigned int num_command_slots; |
3483 | unsigned long timeout, timetaken; | 3206 | unsigned long timeout, timetaken; |
3484 | unsigned char *buf; | ||
3485 | struct smart_attr attr242; | ||
3486 | 3207 | ||
3487 | dd->mmio = pcim_iomap_table(dd->pdev)[MTIP_ABAR]; | 3208 | dd->mmio = pcim_iomap_table(dd->pdev)[MTIP_ABAR]; |
3488 | 3209 | ||
@@ -3513,8 +3234,6 @@ static int mtip_hw_init(struct driver_data *dd) | |||
3513 | else | 3234 | else |
3514 | dd->unal_qdepth = 0; | 3235 | dd->unal_qdepth = 0; |
3515 | 3236 | ||
3516 | /* Counting semaphore to track command slot usage */ | ||
3517 | sema_init(&dd->port->cmd_slot, num_command_slots - 1 - dd->unal_qdepth); | ||
3518 | sema_init(&dd->port->cmd_slot_unal, dd->unal_qdepth); | 3237 | sema_init(&dd->port->cmd_slot_unal, dd->unal_qdepth); |
3519 | 3238 | ||
3520 | /* Spinlock to prevent concurrent issue */ | 3239 | /* Spinlock to prevent concurrent issue */ |
@@ -3599,73 +3318,16 @@ static int mtip_hw_init(struct driver_data *dd) | |||
3599 | writel(readl(dd->mmio + HOST_CTL) | HOST_IRQ_EN, | 3318 | writel(readl(dd->mmio + HOST_CTL) | HOST_IRQ_EN, |
3600 | dd->mmio + HOST_CTL); | 3319 | dd->mmio + HOST_CTL); |
3601 | 3320 | ||
3602 | init_timer(&dd->port->cmd_timer); | ||
3603 | init_waitqueue_head(&dd->port->svc_wait); | 3321 | init_waitqueue_head(&dd->port->svc_wait); |
3604 | 3322 | ||
3605 | dd->port->cmd_timer.data = (unsigned long int) dd->port; | ||
3606 | dd->port->cmd_timer.function = mtip_timeout_function; | ||
3607 | mod_timer(&dd->port->cmd_timer, | ||
3608 | jiffies + msecs_to_jiffies(MTIP_TIMEOUT_CHECK_PERIOD)); | ||
3609 | |||
3610 | |||
3611 | if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag)) { | 3323 | if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag)) { |
3612 | rv = -EFAULT; | 3324 | rv = -EFAULT; |
3613 | goto out3; | 3325 | goto out3; |
3614 | } | 3326 | } |
3615 | 3327 | ||
3616 | if (mtip_get_identify(dd->port, NULL) < 0) { | ||
3617 | rv = -EFAULT; | ||
3618 | goto out3; | ||
3619 | } | ||
3620 | mtip_dump_identify(dd->port); | ||
3621 | |||
3622 | if (*(dd->port->identify + MTIP_FTL_REBUILD_OFFSET) == | ||
3623 | MTIP_FTL_REBUILD_MAGIC) { | ||
3624 | set_bit(MTIP_PF_REBUILD_BIT, &dd->port->flags); | ||
3625 | return MTIP_FTL_REBUILD_MAGIC; | ||
3626 | } | ||
3627 | |||
3628 | /* check write protect, over temp and rebuild statuses */ | ||
3629 | rv = mtip_read_log_page(dd->port, ATA_LOG_SATA_NCQ, | ||
3630 | dd->port->log_buf, | ||
3631 | dd->port->log_buf_dma, 1); | ||
3632 | if (rv) { | ||
3633 | dev_warn(&dd->pdev->dev, | ||
3634 | "Error in READ LOG EXT (10h) command\n"); | ||
3635 | /* non-critical error, don't fail the load */ | ||
3636 | } else { | ||
3637 | buf = (unsigned char *)dd->port->log_buf; | ||
3638 | if (buf[259] & 0x1) { | ||
3639 | dev_info(&dd->pdev->dev, | ||
3640 | "Write protect bit is set.\n"); | ||
3641 | set_bit(MTIP_DDF_WRITE_PROTECT_BIT, &dd->dd_flag); | ||
3642 | } | ||
3643 | if (buf[288] == 0xF7) { | ||
3644 | dev_info(&dd->pdev->dev, | ||
3645 | "Exceeded Tmax, drive in thermal shutdown.\n"); | ||
3646 | set_bit(MTIP_DDF_OVER_TEMP_BIT, &dd->dd_flag); | ||
3647 | } | ||
3648 | if (buf[288] == 0xBF) { | ||
3649 | dev_info(&dd->pdev->dev, | ||
3650 | "Drive is in security locked state.\n"); | ||
3651 | set_bit(MTIP_DDF_SEC_LOCK_BIT, &dd->dd_flag); | ||
3652 | } | ||
3653 | } | ||
3654 | |||
3655 | /* get write protect progess */ | ||
3656 | memset(&attr242, 0, sizeof(struct smart_attr)); | ||
3657 | if (mtip_get_smart_attr(dd->port, 242, &attr242)) | ||
3658 | dev_warn(&dd->pdev->dev, | ||
3659 | "Unable to check write protect progress\n"); | ||
3660 | else | ||
3661 | dev_info(&dd->pdev->dev, | ||
3662 | "Write protect progress: %u%% (%u blocks)\n", | ||
3663 | attr242.cur, le32_to_cpu(attr242.data)); | ||
3664 | return rv; | 3328 | return rv; |
3665 | 3329 | ||
3666 | out3: | 3330 | out3: |
3667 | del_timer_sync(&dd->port->cmd_timer); | ||
3668 | |||
3669 | /* Disable interrupts on the HBA. */ | 3331 | /* Disable interrupts on the HBA. */ |
3670 | writel(readl(dd->mmio + HOST_CTL) & ~HOST_IRQ_EN, | 3332 | writel(readl(dd->mmio + HOST_CTL) & ~HOST_IRQ_EN, |
3671 | dd->mmio + HOST_CTL); | 3333 | dd->mmio + HOST_CTL); |
@@ -3685,6 +3347,22 @@ out1: | |||
3685 | return rv; | 3347 | return rv; |
3686 | } | 3348 | } |
3687 | 3349 | ||
3350 | static void mtip_standby_drive(struct driver_data *dd) | ||
3351 | { | ||
3352 | if (dd->sr) | ||
3353 | return; | ||
3354 | |||
3355 | /* | ||
3356 | * Send standby immediate (E0h) to the drive so that it | ||
3357 | * saves its state. | ||
3358 | */ | ||
3359 | if (!test_bit(MTIP_PF_REBUILD_BIT, &dd->port->flags) && | ||
3360 | !test_bit(MTIP_DDF_SEC_LOCK_BIT, &dd->dd_flag)) | ||
3361 | if (mtip_standby_immediate(dd->port)) | ||
3362 | dev_warn(&dd->pdev->dev, | ||
3363 | "STANDBY IMMEDIATE failed\n"); | ||
3364 | } | ||
3365 | |||
3688 | /* | 3366 | /* |
3689 | * Called to deinitialize an interface. | 3367 | * Called to deinitialize an interface. |
3690 | * | 3368 | * |
@@ -3700,12 +3378,6 @@ static int mtip_hw_exit(struct driver_data *dd) | |||
3700 | * saves its state. | 3378 | * saves its state. |
3701 | */ | 3379 | */ |
3702 | if (!dd->sr) { | 3380 | if (!dd->sr) { |
3703 | if (!test_bit(MTIP_PF_REBUILD_BIT, &dd->port->flags) && | ||
3704 | !test_bit(MTIP_DDF_SEC_LOCK_BIT, &dd->dd_flag)) | ||
3705 | if (mtip_standby_immediate(dd->port)) | ||
3706 | dev_warn(&dd->pdev->dev, | ||
3707 | "STANDBY IMMEDIATE failed\n"); | ||
3708 | |||
3709 | /* de-initialize the port. */ | 3381 | /* de-initialize the port. */ |
3710 | mtip_deinit_port(dd->port); | 3382 | mtip_deinit_port(dd->port); |
3711 | 3383 | ||
@@ -3714,8 +3386,6 @@ static int mtip_hw_exit(struct driver_data *dd) | |||
3714 | dd->mmio + HOST_CTL); | 3386 | dd->mmio + HOST_CTL); |
3715 | } | 3387 | } |
3716 | 3388 | ||
3717 | del_timer_sync(&dd->port->cmd_timer); | ||
3718 | |||
3719 | /* Release the IRQ. */ | 3389 | /* Release the IRQ. */ |
3720 | irq_set_affinity_hint(dd->pdev->irq, NULL); | 3390 | irq_set_affinity_hint(dd->pdev->irq, NULL); |
3721 | devm_free_irq(&dd->pdev->dev, dd->pdev->irq, dd); | 3391 | devm_free_irq(&dd->pdev->dev, dd->pdev->irq, dd); |
@@ -4032,100 +3702,138 @@ static const struct block_device_operations mtip_block_ops = { | |||
4032 | * | 3702 | * |
4033 | * @queue Pointer to the request queue. Unused other than to obtain | 3703 | * @queue Pointer to the request queue. Unused other than to obtain |
4034 | * the driver data structure. | 3704 | * the driver data structure. |
4035 | * @bio Pointer to the BIO. | 3705 | * @rq Pointer to the request. |
4036 | * | 3706 | * |
4037 | */ | 3707 | */ |
4038 | static void mtip_make_request(struct request_queue *queue, struct bio *bio) | 3708 | static int mtip_submit_request(struct blk_mq_hw_ctx *hctx, struct request *rq) |
4039 | { | 3709 | { |
4040 | struct driver_data *dd = queue->queuedata; | 3710 | struct driver_data *dd = hctx->queue->queuedata; |
4041 | struct scatterlist *sg; | 3711 | struct mtip_cmd *cmd = blk_mq_rq_to_pdu(rq); |
4042 | struct bio_vec bvec; | 3712 | unsigned int nents; |
4043 | struct bvec_iter iter; | ||
4044 | int nents = 0; | ||
4045 | int tag = 0, unaligned = 0; | ||
4046 | 3713 | ||
4047 | if (unlikely(dd->dd_flag & MTIP_DDF_STOP_IO)) { | 3714 | if (unlikely(dd->dd_flag & MTIP_DDF_STOP_IO)) { |
4048 | if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, | 3715 | if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, |
4049 | &dd->dd_flag))) { | 3716 | &dd->dd_flag))) { |
4050 | bio_endio(bio, -ENXIO); | 3717 | return -ENXIO; |
4051 | return; | ||
4052 | } | 3718 | } |
4053 | if (unlikely(test_bit(MTIP_DDF_OVER_TEMP_BIT, &dd->dd_flag))) { | 3719 | if (unlikely(test_bit(MTIP_DDF_OVER_TEMP_BIT, &dd->dd_flag))) { |
4054 | bio_endio(bio, -ENODATA); | 3720 | return -ENODATA; |
4055 | return; | ||
4056 | } | 3721 | } |
4057 | if (unlikely(test_bit(MTIP_DDF_WRITE_PROTECT_BIT, | 3722 | if (unlikely(test_bit(MTIP_DDF_WRITE_PROTECT_BIT, |
4058 | &dd->dd_flag) && | 3723 | &dd->dd_flag) && |
4059 | bio_data_dir(bio))) { | 3724 | rq_data_dir(rq))) { |
4060 | bio_endio(bio, -ENODATA); | 3725 | return -ENODATA; |
4061 | return; | ||
4062 | } | ||
4063 | if (unlikely(test_bit(MTIP_DDF_SEC_LOCK_BIT, &dd->dd_flag))) { | ||
4064 | bio_endio(bio, -ENODATA); | ||
4065 | return; | ||
4066 | } | ||
4067 | if (test_bit(MTIP_DDF_REBUILD_FAILED_BIT, &dd->dd_flag)) { | ||
4068 | bio_endio(bio, -ENXIO); | ||
4069 | return; | ||
4070 | } | 3726 | } |
3727 | if (unlikely(test_bit(MTIP_DDF_SEC_LOCK_BIT, &dd->dd_flag))) | ||
3728 | return -ENODATA; | ||
3729 | if (test_bit(MTIP_DDF_REBUILD_FAILED_BIT, &dd->dd_flag)) | ||
3730 | return -ENXIO; | ||
4071 | } | 3731 | } |
4072 | 3732 | ||
4073 | if (unlikely(bio->bi_rw & REQ_DISCARD)) { | 3733 | if (rq->cmd_flags & REQ_DISCARD) { |
4074 | bio_endio(bio, mtip_send_trim(dd, bio->bi_iter.bi_sector, | 3734 | int err; |
4075 | bio_sectors(bio))); | ||
4076 | return; | ||
4077 | } | ||
4078 | 3735 | ||
4079 | if (unlikely(!bio_has_data(bio))) { | 3736 | err = mtip_send_trim(dd, blk_rq_pos(rq), blk_rq_sectors(rq)); |
4080 | blk_queue_flush(queue, 0); | 3737 | blk_mq_end_io(rq, err); |
4081 | bio_endio(bio, 0); | 3738 | return 0; |
4082 | return; | ||
4083 | } | 3739 | } |
4084 | 3740 | ||
4085 | if (bio_data_dir(bio) == WRITE && bio_sectors(bio) <= 64 && | 3741 | /* Create the scatter list for this request. */ |
4086 | dd->unal_qdepth) { | 3742 | nents = blk_rq_map_sg(hctx->queue, rq, cmd->sg); |
4087 | if (bio->bi_iter.bi_sector % 8 != 0) | 3743 | |
4088 | /* Unaligned on 4k boundaries */ | 3744 | /* Issue the read/write. */ |
4089 | unaligned = 1; | 3745 | mtip_hw_submit_io(dd, rq, cmd, nents, hctx); |
4090 | else if (bio_sectors(bio) % 8 != 0) /* Aligned but not 4k/8k */ | 3746 | return 0; |
4091 | unaligned = 1; | 3747 | } |
3748 | |||
3749 | static bool mtip_check_unal_depth(struct blk_mq_hw_ctx *hctx, | ||
3750 | struct request *rq) | ||
3751 | { | ||
3752 | struct driver_data *dd = hctx->queue->queuedata; | ||
3753 | struct mtip_cmd *cmd = blk_mq_rq_to_pdu(rq); | ||
3754 | |||
3755 | if (!dd->unal_qdepth || rq_data_dir(rq) == READ) | ||
3756 | return false; | ||
3757 | |||
3758 | /* | ||
3759 | * If unaligned depth must be limited on this controller, mark it | ||
3760 | * as unaligned if the IO isn't on a 4k boundary (start of length). | ||
3761 | */ | ||
3762 | if (blk_rq_sectors(rq) <= 64) { | ||
3763 | if ((blk_rq_pos(rq) & 7) || (blk_rq_sectors(rq) & 7)) | ||
3764 | cmd->unaligned = 1; | ||
4092 | } | 3765 | } |
4093 | 3766 | ||
4094 | sg = mtip_hw_get_scatterlist(dd, &tag, unaligned); | 3767 | if (cmd->unaligned && down_trylock(&dd->port->cmd_slot_unal)) |
4095 | if (likely(sg != NULL)) { | 3768 | return true; |
4096 | blk_queue_bounce(queue, &bio); | ||
4097 | 3769 | ||
4098 | if (unlikely((bio)->bi_vcnt > MTIP_MAX_SG)) { | 3770 | return false; |
4099 | dev_warn(&dd->pdev->dev, | 3771 | } |
4100 | "Maximum number of SGL entries exceeded\n"); | ||
4101 | bio_io_error(bio); | ||
4102 | mtip_hw_release_scatterlist(dd, tag, unaligned); | ||
4103 | return; | ||
4104 | } | ||
4105 | 3772 | ||
4106 | /* Create the scatter list for this bio. */ | 3773 | static int mtip_queue_rq(struct blk_mq_hw_ctx *hctx, struct request *rq) |
4107 | bio_for_each_segment(bvec, bio, iter) { | 3774 | { |
4108 | sg_set_page(&sg[nents], | 3775 | int ret; |
4109 | bvec.bv_page, | ||
4110 | bvec.bv_len, | ||
4111 | bvec.bv_offset); | ||
4112 | nents++; | ||
4113 | } | ||
4114 | 3776 | ||
4115 | /* Issue the read/write. */ | 3777 | if (mtip_check_unal_depth(hctx, rq)) |
4116 | mtip_hw_submit_io(dd, | 3778 | return BLK_MQ_RQ_QUEUE_BUSY; |
4117 | bio->bi_iter.bi_sector, | 3779 | |
4118 | bio_sectors(bio), | 3780 | ret = mtip_submit_request(hctx, rq); |
4119 | nents, | 3781 | if (!ret) |
4120 | tag, | 3782 | return BLK_MQ_RQ_QUEUE_OK; |
4121 | bio_endio, | 3783 | |
4122 | bio, | 3784 | rq->errors = ret; |
4123 | bio_data_dir(bio), | 3785 | return BLK_MQ_RQ_QUEUE_ERROR; |
4124 | unaligned); | 3786 | } |
4125 | } else | 3787 | |
4126 | bio_io_error(bio); | 3788 | static void mtip_free_cmd(void *data, struct request *rq, |
3789 | unsigned int hctx_idx, unsigned int request_idx) | ||
3790 | { | ||
3791 | struct driver_data *dd = data; | ||
3792 | struct mtip_cmd *cmd = blk_mq_rq_to_pdu(rq); | ||
3793 | |||
3794 | if (!cmd->command) | ||
3795 | return; | ||
3796 | |||
3797 | dmam_free_coherent(&dd->pdev->dev, CMD_DMA_ALLOC_SZ, | ||
3798 | cmd->command, cmd->command_dma); | ||
3799 | } | ||
3800 | |||
3801 | static int mtip_init_cmd(void *data, struct request *rq, unsigned int hctx_idx, | ||
3802 | unsigned int request_idx, unsigned int numa_node) | ||
3803 | { | ||
3804 | struct driver_data *dd = data; | ||
3805 | struct mtip_cmd *cmd = blk_mq_rq_to_pdu(rq); | ||
3806 | u32 host_cap_64 = readl(dd->mmio + HOST_CAP) & HOST_CAP_64; | ||
3807 | |||
3808 | cmd->command = dmam_alloc_coherent(&dd->pdev->dev, CMD_DMA_ALLOC_SZ, | ||
3809 | &cmd->command_dma, GFP_KERNEL); | ||
3810 | if (!cmd->command) | ||
3811 | return -ENOMEM; | ||
3812 | |||
3813 | memset(cmd->command, 0, CMD_DMA_ALLOC_SZ); | ||
3814 | |||
3815 | /* Point the command headers at the command tables. */ | ||
3816 | cmd->command_header = dd->port->command_list + | ||
3817 | (sizeof(struct mtip_cmd_hdr) * request_idx); | ||
3818 | cmd->command_header_dma = dd->port->command_list_dma + | ||
3819 | (sizeof(struct mtip_cmd_hdr) * request_idx); | ||
3820 | |||
3821 | if (host_cap_64) | ||
3822 | cmd->command_header->ctbau = __force_bit2int cpu_to_le32((cmd->command_dma >> 16) >> 16); | ||
3823 | |||
3824 | cmd->command_header->ctba = __force_bit2int cpu_to_le32(cmd->command_dma & 0xFFFFFFFF); | ||
3825 | |||
3826 | sg_init_table(cmd->sg, MTIP_MAX_SG); | ||
3827 | return 0; | ||
4127 | } | 3828 | } |
4128 | 3829 | ||
3830 | static struct blk_mq_ops mtip_mq_ops = { | ||
3831 | .queue_rq = mtip_queue_rq, | ||
3832 | .map_queue = blk_mq_map_queue, | ||
3833 | .init_request = mtip_init_cmd, | ||
3834 | .exit_request = mtip_free_cmd, | ||
3835 | }; | ||
3836 | |||
4129 | /* | 3837 | /* |
4130 | * Block layer initialization function. | 3838 | * Block layer initialization function. |
4131 | * | 3839 | * |
@@ -4148,11 +3856,7 @@ static int mtip_block_initialize(struct driver_data *dd) | |||
4148 | if (dd->disk) | 3856 | if (dd->disk) |
4149 | goto skip_create_disk; /* hw init done, before rebuild */ | 3857 | goto skip_create_disk; /* hw init done, before rebuild */ |
4150 | 3858 | ||
4151 | /* Initialize the protocol layer. */ | 3859 | if (mtip_hw_init(dd)) { |
4152 | wait_for_rebuild = mtip_hw_init(dd); | ||
4153 | if (wait_for_rebuild < 0) { | ||
4154 | dev_err(&dd->pdev->dev, | ||
4155 | "Protocol layer initialization failed\n"); | ||
4156 | rv = -EINVAL; | 3860 | rv = -EINVAL; |
4157 | goto protocol_init_error; | 3861 | goto protocol_init_error; |
4158 | } | 3862 | } |
@@ -4194,29 +3898,53 @@ static int mtip_block_initialize(struct driver_data *dd) | |||
4194 | 3898 | ||
4195 | mtip_hw_debugfs_init(dd); | 3899 | mtip_hw_debugfs_init(dd); |
4196 | 3900 | ||
4197 | /* | ||
4198 | * if rebuild pending, start the service thread, and delay the block | ||
4199 | * queue creation and add_disk() | ||
4200 | */ | ||
4201 | if (wait_for_rebuild == MTIP_FTL_REBUILD_MAGIC) | ||
4202 | goto start_service_thread; | ||
4203 | |||
4204 | skip_create_disk: | 3901 | skip_create_disk: |
4205 | /* Allocate the request queue. */ | 3902 | memset(&dd->tags, 0, sizeof(dd->tags)); |
4206 | dd->queue = blk_alloc_queue_node(GFP_KERNEL, dd->numa_node); | 3903 | dd->tags.ops = &mtip_mq_ops; |
4207 | if (dd->queue == NULL) { | 3904 | dd->tags.nr_hw_queues = 1; |
3905 | dd->tags.queue_depth = MTIP_MAX_COMMAND_SLOTS; | ||
3906 | dd->tags.reserved_tags = 1; | ||
3907 | dd->tags.cmd_size = sizeof(struct mtip_cmd); | ||
3908 | dd->tags.numa_node = dd->numa_node; | ||
3909 | dd->tags.flags = BLK_MQ_F_SHOULD_MERGE; | ||
3910 | dd->tags.driver_data = dd; | ||
3911 | |||
3912 | rv = blk_mq_alloc_tag_set(&dd->tags); | ||
3913 | if (rv) { | ||
4208 | dev_err(&dd->pdev->dev, | 3914 | dev_err(&dd->pdev->dev, |
4209 | "Unable to allocate request queue\n"); | 3915 | "Unable to allocate request queue\n"); |
4210 | rv = -ENOMEM; | 3916 | rv = -ENOMEM; |
4211 | goto block_queue_alloc_init_error; | 3917 | goto block_queue_alloc_init_error; |
4212 | } | 3918 | } |
4213 | 3919 | ||
4214 | /* Attach our request function to the request queue. */ | 3920 | /* Allocate the request queue. */ |
4215 | blk_queue_make_request(dd->queue, mtip_make_request); | 3921 | dd->queue = blk_mq_init_queue(&dd->tags); |
3922 | if (IS_ERR(dd->queue)) { | ||
3923 | dev_err(&dd->pdev->dev, | ||
3924 | "Unable to allocate request queue\n"); | ||
3925 | rv = -ENOMEM; | ||
3926 | goto block_queue_alloc_init_error; | ||
3927 | } | ||
4216 | 3928 | ||
4217 | dd->disk->queue = dd->queue; | 3929 | dd->disk->queue = dd->queue; |
4218 | dd->queue->queuedata = dd; | 3930 | dd->queue->queuedata = dd; |
4219 | 3931 | ||
3932 | /* Initialize the protocol layer. */ | ||
3933 | wait_for_rebuild = mtip_hw_get_identify(dd); | ||
3934 | if (wait_for_rebuild < 0) { | ||
3935 | dev_err(&dd->pdev->dev, | ||
3936 | "Protocol layer initialization failed\n"); | ||
3937 | rv = -EINVAL; | ||
3938 | goto init_hw_cmds_error; | ||
3939 | } | ||
3940 | |||
3941 | /* | ||
3942 | * if rebuild pending, start the service thread, and delay the block | ||
3943 | * queue creation and add_disk() | ||
3944 | */ | ||
3945 | if (wait_for_rebuild == MTIP_FTL_REBUILD_MAGIC) | ||
3946 | goto start_service_thread; | ||
3947 | |||
4220 | /* Set device limits. */ | 3948 | /* Set device limits. */ |
4221 | set_bit(QUEUE_FLAG_NONROT, &dd->queue->queue_flags); | 3949 | set_bit(QUEUE_FLAG_NONROT, &dd->queue->queue_flags); |
4222 | blk_queue_max_segments(dd->queue, MTIP_MAX_SG); | 3950 | blk_queue_max_segments(dd->queue, MTIP_MAX_SG); |
@@ -4295,8 +4023,9 @@ kthread_run_error: | |||
4295 | del_gendisk(dd->disk); | 4023 | del_gendisk(dd->disk); |
4296 | 4024 | ||
4297 | read_capacity_error: | 4025 | read_capacity_error: |
4026 | init_hw_cmds_error: | ||
4298 | blk_cleanup_queue(dd->queue); | 4027 | blk_cleanup_queue(dd->queue); |
4299 | 4028 | blk_mq_free_tag_set(&dd->tags); | |
4300 | block_queue_alloc_init_error: | 4029 | block_queue_alloc_init_error: |
4301 | mtip_hw_debugfs_exit(dd); | 4030 | mtip_hw_debugfs_exit(dd); |
4302 | disk_index_error: | 4031 | disk_index_error: |
@@ -4345,6 +4074,9 @@ static int mtip_block_remove(struct driver_data *dd) | |||
4345 | kobject_put(kobj); | 4074 | kobject_put(kobj); |
4346 | } | 4075 | } |
4347 | } | 4076 | } |
4077 | |||
4078 | mtip_standby_drive(dd); | ||
4079 | |||
4348 | /* | 4080 | /* |
4349 | * Delete our gendisk structure. This also removes the device | 4081 | * Delete our gendisk structure. This also removes the device |
4350 | * from /dev | 4082 | * from /dev |
@@ -4357,6 +4089,7 @@ static int mtip_block_remove(struct driver_data *dd) | |||
4357 | if (dd->disk->queue) { | 4089 | if (dd->disk->queue) { |
4358 | del_gendisk(dd->disk); | 4090 | del_gendisk(dd->disk); |
4359 | blk_cleanup_queue(dd->queue); | 4091 | blk_cleanup_queue(dd->queue); |
4092 | blk_mq_free_tag_set(&dd->tags); | ||
4360 | dd->queue = NULL; | 4093 | dd->queue = NULL; |
4361 | } else | 4094 | } else |
4362 | put_disk(dd->disk); | 4095 | put_disk(dd->disk); |
@@ -4391,6 +4124,8 @@ static int mtip_block_remove(struct driver_data *dd) | |||
4391 | */ | 4124 | */ |
4392 | static int mtip_block_shutdown(struct driver_data *dd) | 4125 | static int mtip_block_shutdown(struct driver_data *dd) |
4393 | { | 4126 | { |
4127 | mtip_hw_shutdown(dd); | ||
4128 | |||
4394 | /* Delete our gendisk structure, and cleanup the blk queue. */ | 4129 | /* Delete our gendisk structure, and cleanup the blk queue. */ |
4395 | if (dd->disk) { | 4130 | if (dd->disk) { |
4396 | dev_info(&dd->pdev->dev, | 4131 | dev_info(&dd->pdev->dev, |
@@ -4399,6 +4134,7 @@ static int mtip_block_shutdown(struct driver_data *dd) | |||
4399 | if (dd->disk->queue) { | 4134 | if (dd->disk->queue) { |
4400 | del_gendisk(dd->disk); | 4135 | del_gendisk(dd->disk); |
4401 | blk_cleanup_queue(dd->queue); | 4136 | blk_cleanup_queue(dd->queue); |
4137 | blk_mq_free_tag_set(&dd->tags); | ||
4402 | } else | 4138 | } else |
4403 | put_disk(dd->disk); | 4139 | put_disk(dd->disk); |
4404 | dd->disk = NULL; | 4140 | dd->disk = NULL; |
@@ -4408,8 +4144,6 @@ static int mtip_block_shutdown(struct driver_data *dd) | |||
4408 | spin_lock(&rssd_index_lock); | 4144 | spin_lock(&rssd_index_lock); |
4409 | ida_remove(&rssd_index_ida, dd->index); | 4145 | ida_remove(&rssd_index_ida, dd->index); |
4410 | spin_unlock(&rssd_index_lock); | 4146 | spin_unlock(&rssd_index_lock); |
4411 | |||
4412 | mtip_hw_shutdown(dd); | ||
4413 | return 0; | 4147 | return 0; |
4414 | } | 4148 | } |
4415 | 4149 | ||
@@ -4479,6 +4213,57 @@ static DEFINE_HANDLER(5); | |||
4479 | static DEFINE_HANDLER(6); | 4213 | static DEFINE_HANDLER(6); |
4480 | static DEFINE_HANDLER(7); | 4214 | static DEFINE_HANDLER(7); |
4481 | 4215 | ||
4216 | static void mtip_disable_link_opts(struct driver_data *dd, struct pci_dev *pdev) | ||
4217 | { | ||
4218 | int pos; | ||
4219 | unsigned short pcie_dev_ctrl; | ||
4220 | |||
4221 | pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); | ||
4222 | if (pos) { | ||
4223 | pci_read_config_word(pdev, | ||
4224 | pos + PCI_EXP_DEVCTL, | ||
4225 | &pcie_dev_ctrl); | ||
4226 | if (pcie_dev_ctrl & (1 << 11) || | ||
4227 | pcie_dev_ctrl & (1 << 4)) { | ||
4228 | dev_info(&dd->pdev->dev, | ||
4229 | "Disabling ERO/No-Snoop on bridge device %04x:%04x\n", | ||
4230 | pdev->vendor, pdev->device); | ||
4231 | pcie_dev_ctrl &= ~(PCI_EXP_DEVCTL_NOSNOOP_EN | | ||
4232 | PCI_EXP_DEVCTL_RELAX_EN); | ||
4233 | pci_write_config_word(pdev, | ||
4234 | pos + PCI_EXP_DEVCTL, | ||
4235 | pcie_dev_ctrl); | ||
4236 | } | ||
4237 | } | ||
4238 | } | ||
4239 | |||
4240 | static void mtip_fix_ero_nosnoop(struct driver_data *dd, struct pci_dev *pdev) | ||
4241 | { | ||
4242 | /* | ||
4243 | * This workaround is specific to AMD/ATI chipset with a PCI upstream | ||
4244 | * device with device id 0x5aXX | ||
4245 | */ | ||
4246 | if (pdev->bus && pdev->bus->self) { | ||
4247 | if (pdev->bus->self->vendor == PCI_VENDOR_ID_ATI && | ||
4248 | ((pdev->bus->self->device & 0xff00) == 0x5a00)) { | ||
4249 | mtip_disable_link_opts(dd, pdev->bus->self); | ||
4250 | } else { | ||
4251 | /* Check further up the topology */ | ||
4252 | struct pci_dev *parent_dev = pdev->bus->self; | ||
4253 | if (parent_dev->bus && | ||
4254 | parent_dev->bus->parent && | ||
4255 | parent_dev->bus->parent->self && | ||
4256 | parent_dev->bus->parent->self->vendor == | ||
4257 | PCI_VENDOR_ID_ATI && | ||
4258 | (parent_dev->bus->parent->self->device & | ||
4259 | 0xff00) == 0x5a00) { | ||
4260 | mtip_disable_link_opts(dd, | ||
4261 | parent_dev->bus->parent->self); | ||
4262 | } | ||
4263 | } | ||
4264 | } | ||
4265 | } | ||
4266 | |||
4482 | /* | 4267 | /* |
4483 | * Called for each supported PCI device detected. | 4268 | * Called for each supported PCI device detected. |
4484 | * | 4269 | * |
@@ -4630,6 +4415,8 @@ static int mtip_pci_probe(struct pci_dev *pdev, | |||
4630 | goto msi_initialize_err; | 4415 | goto msi_initialize_err; |
4631 | } | 4416 | } |
4632 | 4417 | ||
4418 | mtip_fix_ero_nosnoop(dd, pdev); | ||
4419 | |||
4633 | /* Initialize the block layer. */ | 4420 | /* Initialize the block layer. */ |
4634 | rv = mtip_block_initialize(dd); | 4421 | rv = mtip_block_initialize(dd); |
4635 | if (rv < 0) { | 4422 | if (rv < 0) { |
@@ -4710,8 +4497,6 @@ static void mtip_pci_remove(struct pci_dev *pdev) | |||
4710 | dev_warn(&dd->pdev->dev, | 4497 | dev_warn(&dd->pdev->dev, |
4711 | "Completion workers still active!\n"); | 4498 | "Completion workers still active!\n"); |
4712 | } | 4499 | } |
4713 | /* Cleanup the outstanding commands */ | ||
4714 | mtip_command_cleanup(dd); | ||
4715 | 4500 | ||
4716 | /* Clean up the block layer. */ | 4501 | /* Clean up the block layer. */ |
4717 | mtip_block_remove(dd); | 4502 | mtip_block_remove(dd); |
@@ -4737,8 +4522,6 @@ static void mtip_pci_remove(struct pci_dev *pdev) | |||
4737 | 4522 | ||
4738 | pcim_iounmap_regions(pdev, 1 << MTIP_ABAR); | 4523 | pcim_iounmap_regions(pdev, 1 << MTIP_ABAR); |
4739 | pci_set_drvdata(pdev, NULL); | 4524 | pci_set_drvdata(pdev, NULL); |
4740 | pci_dev_put(pdev); | ||
4741 | |||
4742 | } | 4525 | } |
4743 | 4526 | ||
4744 | /* | 4527 | /* |
@@ -4935,13 +4718,13 @@ static int __init mtip_init(void) | |||
4935 | */ | 4718 | */ |
4936 | static void __exit mtip_exit(void) | 4719 | static void __exit mtip_exit(void) |
4937 | { | 4720 | { |
4938 | debugfs_remove_recursive(dfs_parent); | ||
4939 | |||
4940 | /* Release the allocated major block device number. */ | 4721 | /* Release the allocated major block device number. */ |
4941 | unregister_blkdev(mtip_major, MTIP_DRV_NAME); | 4722 | unregister_blkdev(mtip_major, MTIP_DRV_NAME); |
4942 | 4723 | ||
4943 | /* Unregister the PCI driver. */ | 4724 | /* Unregister the PCI driver. */ |
4944 | pci_unregister_driver(&mtip_pci_driver); | 4725 | pci_unregister_driver(&mtip_pci_driver); |
4726 | |||
4727 | debugfs_remove_recursive(dfs_parent); | ||
4945 | } | 4728 | } |
4946 | 4729 | ||
4947 | MODULE_AUTHOR("Micron Technology, Inc"); | 4730 | MODULE_AUTHOR("Micron Technology, Inc"); |
diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h index ffb955e7ccb9..4b9b554234bc 100644 --- a/drivers/block/mtip32xx/mtip32xx.h +++ b/drivers/block/mtip32xx/mtip32xx.h | |||
@@ -40,9 +40,11 @@ | |||
40 | #define MTIP_MAX_RETRIES 2 | 40 | #define MTIP_MAX_RETRIES 2 |
41 | 41 | ||
42 | /* Various timeout values in ms */ | 42 | /* Various timeout values in ms */ |
43 | #define MTIP_NCQ_COMMAND_TIMEOUT_MS 5000 | 43 | #define MTIP_NCQ_CMD_TIMEOUT_MS 15000 |
44 | #define MTIP_IOCTL_COMMAND_TIMEOUT_MS 5000 | 44 | #define MTIP_IOCTL_CMD_TIMEOUT_MS 5000 |
45 | #define MTIP_INTERNAL_COMMAND_TIMEOUT_MS 5000 | 45 | #define MTIP_INT_CMD_TIMEOUT_MS 5000 |
46 | #define MTIP_QUIESCE_IO_TIMEOUT_MS (MTIP_NCQ_CMD_TIMEOUT_MS * \ | ||
47 | (MTIP_MAX_RETRIES + 1)) | ||
46 | 48 | ||
47 | /* check for timeouts every 500ms */ | 49 | /* check for timeouts every 500ms */ |
48 | #define MTIP_TIMEOUT_CHECK_PERIOD 500 | 50 | #define MTIP_TIMEOUT_CHECK_PERIOD 500 |
@@ -331,12 +333,8 @@ struct mtip_cmd { | |||
331 | */ | 333 | */ |
332 | void (*comp_func)(struct mtip_port *port, | 334 | void (*comp_func)(struct mtip_port *port, |
333 | int tag, | 335 | int tag, |
334 | void *data, | 336 | struct mtip_cmd *cmd, |
335 | int status); | 337 | int status); |
336 | /* Additional callback function that may be called by comp_func() */ | ||
337 | void (*async_callback)(void *data, int status); | ||
338 | |||
339 | void *async_data; /* Addl. data passed to async_callback() */ | ||
340 | 338 | ||
341 | int scatter_ents; /* Number of scatter list entries used */ | 339 | int scatter_ents; /* Number of scatter list entries used */ |
342 | 340 | ||
@@ -347,10 +345,6 @@ struct mtip_cmd { | |||
347 | int retries; /* The number of retries left for this command. */ | 345 | int retries; /* The number of retries left for this command. */ |
348 | 346 | ||
349 | int direction; /* Data transfer direction */ | 347 | int direction; /* Data transfer direction */ |
350 | |||
351 | unsigned long comp_time; /* command completion time, in jiffies */ | ||
352 | |||
353 | atomic_t active; /* declares if this command sent to the drive. */ | ||
354 | }; | 348 | }; |
355 | 349 | ||
356 | /* Structure used to describe a port. */ | 350 | /* Structure used to describe a port. */ |
@@ -436,12 +430,6 @@ struct mtip_port { | |||
436 | * or error handling is active | 430 | * or error handling is active |
437 | */ | 431 | */ |
438 | unsigned long cmds_to_issue[SLOTBITS_IN_LONGS]; | 432 | unsigned long cmds_to_issue[SLOTBITS_IN_LONGS]; |
439 | /* | ||
440 | * Array of command slots. Structure includes pointers to the | ||
441 | * command header and command table, and completion function and data | ||
442 | * pointers. | ||
443 | */ | ||
444 | struct mtip_cmd commands[MTIP_MAX_COMMAND_SLOTS]; | ||
445 | /* Used by mtip_service_thread to wait for an event */ | 433 | /* Used by mtip_service_thread to wait for an event */ |
446 | wait_queue_head_t svc_wait; | 434 | wait_queue_head_t svc_wait; |
447 | /* | 435 | /* |
@@ -452,13 +440,7 @@ struct mtip_port { | |||
452 | /* | 440 | /* |
453 | * Timer used to complete commands that have been active for too long. | 441 | * Timer used to complete commands that have been active for too long. |
454 | */ | 442 | */ |
455 | struct timer_list cmd_timer; | ||
456 | unsigned long ic_pause_timer; | 443 | unsigned long ic_pause_timer; |
457 | /* | ||
458 | * Semaphore used to block threads if there are no | ||
459 | * command slots available. | ||
460 | */ | ||
461 | struct semaphore cmd_slot; | ||
462 | 444 | ||
463 | /* Semaphore to control queue depth of unaligned IOs */ | 445 | /* Semaphore to control queue depth of unaligned IOs */ |
464 | struct semaphore cmd_slot_unal; | 446 | struct semaphore cmd_slot_unal; |
@@ -485,6 +467,8 @@ struct driver_data { | |||
485 | 467 | ||
486 | struct request_queue *queue; /* Our request queue. */ | 468 | struct request_queue *queue; /* Our request queue. */ |
487 | 469 | ||
470 | struct blk_mq_tag_set tags; /* blk_mq tags */ | ||
471 | |||
488 | struct mtip_port *port; /* Pointer to the port data structure. */ | 472 | struct mtip_port *port; /* Pointer to the port data structure. */ |
489 | 473 | ||
490 | unsigned product_type; /* magic value declaring the product type */ | 474 | unsigned product_type; /* magic value declaring the product type */ |
diff --git a/drivers/block/null_blk.c b/drivers/block/null_blk.c index b40af63a5476..77087a29b127 100644 --- a/drivers/block/null_blk.c +++ b/drivers/block/null_blk.c | |||
@@ -203,8 +203,8 @@ static enum hrtimer_restart null_cmd_timer_expired(struct hrtimer *timer) | |||
203 | entry = llist_reverse_order(entry); | 203 | entry = llist_reverse_order(entry); |
204 | do { | 204 | do { |
205 | cmd = container_of(entry, struct nullb_cmd, ll_list); | 205 | cmd = container_of(entry, struct nullb_cmd, ll_list); |
206 | end_cmd(cmd); | ||
207 | entry = entry->next; | 206 | entry = entry->next; |
207 | end_cmd(cmd); | ||
208 | } while (entry); | 208 | } while (entry); |
209 | } | 209 | } |
210 | 210 | ||
diff --git a/drivers/block/skd_main.c b/drivers/block/skd_main.c index c48d9084c965..608532d3f8c9 100644 --- a/drivers/block/skd_main.c +++ b/drivers/block/skd_main.c | |||
@@ -3944,15 +3944,14 @@ static int skd_acquire_msix(struct skd_device *skdev) | |||
3944 | for (i = 0; i < SKD_MAX_MSIX_COUNT; i++) | 3944 | for (i = 0; i < SKD_MAX_MSIX_COUNT; i++) |
3945 | entries[i].entry = i; | 3945 | entries[i].entry = i; |
3946 | 3946 | ||
3947 | rc = pci_enable_msix_range(pdev, entries, | 3947 | rc = pci_enable_msix_exact(pdev, entries, SKD_MAX_MSIX_COUNT); |
3948 | SKD_MIN_MSIX_COUNT, SKD_MAX_MSIX_COUNT); | 3948 | if (rc) { |
3949 | if (rc < 0) { | ||
3950 | pr_err("(%s): failed to enable MSI-X %d\n", | 3949 | pr_err("(%s): failed to enable MSI-X %d\n", |
3951 | skd_name(skdev), rc); | 3950 | skd_name(skdev), rc); |
3952 | goto msix_out; | 3951 | goto msix_out; |
3953 | } | 3952 | } |
3954 | 3953 | ||
3955 | skdev->msix_count = rc; | 3954 | skdev->msix_count = SKD_MAX_MSIX_COUNT; |
3956 | skdev->msix_entries = kzalloc(sizeof(struct skd_msix_entry) * | 3955 | skdev->msix_entries = kzalloc(sizeof(struct skd_msix_entry) * |
3957 | skdev->msix_count, GFP_KERNEL); | 3956 | skdev->msix_count, GFP_KERNEL); |
3958 | if (!skdev->msix_entries) { | 3957 | if (!skdev->msix_entries) { |
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index c8f286e8d80f..f63d358f3d93 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c | |||
@@ -162,6 +162,7 @@ static int virtio_queue_rq(struct blk_mq_hw_ctx *hctx, struct request *req) | |||
162 | unsigned int num; | 162 | unsigned int num; |
163 | const bool last = (req->cmd_flags & REQ_END) != 0; | 163 | const bool last = (req->cmd_flags & REQ_END) != 0; |
164 | int err; | 164 | int err; |
165 | bool notify = false; | ||
165 | 166 | ||
166 | BUG_ON(req->nr_phys_segments + 2 > vblk->sg_elems); | 167 | BUG_ON(req->nr_phys_segments + 2 > vblk->sg_elems); |
167 | 168 | ||
@@ -214,10 +215,12 @@ static int virtio_queue_rq(struct blk_mq_hw_ctx *hctx, struct request *req) | |||
214 | return BLK_MQ_RQ_QUEUE_ERROR; | 215 | return BLK_MQ_RQ_QUEUE_ERROR; |
215 | } | 216 | } |
216 | 217 | ||
217 | if (last) | 218 | if (last && virtqueue_kick_prepare(vblk->vq)) |
218 | virtqueue_kick(vblk->vq); | 219 | notify = true; |
219 | |||
220 | spin_unlock_irqrestore(&vblk->vq_lock, flags); | 220 | spin_unlock_irqrestore(&vblk->vq_lock, flags); |
221 | |||
222 | if (notify) | ||
223 | virtqueue_notify(vblk->vq); | ||
221 | return BLK_MQ_RQ_QUEUE_OK; | 224 | return BLK_MQ_RQ_QUEUE_OK; |
222 | } | 225 | } |
223 | 226 | ||
diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h index be052773ad03..f65b807e3236 100644 --- a/drivers/block/xen-blkback/common.h +++ b/drivers/block/xen-blkback/common.h | |||
@@ -314,7 +314,7 @@ struct xen_blkif { | |||
314 | unsigned long long st_rd_sect; | 314 | unsigned long long st_rd_sect; |
315 | unsigned long long st_wr_sect; | 315 | unsigned long long st_wr_sect; |
316 | 316 | ||
317 | wait_queue_head_t waiting_to_free; | 317 | struct work_struct free_work; |
318 | /* Thread shutdown wait queue. */ | 318 | /* Thread shutdown wait queue. */ |
319 | wait_queue_head_t shutdown_wq; | 319 | wait_queue_head_t shutdown_wq; |
320 | }; | 320 | }; |
@@ -361,7 +361,7 @@ struct pending_req { | |||
361 | #define xen_blkif_put(_b) \ | 361 | #define xen_blkif_put(_b) \ |
362 | do { \ | 362 | do { \ |
363 | if (atomic_dec_and_test(&(_b)->refcnt)) \ | 363 | if (atomic_dec_and_test(&(_b)->refcnt)) \ |
364 | wake_up(&(_b)->waiting_to_free);\ | 364 | schedule_work(&(_b)->free_work);\ |
365 | } while (0) | 365 | } while (0) |
366 | 366 | ||
367 | struct phys_req { | 367 | struct phys_req { |
diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c index 9a547e6b6ebf..3a8b810b4980 100644 --- a/drivers/block/xen-blkback/xenbus.c +++ b/drivers/block/xen-blkback/xenbus.c | |||
@@ -35,12 +35,26 @@ static void connect(struct backend_info *); | |||
35 | static int connect_ring(struct backend_info *); | 35 | static int connect_ring(struct backend_info *); |
36 | static void backend_changed(struct xenbus_watch *, const char **, | 36 | static void backend_changed(struct xenbus_watch *, const char **, |
37 | unsigned int); | 37 | unsigned int); |
38 | static void xen_blkif_free(struct xen_blkif *blkif); | ||
39 | static void xen_vbd_free(struct xen_vbd *vbd); | ||
38 | 40 | ||
39 | struct xenbus_device *xen_blkbk_xenbus(struct backend_info *be) | 41 | struct xenbus_device *xen_blkbk_xenbus(struct backend_info *be) |
40 | { | 42 | { |
41 | return be->dev; | 43 | return be->dev; |
42 | } | 44 | } |
43 | 45 | ||
46 | /* | ||
47 | * The last request could free the device from softirq context and | ||
48 | * xen_blkif_free() can sleep. | ||
49 | */ | ||
50 | static void xen_blkif_deferred_free(struct work_struct *work) | ||
51 | { | ||
52 | struct xen_blkif *blkif; | ||
53 | |||
54 | blkif = container_of(work, struct xen_blkif, free_work); | ||
55 | xen_blkif_free(blkif); | ||
56 | } | ||
57 | |||
44 | static int blkback_name(struct xen_blkif *blkif, char *buf) | 58 | static int blkback_name(struct xen_blkif *blkif, char *buf) |
45 | { | 59 | { |
46 | char *devpath, *devname; | 60 | char *devpath, *devname; |
@@ -121,7 +135,6 @@ static struct xen_blkif *xen_blkif_alloc(domid_t domid) | |||
121 | init_completion(&blkif->drain_complete); | 135 | init_completion(&blkif->drain_complete); |
122 | atomic_set(&blkif->drain, 0); | 136 | atomic_set(&blkif->drain, 0); |
123 | blkif->st_print = jiffies; | 137 | blkif->st_print = jiffies; |
124 | init_waitqueue_head(&blkif->waiting_to_free); | ||
125 | blkif->persistent_gnts.rb_node = NULL; | 138 | blkif->persistent_gnts.rb_node = NULL; |
126 | spin_lock_init(&blkif->free_pages_lock); | 139 | spin_lock_init(&blkif->free_pages_lock); |
127 | INIT_LIST_HEAD(&blkif->free_pages); | 140 | INIT_LIST_HEAD(&blkif->free_pages); |
@@ -132,6 +145,7 @@ static struct xen_blkif *xen_blkif_alloc(domid_t domid) | |||
132 | INIT_WORK(&blkif->persistent_purge_work, xen_blkbk_unmap_purged_grants); | 145 | INIT_WORK(&blkif->persistent_purge_work, xen_blkbk_unmap_purged_grants); |
133 | 146 | ||
134 | INIT_LIST_HEAD(&blkif->pending_free); | 147 | INIT_LIST_HEAD(&blkif->pending_free); |
148 | INIT_WORK(&blkif->free_work, xen_blkif_deferred_free); | ||
135 | 149 | ||
136 | for (i = 0; i < XEN_BLKIF_REQS; i++) { | 150 | for (i = 0; i < XEN_BLKIF_REQS; i++) { |
137 | req = kzalloc(sizeof(*req), GFP_KERNEL); | 151 | req = kzalloc(sizeof(*req), GFP_KERNEL); |
@@ -231,7 +245,7 @@ static int xen_blkif_map(struct xen_blkif *blkif, unsigned long shared_page, | |||
231 | return 0; | 245 | return 0; |
232 | } | 246 | } |
233 | 247 | ||
234 | static void xen_blkif_disconnect(struct xen_blkif *blkif) | 248 | static int xen_blkif_disconnect(struct xen_blkif *blkif) |
235 | { | 249 | { |
236 | if (blkif->xenblkd) { | 250 | if (blkif->xenblkd) { |
237 | kthread_stop(blkif->xenblkd); | 251 | kthread_stop(blkif->xenblkd); |
@@ -239,9 +253,12 @@ static void xen_blkif_disconnect(struct xen_blkif *blkif) | |||
239 | blkif->xenblkd = NULL; | 253 | blkif->xenblkd = NULL; |
240 | } | 254 | } |
241 | 255 | ||
242 | atomic_dec(&blkif->refcnt); | 256 | /* The above kthread_stop() guarantees that at this point we |
243 | wait_event(blkif->waiting_to_free, atomic_read(&blkif->refcnt) == 0); | 257 | * don't have any discard_io or other_io requests. So, checking |
244 | atomic_inc(&blkif->refcnt); | 258 | * for inflight IO is enough. |
259 | */ | ||
260 | if (atomic_read(&blkif->inflight) > 0) | ||
261 | return -EBUSY; | ||
245 | 262 | ||
246 | if (blkif->irq) { | 263 | if (blkif->irq) { |
247 | unbind_from_irqhandler(blkif->irq, blkif); | 264 | unbind_from_irqhandler(blkif->irq, blkif); |
@@ -252,6 +269,8 @@ static void xen_blkif_disconnect(struct xen_blkif *blkif) | |||
252 | xenbus_unmap_ring_vfree(blkif->be->dev, blkif->blk_ring); | 269 | xenbus_unmap_ring_vfree(blkif->be->dev, blkif->blk_ring); |
253 | blkif->blk_rings.common.sring = NULL; | 270 | blkif->blk_rings.common.sring = NULL; |
254 | } | 271 | } |
272 | |||
273 | return 0; | ||
255 | } | 274 | } |
256 | 275 | ||
257 | static void xen_blkif_free(struct xen_blkif *blkif) | 276 | static void xen_blkif_free(struct xen_blkif *blkif) |
@@ -259,8 +278,8 @@ static void xen_blkif_free(struct xen_blkif *blkif) | |||
259 | struct pending_req *req, *n; | 278 | struct pending_req *req, *n; |
260 | int i = 0, j; | 279 | int i = 0, j; |
261 | 280 | ||
262 | if (!atomic_dec_and_test(&blkif->refcnt)) | 281 | xen_blkif_disconnect(blkif); |
263 | BUG(); | 282 | xen_vbd_free(&blkif->vbd); |
264 | 283 | ||
265 | /* Remove all persistent grants and the cache of ballooned pages. */ | 284 | /* Remove all persistent grants and the cache of ballooned pages. */ |
266 | xen_blkbk_free_caches(blkif); | 285 | xen_blkbk_free_caches(blkif); |
@@ -449,16 +468,15 @@ static int xen_blkbk_remove(struct xenbus_device *dev) | |||
449 | be->backend_watch.node = NULL; | 468 | be->backend_watch.node = NULL; |
450 | } | 469 | } |
451 | 470 | ||
471 | dev_set_drvdata(&dev->dev, NULL); | ||
472 | |||
452 | if (be->blkif) { | 473 | if (be->blkif) { |
453 | xen_blkif_disconnect(be->blkif); | 474 | xen_blkif_disconnect(be->blkif); |
454 | xen_vbd_free(&be->blkif->vbd); | 475 | xen_blkif_put(be->blkif); |
455 | xen_blkif_free(be->blkif); | ||
456 | be->blkif = NULL; | ||
457 | } | 476 | } |
458 | 477 | ||
459 | kfree(be->mode); | 478 | kfree(be->mode); |
460 | kfree(be); | 479 | kfree(be); |
461 | dev_set_drvdata(&dev->dev, NULL); | ||
462 | return 0; | 480 | return 0; |
463 | } | 481 | } |
464 | 482 | ||
@@ -481,10 +499,15 @@ static void xen_blkbk_discard(struct xenbus_transaction xbt, struct backend_info | |||
481 | struct xenbus_device *dev = be->dev; | 499 | struct xenbus_device *dev = be->dev; |
482 | struct xen_blkif *blkif = be->blkif; | 500 | struct xen_blkif *blkif = be->blkif; |
483 | int err; | 501 | int err; |
484 | int state = 0; | 502 | int state = 0, discard_enable; |
485 | struct block_device *bdev = be->blkif->vbd.bdev; | 503 | struct block_device *bdev = be->blkif->vbd.bdev; |
486 | struct request_queue *q = bdev_get_queue(bdev); | 504 | struct request_queue *q = bdev_get_queue(bdev); |
487 | 505 | ||
506 | err = xenbus_scanf(XBT_NIL, dev->nodename, "discard-enable", "%d", | ||
507 | &discard_enable); | ||
508 | if (err == 1 && !discard_enable) | ||
509 | return; | ||
510 | |||
488 | if (blk_queue_discard(q)) { | 511 | if (blk_queue_discard(q)) { |
489 | err = xenbus_printf(xbt, dev->nodename, | 512 | err = xenbus_printf(xbt, dev->nodename, |
490 | "discard-granularity", "%u", | 513 | "discard-granularity", "%u", |
@@ -700,7 +723,11 @@ static void frontend_changed(struct xenbus_device *dev, | |||
700 | * Enforce precondition before potential leak point. | 723 | * Enforce precondition before potential leak point. |
701 | * xen_blkif_disconnect() is idempotent. | 724 | * xen_blkif_disconnect() is idempotent. |
702 | */ | 725 | */ |
703 | xen_blkif_disconnect(be->blkif); | 726 | err = xen_blkif_disconnect(be->blkif); |
727 | if (err) { | ||
728 | xenbus_dev_fatal(dev, err, "pending I/O"); | ||
729 | break; | ||
730 | } | ||
704 | 731 | ||
705 | err = connect_ring(be); | 732 | err = connect_ring(be); |
706 | if (err) | 733 | if (err) |
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 283a30e88287..5deb235bd18f 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c | |||
@@ -1635,36 +1635,24 @@ blkfront_closing(struct blkfront_info *info) | |||
1635 | static void blkfront_setup_discard(struct blkfront_info *info) | 1635 | static void blkfront_setup_discard(struct blkfront_info *info) |
1636 | { | 1636 | { |
1637 | int err; | 1637 | int err; |
1638 | char *type; | ||
1639 | unsigned int discard_granularity; | 1638 | unsigned int discard_granularity; |
1640 | unsigned int discard_alignment; | 1639 | unsigned int discard_alignment; |
1641 | unsigned int discard_secure; | 1640 | unsigned int discard_secure; |
1642 | 1641 | ||
1643 | type = xenbus_read(XBT_NIL, info->xbdev->otherend, "type", NULL); | 1642 | info->feature_discard = 1; |
1644 | if (IS_ERR(type)) | 1643 | err = xenbus_gather(XBT_NIL, info->xbdev->otherend, |
1645 | return; | 1644 | "discard-granularity", "%u", &discard_granularity, |
1646 | 1645 | "discard-alignment", "%u", &discard_alignment, | |
1647 | info->feature_secdiscard = 0; | 1646 | NULL); |
1648 | if (strncmp(type, "phy", 3) == 0) { | 1647 | if (!err) { |
1649 | err = xenbus_gather(XBT_NIL, info->xbdev->otherend, | 1648 | info->discard_granularity = discard_granularity; |
1650 | "discard-granularity", "%u", &discard_granularity, | 1649 | info->discard_alignment = discard_alignment; |
1651 | "discard-alignment", "%u", &discard_alignment, | 1650 | } |
1652 | NULL); | 1651 | err = xenbus_gather(XBT_NIL, info->xbdev->otherend, |
1653 | if (!err) { | 1652 | "discard-secure", "%d", &discard_secure, |
1654 | info->feature_discard = 1; | 1653 | NULL); |
1655 | info->discard_granularity = discard_granularity; | 1654 | if (!err) |
1656 | info->discard_alignment = discard_alignment; | 1655 | info->feature_secdiscard = !!discard_secure; |
1657 | } | ||
1658 | err = xenbus_gather(XBT_NIL, info->xbdev->otherend, | ||
1659 | "discard-secure", "%d", &discard_secure, | ||
1660 | NULL); | ||
1661 | if (!err) | ||
1662 | info->feature_secdiscard = discard_secure; | ||
1663 | |||
1664 | } else if (strncmp(type, "file", 4) == 0) | ||
1665 | info->feature_discard = 1; | ||
1666 | |||
1667 | kfree(type); | ||
1668 | } | 1656 | } |
1669 | 1657 | ||
1670 | static int blkfront_setup_indirect(struct blkfront_info *info) | 1658 | static int blkfront_setup_indirect(struct blkfront_info *info) |
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index 8a3aff724d98..49ac5662585b 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c | |||
@@ -312,36 +312,24 @@ static const char *mrw_format_status[] = { | |||
312 | 312 | ||
313 | static const char *mrw_address_space[] = { "DMA", "GAA" }; | 313 | static const char *mrw_address_space[] = { "DMA", "GAA" }; |
314 | 314 | ||
315 | #if (ERRLOGMASK!=CD_NOTHING) | 315 | #if (ERRLOGMASK != CD_NOTHING) |
316 | #define cdinfo(type, fmt, args...) \ | 316 | #define cd_dbg(type, fmt, ...) \ |
317 | do { \ | 317 | do { \ |
318 | if ((ERRLOGMASK & type) || debug == 1) \ | 318 | if ((ERRLOGMASK & type) || debug == 1) \ |
319 | pr_info(fmt, ##args); \ | 319 | pr_debug(fmt, ##__VA_ARGS__); \ |
320 | } while (0) | 320 | } while (0) |
321 | #else | 321 | #else |
322 | #define cdinfo(type, fmt, args...) \ | 322 | #define cd_dbg(type, fmt, ...) \ |
323 | do { \ | 323 | do { \ |
324 | if (0 && (ERRLOGMASK & type) || debug == 1) \ | 324 | if (0 && (ERRLOGMASK & type) || debug == 1) \ |
325 | pr_info(fmt, ##args); \ | 325 | pr_debug(fmt, ##__VA_ARGS__); \ |
326 | } while (0) | 326 | } while (0) |
327 | #endif | 327 | #endif |
328 | 328 | ||
329 | /* These are used to simplify getting data in from and back to user land */ | ||
330 | #define IOCTL_IN(arg, type, in) \ | ||
331 | if (copy_from_user(&(in), (type __user *) (arg), sizeof (in))) \ | ||
332 | return -EFAULT; | ||
333 | |||
334 | #define IOCTL_OUT(arg, type, out) \ | ||
335 | if (copy_to_user((type __user *) (arg), &(out), sizeof (out))) \ | ||
336 | return -EFAULT; | ||
337 | |||
338 | /* The (cdo->capability & ~cdi->mask & CDC_XXX) construct was used in | 329 | /* The (cdo->capability & ~cdi->mask & CDC_XXX) construct was used in |
339 | a lot of places. This macro makes the code more clear. */ | 330 | a lot of places. This macro makes the code more clear. */ |
340 | #define CDROM_CAN(type) (cdi->ops->capability & ~cdi->mask & (type)) | 331 | #define CDROM_CAN(type) (cdi->ops->capability & ~cdi->mask & (type)) |
341 | 332 | ||
342 | /* used in the audio ioctls */ | ||
343 | #define CHECKAUDIO if ((ret=check_for_audio_disc(cdi, cdo))) return ret | ||
344 | |||
345 | /* | 333 | /* |
346 | * Another popular OS uses 7 seconds as the hard timeout for default | 334 | * Another popular OS uses 7 seconds as the hard timeout for default |
347 | * commands, so it is a good choice for us as well. | 335 | * commands, so it is a good choice for us as well. |
@@ -349,21 +337,6 @@ do { \ | |||
349 | #define CDROM_DEF_TIMEOUT (7 * HZ) | 337 | #define CDROM_DEF_TIMEOUT (7 * HZ) |
350 | 338 | ||
351 | /* Not-exported routines. */ | 339 | /* Not-exported routines. */ |
352 | static int open_for_data(struct cdrom_device_info * cdi); | ||
353 | static int check_for_audio_disc(struct cdrom_device_info * cdi, | ||
354 | struct cdrom_device_ops * cdo); | ||
355 | static void sanitize_format(union cdrom_addr *addr, | ||
356 | u_char * curr, u_char requested); | ||
357 | static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, | ||
358 | unsigned long arg); | ||
359 | |||
360 | int cdrom_get_last_written(struct cdrom_device_info *, long *); | ||
361 | static int cdrom_get_next_writable(struct cdrom_device_info *, long *); | ||
362 | static void cdrom_count_tracks(struct cdrom_device_info *, tracktype*); | ||
363 | |||
364 | static int cdrom_mrw_exit(struct cdrom_device_info *cdi); | ||
365 | |||
366 | static int cdrom_get_disc_info(struct cdrom_device_info *cdi, disc_information *di); | ||
367 | 340 | ||
368 | static void cdrom_sysctl_register(void); | 341 | static void cdrom_sysctl_register(void); |
369 | 342 | ||
@@ -382,113 +355,65 @@ static int cdrom_dummy_generic_packet(struct cdrom_device_info *cdi, | |||
382 | return -EIO; | 355 | return -EIO; |
383 | } | 356 | } |
384 | 357 | ||
385 | /* This macro makes sure we don't have to check on cdrom_device_ops | 358 | static int cdrom_flush_cache(struct cdrom_device_info *cdi) |
386 | * existence in the run-time routines below. Change_capability is a | ||
387 | * hack to have the capability flags defined const, while we can still | ||
388 | * change it here without gcc complaining at every line. | ||
389 | */ | ||
390 | #define ENSURE(call, bits) if (cdo->call == NULL) *change_capability &= ~(bits) | ||
391 | |||
392 | int register_cdrom(struct cdrom_device_info *cdi) | ||
393 | { | ||
394 | static char banner_printed; | ||
395 | struct cdrom_device_ops *cdo = cdi->ops; | ||
396 | int *change_capability = (int *)&cdo->capability; /* hack */ | ||
397 | |||
398 | cdinfo(CD_OPEN, "entering register_cdrom\n"); | ||
399 | |||
400 | if (cdo->open == NULL || cdo->release == NULL) | ||
401 | return -EINVAL; | ||
402 | if (!banner_printed) { | ||
403 | pr_info("Uniform CD-ROM driver " REVISION "\n"); | ||
404 | banner_printed = 1; | ||
405 | cdrom_sysctl_register(); | ||
406 | } | ||
407 | |||
408 | ENSURE(drive_status, CDC_DRIVE_STATUS ); | ||
409 | if (cdo->check_events == NULL && cdo->media_changed == NULL) | ||
410 | *change_capability = ~(CDC_MEDIA_CHANGED | CDC_SELECT_DISC); | ||
411 | ENSURE(tray_move, CDC_CLOSE_TRAY | CDC_OPEN_TRAY); | ||
412 | ENSURE(lock_door, CDC_LOCK); | ||
413 | ENSURE(select_speed, CDC_SELECT_SPEED); | ||
414 | ENSURE(get_last_session, CDC_MULTI_SESSION); | ||
415 | ENSURE(get_mcn, CDC_MCN); | ||
416 | ENSURE(reset, CDC_RESET); | ||
417 | ENSURE(generic_packet, CDC_GENERIC_PACKET); | ||
418 | cdi->mc_flags = 0; | ||
419 | cdo->n_minors = 0; | ||
420 | cdi->options = CDO_USE_FFLAGS; | ||
421 | |||
422 | if (autoclose==1 && CDROM_CAN(CDC_CLOSE_TRAY)) | ||
423 | cdi->options |= (int) CDO_AUTO_CLOSE; | ||
424 | if (autoeject==1 && CDROM_CAN(CDC_OPEN_TRAY)) | ||
425 | cdi->options |= (int) CDO_AUTO_EJECT; | ||
426 | if (lockdoor==1) | ||
427 | cdi->options |= (int) CDO_LOCK; | ||
428 | if (check_media_type==1) | ||
429 | cdi->options |= (int) CDO_CHECK_TYPE; | ||
430 | |||
431 | if (CDROM_CAN(CDC_MRW_W)) | ||
432 | cdi->exit = cdrom_mrw_exit; | ||
433 | |||
434 | if (cdi->disk) | ||
435 | cdi->cdda_method = CDDA_BPC_FULL; | ||
436 | else | ||
437 | cdi->cdda_method = CDDA_OLD; | ||
438 | |||
439 | if (!cdo->generic_packet) | ||
440 | cdo->generic_packet = cdrom_dummy_generic_packet; | ||
441 | |||
442 | cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" registered\n", cdi->name); | ||
443 | mutex_lock(&cdrom_mutex); | ||
444 | list_add(&cdi->list, &cdrom_list); | ||
445 | mutex_unlock(&cdrom_mutex); | ||
446 | return 0; | ||
447 | } | ||
448 | #undef ENSURE | ||
449 | |||
450 | void unregister_cdrom(struct cdrom_device_info *cdi) | ||
451 | { | 359 | { |
452 | cdinfo(CD_OPEN, "entering unregister_cdrom\n"); | 360 | struct packet_command cgc; |
453 | 361 | ||
454 | mutex_lock(&cdrom_mutex); | 362 | init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE); |
455 | list_del(&cdi->list); | 363 | cgc.cmd[0] = GPCMD_FLUSH_CACHE; |
456 | mutex_unlock(&cdrom_mutex); | ||
457 | 364 | ||
458 | if (cdi->exit) | 365 | cgc.timeout = 5 * 60 * HZ; |
459 | cdi->exit(cdi); | ||
460 | 366 | ||
461 | cdi->ops->n_minors--; | 367 | return cdi->ops->generic_packet(cdi, &cgc); |
462 | cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" unregistered\n", cdi->name); | ||
463 | } | 368 | } |
464 | 369 | ||
465 | int cdrom_get_media_event(struct cdrom_device_info *cdi, | 370 | /* requires CD R/RW */ |
466 | struct media_event_desc *med) | 371 | static int cdrom_get_disc_info(struct cdrom_device_info *cdi, |
372 | disc_information *di) | ||
467 | { | 373 | { |
374 | struct cdrom_device_ops *cdo = cdi->ops; | ||
468 | struct packet_command cgc; | 375 | struct packet_command cgc; |
469 | unsigned char buffer[8]; | 376 | int ret, buflen; |
470 | struct event_header *eh = (struct event_header *) buffer; | ||
471 | 377 | ||
472 | init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); | 378 | /* set up command and get the disc info */ |
473 | cgc.cmd[0] = GPCMD_GET_EVENT_STATUS_NOTIFICATION; | 379 | init_cdrom_command(&cgc, di, sizeof(*di), CGC_DATA_READ); |
474 | cgc.cmd[1] = 1; /* IMMED */ | 380 | cgc.cmd[0] = GPCMD_READ_DISC_INFO; |
475 | cgc.cmd[4] = 1 << 4; /* media event */ | 381 | cgc.cmd[8] = cgc.buflen = 2; |
476 | cgc.cmd[8] = sizeof(buffer); | ||
477 | cgc.quiet = 1; | 382 | cgc.quiet = 1; |
478 | 383 | ||
479 | if (cdi->ops->generic_packet(cdi, &cgc)) | 384 | ret = cdo->generic_packet(cdi, &cgc); |
480 | return 1; | 385 | if (ret) |
386 | return ret; | ||
481 | 387 | ||
482 | if (be16_to_cpu(eh->data_len) < sizeof(*med)) | 388 | /* not all drives have the same disc_info length, so requeue |
483 | return 1; | 389 | * packet with the length the drive tells us it can supply |
390 | */ | ||
391 | buflen = be16_to_cpu(di->disc_information_length) + | ||
392 | sizeof(di->disc_information_length); | ||
484 | 393 | ||
485 | if (eh->nea || eh->notification_class != 0x4) | 394 | if (buflen > sizeof(disc_information)) |
486 | return 1; | 395 | buflen = sizeof(disc_information); |
487 | 396 | ||
488 | memcpy(med, &buffer[sizeof(*eh)], sizeof(*med)); | 397 | cgc.cmd[8] = cgc.buflen = buflen; |
489 | return 0; | 398 | ret = cdo->generic_packet(cdi, &cgc); |
399 | if (ret) | ||
400 | return ret; | ||
401 | |||
402 | /* return actual fill size */ | ||
403 | return buflen; | ||
490 | } | 404 | } |
491 | 405 | ||
406 | /* This macro makes sure we don't have to check on cdrom_device_ops | ||
407 | * existence in the run-time routines below. Change_capability is a | ||
408 | * hack to have the capability flags defined const, while we can still | ||
409 | * change it here without gcc complaining at every line. | ||
410 | */ | ||
411 | #define ENSURE(call, bits) \ | ||
412 | do { \ | ||
413 | if (cdo->call == NULL) \ | ||
414 | *change_capability &= ~(bits); \ | ||
415 | } while (0) | ||
416 | |||
492 | /* | 417 | /* |
493 | * the first prototypes used 0x2c as the page code for the mrw mode page, | 418 | * the first prototypes used 0x2c as the page code for the mrw mode page, |
494 | * subsequently this was changed to 0x03. probe the one used by this drive | 419 | * subsequently this was changed to 0x03. probe the one used by this drive |
@@ -605,18 +530,6 @@ static int cdrom_mrw_bgformat_susp(struct cdrom_device_info *cdi, int immed) | |||
605 | return cdi->ops->generic_packet(cdi, &cgc); | 530 | return cdi->ops->generic_packet(cdi, &cgc); |
606 | } | 531 | } |
607 | 532 | ||
608 | static int cdrom_flush_cache(struct cdrom_device_info *cdi) | ||
609 | { | ||
610 | struct packet_command cgc; | ||
611 | |||
612 | init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE); | ||
613 | cgc.cmd[0] = GPCMD_FLUSH_CACHE; | ||
614 | |||
615 | cgc.timeout = 5 * 60 * HZ; | ||
616 | |||
617 | return cdi->ops->generic_packet(cdi, &cgc); | ||
618 | } | ||
619 | |||
620 | static int cdrom_mrw_exit(struct cdrom_device_info *cdi) | 533 | static int cdrom_mrw_exit(struct cdrom_device_info *cdi) |
621 | { | 534 | { |
622 | disc_information di; | 535 | disc_information di; |
@@ -650,17 +563,19 @@ static int cdrom_mrw_set_lba_space(struct cdrom_device_info *cdi, int space) | |||
650 | cgc.buffer = buffer; | 563 | cgc.buffer = buffer; |
651 | cgc.buflen = sizeof(buffer); | 564 | cgc.buflen = sizeof(buffer); |
652 | 565 | ||
653 | if ((ret = cdrom_mode_sense(cdi, &cgc, cdi->mrw_mode_page, 0))) | 566 | ret = cdrom_mode_sense(cdi, &cgc, cdi->mrw_mode_page, 0); |
567 | if (ret) | ||
654 | return ret; | 568 | return ret; |
655 | 569 | ||
656 | mph = (struct mode_page_header *) buffer; | 570 | mph = (struct mode_page_header *)buffer; |
657 | offset = be16_to_cpu(mph->desc_length); | 571 | offset = be16_to_cpu(mph->desc_length); |
658 | size = be16_to_cpu(mph->mode_data_length) + 2; | 572 | size = be16_to_cpu(mph->mode_data_length) + 2; |
659 | 573 | ||
660 | buffer[offset + 3] = space; | 574 | buffer[offset + 3] = space; |
661 | cgc.buflen = size; | 575 | cgc.buflen = size; |
662 | 576 | ||
663 | if ((ret = cdrom_mode_select(cdi, &cgc))) | 577 | ret = cdrom_mode_select(cdi, &cgc); |
578 | if (ret) | ||
664 | return ret; | 579 | return ret; |
665 | 580 | ||
666 | pr_info("%s: mrw address space %s selected\n", | 581 | pr_info("%s: mrw address space %s selected\n", |
@@ -668,6 +583,106 @@ static int cdrom_mrw_set_lba_space(struct cdrom_device_info *cdi, int space) | |||
668 | return 0; | 583 | return 0; |
669 | } | 584 | } |
670 | 585 | ||
586 | int register_cdrom(struct cdrom_device_info *cdi) | ||
587 | { | ||
588 | static char banner_printed; | ||
589 | struct cdrom_device_ops *cdo = cdi->ops; | ||
590 | int *change_capability = (int *)&cdo->capability; /* hack */ | ||
591 | |||
592 | cd_dbg(CD_OPEN, "entering register_cdrom\n"); | ||
593 | |||
594 | if (cdo->open == NULL || cdo->release == NULL) | ||
595 | return -EINVAL; | ||
596 | if (!banner_printed) { | ||
597 | pr_info("Uniform CD-ROM driver " REVISION "\n"); | ||
598 | banner_printed = 1; | ||
599 | cdrom_sysctl_register(); | ||
600 | } | ||
601 | |||
602 | ENSURE(drive_status, CDC_DRIVE_STATUS); | ||
603 | if (cdo->check_events == NULL && cdo->media_changed == NULL) | ||
604 | *change_capability = ~(CDC_MEDIA_CHANGED | CDC_SELECT_DISC); | ||
605 | ENSURE(tray_move, CDC_CLOSE_TRAY | CDC_OPEN_TRAY); | ||
606 | ENSURE(lock_door, CDC_LOCK); | ||
607 | ENSURE(select_speed, CDC_SELECT_SPEED); | ||
608 | ENSURE(get_last_session, CDC_MULTI_SESSION); | ||
609 | ENSURE(get_mcn, CDC_MCN); | ||
610 | ENSURE(reset, CDC_RESET); | ||
611 | ENSURE(generic_packet, CDC_GENERIC_PACKET); | ||
612 | cdi->mc_flags = 0; | ||
613 | cdo->n_minors = 0; | ||
614 | cdi->options = CDO_USE_FFLAGS; | ||
615 | |||
616 | if (autoclose == 1 && CDROM_CAN(CDC_CLOSE_TRAY)) | ||
617 | cdi->options |= (int) CDO_AUTO_CLOSE; | ||
618 | if (autoeject == 1 && CDROM_CAN(CDC_OPEN_TRAY)) | ||
619 | cdi->options |= (int) CDO_AUTO_EJECT; | ||
620 | if (lockdoor == 1) | ||
621 | cdi->options |= (int) CDO_LOCK; | ||
622 | if (check_media_type == 1) | ||
623 | cdi->options |= (int) CDO_CHECK_TYPE; | ||
624 | |||
625 | if (CDROM_CAN(CDC_MRW_W)) | ||
626 | cdi->exit = cdrom_mrw_exit; | ||
627 | |||
628 | if (cdi->disk) | ||
629 | cdi->cdda_method = CDDA_BPC_FULL; | ||
630 | else | ||
631 | cdi->cdda_method = CDDA_OLD; | ||
632 | |||
633 | if (!cdo->generic_packet) | ||
634 | cdo->generic_packet = cdrom_dummy_generic_packet; | ||
635 | |||
636 | cd_dbg(CD_REG_UNREG, "drive \"/dev/%s\" registered\n", cdi->name); | ||
637 | mutex_lock(&cdrom_mutex); | ||
638 | list_add(&cdi->list, &cdrom_list); | ||
639 | mutex_unlock(&cdrom_mutex); | ||
640 | return 0; | ||
641 | } | ||
642 | #undef ENSURE | ||
643 | |||
644 | void unregister_cdrom(struct cdrom_device_info *cdi) | ||
645 | { | ||
646 | cd_dbg(CD_OPEN, "entering unregister_cdrom\n"); | ||
647 | |||
648 | mutex_lock(&cdrom_mutex); | ||
649 | list_del(&cdi->list); | ||
650 | mutex_unlock(&cdrom_mutex); | ||
651 | |||
652 | if (cdi->exit) | ||
653 | cdi->exit(cdi); | ||
654 | |||
655 | cdi->ops->n_minors--; | ||
656 | cd_dbg(CD_REG_UNREG, "drive \"/dev/%s\" unregistered\n", cdi->name); | ||
657 | } | ||
658 | |||
659 | int cdrom_get_media_event(struct cdrom_device_info *cdi, | ||
660 | struct media_event_desc *med) | ||
661 | { | ||
662 | struct packet_command cgc; | ||
663 | unsigned char buffer[8]; | ||
664 | struct event_header *eh = (struct event_header *)buffer; | ||
665 | |||
666 | init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); | ||
667 | cgc.cmd[0] = GPCMD_GET_EVENT_STATUS_NOTIFICATION; | ||
668 | cgc.cmd[1] = 1; /* IMMED */ | ||
669 | cgc.cmd[4] = 1 << 4; /* media event */ | ||
670 | cgc.cmd[8] = sizeof(buffer); | ||
671 | cgc.quiet = 1; | ||
672 | |||
673 | if (cdi->ops->generic_packet(cdi, &cgc)) | ||
674 | return 1; | ||
675 | |||
676 | if (be16_to_cpu(eh->data_len) < sizeof(*med)) | ||
677 | return 1; | ||
678 | |||
679 | if (eh->nea || eh->notification_class != 0x4) | ||
680 | return 1; | ||
681 | |||
682 | memcpy(med, &buffer[sizeof(*eh)], sizeof(*med)); | ||
683 | return 0; | ||
684 | } | ||
685 | |||
671 | static int cdrom_get_random_writable(struct cdrom_device_info *cdi, | 686 | static int cdrom_get_random_writable(struct cdrom_device_info *cdi, |
672 | struct rwrt_feature_desc *rfd) | 687 | struct rwrt_feature_desc *rfd) |
673 | { | 688 | { |
@@ -839,7 +854,7 @@ static int cdrom_ram_open_write(struct cdrom_device_info *cdi) | |||
839 | else if (CDF_RWRT == be16_to_cpu(rfd.feature_code)) | 854 | else if (CDF_RWRT == be16_to_cpu(rfd.feature_code)) |
840 | ret = !rfd.curr; | 855 | ret = !rfd.curr; |
841 | 856 | ||
842 | cdinfo(CD_OPEN, "can open for random write\n"); | 857 | cd_dbg(CD_OPEN, "can open for random write\n"); |
843 | return ret; | 858 | return ret; |
844 | } | 859 | } |
845 | 860 | ||
@@ -928,12 +943,12 @@ static void cdrom_dvd_rw_close_write(struct cdrom_device_info *cdi) | |||
928 | struct packet_command cgc; | 943 | struct packet_command cgc; |
929 | 944 | ||
930 | if (cdi->mmc3_profile != 0x1a) { | 945 | if (cdi->mmc3_profile != 0x1a) { |
931 | cdinfo(CD_CLOSE, "%s: No DVD+RW\n", cdi->name); | 946 | cd_dbg(CD_CLOSE, "%s: No DVD+RW\n", cdi->name); |
932 | return; | 947 | return; |
933 | } | 948 | } |
934 | 949 | ||
935 | if (!cdi->media_written) { | 950 | if (!cdi->media_written) { |
936 | cdinfo(CD_CLOSE, "%s: DVD+RW media clean\n", cdi->name); | 951 | cd_dbg(CD_CLOSE, "%s: DVD+RW media clean\n", cdi->name); |
937 | return; | 952 | return; |
938 | } | 953 | } |
939 | 954 | ||
@@ -969,82 +984,74 @@ static int cdrom_close_write(struct cdrom_device_info *cdi) | |||
969 | #endif | 984 | #endif |
970 | } | 985 | } |
971 | 986 | ||
972 | /* We use the open-option O_NONBLOCK to indicate that the | 987 | /* badly broken, I know. Is due for a fixup anytime. */ |
973 | * purpose of opening is only for subsequent ioctl() calls; no device | 988 | static void cdrom_count_tracks(struct cdrom_device_info *cdi, tracktype *tracks) |
974 | * integrity checks are performed. | ||
975 | * | ||
976 | * We hope that all cd-player programs will adopt this convention. It | ||
977 | * is in their own interest: device control becomes a lot easier | ||
978 | * this way. | ||
979 | */ | ||
980 | int cdrom_open(struct cdrom_device_info *cdi, struct block_device *bdev, fmode_t mode) | ||
981 | { | 989 | { |
982 | int ret; | 990 | struct cdrom_tochdr header; |
983 | 991 | struct cdrom_tocentry entry; | |
984 | cdinfo(CD_OPEN, "entering cdrom_open\n"); | 992 | int ret, i; |
985 | 993 | tracks->data = 0; | |
986 | /* open is event synchronization point, check events first */ | 994 | tracks->audio = 0; |
987 | check_disk_change(bdev); | 995 | tracks->cdi = 0; |
988 | 996 | tracks->xa = 0; | |
989 | /* if this was a O_NONBLOCK open and we should honor the flags, | 997 | tracks->error = 0; |
990 | * do a quick open without drive/disc integrity checks. */ | 998 | cd_dbg(CD_COUNT_TRACKS, "entering cdrom_count_tracks\n"); |
991 | cdi->use_count++; | 999 | /* Grab the TOC header so we can see how many tracks there are */ |
992 | if ((mode & FMODE_NDELAY) && (cdi->options & CDO_USE_FFLAGS)) { | 1000 | ret = cdi->ops->audio_ioctl(cdi, CDROMREADTOCHDR, &header); |
993 | ret = cdi->ops->open(cdi, 1); | 1001 | if (ret) { |
994 | } else { | 1002 | if (ret == -ENOMEDIUM) |
995 | ret = open_for_data(cdi); | 1003 | tracks->error = CDS_NO_DISC; |
996 | if (ret) | 1004 | else |
997 | goto err; | 1005 | tracks->error = CDS_NO_INFO; |
998 | cdrom_mmc3_profile(cdi); | 1006 | return; |
999 | if (mode & FMODE_WRITE) { | ||
1000 | ret = -EROFS; | ||
1001 | if (cdrom_open_write(cdi)) | ||
1002 | goto err_release; | ||
1003 | if (!CDROM_CAN(CDC_RAM)) | ||
1004 | goto err_release; | ||
1005 | ret = 0; | ||
1006 | cdi->media_written = 0; | ||
1007 | } | ||
1008 | } | 1007 | } |
1009 | 1008 | /* check what type of tracks are on this disc */ | |
1010 | if (ret) | 1009 | entry.cdte_format = CDROM_MSF; |
1011 | goto err; | 1010 | for (i = header.cdth_trk0; i <= header.cdth_trk1; i++) { |
1012 | 1011 | entry.cdte_track = i; | |
1013 | cdinfo(CD_OPEN, "Use count for \"/dev/%s\" now %d\n", | 1012 | if (cdi->ops->audio_ioctl(cdi, CDROMREADTOCENTRY, &entry)) { |
1014 | cdi->name, cdi->use_count); | 1013 | tracks->error = CDS_NO_INFO; |
1015 | return 0; | 1014 | return; |
1016 | err_release: | 1015 | } |
1017 | if (CDROM_CAN(CDC_LOCK) && cdi->options & CDO_LOCK) { | 1016 | if (entry.cdte_ctrl & CDROM_DATA_TRACK) { |
1018 | cdi->ops->lock_door(cdi, 0); | 1017 | if (entry.cdte_format == 0x10) |
1019 | cdinfo(CD_OPEN, "door unlocked.\n"); | 1018 | tracks->cdi++; |
1019 | else if (entry.cdte_format == 0x20) | ||
1020 | tracks->xa++; | ||
1021 | else | ||
1022 | tracks->data++; | ||
1023 | } else { | ||
1024 | tracks->audio++; | ||
1025 | } | ||
1026 | cd_dbg(CD_COUNT_TRACKS, "track %d: format=%d, ctrl=%d\n", | ||
1027 | i, entry.cdte_format, entry.cdte_ctrl); | ||
1020 | } | 1028 | } |
1021 | cdi->ops->release(cdi); | 1029 | cd_dbg(CD_COUNT_TRACKS, "disc has %d tracks: %d=audio %d=data %d=Cd-I %d=XA\n", |
1022 | err: | 1030 | header.cdth_trk1, tracks->audio, tracks->data, |
1023 | cdi->use_count--; | 1031 | tracks->cdi, tracks->xa); |
1024 | return ret; | ||
1025 | } | 1032 | } |
1026 | 1033 | ||
1027 | static | 1034 | static |
1028 | int open_for_data(struct cdrom_device_info * cdi) | 1035 | int open_for_data(struct cdrom_device_info *cdi) |
1029 | { | 1036 | { |
1030 | int ret; | 1037 | int ret; |
1031 | struct cdrom_device_ops *cdo = cdi->ops; | 1038 | struct cdrom_device_ops *cdo = cdi->ops; |
1032 | tracktype tracks; | 1039 | tracktype tracks; |
1033 | cdinfo(CD_OPEN, "entering open_for_data\n"); | 1040 | cd_dbg(CD_OPEN, "entering open_for_data\n"); |
1034 | /* Check if the driver can report drive status. If it can, we | 1041 | /* Check if the driver can report drive status. If it can, we |
1035 | can do clever things. If it can't, well, we at least tried! */ | 1042 | can do clever things. If it can't, well, we at least tried! */ |
1036 | if (cdo->drive_status != NULL) { | 1043 | if (cdo->drive_status != NULL) { |
1037 | ret = cdo->drive_status(cdi, CDSL_CURRENT); | 1044 | ret = cdo->drive_status(cdi, CDSL_CURRENT); |
1038 | cdinfo(CD_OPEN, "drive_status=%d\n", ret); | 1045 | cd_dbg(CD_OPEN, "drive_status=%d\n", ret); |
1039 | if (ret == CDS_TRAY_OPEN) { | 1046 | if (ret == CDS_TRAY_OPEN) { |
1040 | cdinfo(CD_OPEN, "the tray is open...\n"); | 1047 | cd_dbg(CD_OPEN, "the tray is open...\n"); |
1041 | /* can/may i close it? */ | 1048 | /* can/may i close it? */ |
1042 | if (CDROM_CAN(CDC_CLOSE_TRAY) && | 1049 | if (CDROM_CAN(CDC_CLOSE_TRAY) && |
1043 | cdi->options & CDO_AUTO_CLOSE) { | 1050 | cdi->options & CDO_AUTO_CLOSE) { |
1044 | cdinfo(CD_OPEN, "trying to close the tray.\n"); | 1051 | cd_dbg(CD_OPEN, "trying to close the tray\n"); |
1045 | ret=cdo->tray_move(cdi,0); | 1052 | ret=cdo->tray_move(cdi,0); |
1046 | if (ret) { | 1053 | if (ret) { |
1047 | cdinfo(CD_OPEN, "bummer. tried to close the tray but failed.\n"); | 1054 | cd_dbg(CD_OPEN, "bummer. tried to close the tray but failed.\n"); |
1048 | /* Ignore the error from the low | 1055 | /* Ignore the error from the low |
1049 | level driver. We don't care why it | 1056 | level driver. We don't care why it |
1050 | couldn't close the tray. We only care | 1057 | couldn't close the tray. We only care |
@@ -1054,19 +1061,19 @@ int open_for_data(struct cdrom_device_info * cdi) | |||
1054 | goto clean_up_and_return; | 1061 | goto clean_up_and_return; |
1055 | } | 1062 | } |
1056 | } else { | 1063 | } else { |
1057 | cdinfo(CD_OPEN, "bummer. this drive can't close the tray.\n"); | 1064 | cd_dbg(CD_OPEN, "bummer. this drive can't close the tray.\n"); |
1058 | ret=-ENOMEDIUM; | 1065 | ret=-ENOMEDIUM; |
1059 | goto clean_up_and_return; | 1066 | goto clean_up_and_return; |
1060 | } | 1067 | } |
1061 | /* Ok, the door should be closed now.. Check again */ | 1068 | /* Ok, the door should be closed now.. Check again */ |
1062 | ret = cdo->drive_status(cdi, CDSL_CURRENT); | 1069 | ret = cdo->drive_status(cdi, CDSL_CURRENT); |
1063 | if ((ret == CDS_NO_DISC) || (ret==CDS_TRAY_OPEN)) { | 1070 | if ((ret == CDS_NO_DISC) || (ret==CDS_TRAY_OPEN)) { |
1064 | cdinfo(CD_OPEN, "bummer. the tray is still not closed.\n"); | 1071 | cd_dbg(CD_OPEN, "bummer. the tray is still not closed.\n"); |
1065 | cdinfo(CD_OPEN, "tray might not contain a medium.\n"); | 1072 | cd_dbg(CD_OPEN, "tray might not contain a medium\n"); |
1066 | ret=-ENOMEDIUM; | 1073 | ret=-ENOMEDIUM; |
1067 | goto clean_up_and_return; | 1074 | goto clean_up_and_return; |
1068 | } | 1075 | } |
1069 | cdinfo(CD_OPEN, "the tray is now closed.\n"); | 1076 | cd_dbg(CD_OPEN, "the tray is now closed\n"); |
1070 | } | 1077 | } |
1071 | /* the door should be closed now, check for the disc */ | 1078 | /* the door should be closed now, check for the disc */ |
1072 | ret = cdo->drive_status(cdi, CDSL_CURRENT); | 1079 | ret = cdo->drive_status(cdi, CDSL_CURRENT); |
@@ -1077,7 +1084,7 @@ int open_for_data(struct cdrom_device_info * cdi) | |||
1077 | } | 1084 | } |
1078 | cdrom_count_tracks(cdi, &tracks); | 1085 | cdrom_count_tracks(cdi, &tracks); |
1079 | if (tracks.error == CDS_NO_DISC) { | 1086 | if (tracks.error == CDS_NO_DISC) { |
1080 | cdinfo(CD_OPEN, "bummer. no disc.\n"); | 1087 | cd_dbg(CD_OPEN, "bummer. no disc.\n"); |
1081 | ret=-ENOMEDIUM; | 1088 | ret=-ENOMEDIUM; |
1082 | goto clean_up_and_return; | 1089 | goto clean_up_and_return; |
1083 | } | 1090 | } |
@@ -1087,34 +1094,34 @@ int open_for_data(struct cdrom_device_info * cdi) | |||
1087 | if (cdi->options & CDO_CHECK_TYPE) { | 1094 | if (cdi->options & CDO_CHECK_TYPE) { |
1088 | /* give people a warning shot, now that CDO_CHECK_TYPE | 1095 | /* give people a warning shot, now that CDO_CHECK_TYPE |
1089 | is the default case! */ | 1096 | is the default case! */ |
1090 | cdinfo(CD_OPEN, "bummer. wrong media type.\n"); | 1097 | cd_dbg(CD_OPEN, "bummer. wrong media type.\n"); |
1091 | cdinfo(CD_WARNING, "pid %d must open device O_NONBLOCK!\n", | 1098 | cd_dbg(CD_WARNING, "pid %d must open device O_NONBLOCK!\n", |
1092 | (unsigned int)task_pid_nr(current)); | 1099 | (unsigned int)task_pid_nr(current)); |
1093 | ret=-EMEDIUMTYPE; | 1100 | ret=-EMEDIUMTYPE; |
1094 | goto clean_up_and_return; | 1101 | goto clean_up_and_return; |
1095 | } | 1102 | } |
1096 | else { | 1103 | else { |
1097 | cdinfo(CD_OPEN, "wrong media type, but CDO_CHECK_TYPE not set.\n"); | 1104 | cd_dbg(CD_OPEN, "wrong media type, but CDO_CHECK_TYPE not set\n"); |
1098 | } | 1105 | } |
1099 | } | 1106 | } |
1100 | 1107 | ||
1101 | cdinfo(CD_OPEN, "all seems well, opening the device.\n"); | 1108 | cd_dbg(CD_OPEN, "all seems well, opening the devicen"); |
1102 | 1109 | ||
1103 | /* all seems well, we can open the device */ | 1110 | /* all seems well, we can open the device */ |
1104 | ret = cdo->open(cdi, 0); /* open for data */ | 1111 | ret = cdo->open(cdi, 0); /* open for data */ |
1105 | cdinfo(CD_OPEN, "opening the device gave me %d.\n", ret); | 1112 | cd_dbg(CD_OPEN, "opening the device gave me %d\n", ret); |
1106 | /* After all this careful checking, we shouldn't have problems | 1113 | /* After all this careful checking, we shouldn't have problems |
1107 | opening the device, but we don't want the device locked if | 1114 | opening the device, but we don't want the device locked if |
1108 | this somehow fails... */ | 1115 | this somehow fails... */ |
1109 | if (ret) { | 1116 | if (ret) { |
1110 | cdinfo(CD_OPEN, "open device failed.\n"); | 1117 | cd_dbg(CD_OPEN, "open device failed\n"); |
1111 | goto clean_up_and_return; | 1118 | goto clean_up_and_return; |
1112 | } | 1119 | } |
1113 | if (CDROM_CAN(CDC_LOCK) && (cdi->options & CDO_LOCK)) { | 1120 | if (CDROM_CAN(CDC_LOCK) && (cdi->options & CDO_LOCK)) { |
1114 | cdo->lock_door(cdi, 1); | 1121 | cdo->lock_door(cdi, 1); |
1115 | cdinfo(CD_OPEN, "door locked.\n"); | 1122 | cd_dbg(CD_OPEN, "door locked\n"); |
1116 | } | 1123 | } |
1117 | cdinfo(CD_OPEN, "device opened successfully.\n"); | 1124 | cd_dbg(CD_OPEN, "device opened successfully\n"); |
1118 | return ret; | 1125 | return ret; |
1119 | 1126 | ||
1120 | /* Something failed. Try to unlock the drive, because some drivers | 1127 | /* Something failed. Try to unlock the drive, because some drivers |
@@ -1123,14 +1130,70 @@ int open_for_data(struct cdrom_device_info * cdi) | |||
1123 | This ensures that the drive gets unlocked after a mount fails. This | 1130 | This ensures that the drive gets unlocked after a mount fails. This |
1124 | is a goto to avoid bloating the driver with redundant code. */ | 1131 | is a goto to avoid bloating the driver with redundant code. */ |
1125 | clean_up_and_return: | 1132 | clean_up_and_return: |
1126 | cdinfo(CD_OPEN, "open failed.\n"); | 1133 | cd_dbg(CD_OPEN, "open failed\n"); |
1127 | if (CDROM_CAN(CDC_LOCK) && cdi->options & CDO_LOCK) { | 1134 | if (CDROM_CAN(CDC_LOCK) && cdi->options & CDO_LOCK) { |
1128 | cdo->lock_door(cdi, 0); | 1135 | cdo->lock_door(cdi, 0); |
1129 | cdinfo(CD_OPEN, "door unlocked.\n"); | 1136 | cd_dbg(CD_OPEN, "door unlocked\n"); |
1130 | } | 1137 | } |
1131 | return ret; | 1138 | return ret; |
1132 | } | 1139 | } |
1133 | 1140 | ||
1141 | /* We use the open-option O_NONBLOCK to indicate that the | ||
1142 | * purpose of opening is only for subsequent ioctl() calls; no device | ||
1143 | * integrity checks are performed. | ||
1144 | * | ||
1145 | * We hope that all cd-player programs will adopt this convention. It | ||
1146 | * is in their own interest: device control becomes a lot easier | ||
1147 | * this way. | ||
1148 | */ | ||
1149 | int cdrom_open(struct cdrom_device_info *cdi, struct block_device *bdev, | ||
1150 | fmode_t mode) | ||
1151 | { | ||
1152 | int ret; | ||
1153 | |||
1154 | cd_dbg(CD_OPEN, "entering cdrom_open\n"); | ||
1155 | |||
1156 | /* open is event synchronization point, check events first */ | ||
1157 | check_disk_change(bdev); | ||
1158 | |||
1159 | /* if this was a O_NONBLOCK open and we should honor the flags, | ||
1160 | * do a quick open without drive/disc integrity checks. */ | ||
1161 | cdi->use_count++; | ||
1162 | if ((mode & FMODE_NDELAY) && (cdi->options & CDO_USE_FFLAGS)) { | ||
1163 | ret = cdi->ops->open(cdi, 1); | ||
1164 | } else { | ||
1165 | ret = open_for_data(cdi); | ||
1166 | if (ret) | ||
1167 | goto err; | ||
1168 | cdrom_mmc3_profile(cdi); | ||
1169 | if (mode & FMODE_WRITE) { | ||
1170 | ret = -EROFS; | ||
1171 | if (cdrom_open_write(cdi)) | ||
1172 | goto err_release; | ||
1173 | if (!CDROM_CAN(CDC_RAM)) | ||
1174 | goto err_release; | ||
1175 | ret = 0; | ||
1176 | cdi->media_written = 0; | ||
1177 | } | ||
1178 | } | ||
1179 | |||
1180 | if (ret) | ||
1181 | goto err; | ||
1182 | |||
1183 | cd_dbg(CD_OPEN, "Use count for \"/dev/%s\" now %d\n", | ||
1184 | cdi->name, cdi->use_count); | ||
1185 | return 0; | ||
1186 | err_release: | ||
1187 | if (CDROM_CAN(CDC_LOCK) && cdi->options & CDO_LOCK) { | ||
1188 | cdi->ops->lock_door(cdi, 0); | ||
1189 | cd_dbg(CD_OPEN, "door unlocked\n"); | ||
1190 | } | ||
1191 | cdi->ops->release(cdi); | ||
1192 | err: | ||
1193 | cdi->use_count--; | ||
1194 | return ret; | ||
1195 | } | ||
1196 | |||
1134 | /* This code is similar to that in open_for_data. The routine is called | 1197 | /* This code is similar to that in open_for_data. The routine is called |
1135 | whenever an audio play operation is requested. | 1198 | whenever an audio play operation is requested. |
1136 | */ | 1199 | */ |
@@ -1139,21 +1202,21 @@ static int check_for_audio_disc(struct cdrom_device_info * cdi, | |||
1139 | { | 1202 | { |
1140 | int ret; | 1203 | int ret; |
1141 | tracktype tracks; | 1204 | tracktype tracks; |
1142 | cdinfo(CD_OPEN, "entering check_for_audio_disc\n"); | 1205 | cd_dbg(CD_OPEN, "entering check_for_audio_disc\n"); |
1143 | if (!(cdi->options & CDO_CHECK_TYPE)) | 1206 | if (!(cdi->options & CDO_CHECK_TYPE)) |
1144 | return 0; | 1207 | return 0; |
1145 | if (cdo->drive_status != NULL) { | 1208 | if (cdo->drive_status != NULL) { |
1146 | ret = cdo->drive_status(cdi, CDSL_CURRENT); | 1209 | ret = cdo->drive_status(cdi, CDSL_CURRENT); |
1147 | cdinfo(CD_OPEN, "drive_status=%d\n", ret); | 1210 | cd_dbg(CD_OPEN, "drive_status=%d\n", ret); |
1148 | if (ret == CDS_TRAY_OPEN) { | 1211 | if (ret == CDS_TRAY_OPEN) { |
1149 | cdinfo(CD_OPEN, "the tray is open...\n"); | 1212 | cd_dbg(CD_OPEN, "the tray is open...\n"); |
1150 | /* can/may i close it? */ | 1213 | /* can/may i close it? */ |
1151 | if (CDROM_CAN(CDC_CLOSE_TRAY) && | 1214 | if (CDROM_CAN(CDC_CLOSE_TRAY) && |
1152 | cdi->options & CDO_AUTO_CLOSE) { | 1215 | cdi->options & CDO_AUTO_CLOSE) { |
1153 | cdinfo(CD_OPEN, "trying to close the tray.\n"); | 1216 | cd_dbg(CD_OPEN, "trying to close the tray\n"); |
1154 | ret=cdo->tray_move(cdi,0); | 1217 | ret=cdo->tray_move(cdi,0); |
1155 | if (ret) { | 1218 | if (ret) { |
1156 | cdinfo(CD_OPEN, "bummer. tried to close tray but failed.\n"); | 1219 | cd_dbg(CD_OPEN, "bummer. tried to close tray but failed.\n"); |
1157 | /* Ignore the error from the low | 1220 | /* Ignore the error from the low |
1158 | level driver. We don't care why it | 1221 | level driver. We don't care why it |
1159 | couldn't close the tray. We only care | 1222 | couldn't close the tray. We only care |
@@ -1162,20 +1225,20 @@ static int check_for_audio_disc(struct cdrom_device_info * cdi, | |||
1162 | return -ENOMEDIUM; | 1225 | return -ENOMEDIUM; |
1163 | } | 1226 | } |
1164 | } else { | 1227 | } else { |
1165 | cdinfo(CD_OPEN, "bummer. this driver can't close the tray.\n"); | 1228 | cd_dbg(CD_OPEN, "bummer. this driver can't close the tray.\n"); |
1166 | return -ENOMEDIUM; | 1229 | return -ENOMEDIUM; |
1167 | } | 1230 | } |
1168 | /* Ok, the door should be closed now.. Check again */ | 1231 | /* Ok, the door should be closed now.. Check again */ |
1169 | ret = cdo->drive_status(cdi, CDSL_CURRENT); | 1232 | ret = cdo->drive_status(cdi, CDSL_CURRENT); |
1170 | if ((ret == CDS_NO_DISC) || (ret==CDS_TRAY_OPEN)) { | 1233 | if ((ret == CDS_NO_DISC) || (ret==CDS_TRAY_OPEN)) { |
1171 | cdinfo(CD_OPEN, "bummer. the tray is still not closed.\n"); | 1234 | cd_dbg(CD_OPEN, "bummer. the tray is still not closed.\n"); |
1172 | return -ENOMEDIUM; | 1235 | return -ENOMEDIUM; |
1173 | } | 1236 | } |
1174 | if (ret!=CDS_DISC_OK) { | 1237 | if (ret!=CDS_DISC_OK) { |
1175 | cdinfo(CD_OPEN, "bummer. disc isn't ready.\n"); | 1238 | cd_dbg(CD_OPEN, "bummer. disc isn't ready.\n"); |
1176 | return -EIO; | 1239 | return -EIO; |
1177 | } | 1240 | } |
1178 | cdinfo(CD_OPEN, "the tray is now closed.\n"); | 1241 | cd_dbg(CD_OPEN, "the tray is now closed\n"); |
1179 | } | 1242 | } |
1180 | } | 1243 | } |
1181 | cdrom_count_tracks(cdi, &tracks); | 1244 | cdrom_count_tracks(cdi, &tracks); |
@@ -1193,17 +1256,18 @@ void cdrom_release(struct cdrom_device_info *cdi, fmode_t mode) | |||
1193 | struct cdrom_device_ops *cdo = cdi->ops; | 1256 | struct cdrom_device_ops *cdo = cdi->ops; |
1194 | int opened_for_data; | 1257 | int opened_for_data; |
1195 | 1258 | ||
1196 | cdinfo(CD_CLOSE, "entering cdrom_release\n"); | 1259 | cd_dbg(CD_CLOSE, "entering cdrom_release\n"); |
1197 | 1260 | ||
1198 | if (cdi->use_count > 0) | 1261 | if (cdi->use_count > 0) |
1199 | cdi->use_count--; | 1262 | cdi->use_count--; |
1200 | 1263 | ||
1201 | if (cdi->use_count == 0) { | 1264 | if (cdi->use_count == 0) { |
1202 | cdinfo(CD_CLOSE, "Use count for \"/dev/%s\" now zero\n", cdi->name); | 1265 | cd_dbg(CD_CLOSE, "Use count for \"/dev/%s\" now zero\n", |
1266 | cdi->name); | ||
1203 | cdrom_dvd_rw_close_write(cdi); | 1267 | cdrom_dvd_rw_close_write(cdi); |
1204 | 1268 | ||
1205 | if ((cdo->capability & CDC_LOCK) && !cdi->keeplocked) { | 1269 | if ((cdo->capability & CDC_LOCK) && !cdi->keeplocked) { |
1206 | cdinfo(CD_CLOSE, "Unlocking door!\n"); | 1270 | cd_dbg(CD_CLOSE, "Unlocking door!\n"); |
1207 | cdo->lock_door(cdi, 0); | 1271 | cdo->lock_door(cdi, 0); |
1208 | } | 1272 | } |
1209 | } | 1273 | } |
@@ -1262,7 +1326,7 @@ static int cdrom_slot_status(struct cdrom_device_info *cdi, int slot) | |||
1262 | struct cdrom_changer_info *info; | 1326 | struct cdrom_changer_info *info; |
1263 | int ret; | 1327 | int ret; |
1264 | 1328 | ||
1265 | cdinfo(CD_CHANGER, "entering cdrom_slot_status()\n"); | 1329 | cd_dbg(CD_CHANGER, "entering cdrom_slot_status()\n"); |
1266 | if (cdi->sanyo_slot) | 1330 | if (cdi->sanyo_slot) |
1267 | return CDS_NO_INFO; | 1331 | return CDS_NO_INFO; |
1268 | 1332 | ||
@@ -1292,7 +1356,7 @@ int cdrom_number_of_slots(struct cdrom_device_info *cdi) | |||
1292 | int nslots = 1; | 1356 | int nslots = 1; |
1293 | struct cdrom_changer_info *info; | 1357 | struct cdrom_changer_info *info; |
1294 | 1358 | ||
1295 | cdinfo(CD_CHANGER, "entering cdrom_number_of_slots()\n"); | 1359 | cd_dbg(CD_CHANGER, "entering cdrom_number_of_slots()\n"); |
1296 | /* cdrom_read_mech_status requires a valid value for capacity: */ | 1360 | /* cdrom_read_mech_status requires a valid value for capacity: */ |
1297 | cdi->capacity = 0; | 1361 | cdi->capacity = 0; |
1298 | 1362 | ||
@@ -1313,7 +1377,7 @@ static int cdrom_load_unload(struct cdrom_device_info *cdi, int slot) | |||
1313 | { | 1377 | { |
1314 | struct packet_command cgc; | 1378 | struct packet_command cgc; |
1315 | 1379 | ||
1316 | cdinfo(CD_CHANGER, "entering cdrom_load_unload()\n"); | 1380 | cd_dbg(CD_CHANGER, "entering cdrom_load_unload()\n"); |
1317 | if (cdi->sanyo_slot && slot < 0) | 1381 | if (cdi->sanyo_slot && slot < 0) |
1318 | return 0; | 1382 | return 0; |
1319 | 1383 | ||
@@ -1342,7 +1406,7 @@ static int cdrom_select_disc(struct cdrom_device_info *cdi, int slot) | |||
1342 | int curslot; | 1406 | int curslot; |
1343 | int ret; | 1407 | int ret; |
1344 | 1408 | ||
1345 | cdinfo(CD_CHANGER, "entering cdrom_select_disc()\n"); | 1409 | cd_dbg(CD_CHANGER, "entering cdrom_select_disc()\n"); |
1346 | if (!CDROM_CAN(CDC_SELECT_DISC)) | 1410 | if (!CDROM_CAN(CDC_SELECT_DISC)) |
1347 | return -EDRIVE_CANT_DO_THIS; | 1411 | return -EDRIVE_CANT_DO_THIS; |
1348 | 1412 | ||
@@ -1476,51 +1540,6 @@ int cdrom_media_changed(struct cdrom_device_info *cdi) | |||
1476 | return media_changed(cdi, 0); | 1540 | return media_changed(cdi, 0); |
1477 | } | 1541 | } |
1478 | 1542 | ||
1479 | /* badly broken, I know. Is due for a fixup anytime. */ | ||
1480 | static void cdrom_count_tracks(struct cdrom_device_info *cdi, tracktype* tracks) | ||
1481 | { | ||
1482 | struct cdrom_tochdr header; | ||
1483 | struct cdrom_tocentry entry; | ||
1484 | int ret, i; | ||
1485 | tracks->data=0; | ||
1486 | tracks->audio=0; | ||
1487 | tracks->cdi=0; | ||
1488 | tracks->xa=0; | ||
1489 | tracks->error=0; | ||
1490 | cdinfo(CD_COUNT_TRACKS, "entering cdrom_count_tracks\n"); | ||
1491 | /* Grab the TOC header so we can see how many tracks there are */ | ||
1492 | if ((ret = cdi->ops->audio_ioctl(cdi, CDROMREADTOCHDR, &header))) { | ||
1493 | if (ret == -ENOMEDIUM) | ||
1494 | tracks->error = CDS_NO_DISC; | ||
1495 | else | ||
1496 | tracks->error = CDS_NO_INFO; | ||
1497 | return; | ||
1498 | } | ||
1499 | /* check what type of tracks are on this disc */ | ||
1500 | entry.cdte_format = CDROM_MSF; | ||
1501 | for (i = header.cdth_trk0; i <= header.cdth_trk1; i++) { | ||
1502 | entry.cdte_track = i; | ||
1503 | if (cdi->ops->audio_ioctl(cdi, CDROMREADTOCENTRY, &entry)) { | ||
1504 | tracks->error=CDS_NO_INFO; | ||
1505 | return; | ||
1506 | } | ||
1507 | if (entry.cdte_ctrl & CDROM_DATA_TRACK) { | ||
1508 | if (entry.cdte_format == 0x10) | ||
1509 | tracks->cdi++; | ||
1510 | else if (entry.cdte_format == 0x20) | ||
1511 | tracks->xa++; | ||
1512 | else | ||
1513 | tracks->data++; | ||
1514 | } else | ||
1515 | tracks->audio++; | ||
1516 | cdinfo(CD_COUNT_TRACKS, "track %d: format=%d, ctrl=%d\n", | ||
1517 | i, entry.cdte_format, entry.cdte_ctrl); | ||
1518 | } | ||
1519 | cdinfo(CD_COUNT_TRACKS, "disc has %d tracks: %d=audio %d=data %d=Cd-I %d=XA\n", | ||
1520 | header.cdth_trk1, tracks->audio, tracks->data, | ||
1521 | tracks->cdi, tracks->xa); | ||
1522 | } | ||
1523 | |||
1524 | /* Requests to the low-level drivers will /always/ be done in the | 1543 | /* Requests to the low-level drivers will /always/ be done in the |
1525 | following format convention: | 1544 | following format convention: |
1526 | 1545 | ||
@@ -1632,7 +1651,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) | |||
1632 | switch (ai->type) { | 1651 | switch (ai->type) { |
1633 | /* LU data send */ | 1652 | /* LU data send */ |
1634 | case DVD_LU_SEND_AGID: | 1653 | case DVD_LU_SEND_AGID: |
1635 | cdinfo(CD_DVD, "entering DVD_LU_SEND_AGID\n"); | 1654 | cd_dbg(CD_DVD, "entering DVD_LU_SEND_AGID\n"); |
1636 | cgc.quiet = 1; | 1655 | cgc.quiet = 1; |
1637 | setup_report_key(&cgc, ai->lsa.agid, 0); | 1656 | setup_report_key(&cgc, ai->lsa.agid, 0); |
1638 | 1657 | ||
@@ -1644,7 +1663,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) | |||
1644 | break; | 1663 | break; |
1645 | 1664 | ||
1646 | case DVD_LU_SEND_KEY1: | 1665 | case DVD_LU_SEND_KEY1: |
1647 | cdinfo(CD_DVD, "entering DVD_LU_SEND_KEY1\n"); | 1666 | cd_dbg(CD_DVD, "entering DVD_LU_SEND_KEY1\n"); |
1648 | setup_report_key(&cgc, ai->lsk.agid, 2); | 1667 | setup_report_key(&cgc, ai->lsk.agid, 2); |
1649 | 1668 | ||
1650 | if ((ret = cdo->generic_packet(cdi, &cgc))) | 1669 | if ((ret = cdo->generic_packet(cdi, &cgc))) |
@@ -1655,7 +1674,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) | |||
1655 | break; | 1674 | break; |
1656 | 1675 | ||
1657 | case DVD_LU_SEND_CHALLENGE: | 1676 | case DVD_LU_SEND_CHALLENGE: |
1658 | cdinfo(CD_DVD, "entering DVD_LU_SEND_CHALLENGE\n"); | 1677 | cd_dbg(CD_DVD, "entering DVD_LU_SEND_CHALLENGE\n"); |
1659 | setup_report_key(&cgc, ai->lsc.agid, 1); | 1678 | setup_report_key(&cgc, ai->lsc.agid, 1); |
1660 | 1679 | ||
1661 | if ((ret = cdo->generic_packet(cdi, &cgc))) | 1680 | if ((ret = cdo->generic_packet(cdi, &cgc))) |
@@ -1667,7 +1686,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) | |||
1667 | 1686 | ||
1668 | /* Post-auth key */ | 1687 | /* Post-auth key */ |
1669 | case DVD_LU_SEND_TITLE_KEY: | 1688 | case DVD_LU_SEND_TITLE_KEY: |
1670 | cdinfo(CD_DVD, "entering DVD_LU_SEND_TITLE_KEY\n"); | 1689 | cd_dbg(CD_DVD, "entering DVD_LU_SEND_TITLE_KEY\n"); |
1671 | cgc.quiet = 1; | 1690 | cgc.quiet = 1; |
1672 | setup_report_key(&cgc, ai->lstk.agid, 4); | 1691 | setup_report_key(&cgc, ai->lstk.agid, 4); |
1673 | cgc.cmd[5] = ai->lstk.lba; | 1692 | cgc.cmd[5] = ai->lstk.lba; |
@@ -1686,7 +1705,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) | |||
1686 | break; | 1705 | break; |
1687 | 1706 | ||
1688 | case DVD_LU_SEND_ASF: | 1707 | case DVD_LU_SEND_ASF: |
1689 | cdinfo(CD_DVD, "entering DVD_LU_SEND_ASF\n"); | 1708 | cd_dbg(CD_DVD, "entering DVD_LU_SEND_ASF\n"); |
1690 | setup_report_key(&cgc, ai->lsasf.agid, 5); | 1709 | setup_report_key(&cgc, ai->lsasf.agid, 5); |
1691 | 1710 | ||
1692 | if ((ret = cdo->generic_packet(cdi, &cgc))) | 1711 | if ((ret = cdo->generic_packet(cdi, &cgc))) |
@@ -1697,7 +1716,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) | |||
1697 | 1716 | ||
1698 | /* LU data receive (LU changes state) */ | 1717 | /* LU data receive (LU changes state) */ |
1699 | case DVD_HOST_SEND_CHALLENGE: | 1718 | case DVD_HOST_SEND_CHALLENGE: |
1700 | cdinfo(CD_DVD, "entering DVD_HOST_SEND_CHALLENGE\n"); | 1719 | cd_dbg(CD_DVD, "entering DVD_HOST_SEND_CHALLENGE\n"); |
1701 | setup_send_key(&cgc, ai->hsc.agid, 1); | 1720 | setup_send_key(&cgc, ai->hsc.agid, 1); |
1702 | buf[1] = 0xe; | 1721 | buf[1] = 0xe; |
1703 | copy_chal(&buf[4], ai->hsc.chal); | 1722 | copy_chal(&buf[4], ai->hsc.chal); |
@@ -1709,7 +1728,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) | |||
1709 | break; | 1728 | break; |
1710 | 1729 | ||
1711 | case DVD_HOST_SEND_KEY2: | 1730 | case DVD_HOST_SEND_KEY2: |
1712 | cdinfo(CD_DVD, "entering DVD_HOST_SEND_KEY2\n"); | 1731 | cd_dbg(CD_DVD, "entering DVD_HOST_SEND_KEY2\n"); |
1713 | setup_send_key(&cgc, ai->hsk.agid, 3); | 1732 | setup_send_key(&cgc, ai->hsk.agid, 3); |
1714 | buf[1] = 0xa; | 1733 | buf[1] = 0xa; |
1715 | copy_key(&buf[4], ai->hsk.key); | 1734 | copy_key(&buf[4], ai->hsk.key); |
@@ -1724,7 +1743,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) | |||
1724 | /* Misc */ | 1743 | /* Misc */ |
1725 | case DVD_INVALIDATE_AGID: | 1744 | case DVD_INVALIDATE_AGID: |
1726 | cgc.quiet = 1; | 1745 | cgc.quiet = 1; |
1727 | cdinfo(CD_DVD, "entering DVD_INVALIDATE_AGID\n"); | 1746 | cd_dbg(CD_DVD, "entering DVD_INVALIDATE_AGID\n"); |
1728 | setup_report_key(&cgc, ai->lsa.agid, 0x3f); | 1747 | setup_report_key(&cgc, ai->lsa.agid, 0x3f); |
1729 | if ((ret = cdo->generic_packet(cdi, &cgc))) | 1748 | if ((ret = cdo->generic_packet(cdi, &cgc))) |
1730 | return ret; | 1749 | return ret; |
@@ -1732,7 +1751,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) | |||
1732 | 1751 | ||
1733 | /* Get region settings */ | 1752 | /* Get region settings */ |
1734 | case DVD_LU_SEND_RPC_STATE: | 1753 | case DVD_LU_SEND_RPC_STATE: |
1735 | cdinfo(CD_DVD, "entering DVD_LU_SEND_RPC_STATE\n"); | 1754 | cd_dbg(CD_DVD, "entering DVD_LU_SEND_RPC_STATE\n"); |
1736 | setup_report_key(&cgc, 0, 8); | 1755 | setup_report_key(&cgc, 0, 8); |
1737 | memset(&rpc_state, 0, sizeof(rpc_state_t)); | 1756 | memset(&rpc_state, 0, sizeof(rpc_state_t)); |
1738 | cgc.buffer = (char *) &rpc_state; | 1757 | cgc.buffer = (char *) &rpc_state; |
@@ -1749,7 +1768,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) | |||
1749 | 1768 | ||
1750 | /* Set region settings */ | 1769 | /* Set region settings */ |
1751 | case DVD_HOST_SEND_RPC_STATE: | 1770 | case DVD_HOST_SEND_RPC_STATE: |
1752 | cdinfo(CD_DVD, "entering DVD_HOST_SEND_RPC_STATE\n"); | 1771 | cd_dbg(CD_DVD, "entering DVD_HOST_SEND_RPC_STATE\n"); |
1753 | setup_send_key(&cgc, 0, 6); | 1772 | setup_send_key(&cgc, 0, 6); |
1754 | buf[1] = 6; | 1773 | buf[1] = 6; |
1755 | buf[4] = ai->hrpcs.pdrc; | 1774 | buf[4] = ai->hrpcs.pdrc; |
@@ -1759,7 +1778,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) | |||
1759 | break; | 1778 | break; |
1760 | 1779 | ||
1761 | default: | 1780 | default: |
1762 | cdinfo(CD_WARNING, "Invalid DVD key ioctl (%d)\n", ai->type); | 1781 | cd_dbg(CD_WARNING, "Invalid DVD key ioctl (%d)\n", ai->type); |
1763 | return -ENOTTY; | 1782 | return -ENOTTY; |
1764 | } | 1783 | } |
1765 | 1784 | ||
@@ -1891,7 +1910,8 @@ static int dvd_read_bca(struct cdrom_device_info *cdi, dvd_struct *s, | |||
1891 | 1910 | ||
1892 | s->bca.len = buf[0] << 8 | buf[1]; | 1911 | s->bca.len = buf[0] << 8 | buf[1]; |
1893 | if (s->bca.len < 12 || s->bca.len > 188) { | 1912 | if (s->bca.len < 12 || s->bca.len > 188) { |
1894 | cdinfo(CD_WARNING, "Received invalid BCA length (%d)\n", s->bca.len); | 1913 | cd_dbg(CD_WARNING, "Received invalid BCA length (%d)\n", |
1914 | s->bca.len); | ||
1895 | ret = -EIO; | 1915 | ret = -EIO; |
1896 | goto out; | 1916 | goto out; |
1897 | } | 1917 | } |
@@ -1927,14 +1947,13 @@ static int dvd_read_manufact(struct cdrom_device_info *cdi, dvd_struct *s, | |||
1927 | 1947 | ||
1928 | s->manufact.len = buf[0] << 8 | buf[1]; | 1948 | s->manufact.len = buf[0] << 8 | buf[1]; |
1929 | if (s->manufact.len < 0) { | 1949 | if (s->manufact.len < 0) { |
1930 | cdinfo(CD_WARNING, "Received invalid manufacture info length" | 1950 | cd_dbg(CD_WARNING, "Received invalid manufacture info length (%d)\n", |
1931 | " (%d)\n", s->manufact.len); | 1951 | s->manufact.len); |
1932 | ret = -EIO; | 1952 | ret = -EIO; |
1933 | } else { | 1953 | } else { |
1934 | if (s->manufact.len > 2048) { | 1954 | if (s->manufact.len > 2048) { |
1935 | cdinfo(CD_WARNING, "Received invalid manufacture info " | 1955 | cd_dbg(CD_WARNING, "Received invalid manufacture info length (%d): truncating to 2048\n", |
1936 | "length (%d): truncating to 2048\n", | 1956 | s->manufact.len); |
1937 | s->manufact.len); | ||
1938 | s->manufact.len = 2048; | 1957 | s->manufact.len = 2048; |
1939 | } | 1958 | } |
1940 | memcpy(s->manufact.value, &buf[4], s->manufact.len); | 1959 | memcpy(s->manufact.value, &buf[4], s->manufact.len); |
@@ -1965,8 +1984,8 @@ static int dvd_read_struct(struct cdrom_device_info *cdi, dvd_struct *s, | |||
1965 | return dvd_read_manufact(cdi, s, cgc); | 1984 | return dvd_read_manufact(cdi, s, cgc); |
1966 | 1985 | ||
1967 | default: | 1986 | default: |
1968 | cdinfo(CD_WARNING, ": Invalid DVD structure read requested (%d)\n", | 1987 | cd_dbg(CD_WARNING, ": Invalid DVD structure read requested (%d)\n", |
1969 | s->type); | 1988 | s->type); |
1970 | return -EINVAL; | 1989 | return -EINVAL; |
1971 | } | 1990 | } |
1972 | } | 1991 | } |
@@ -2255,7 +2274,7 @@ static int cdrom_ioctl_multisession(struct cdrom_device_info *cdi, | |||
2255 | u8 requested_format; | 2274 | u8 requested_format; |
2256 | int ret; | 2275 | int ret; |
2257 | 2276 | ||
2258 | cdinfo(CD_DO_IOCTL, "entering CDROMMULTISESSION\n"); | 2277 | cd_dbg(CD_DO_IOCTL, "entering CDROMMULTISESSION\n"); |
2259 | 2278 | ||
2260 | if (!(cdi->ops->capability & CDC_MULTI_SESSION)) | 2279 | if (!(cdi->ops->capability & CDC_MULTI_SESSION)) |
2261 | return -ENOSYS; | 2280 | return -ENOSYS; |
@@ -2277,13 +2296,13 @@ static int cdrom_ioctl_multisession(struct cdrom_device_info *cdi, | |||
2277 | if (copy_to_user(argp, &ms_info, sizeof(ms_info))) | 2296 | if (copy_to_user(argp, &ms_info, sizeof(ms_info))) |
2278 | return -EFAULT; | 2297 | return -EFAULT; |
2279 | 2298 | ||
2280 | cdinfo(CD_DO_IOCTL, "CDROMMULTISESSION successful\n"); | 2299 | cd_dbg(CD_DO_IOCTL, "CDROMMULTISESSION successful\n"); |
2281 | return 0; | 2300 | return 0; |
2282 | } | 2301 | } |
2283 | 2302 | ||
2284 | static int cdrom_ioctl_eject(struct cdrom_device_info *cdi) | 2303 | static int cdrom_ioctl_eject(struct cdrom_device_info *cdi) |
2285 | { | 2304 | { |
2286 | cdinfo(CD_DO_IOCTL, "entering CDROMEJECT\n"); | 2305 | cd_dbg(CD_DO_IOCTL, "entering CDROMEJECT\n"); |
2287 | 2306 | ||
2288 | if (!CDROM_CAN(CDC_OPEN_TRAY)) | 2307 | if (!CDROM_CAN(CDC_OPEN_TRAY)) |
2289 | return -ENOSYS; | 2308 | return -ENOSYS; |
@@ -2300,7 +2319,7 @@ static int cdrom_ioctl_eject(struct cdrom_device_info *cdi) | |||
2300 | 2319 | ||
2301 | static int cdrom_ioctl_closetray(struct cdrom_device_info *cdi) | 2320 | static int cdrom_ioctl_closetray(struct cdrom_device_info *cdi) |
2302 | { | 2321 | { |
2303 | cdinfo(CD_DO_IOCTL, "entering CDROMCLOSETRAY\n"); | 2322 | cd_dbg(CD_DO_IOCTL, "entering CDROMCLOSETRAY\n"); |
2304 | 2323 | ||
2305 | if (!CDROM_CAN(CDC_CLOSE_TRAY)) | 2324 | if (!CDROM_CAN(CDC_CLOSE_TRAY)) |
2306 | return -ENOSYS; | 2325 | return -ENOSYS; |
@@ -2310,7 +2329,7 @@ static int cdrom_ioctl_closetray(struct cdrom_device_info *cdi) | |||
2310 | static int cdrom_ioctl_eject_sw(struct cdrom_device_info *cdi, | 2329 | static int cdrom_ioctl_eject_sw(struct cdrom_device_info *cdi, |
2311 | unsigned long arg) | 2330 | unsigned long arg) |
2312 | { | 2331 | { |
2313 | cdinfo(CD_DO_IOCTL, "entering CDROMEJECT_SW\n"); | 2332 | cd_dbg(CD_DO_IOCTL, "entering CDROMEJECT_SW\n"); |
2314 | 2333 | ||
2315 | if (!CDROM_CAN(CDC_OPEN_TRAY)) | 2334 | if (!CDROM_CAN(CDC_OPEN_TRAY)) |
2316 | return -ENOSYS; | 2335 | return -ENOSYS; |
@@ -2329,7 +2348,7 @@ static int cdrom_ioctl_media_changed(struct cdrom_device_info *cdi, | |||
2329 | struct cdrom_changer_info *info; | 2348 | struct cdrom_changer_info *info; |
2330 | int ret; | 2349 | int ret; |
2331 | 2350 | ||
2332 | cdinfo(CD_DO_IOCTL, "entering CDROM_MEDIA_CHANGED\n"); | 2351 | cd_dbg(CD_DO_IOCTL, "entering CDROM_MEDIA_CHANGED\n"); |
2333 | 2352 | ||
2334 | if (!CDROM_CAN(CDC_MEDIA_CHANGED)) | 2353 | if (!CDROM_CAN(CDC_MEDIA_CHANGED)) |
2335 | return -ENOSYS; | 2354 | return -ENOSYS; |
@@ -2355,7 +2374,7 @@ static int cdrom_ioctl_media_changed(struct cdrom_device_info *cdi, | |||
2355 | static int cdrom_ioctl_set_options(struct cdrom_device_info *cdi, | 2374 | static int cdrom_ioctl_set_options(struct cdrom_device_info *cdi, |
2356 | unsigned long arg) | 2375 | unsigned long arg) |
2357 | { | 2376 | { |
2358 | cdinfo(CD_DO_IOCTL, "entering CDROM_SET_OPTIONS\n"); | 2377 | cd_dbg(CD_DO_IOCTL, "entering CDROM_SET_OPTIONS\n"); |
2359 | 2378 | ||
2360 | /* | 2379 | /* |
2361 | * Options need to be in sync with capability. | 2380 | * Options need to be in sync with capability. |
@@ -2383,7 +2402,7 @@ static int cdrom_ioctl_set_options(struct cdrom_device_info *cdi, | |||
2383 | static int cdrom_ioctl_clear_options(struct cdrom_device_info *cdi, | 2402 | static int cdrom_ioctl_clear_options(struct cdrom_device_info *cdi, |
2384 | unsigned long arg) | 2403 | unsigned long arg) |
2385 | { | 2404 | { |
2386 | cdinfo(CD_DO_IOCTL, "entering CDROM_CLEAR_OPTIONS\n"); | 2405 | cd_dbg(CD_DO_IOCTL, "entering CDROM_CLEAR_OPTIONS\n"); |
2387 | 2406 | ||
2388 | cdi->options &= ~(int) arg; | 2407 | cdi->options &= ~(int) arg; |
2389 | return cdi->options; | 2408 | return cdi->options; |
@@ -2392,7 +2411,7 @@ static int cdrom_ioctl_clear_options(struct cdrom_device_info *cdi, | |||
2392 | static int cdrom_ioctl_select_speed(struct cdrom_device_info *cdi, | 2411 | static int cdrom_ioctl_select_speed(struct cdrom_device_info *cdi, |
2393 | unsigned long arg) | 2412 | unsigned long arg) |
2394 | { | 2413 | { |
2395 | cdinfo(CD_DO_IOCTL, "entering CDROM_SELECT_SPEED\n"); | 2414 | cd_dbg(CD_DO_IOCTL, "entering CDROM_SELECT_SPEED\n"); |
2396 | 2415 | ||
2397 | if (!CDROM_CAN(CDC_SELECT_SPEED)) | 2416 | if (!CDROM_CAN(CDC_SELECT_SPEED)) |
2398 | return -ENOSYS; | 2417 | return -ENOSYS; |
@@ -2402,7 +2421,7 @@ static int cdrom_ioctl_select_speed(struct cdrom_device_info *cdi, | |||
2402 | static int cdrom_ioctl_select_disc(struct cdrom_device_info *cdi, | 2421 | static int cdrom_ioctl_select_disc(struct cdrom_device_info *cdi, |
2403 | unsigned long arg) | 2422 | unsigned long arg) |
2404 | { | 2423 | { |
2405 | cdinfo(CD_DO_IOCTL, "entering CDROM_SELECT_DISC\n"); | 2424 | cd_dbg(CD_DO_IOCTL, "entering CDROM_SELECT_DISC\n"); |
2406 | 2425 | ||
2407 | if (!CDROM_CAN(CDC_SELECT_DISC)) | 2426 | if (!CDROM_CAN(CDC_SELECT_DISC)) |
2408 | return -ENOSYS; | 2427 | return -ENOSYS; |
@@ -2420,14 +2439,14 @@ static int cdrom_ioctl_select_disc(struct cdrom_device_info *cdi, | |||
2420 | if (cdi->ops->select_disc) | 2439 | if (cdi->ops->select_disc) |
2421 | return cdi->ops->select_disc(cdi, arg); | 2440 | return cdi->ops->select_disc(cdi, arg); |
2422 | 2441 | ||
2423 | cdinfo(CD_CHANGER, "Using generic cdrom_select_disc()\n"); | 2442 | cd_dbg(CD_CHANGER, "Using generic cdrom_select_disc()\n"); |
2424 | return cdrom_select_disc(cdi, arg); | 2443 | return cdrom_select_disc(cdi, arg); |
2425 | } | 2444 | } |
2426 | 2445 | ||
2427 | static int cdrom_ioctl_reset(struct cdrom_device_info *cdi, | 2446 | static int cdrom_ioctl_reset(struct cdrom_device_info *cdi, |
2428 | struct block_device *bdev) | 2447 | struct block_device *bdev) |
2429 | { | 2448 | { |
2430 | cdinfo(CD_DO_IOCTL, "entering CDROM_RESET\n"); | 2449 | cd_dbg(CD_DO_IOCTL, "entering CDROM_RESET\n"); |
2431 | 2450 | ||
2432 | if (!capable(CAP_SYS_ADMIN)) | 2451 | if (!capable(CAP_SYS_ADMIN)) |
2433 | return -EACCES; | 2452 | return -EACCES; |
@@ -2440,7 +2459,7 @@ static int cdrom_ioctl_reset(struct cdrom_device_info *cdi, | |||
2440 | static int cdrom_ioctl_lock_door(struct cdrom_device_info *cdi, | 2459 | static int cdrom_ioctl_lock_door(struct cdrom_device_info *cdi, |
2441 | unsigned long arg) | 2460 | unsigned long arg) |
2442 | { | 2461 | { |
2443 | cdinfo(CD_DO_IOCTL, "%socking door.\n", arg ? "L" : "Unl"); | 2462 | cd_dbg(CD_DO_IOCTL, "%socking door\n", arg ? "L" : "Unl"); |
2444 | 2463 | ||
2445 | if (!CDROM_CAN(CDC_LOCK)) | 2464 | if (!CDROM_CAN(CDC_LOCK)) |
2446 | return -EDRIVE_CANT_DO_THIS; | 2465 | return -EDRIVE_CANT_DO_THIS; |
@@ -2459,7 +2478,7 @@ static int cdrom_ioctl_lock_door(struct cdrom_device_info *cdi, | |||
2459 | static int cdrom_ioctl_debug(struct cdrom_device_info *cdi, | 2478 | static int cdrom_ioctl_debug(struct cdrom_device_info *cdi, |
2460 | unsigned long arg) | 2479 | unsigned long arg) |
2461 | { | 2480 | { |
2462 | cdinfo(CD_DO_IOCTL, "%sabling debug.\n", arg ? "En" : "Dis"); | 2481 | cd_dbg(CD_DO_IOCTL, "%sabling debug\n", arg ? "En" : "Dis"); |
2463 | 2482 | ||
2464 | if (!capable(CAP_SYS_ADMIN)) | 2483 | if (!capable(CAP_SYS_ADMIN)) |
2465 | return -EACCES; | 2484 | return -EACCES; |
@@ -2469,7 +2488,7 @@ static int cdrom_ioctl_debug(struct cdrom_device_info *cdi, | |||
2469 | 2488 | ||
2470 | static int cdrom_ioctl_get_capability(struct cdrom_device_info *cdi) | 2489 | static int cdrom_ioctl_get_capability(struct cdrom_device_info *cdi) |
2471 | { | 2490 | { |
2472 | cdinfo(CD_DO_IOCTL, "entering CDROM_GET_CAPABILITY\n"); | 2491 | cd_dbg(CD_DO_IOCTL, "entering CDROM_GET_CAPABILITY\n"); |
2473 | return (cdi->ops->capability & ~cdi->mask); | 2492 | return (cdi->ops->capability & ~cdi->mask); |
2474 | } | 2493 | } |
2475 | 2494 | ||
@@ -2485,7 +2504,7 @@ static int cdrom_ioctl_get_mcn(struct cdrom_device_info *cdi, | |||
2485 | struct cdrom_mcn mcn; | 2504 | struct cdrom_mcn mcn; |
2486 | int ret; | 2505 | int ret; |
2487 | 2506 | ||
2488 | cdinfo(CD_DO_IOCTL, "entering CDROM_GET_MCN\n"); | 2507 | cd_dbg(CD_DO_IOCTL, "entering CDROM_GET_MCN\n"); |
2489 | 2508 | ||
2490 | if (!(cdi->ops->capability & CDC_MCN)) | 2509 | if (!(cdi->ops->capability & CDC_MCN)) |
2491 | return -ENOSYS; | 2510 | return -ENOSYS; |
@@ -2495,14 +2514,14 @@ static int cdrom_ioctl_get_mcn(struct cdrom_device_info *cdi, | |||
2495 | 2514 | ||
2496 | if (copy_to_user(argp, &mcn, sizeof(mcn))) | 2515 | if (copy_to_user(argp, &mcn, sizeof(mcn))) |
2497 | return -EFAULT; | 2516 | return -EFAULT; |
2498 | cdinfo(CD_DO_IOCTL, "CDROM_GET_MCN successful\n"); | 2517 | cd_dbg(CD_DO_IOCTL, "CDROM_GET_MCN successful\n"); |
2499 | return 0; | 2518 | return 0; |
2500 | } | 2519 | } |
2501 | 2520 | ||
2502 | static int cdrom_ioctl_drive_status(struct cdrom_device_info *cdi, | 2521 | static int cdrom_ioctl_drive_status(struct cdrom_device_info *cdi, |
2503 | unsigned long arg) | 2522 | unsigned long arg) |
2504 | { | 2523 | { |
2505 | cdinfo(CD_DO_IOCTL, "entering CDROM_DRIVE_STATUS\n"); | 2524 | cd_dbg(CD_DO_IOCTL, "entering CDROM_DRIVE_STATUS\n"); |
2506 | 2525 | ||
2507 | if (!(cdi->ops->capability & CDC_DRIVE_STATUS)) | 2526 | if (!(cdi->ops->capability & CDC_DRIVE_STATUS)) |
2508 | return -ENOSYS; | 2527 | return -ENOSYS; |
@@ -2535,7 +2554,7 @@ static int cdrom_ioctl_disc_status(struct cdrom_device_info *cdi) | |||
2535 | { | 2554 | { |
2536 | tracktype tracks; | 2555 | tracktype tracks; |
2537 | 2556 | ||
2538 | cdinfo(CD_DO_IOCTL, "entering CDROM_DISC_STATUS\n"); | 2557 | cd_dbg(CD_DO_IOCTL, "entering CDROM_DISC_STATUS\n"); |
2539 | 2558 | ||
2540 | cdrom_count_tracks(cdi, &tracks); | 2559 | cdrom_count_tracks(cdi, &tracks); |
2541 | if (tracks.error) | 2560 | if (tracks.error) |
@@ -2557,13 +2576,13 @@ static int cdrom_ioctl_disc_status(struct cdrom_device_info *cdi) | |||
2557 | return CDS_DATA_1; | 2576 | return CDS_DATA_1; |
2558 | /* Policy mode off */ | 2577 | /* Policy mode off */ |
2559 | 2578 | ||
2560 | cdinfo(CD_WARNING,"This disc doesn't have any tracks I recognize!\n"); | 2579 | cd_dbg(CD_WARNING, "This disc doesn't have any tracks I recognize!\n"); |
2561 | return CDS_NO_INFO; | 2580 | return CDS_NO_INFO; |
2562 | } | 2581 | } |
2563 | 2582 | ||
2564 | static int cdrom_ioctl_changer_nslots(struct cdrom_device_info *cdi) | 2583 | static int cdrom_ioctl_changer_nslots(struct cdrom_device_info *cdi) |
2565 | { | 2584 | { |
2566 | cdinfo(CD_DO_IOCTL, "entering CDROM_CHANGER_NSLOTS\n"); | 2585 | cd_dbg(CD_DO_IOCTL, "entering CDROM_CHANGER_NSLOTS\n"); |
2567 | return cdi->capacity; | 2586 | return cdi->capacity; |
2568 | } | 2587 | } |
2569 | 2588 | ||
@@ -2574,7 +2593,7 @@ static int cdrom_ioctl_get_subchnl(struct cdrom_device_info *cdi, | |||
2574 | u8 requested, back; | 2593 | u8 requested, back; |
2575 | int ret; | 2594 | int ret; |
2576 | 2595 | ||
2577 | /* cdinfo(CD_DO_IOCTL,"entering CDROMSUBCHNL\n");*/ | 2596 | /* cd_dbg(CD_DO_IOCTL,"entering CDROMSUBCHNL\n");*/ |
2578 | 2597 | ||
2579 | if (copy_from_user(&q, argp, sizeof(q))) | 2598 | if (copy_from_user(&q, argp, sizeof(q))) |
2580 | return -EFAULT; | 2599 | return -EFAULT; |
@@ -2594,7 +2613,7 @@ static int cdrom_ioctl_get_subchnl(struct cdrom_device_info *cdi, | |||
2594 | 2613 | ||
2595 | if (copy_to_user(argp, &q, sizeof(q))) | 2614 | if (copy_to_user(argp, &q, sizeof(q))) |
2596 | return -EFAULT; | 2615 | return -EFAULT; |
2597 | /* cdinfo(CD_DO_IOCTL, "CDROMSUBCHNL successful\n"); */ | 2616 | /* cd_dbg(CD_DO_IOCTL, "CDROMSUBCHNL successful\n"); */ |
2598 | return 0; | 2617 | return 0; |
2599 | } | 2618 | } |
2600 | 2619 | ||
@@ -2604,7 +2623,7 @@ static int cdrom_ioctl_read_tochdr(struct cdrom_device_info *cdi, | |||
2604 | struct cdrom_tochdr header; | 2623 | struct cdrom_tochdr header; |
2605 | int ret; | 2624 | int ret; |
2606 | 2625 | ||
2607 | /* cdinfo(CD_DO_IOCTL, "entering CDROMREADTOCHDR\n"); */ | 2626 | /* cd_dbg(CD_DO_IOCTL, "entering CDROMREADTOCHDR\n"); */ |
2608 | 2627 | ||
2609 | if (copy_from_user(&header, argp, sizeof(header))) | 2628 | if (copy_from_user(&header, argp, sizeof(header))) |
2610 | return -EFAULT; | 2629 | return -EFAULT; |
@@ -2615,7 +2634,7 @@ static int cdrom_ioctl_read_tochdr(struct cdrom_device_info *cdi, | |||
2615 | 2634 | ||
2616 | if (copy_to_user(argp, &header, sizeof(header))) | 2635 | if (copy_to_user(argp, &header, sizeof(header))) |
2617 | return -EFAULT; | 2636 | return -EFAULT; |
2618 | /* cdinfo(CD_DO_IOCTL, "CDROMREADTOCHDR successful\n"); */ | 2637 | /* cd_dbg(CD_DO_IOCTL, "CDROMREADTOCHDR successful\n"); */ |
2619 | return 0; | 2638 | return 0; |
2620 | } | 2639 | } |
2621 | 2640 | ||
@@ -2626,7 +2645,7 @@ static int cdrom_ioctl_read_tocentry(struct cdrom_device_info *cdi, | |||
2626 | u8 requested_format; | 2645 | u8 requested_format; |
2627 | int ret; | 2646 | int ret; |
2628 | 2647 | ||
2629 | /* cdinfo(CD_DO_IOCTL, "entering CDROMREADTOCENTRY\n"); */ | 2648 | /* cd_dbg(CD_DO_IOCTL, "entering CDROMREADTOCENTRY\n"); */ |
2630 | 2649 | ||
2631 | if (copy_from_user(&entry, argp, sizeof(entry))) | 2650 | if (copy_from_user(&entry, argp, sizeof(entry))) |
2632 | return -EFAULT; | 2651 | return -EFAULT; |
@@ -2643,7 +2662,7 @@ static int cdrom_ioctl_read_tocentry(struct cdrom_device_info *cdi, | |||
2643 | 2662 | ||
2644 | if (copy_to_user(argp, &entry, sizeof(entry))) | 2663 | if (copy_to_user(argp, &entry, sizeof(entry))) |
2645 | return -EFAULT; | 2664 | return -EFAULT; |
2646 | /* cdinfo(CD_DO_IOCTL, "CDROMREADTOCENTRY successful\n"); */ | 2665 | /* cd_dbg(CD_DO_IOCTL, "CDROMREADTOCENTRY successful\n"); */ |
2647 | return 0; | 2666 | return 0; |
2648 | } | 2667 | } |
2649 | 2668 | ||
@@ -2652,7 +2671,7 @@ static int cdrom_ioctl_play_msf(struct cdrom_device_info *cdi, | |||
2652 | { | 2671 | { |
2653 | struct cdrom_msf msf; | 2672 | struct cdrom_msf msf; |
2654 | 2673 | ||
2655 | cdinfo(CD_DO_IOCTL, "entering CDROMPLAYMSF\n"); | 2674 | cd_dbg(CD_DO_IOCTL, "entering CDROMPLAYMSF\n"); |
2656 | 2675 | ||
2657 | if (!CDROM_CAN(CDC_PLAY_AUDIO)) | 2676 | if (!CDROM_CAN(CDC_PLAY_AUDIO)) |
2658 | return -ENOSYS; | 2677 | return -ENOSYS; |
@@ -2667,7 +2686,7 @@ static int cdrom_ioctl_play_trkind(struct cdrom_device_info *cdi, | |||
2667 | struct cdrom_ti ti; | 2686 | struct cdrom_ti ti; |
2668 | int ret; | 2687 | int ret; |
2669 | 2688 | ||
2670 | cdinfo(CD_DO_IOCTL, "entering CDROMPLAYTRKIND\n"); | 2689 | cd_dbg(CD_DO_IOCTL, "entering CDROMPLAYTRKIND\n"); |
2671 | 2690 | ||
2672 | if (!CDROM_CAN(CDC_PLAY_AUDIO)) | 2691 | if (!CDROM_CAN(CDC_PLAY_AUDIO)) |
2673 | return -ENOSYS; | 2692 | return -ENOSYS; |
@@ -2684,7 +2703,7 @@ static int cdrom_ioctl_volctrl(struct cdrom_device_info *cdi, | |||
2684 | { | 2703 | { |
2685 | struct cdrom_volctrl volume; | 2704 | struct cdrom_volctrl volume; |
2686 | 2705 | ||
2687 | cdinfo(CD_DO_IOCTL, "entering CDROMVOLCTRL\n"); | 2706 | cd_dbg(CD_DO_IOCTL, "entering CDROMVOLCTRL\n"); |
2688 | 2707 | ||
2689 | if (!CDROM_CAN(CDC_PLAY_AUDIO)) | 2708 | if (!CDROM_CAN(CDC_PLAY_AUDIO)) |
2690 | return -ENOSYS; | 2709 | return -ENOSYS; |
@@ -2699,7 +2718,7 @@ static int cdrom_ioctl_volread(struct cdrom_device_info *cdi, | |||
2699 | struct cdrom_volctrl volume; | 2718 | struct cdrom_volctrl volume; |
2700 | int ret; | 2719 | int ret; |
2701 | 2720 | ||
2702 | cdinfo(CD_DO_IOCTL, "entering CDROMVOLREAD\n"); | 2721 | cd_dbg(CD_DO_IOCTL, "entering CDROMVOLREAD\n"); |
2703 | 2722 | ||
2704 | if (!CDROM_CAN(CDC_PLAY_AUDIO)) | 2723 | if (!CDROM_CAN(CDC_PLAY_AUDIO)) |
2705 | return -ENOSYS; | 2724 | return -ENOSYS; |
@@ -2718,7 +2737,7 @@ static int cdrom_ioctl_audioctl(struct cdrom_device_info *cdi, | |||
2718 | { | 2737 | { |
2719 | int ret; | 2738 | int ret; |
2720 | 2739 | ||
2721 | cdinfo(CD_DO_IOCTL, "doing audio ioctl (start/stop/pause/resume)\n"); | 2740 | cd_dbg(CD_DO_IOCTL, "doing audio ioctl (start/stop/pause/resume)\n"); |
2722 | 2741 | ||
2723 | if (!CDROM_CAN(CDC_PLAY_AUDIO)) | 2742 | if (!CDROM_CAN(CDC_PLAY_AUDIO)) |
2724 | return -ENOSYS; | 2743 | return -ENOSYS; |
@@ -2729,103 +2748,6 @@ static int cdrom_ioctl_audioctl(struct cdrom_device_info *cdi, | |||
2729 | } | 2748 | } |
2730 | 2749 | ||
2731 | /* | 2750 | /* |
2732 | * Just about every imaginable ioctl is supported in the Uniform layer | ||
2733 | * these days. | ||
2734 | * ATAPI / SCSI specific code now mainly resides in mmc_ioctl(). | ||
2735 | */ | ||
2736 | int cdrom_ioctl(struct cdrom_device_info *cdi, struct block_device *bdev, | ||
2737 | fmode_t mode, unsigned int cmd, unsigned long arg) | ||
2738 | { | ||
2739 | void __user *argp = (void __user *)arg; | ||
2740 | int ret; | ||
2741 | |||
2742 | /* | ||
2743 | * Try the generic SCSI command ioctl's first. | ||
2744 | */ | ||
2745 | ret = scsi_cmd_blk_ioctl(bdev, mode, cmd, argp); | ||
2746 | if (ret != -ENOTTY) | ||
2747 | return ret; | ||
2748 | |||
2749 | switch (cmd) { | ||
2750 | case CDROMMULTISESSION: | ||
2751 | return cdrom_ioctl_multisession(cdi, argp); | ||
2752 | case CDROMEJECT: | ||
2753 | return cdrom_ioctl_eject(cdi); | ||
2754 | case CDROMCLOSETRAY: | ||
2755 | return cdrom_ioctl_closetray(cdi); | ||
2756 | case CDROMEJECT_SW: | ||
2757 | return cdrom_ioctl_eject_sw(cdi, arg); | ||
2758 | case CDROM_MEDIA_CHANGED: | ||
2759 | return cdrom_ioctl_media_changed(cdi, arg); | ||
2760 | case CDROM_SET_OPTIONS: | ||
2761 | return cdrom_ioctl_set_options(cdi, arg); | ||
2762 | case CDROM_CLEAR_OPTIONS: | ||
2763 | return cdrom_ioctl_clear_options(cdi, arg); | ||
2764 | case CDROM_SELECT_SPEED: | ||
2765 | return cdrom_ioctl_select_speed(cdi, arg); | ||
2766 | case CDROM_SELECT_DISC: | ||
2767 | return cdrom_ioctl_select_disc(cdi, arg); | ||
2768 | case CDROMRESET: | ||
2769 | return cdrom_ioctl_reset(cdi, bdev); | ||
2770 | case CDROM_LOCKDOOR: | ||
2771 | return cdrom_ioctl_lock_door(cdi, arg); | ||
2772 | case CDROM_DEBUG: | ||
2773 | return cdrom_ioctl_debug(cdi, arg); | ||
2774 | case CDROM_GET_CAPABILITY: | ||
2775 | return cdrom_ioctl_get_capability(cdi); | ||
2776 | case CDROM_GET_MCN: | ||
2777 | return cdrom_ioctl_get_mcn(cdi, argp); | ||
2778 | case CDROM_DRIVE_STATUS: | ||
2779 | return cdrom_ioctl_drive_status(cdi, arg); | ||
2780 | case CDROM_DISC_STATUS: | ||
2781 | return cdrom_ioctl_disc_status(cdi); | ||
2782 | case CDROM_CHANGER_NSLOTS: | ||
2783 | return cdrom_ioctl_changer_nslots(cdi); | ||
2784 | } | ||
2785 | |||
2786 | /* | ||
2787 | * Use the ioctls that are implemented through the generic_packet() | ||
2788 | * interface. this may look at bit funny, but if -ENOTTY is | ||
2789 | * returned that particular ioctl is not implemented and we | ||
2790 | * let it go through the device specific ones. | ||
2791 | */ | ||
2792 | if (CDROM_CAN(CDC_GENERIC_PACKET)) { | ||
2793 | ret = mmc_ioctl(cdi, cmd, arg); | ||
2794 | if (ret != -ENOTTY) | ||
2795 | return ret; | ||
2796 | } | ||
2797 | |||
2798 | /* | ||
2799 | * Note: most of the cdinfo() calls are commented out here, | ||
2800 | * because they fill up the sys log when CD players poll | ||
2801 | * the drive. | ||
2802 | */ | ||
2803 | switch (cmd) { | ||
2804 | case CDROMSUBCHNL: | ||
2805 | return cdrom_ioctl_get_subchnl(cdi, argp); | ||
2806 | case CDROMREADTOCHDR: | ||
2807 | return cdrom_ioctl_read_tochdr(cdi, argp); | ||
2808 | case CDROMREADTOCENTRY: | ||
2809 | return cdrom_ioctl_read_tocentry(cdi, argp); | ||
2810 | case CDROMPLAYMSF: | ||
2811 | return cdrom_ioctl_play_msf(cdi, argp); | ||
2812 | case CDROMPLAYTRKIND: | ||
2813 | return cdrom_ioctl_play_trkind(cdi, argp); | ||
2814 | case CDROMVOLCTRL: | ||
2815 | return cdrom_ioctl_volctrl(cdi, argp); | ||
2816 | case CDROMVOLREAD: | ||
2817 | return cdrom_ioctl_volread(cdi, argp); | ||
2818 | case CDROMSTART: | ||
2819 | case CDROMSTOP: | ||
2820 | case CDROMPAUSE: | ||
2821 | case CDROMRESUME: | ||
2822 | return cdrom_ioctl_audioctl(cdi, cmd); | ||
2823 | } | ||
2824 | |||
2825 | return -ENOSYS; | ||
2826 | } | ||
2827 | |||
2828 | /* | ||
2829 | * Required when we need to use READ_10 to issue other than 2048 block | 2751 | * Required when we need to use READ_10 to issue other than 2048 block |
2830 | * reads | 2752 | * reads |
2831 | */ | 2753 | */ |
@@ -2854,10 +2776,158 @@ static int cdrom_switch_blocksize(struct cdrom_device_info *cdi, int size) | |||
2854 | return cdo->generic_packet(cdi, &cgc); | 2776 | return cdo->generic_packet(cdi, &cgc); |
2855 | } | 2777 | } |
2856 | 2778 | ||
2779 | static int cdrom_get_track_info(struct cdrom_device_info *cdi, | ||
2780 | __u16 track, __u8 type, track_information *ti) | ||
2781 | { | ||
2782 | struct cdrom_device_ops *cdo = cdi->ops; | ||
2783 | struct packet_command cgc; | ||
2784 | int ret, buflen; | ||
2785 | |||
2786 | init_cdrom_command(&cgc, ti, 8, CGC_DATA_READ); | ||
2787 | cgc.cmd[0] = GPCMD_READ_TRACK_RZONE_INFO; | ||
2788 | cgc.cmd[1] = type & 3; | ||
2789 | cgc.cmd[4] = (track & 0xff00) >> 8; | ||
2790 | cgc.cmd[5] = track & 0xff; | ||
2791 | cgc.cmd[8] = 8; | ||
2792 | cgc.quiet = 1; | ||
2793 | |||
2794 | ret = cdo->generic_packet(cdi, &cgc); | ||
2795 | if (ret) | ||
2796 | return ret; | ||
2797 | |||
2798 | buflen = be16_to_cpu(ti->track_information_length) + | ||
2799 | sizeof(ti->track_information_length); | ||
2800 | |||
2801 | if (buflen > sizeof(track_information)) | ||
2802 | buflen = sizeof(track_information); | ||
2803 | |||
2804 | cgc.cmd[8] = cgc.buflen = buflen; | ||
2805 | ret = cdo->generic_packet(cdi, &cgc); | ||
2806 | if (ret) | ||
2807 | return ret; | ||
2808 | |||
2809 | /* return actual fill size */ | ||
2810 | return buflen; | ||
2811 | } | ||
2812 | |||
2813 | /* return the last written block on the CD-R media. this is for the udf | ||
2814 | file system. */ | ||
2815 | int cdrom_get_last_written(struct cdrom_device_info *cdi, long *last_written) | ||
2816 | { | ||
2817 | struct cdrom_tocentry toc; | ||
2818 | disc_information di; | ||
2819 | track_information ti; | ||
2820 | __u32 last_track; | ||
2821 | int ret = -1, ti_size; | ||
2822 | |||
2823 | if (!CDROM_CAN(CDC_GENERIC_PACKET)) | ||
2824 | goto use_toc; | ||
2825 | |||
2826 | ret = cdrom_get_disc_info(cdi, &di); | ||
2827 | if (ret < (int)(offsetof(typeof(di), last_track_lsb) | ||
2828 | + sizeof(di.last_track_lsb))) | ||
2829 | goto use_toc; | ||
2830 | |||
2831 | /* if unit didn't return msb, it's zeroed by cdrom_get_disc_info */ | ||
2832 | last_track = (di.last_track_msb << 8) | di.last_track_lsb; | ||
2833 | ti_size = cdrom_get_track_info(cdi, last_track, 1, &ti); | ||
2834 | if (ti_size < (int)offsetof(typeof(ti), track_start)) | ||
2835 | goto use_toc; | ||
2836 | |||
2837 | /* if this track is blank, try the previous. */ | ||
2838 | if (ti.blank) { | ||
2839 | if (last_track == 1) | ||
2840 | goto use_toc; | ||
2841 | last_track--; | ||
2842 | ti_size = cdrom_get_track_info(cdi, last_track, 1, &ti); | ||
2843 | } | ||
2844 | |||
2845 | if (ti_size < (int)(offsetof(typeof(ti), track_size) | ||
2846 | + sizeof(ti.track_size))) | ||
2847 | goto use_toc; | ||
2848 | |||
2849 | /* if last recorded field is valid, return it. */ | ||
2850 | if (ti.lra_v && ti_size >= (int)(offsetof(typeof(ti), last_rec_address) | ||
2851 | + sizeof(ti.last_rec_address))) { | ||
2852 | *last_written = be32_to_cpu(ti.last_rec_address); | ||
2853 | } else { | ||
2854 | /* make it up instead */ | ||
2855 | *last_written = be32_to_cpu(ti.track_start) + | ||
2856 | be32_to_cpu(ti.track_size); | ||
2857 | if (ti.free_blocks) | ||
2858 | *last_written -= (be32_to_cpu(ti.free_blocks) + 7); | ||
2859 | } | ||
2860 | return 0; | ||
2861 | |||
2862 | /* this is where we end up if the drive either can't do a | ||
2863 | GPCMD_READ_DISC_INFO or GPCMD_READ_TRACK_RZONE_INFO or if | ||
2864 | it doesn't give enough information or fails. then we return | ||
2865 | the toc contents. */ | ||
2866 | use_toc: | ||
2867 | toc.cdte_format = CDROM_MSF; | ||
2868 | toc.cdte_track = CDROM_LEADOUT; | ||
2869 | if ((ret = cdi->ops->audio_ioctl(cdi, CDROMREADTOCENTRY, &toc))) | ||
2870 | return ret; | ||
2871 | sanitize_format(&toc.cdte_addr, &toc.cdte_format, CDROM_LBA); | ||
2872 | *last_written = toc.cdte_addr.lba; | ||
2873 | return 0; | ||
2874 | } | ||
2875 | |||
2876 | /* return the next writable block. also for udf file system. */ | ||
2877 | static int cdrom_get_next_writable(struct cdrom_device_info *cdi, | ||
2878 | long *next_writable) | ||
2879 | { | ||
2880 | disc_information di; | ||
2881 | track_information ti; | ||
2882 | __u16 last_track; | ||
2883 | int ret, ti_size; | ||
2884 | |||
2885 | if (!CDROM_CAN(CDC_GENERIC_PACKET)) | ||
2886 | goto use_last_written; | ||
2887 | |||
2888 | ret = cdrom_get_disc_info(cdi, &di); | ||
2889 | if (ret < 0 || ret < offsetof(typeof(di), last_track_lsb) | ||
2890 | + sizeof(di.last_track_lsb)) | ||
2891 | goto use_last_written; | ||
2892 | |||
2893 | /* if unit didn't return msb, it's zeroed by cdrom_get_disc_info */ | ||
2894 | last_track = (di.last_track_msb << 8) | di.last_track_lsb; | ||
2895 | ti_size = cdrom_get_track_info(cdi, last_track, 1, &ti); | ||
2896 | if (ti_size < 0 || ti_size < offsetof(typeof(ti), track_start)) | ||
2897 | goto use_last_written; | ||
2898 | |||
2899 | /* if this track is blank, try the previous. */ | ||
2900 | if (ti.blank) { | ||
2901 | if (last_track == 1) | ||
2902 | goto use_last_written; | ||
2903 | last_track--; | ||
2904 | ti_size = cdrom_get_track_info(cdi, last_track, 1, &ti); | ||
2905 | if (ti_size < 0) | ||
2906 | goto use_last_written; | ||
2907 | } | ||
2908 | |||
2909 | /* if next recordable address field is valid, use it. */ | ||
2910 | if (ti.nwa_v && ti_size >= offsetof(typeof(ti), next_writable) | ||
2911 | + sizeof(ti.next_writable)) { | ||
2912 | *next_writable = be32_to_cpu(ti.next_writable); | ||
2913 | return 0; | ||
2914 | } | ||
2915 | |||
2916 | use_last_written: | ||
2917 | ret = cdrom_get_last_written(cdi, next_writable); | ||
2918 | if (ret) { | ||
2919 | *next_writable = 0; | ||
2920 | return ret; | ||
2921 | } else { | ||
2922 | *next_writable += 7; | ||
2923 | return 0; | ||
2924 | } | ||
2925 | } | ||
2926 | |||
2857 | static noinline int mmc_ioctl_cdrom_read_data(struct cdrom_device_info *cdi, | 2927 | static noinline int mmc_ioctl_cdrom_read_data(struct cdrom_device_info *cdi, |
2858 | void __user *arg, | 2928 | void __user *arg, |
2859 | struct packet_command *cgc, | 2929 | struct packet_command *cgc, |
2860 | int cmd) | 2930 | int cmd) |
2861 | { | 2931 | { |
2862 | struct request_sense sense; | 2932 | struct request_sense sense; |
2863 | struct cdrom_msf msf; | 2933 | struct cdrom_msf msf; |
@@ -2876,7 +2946,8 @@ static noinline int mmc_ioctl_cdrom_read_data(struct cdrom_device_info *cdi, | |||
2876 | blocksize = CD_FRAMESIZE_RAW0; | 2946 | blocksize = CD_FRAMESIZE_RAW0; |
2877 | break; | 2947 | break; |
2878 | } | 2948 | } |
2879 | IOCTL_IN(arg, struct cdrom_msf, msf); | 2949 | if (copy_from_user(&msf, (struct cdrom_msf __user *)arg, sizeof(msf))) |
2950 | return -EFAULT; | ||
2880 | lba = msf_to_lba(msf.cdmsf_min0, msf.cdmsf_sec0, msf.cdmsf_frame0); | 2951 | lba = msf_to_lba(msf.cdmsf_min0, msf.cdmsf_sec0, msf.cdmsf_frame0); |
2881 | /* FIXME: we need upper bound checking, too!! */ | 2952 | /* FIXME: we need upper bound checking, too!! */ |
2882 | if (lba < 0) | 2953 | if (lba < 0) |
@@ -2891,8 +2962,8 @@ static noinline int mmc_ioctl_cdrom_read_data(struct cdrom_device_info *cdi, | |||
2891 | cgc->data_direction = CGC_DATA_READ; | 2962 | cgc->data_direction = CGC_DATA_READ; |
2892 | ret = cdrom_read_block(cdi, cgc, lba, 1, format, blocksize); | 2963 | ret = cdrom_read_block(cdi, cgc, lba, 1, format, blocksize); |
2893 | if (ret && sense.sense_key == 0x05 && | 2964 | if (ret && sense.sense_key == 0x05 && |
2894 | sense.asc == 0x20 && | 2965 | sense.asc == 0x20 && |
2895 | sense.ascq == 0x00) { | 2966 | sense.ascq == 0x00) { |
2896 | /* | 2967 | /* |
2897 | * SCSI-II devices are not required to support | 2968 | * SCSI-II devices are not required to support |
2898 | * READ_CD, so let's try switching block size | 2969 | * READ_CD, so let's try switching block size |
@@ -2913,12 +2984,14 @@ out: | |||
2913 | } | 2984 | } |
2914 | 2985 | ||
2915 | static noinline int mmc_ioctl_cdrom_read_audio(struct cdrom_device_info *cdi, | 2986 | static noinline int mmc_ioctl_cdrom_read_audio(struct cdrom_device_info *cdi, |
2916 | void __user *arg) | 2987 | void __user *arg) |
2917 | { | 2988 | { |
2918 | struct cdrom_read_audio ra; | 2989 | struct cdrom_read_audio ra; |
2919 | int lba; | 2990 | int lba; |
2920 | 2991 | ||
2921 | IOCTL_IN(arg, struct cdrom_read_audio, ra); | 2992 | if (copy_from_user(&ra, (struct cdrom_read_audio __user *)arg, |
2993 | sizeof(ra))) | ||
2994 | return -EFAULT; | ||
2922 | 2995 | ||
2923 | if (ra.addr_format == CDROM_MSF) | 2996 | if (ra.addr_format == CDROM_MSF) |
2924 | lba = msf_to_lba(ra.addr.msf.minute, | 2997 | lba = msf_to_lba(ra.addr.msf.minute, |
@@ -2937,12 +3010,13 @@ static noinline int mmc_ioctl_cdrom_read_audio(struct cdrom_device_info *cdi, | |||
2937 | } | 3010 | } |
2938 | 3011 | ||
2939 | static noinline int mmc_ioctl_cdrom_subchannel(struct cdrom_device_info *cdi, | 3012 | static noinline int mmc_ioctl_cdrom_subchannel(struct cdrom_device_info *cdi, |
2940 | void __user *arg) | 3013 | void __user *arg) |
2941 | { | 3014 | { |
2942 | int ret; | 3015 | int ret; |
2943 | struct cdrom_subchnl q; | 3016 | struct cdrom_subchnl q; |
2944 | u_char requested, back; | 3017 | u_char requested, back; |
2945 | IOCTL_IN(arg, struct cdrom_subchnl, q); | 3018 | if (copy_from_user(&q, (struct cdrom_subchnl __user *)arg, sizeof(q))) |
3019 | return -EFAULT; | ||
2946 | requested = q.cdsc_format; | 3020 | requested = q.cdsc_format; |
2947 | if (!((requested == CDROM_MSF) || | 3021 | if (!((requested == CDROM_MSF) || |
2948 | (requested == CDROM_LBA))) | 3022 | (requested == CDROM_LBA))) |
@@ -2954,19 +3028,21 @@ static noinline int mmc_ioctl_cdrom_subchannel(struct cdrom_device_info *cdi, | |||
2954 | back = q.cdsc_format; /* local copy */ | 3028 | back = q.cdsc_format; /* local copy */ |
2955 | sanitize_format(&q.cdsc_absaddr, &back, requested); | 3029 | sanitize_format(&q.cdsc_absaddr, &back, requested); |
2956 | sanitize_format(&q.cdsc_reladdr, &q.cdsc_format, requested); | 3030 | sanitize_format(&q.cdsc_reladdr, &q.cdsc_format, requested); |
2957 | IOCTL_OUT(arg, struct cdrom_subchnl, q); | 3031 | if (copy_to_user((struct cdrom_subchnl __user *)arg, &q, sizeof(q))) |
2958 | /* cdinfo(CD_DO_IOCTL, "CDROMSUBCHNL successful\n"); */ | 3032 | return -EFAULT; |
3033 | /* cd_dbg(CD_DO_IOCTL, "CDROMSUBCHNL successful\n"); */ | ||
2959 | return 0; | 3034 | return 0; |
2960 | } | 3035 | } |
2961 | 3036 | ||
2962 | static noinline int mmc_ioctl_cdrom_play_msf(struct cdrom_device_info *cdi, | 3037 | static noinline int mmc_ioctl_cdrom_play_msf(struct cdrom_device_info *cdi, |
2963 | void __user *arg, | 3038 | void __user *arg, |
2964 | struct packet_command *cgc) | 3039 | struct packet_command *cgc) |
2965 | { | 3040 | { |
2966 | struct cdrom_device_ops *cdo = cdi->ops; | 3041 | struct cdrom_device_ops *cdo = cdi->ops; |
2967 | struct cdrom_msf msf; | 3042 | struct cdrom_msf msf; |
2968 | cdinfo(CD_DO_IOCTL, "entering CDROMPLAYMSF\n"); | 3043 | cd_dbg(CD_DO_IOCTL, "entering CDROMPLAYMSF\n"); |
2969 | IOCTL_IN(arg, struct cdrom_msf, msf); | 3044 | if (copy_from_user(&msf, (struct cdrom_msf __user *)arg, sizeof(msf))) |
3045 | return -EFAULT; | ||
2970 | cgc->cmd[0] = GPCMD_PLAY_AUDIO_MSF; | 3046 | cgc->cmd[0] = GPCMD_PLAY_AUDIO_MSF; |
2971 | cgc->cmd[3] = msf.cdmsf_min0; | 3047 | cgc->cmd[3] = msf.cdmsf_min0; |
2972 | cgc->cmd[4] = msf.cdmsf_sec0; | 3048 | cgc->cmd[4] = msf.cdmsf_sec0; |
@@ -2979,13 +3055,14 @@ static noinline int mmc_ioctl_cdrom_play_msf(struct cdrom_device_info *cdi, | |||
2979 | } | 3055 | } |
2980 | 3056 | ||
2981 | static noinline int mmc_ioctl_cdrom_play_blk(struct cdrom_device_info *cdi, | 3057 | static noinline int mmc_ioctl_cdrom_play_blk(struct cdrom_device_info *cdi, |
2982 | void __user *arg, | 3058 | void __user *arg, |
2983 | struct packet_command *cgc) | 3059 | struct packet_command *cgc) |
2984 | { | 3060 | { |
2985 | struct cdrom_device_ops *cdo = cdi->ops; | 3061 | struct cdrom_device_ops *cdo = cdi->ops; |
2986 | struct cdrom_blk blk; | 3062 | struct cdrom_blk blk; |
2987 | cdinfo(CD_DO_IOCTL, "entering CDROMPLAYBLK\n"); | 3063 | cd_dbg(CD_DO_IOCTL, "entering CDROMPLAYBLK\n"); |
2988 | IOCTL_IN(arg, struct cdrom_blk, blk); | 3064 | if (copy_from_user(&blk, (struct cdrom_blk __user *)arg, sizeof(blk))) |
3065 | return -EFAULT; | ||
2989 | cgc->cmd[0] = GPCMD_PLAY_AUDIO_10; | 3066 | cgc->cmd[0] = GPCMD_PLAY_AUDIO_10; |
2990 | cgc->cmd[2] = (blk.from >> 24) & 0xff; | 3067 | cgc->cmd[2] = (blk.from >> 24) & 0xff; |
2991 | cgc->cmd[3] = (blk.from >> 16) & 0xff; | 3068 | cgc->cmd[3] = (blk.from >> 16) & 0xff; |
@@ -2998,9 +3075,9 @@ static noinline int mmc_ioctl_cdrom_play_blk(struct cdrom_device_info *cdi, | |||
2998 | } | 3075 | } |
2999 | 3076 | ||
3000 | static noinline int mmc_ioctl_cdrom_volume(struct cdrom_device_info *cdi, | 3077 | static noinline int mmc_ioctl_cdrom_volume(struct cdrom_device_info *cdi, |
3001 | void __user *arg, | 3078 | void __user *arg, |
3002 | struct packet_command *cgc, | 3079 | struct packet_command *cgc, |
3003 | unsigned int cmd) | 3080 | unsigned int cmd) |
3004 | { | 3081 | { |
3005 | struct cdrom_volctrl volctrl; | 3082 | struct cdrom_volctrl volctrl; |
3006 | unsigned char buffer[32]; | 3083 | unsigned char buffer[32]; |
@@ -3008,9 +3085,11 @@ static noinline int mmc_ioctl_cdrom_volume(struct cdrom_device_info *cdi, | |||
3008 | unsigned short offset; | 3085 | unsigned short offset; |
3009 | int ret; | 3086 | int ret; |
3010 | 3087 | ||
3011 | cdinfo(CD_DO_IOCTL, "entering CDROMVOLUME\n"); | 3088 | cd_dbg(CD_DO_IOCTL, "entering CDROMVOLUME\n"); |
3012 | 3089 | ||
3013 | IOCTL_IN(arg, struct cdrom_volctrl, volctrl); | 3090 | if (copy_from_user(&volctrl, (struct cdrom_volctrl __user *)arg, |
3091 | sizeof(volctrl))) | ||
3092 | return -EFAULT; | ||
3014 | 3093 | ||
3015 | cgc->buffer = buffer; | 3094 | cgc->buffer = buffer; |
3016 | cgc->buflen = 24; | 3095 | cgc->buflen = 24; |
@@ -3030,14 +3109,14 @@ static noinline int mmc_ioctl_cdrom_volume(struct cdrom_device_info *cdi, | |||
3030 | if (offset + 16 > cgc->buflen) { | 3109 | if (offset + 16 > cgc->buflen) { |
3031 | cgc->buflen = offset + 16; | 3110 | cgc->buflen = offset + 16; |
3032 | ret = cdrom_mode_sense(cdi, cgc, | 3111 | ret = cdrom_mode_sense(cdi, cgc, |
3033 | GPMODE_AUDIO_CTL_PAGE, 0); | 3112 | GPMODE_AUDIO_CTL_PAGE, 0); |
3034 | if (ret) | 3113 | if (ret) |
3035 | return ret; | 3114 | return ret; |
3036 | } | 3115 | } |
3037 | 3116 | ||
3038 | /* sanity check */ | 3117 | /* sanity check */ |
3039 | if ((buffer[offset] & 0x3f) != GPMODE_AUDIO_CTL_PAGE || | 3118 | if ((buffer[offset] & 0x3f) != GPMODE_AUDIO_CTL_PAGE || |
3040 | buffer[offset + 1] < 14) | 3119 | buffer[offset + 1] < 14) |
3041 | return -EINVAL; | 3120 | return -EINVAL; |
3042 | 3121 | ||
3043 | /* now we have the current volume settings. if it was only | 3122 | /* now we have the current volume settings. if it was only |
@@ -3047,7 +3126,9 @@ static noinline int mmc_ioctl_cdrom_volume(struct cdrom_device_info *cdi, | |||
3047 | volctrl.channel1 = buffer[offset+11]; | 3126 | volctrl.channel1 = buffer[offset+11]; |
3048 | volctrl.channel2 = buffer[offset+13]; | 3127 | volctrl.channel2 = buffer[offset+13]; |
3049 | volctrl.channel3 = buffer[offset+15]; | 3128 | volctrl.channel3 = buffer[offset+15]; |
3050 | IOCTL_OUT(arg, struct cdrom_volctrl, volctrl); | 3129 | if (copy_to_user((struct cdrom_volctrl __user *)arg, &volctrl, |
3130 | sizeof(volctrl))) | ||
3131 | return -EFAULT; | ||
3051 | return 0; | 3132 | return 0; |
3052 | } | 3133 | } |
3053 | 3134 | ||
@@ -3069,11 +3150,11 @@ static noinline int mmc_ioctl_cdrom_volume(struct cdrom_device_info *cdi, | |||
3069 | } | 3150 | } |
3070 | 3151 | ||
3071 | static noinline int mmc_ioctl_cdrom_start_stop(struct cdrom_device_info *cdi, | 3152 | static noinline int mmc_ioctl_cdrom_start_stop(struct cdrom_device_info *cdi, |
3072 | struct packet_command *cgc, | 3153 | struct packet_command *cgc, |
3073 | int cmd) | 3154 | int cmd) |
3074 | { | 3155 | { |
3075 | struct cdrom_device_ops *cdo = cdi->ops; | 3156 | struct cdrom_device_ops *cdo = cdi->ops; |
3076 | cdinfo(CD_DO_IOCTL, "entering CDROMSTART/CDROMSTOP\n"); | 3157 | cd_dbg(CD_DO_IOCTL, "entering CDROMSTART/CDROMSTOP\n"); |
3077 | cgc->cmd[0] = GPCMD_START_STOP_UNIT; | 3158 | cgc->cmd[0] = GPCMD_START_STOP_UNIT; |
3078 | cgc->cmd[1] = 1; | 3159 | cgc->cmd[1] = 1; |
3079 | cgc->cmd[4] = (cmd == CDROMSTART) ? 1 : 0; | 3160 | cgc->cmd[4] = (cmd == CDROMSTART) ? 1 : 0; |
@@ -3082,11 +3163,11 @@ static noinline int mmc_ioctl_cdrom_start_stop(struct cdrom_device_info *cdi, | |||
3082 | } | 3163 | } |
3083 | 3164 | ||
3084 | static noinline int mmc_ioctl_cdrom_pause_resume(struct cdrom_device_info *cdi, | 3165 | static noinline int mmc_ioctl_cdrom_pause_resume(struct cdrom_device_info *cdi, |
3085 | struct packet_command *cgc, | 3166 | struct packet_command *cgc, |
3086 | int cmd) | 3167 | int cmd) |
3087 | { | 3168 | { |
3088 | struct cdrom_device_ops *cdo = cdi->ops; | 3169 | struct cdrom_device_ops *cdo = cdi->ops; |
3089 | cdinfo(CD_DO_IOCTL, "entering CDROMPAUSE/CDROMRESUME\n"); | 3170 | cd_dbg(CD_DO_IOCTL, "entering CDROMPAUSE/CDROMRESUME\n"); |
3090 | cgc->cmd[0] = GPCMD_PAUSE_RESUME; | 3171 | cgc->cmd[0] = GPCMD_PAUSE_RESUME; |
3091 | cgc->cmd[8] = (cmd == CDROMRESUME) ? 1 : 0; | 3172 | cgc->cmd[8] = (cmd == CDROMRESUME) ? 1 : 0; |
3092 | cgc->data_direction = CGC_DATA_NONE; | 3173 | cgc->data_direction = CGC_DATA_NONE; |
@@ -3094,8 +3175,8 @@ static noinline int mmc_ioctl_cdrom_pause_resume(struct cdrom_device_info *cdi, | |||
3094 | } | 3175 | } |
3095 | 3176 | ||
3096 | static noinline int mmc_ioctl_dvd_read_struct(struct cdrom_device_info *cdi, | 3177 | static noinline int mmc_ioctl_dvd_read_struct(struct cdrom_device_info *cdi, |
3097 | void __user *arg, | 3178 | void __user *arg, |
3098 | struct packet_command *cgc) | 3179 | struct packet_command *cgc) |
3099 | { | 3180 | { |
3100 | int ret; | 3181 | int ret; |
3101 | dvd_struct *s; | 3182 | dvd_struct *s; |
@@ -3108,7 +3189,7 @@ static noinline int mmc_ioctl_dvd_read_struct(struct cdrom_device_info *cdi, | |||
3108 | if (!s) | 3189 | if (!s) |
3109 | return -ENOMEM; | 3190 | return -ENOMEM; |
3110 | 3191 | ||
3111 | cdinfo(CD_DO_IOCTL, "entering DVD_READ_STRUCT\n"); | 3192 | cd_dbg(CD_DO_IOCTL, "entering DVD_READ_STRUCT\n"); |
3112 | if (copy_from_user(s, arg, size)) { | 3193 | if (copy_from_user(s, arg, size)) { |
3113 | kfree(s); | 3194 | kfree(s); |
3114 | return -EFAULT; | 3195 | return -EFAULT; |
@@ -3126,44 +3207,48 @@ out: | |||
3126 | } | 3207 | } |
3127 | 3208 | ||
3128 | static noinline int mmc_ioctl_dvd_auth(struct cdrom_device_info *cdi, | 3209 | static noinline int mmc_ioctl_dvd_auth(struct cdrom_device_info *cdi, |
3129 | void __user *arg) | 3210 | void __user *arg) |
3130 | { | 3211 | { |
3131 | int ret; | 3212 | int ret; |
3132 | dvd_authinfo ai; | 3213 | dvd_authinfo ai; |
3133 | if (!CDROM_CAN(CDC_DVD)) | 3214 | if (!CDROM_CAN(CDC_DVD)) |
3134 | return -ENOSYS; | 3215 | return -ENOSYS; |
3135 | cdinfo(CD_DO_IOCTL, "entering DVD_AUTH\n"); | 3216 | cd_dbg(CD_DO_IOCTL, "entering DVD_AUTH\n"); |
3136 | IOCTL_IN(arg, dvd_authinfo, ai); | 3217 | if (copy_from_user(&ai, (dvd_authinfo __user *)arg, sizeof(ai))) |
3218 | return -EFAULT; | ||
3137 | ret = dvd_do_auth(cdi, &ai); | 3219 | ret = dvd_do_auth(cdi, &ai); |
3138 | if (ret) | 3220 | if (ret) |
3139 | return ret; | 3221 | return ret; |
3140 | IOCTL_OUT(arg, dvd_authinfo, ai); | 3222 | if (copy_to_user((dvd_authinfo __user *)arg, &ai, sizeof(ai))) |
3223 | return -EFAULT; | ||
3141 | return 0; | 3224 | return 0; |
3142 | } | 3225 | } |
3143 | 3226 | ||
3144 | static noinline int mmc_ioctl_cdrom_next_writable(struct cdrom_device_info *cdi, | 3227 | static noinline int mmc_ioctl_cdrom_next_writable(struct cdrom_device_info *cdi, |
3145 | void __user *arg) | 3228 | void __user *arg) |
3146 | { | 3229 | { |
3147 | int ret; | 3230 | int ret; |
3148 | long next = 0; | 3231 | long next = 0; |
3149 | cdinfo(CD_DO_IOCTL, "entering CDROM_NEXT_WRITABLE\n"); | 3232 | cd_dbg(CD_DO_IOCTL, "entering CDROM_NEXT_WRITABLE\n"); |
3150 | ret = cdrom_get_next_writable(cdi, &next); | 3233 | ret = cdrom_get_next_writable(cdi, &next); |
3151 | if (ret) | 3234 | if (ret) |
3152 | return ret; | 3235 | return ret; |
3153 | IOCTL_OUT(arg, long, next); | 3236 | if (copy_to_user((long __user *)arg, &next, sizeof(next))) |
3237 | return -EFAULT; | ||
3154 | return 0; | 3238 | return 0; |
3155 | } | 3239 | } |
3156 | 3240 | ||
3157 | static noinline int mmc_ioctl_cdrom_last_written(struct cdrom_device_info *cdi, | 3241 | static noinline int mmc_ioctl_cdrom_last_written(struct cdrom_device_info *cdi, |
3158 | void __user *arg) | 3242 | void __user *arg) |
3159 | { | 3243 | { |
3160 | int ret; | 3244 | int ret; |
3161 | long last = 0; | 3245 | long last = 0; |
3162 | cdinfo(CD_DO_IOCTL, "entering CDROM_LAST_WRITTEN\n"); | 3246 | cd_dbg(CD_DO_IOCTL, "entering CDROM_LAST_WRITTEN\n"); |
3163 | ret = cdrom_get_last_written(cdi, &last); | 3247 | ret = cdrom_get_last_written(cdi, &last); |
3164 | if (ret) | 3248 | if (ret) |
3165 | return ret; | 3249 | return ret; |
3166 | IOCTL_OUT(arg, long, last); | 3250 | if (copy_to_user((long __user *)arg, &last, sizeof(last))) |
3251 | return -EFAULT; | ||
3167 | return 0; | 3252 | return 0; |
3168 | } | 3253 | } |
3169 | 3254 | ||
@@ -3212,181 +3297,101 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, | |||
3212 | return -ENOTTY; | 3297 | return -ENOTTY; |
3213 | } | 3298 | } |
3214 | 3299 | ||
3215 | static int cdrom_get_track_info(struct cdrom_device_info *cdi, __u16 track, __u8 type, | 3300 | /* |
3216 | track_information *ti) | 3301 | * Just about every imaginable ioctl is supported in the Uniform layer |
3217 | { | 3302 | * these days. |
3218 | struct cdrom_device_ops *cdo = cdi->ops; | 3303 | * ATAPI / SCSI specific code now mainly resides in mmc_ioctl(). |
3219 | struct packet_command cgc; | 3304 | */ |
3220 | int ret, buflen; | 3305 | int cdrom_ioctl(struct cdrom_device_info *cdi, struct block_device *bdev, |
3221 | 3306 | fmode_t mode, unsigned int cmd, unsigned long arg) | |
3222 | init_cdrom_command(&cgc, ti, 8, CGC_DATA_READ); | ||
3223 | cgc.cmd[0] = GPCMD_READ_TRACK_RZONE_INFO; | ||
3224 | cgc.cmd[1] = type & 3; | ||
3225 | cgc.cmd[4] = (track & 0xff00) >> 8; | ||
3226 | cgc.cmd[5] = track & 0xff; | ||
3227 | cgc.cmd[8] = 8; | ||
3228 | cgc.quiet = 1; | ||
3229 | |||
3230 | if ((ret = cdo->generic_packet(cdi, &cgc))) | ||
3231 | return ret; | ||
3232 | |||
3233 | buflen = be16_to_cpu(ti->track_information_length) + | ||
3234 | sizeof(ti->track_information_length); | ||
3235 | |||
3236 | if (buflen > sizeof(track_information)) | ||
3237 | buflen = sizeof(track_information); | ||
3238 | |||
3239 | cgc.cmd[8] = cgc.buflen = buflen; | ||
3240 | if ((ret = cdo->generic_packet(cdi, &cgc))) | ||
3241 | return ret; | ||
3242 | |||
3243 | /* return actual fill size */ | ||
3244 | return buflen; | ||
3245 | } | ||
3246 | |||
3247 | /* requires CD R/RW */ | ||
3248 | static int cdrom_get_disc_info(struct cdrom_device_info *cdi, disc_information *di) | ||
3249 | { | 3307 | { |
3250 | struct cdrom_device_ops *cdo = cdi->ops; | 3308 | void __user *argp = (void __user *)arg; |
3251 | struct packet_command cgc; | 3309 | int ret; |
3252 | int ret, buflen; | ||
3253 | |||
3254 | /* set up command and get the disc info */ | ||
3255 | init_cdrom_command(&cgc, di, sizeof(*di), CGC_DATA_READ); | ||
3256 | cgc.cmd[0] = GPCMD_READ_DISC_INFO; | ||
3257 | cgc.cmd[8] = cgc.buflen = 2; | ||
3258 | cgc.quiet = 1; | ||
3259 | |||
3260 | if ((ret = cdo->generic_packet(cdi, &cgc))) | ||
3261 | return ret; | ||
3262 | 3310 | ||
3263 | /* not all drives have the same disc_info length, so requeue | 3311 | /* |
3264 | * packet with the length the drive tells us it can supply | 3312 | * Try the generic SCSI command ioctl's first. |
3265 | */ | 3313 | */ |
3266 | buflen = be16_to_cpu(di->disc_information_length) + | 3314 | ret = scsi_cmd_blk_ioctl(bdev, mode, cmd, argp); |
3267 | sizeof(di->disc_information_length); | 3315 | if (ret != -ENOTTY) |
3268 | |||
3269 | if (buflen > sizeof(disc_information)) | ||
3270 | buflen = sizeof(disc_information); | ||
3271 | |||
3272 | cgc.cmd[8] = cgc.buflen = buflen; | ||
3273 | if ((ret = cdo->generic_packet(cdi, &cgc))) | ||
3274 | return ret; | 3316 | return ret; |
3275 | 3317 | ||
3276 | /* return actual fill size */ | 3318 | switch (cmd) { |
3277 | return buflen; | 3319 | case CDROMMULTISESSION: |
3278 | } | 3320 | return cdrom_ioctl_multisession(cdi, argp); |
3279 | 3321 | case CDROMEJECT: | |
3280 | /* return the last written block on the CD-R media. this is for the udf | 3322 | return cdrom_ioctl_eject(cdi); |
3281 | file system. */ | 3323 | case CDROMCLOSETRAY: |
3282 | int cdrom_get_last_written(struct cdrom_device_info *cdi, long *last_written) | 3324 | return cdrom_ioctl_closetray(cdi); |
3283 | { | 3325 | case CDROMEJECT_SW: |
3284 | struct cdrom_tocentry toc; | 3326 | return cdrom_ioctl_eject_sw(cdi, arg); |
3285 | disc_information di; | 3327 | case CDROM_MEDIA_CHANGED: |
3286 | track_information ti; | 3328 | return cdrom_ioctl_media_changed(cdi, arg); |
3287 | __u32 last_track; | 3329 | case CDROM_SET_OPTIONS: |
3288 | int ret = -1, ti_size; | 3330 | return cdrom_ioctl_set_options(cdi, arg); |
3289 | 3331 | case CDROM_CLEAR_OPTIONS: | |
3290 | if (!CDROM_CAN(CDC_GENERIC_PACKET)) | 3332 | return cdrom_ioctl_clear_options(cdi, arg); |
3291 | goto use_toc; | 3333 | case CDROM_SELECT_SPEED: |
3292 | 3334 | return cdrom_ioctl_select_speed(cdi, arg); | |
3293 | ret = cdrom_get_disc_info(cdi, &di); | 3335 | case CDROM_SELECT_DISC: |
3294 | if (ret < (int)(offsetof(typeof(di), last_track_lsb) | 3336 | return cdrom_ioctl_select_disc(cdi, arg); |
3295 | + sizeof(di.last_track_lsb))) | 3337 | case CDROMRESET: |
3296 | goto use_toc; | 3338 | return cdrom_ioctl_reset(cdi, bdev); |
3297 | 3339 | case CDROM_LOCKDOOR: | |
3298 | /* if unit didn't return msb, it's zeroed by cdrom_get_disc_info */ | 3340 | return cdrom_ioctl_lock_door(cdi, arg); |
3299 | last_track = (di.last_track_msb << 8) | di.last_track_lsb; | 3341 | case CDROM_DEBUG: |
3300 | ti_size = cdrom_get_track_info(cdi, last_track, 1, &ti); | 3342 | return cdrom_ioctl_debug(cdi, arg); |
3301 | if (ti_size < (int)offsetof(typeof(ti), track_start)) | 3343 | case CDROM_GET_CAPABILITY: |
3302 | goto use_toc; | 3344 | return cdrom_ioctl_get_capability(cdi); |
3303 | 3345 | case CDROM_GET_MCN: | |
3304 | /* if this track is blank, try the previous. */ | 3346 | return cdrom_ioctl_get_mcn(cdi, argp); |
3305 | if (ti.blank) { | 3347 | case CDROM_DRIVE_STATUS: |
3306 | if (last_track==1) | 3348 | return cdrom_ioctl_drive_status(cdi, arg); |
3307 | goto use_toc; | 3349 | case CDROM_DISC_STATUS: |
3308 | last_track--; | 3350 | return cdrom_ioctl_disc_status(cdi); |
3309 | ti_size = cdrom_get_track_info(cdi, last_track, 1, &ti); | 3351 | case CDROM_CHANGER_NSLOTS: |
3310 | } | 3352 | return cdrom_ioctl_changer_nslots(cdi); |
3311 | |||
3312 | if (ti_size < (int)(offsetof(typeof(ti), track_size) | ||
3313 | + sizeof(ti.track_size))) | ||
3314 | goto use_toc; | ||
3315 | |||
3316 | /* if last recorded field is valid, return it. */ | ||
3317 | if (ti.lra_v && ti_size >= (int)(offsetof(typeof(ti), last_rec_address) | ||
3318 | + sizeof(ti.last_rec_address))) { | ||
3319 | *last_written = be32_to_cpu(ti.last_rec_address); | ||
3320 | } else { | ||
3321 | /* make it up instead */ | ||
3322 | *last_written = be32_to_cpu(ti.track_start) + | ||
3323 | be32_to_cpu(ti.track_size); | ||
3324 | if (ti.free_blocks) | ||
3325 | *last_written -= (be32_to_cpu(ti.free_blocks) + 7); | ||
3326 | } | 3353 | } |
3327 | return 0; | ||
3328 | 3354 | ||
3329 | /* this is where we end up if the drive either can't do a | 3355 | /* |
3330 | GPCMD_READ_DISC_INFO or GPCMD_READ_TRACK_RZONE_INFO or if | 3356 | * Use the ioctls that are implemented through the generic_packet() |
3331 | it doesn't give enough information or fails. then we return | 3357 | * interface. this may look at bit funny, but if -ENOTTY is |
3332 | the toc contents. */ | 3358 | * returned that particular ioctl is not implemented and we |
3333 | use_toc: | 3359 | * let it go through the device specific ones. |
3334 | toc.cdte_format = CDROM_MSF; | 3360 | */ |
3335 | toc.cdte_track = CDROM_LEADOUT; | 3361 | if (CDROM_CAN(CDC_GENERIC_PACKET)) { |
3336 | if ((ret = cdi->ops->audio_ioctl(cdi, CDROMREADTOCENTRY, &toc))) | 3362 | ret = mmc_ioctl(cdi, cmd, arg); |
3337 | return ret; | 3363 | if (ret != -ENOTTY) |
3338 | sanitize_format(&toc.cdte_addr, &toc.cdte_format, CDROM_LBA); | 3364 | return ret; |
3339 | *last_written = toc.cdte_addr.lba; | ||
3340 | return 0; | ||
3341 | } | ||
3342 | |||
3343 | /* return the next writable block. also for udf file system. */ | ||
3344 | static int cdrom_get_next_writable(struct cdrom_device_info *cdi, long *next_writable) | ||
3345 | { | ||
3346 | disc_information di; | ||
3347 | track_information ti; | ||
3348 | __u16 last_track; | ||
3349 | int ret, ti_size; | ||
3350 | |||
3351 | if (!CDROM_CAN(CDC_GENERIC_PACKET)) | ||
3352 | goto use_last_written; | ||
3353 | |||
3354 | ret = cdrom_get_disc_info(cdi, &di); | ||
3355 | if (ret < 0 || ret < offsetof(typeof(di), last_track_lsb) | ||
3356 | + sizeof(di.last_track_lsb)) | ||
3357 | goto use_last_written; | ||
3358 | |||
3359 | /* if unit didn't return msb, it's zeroed by cdrom_get_disc_info */ | ||
3360 | last_track = (di.last_track_msb << 8) | di.last_track_lsb; | ||
3361 | ti_size = cdrom_get_track_info(cdi, last_track, 1, &ti); | ||
3362 | if (ti_size < 0 || ti_size < offsetof(typeof(ti), track_start)) | ||
3363 | goto use_last_written; | ||
3364 | |||
3365 | /* if this track is blank, try the previous. */ | ||
3366 | if (ti.blank) { | ||
3367 | if (last_track == 1) | ||
3368 | goto use_last_written; | ||
3369 | last_track--; | ||
3370 | ti_size = cdrom_get_track_info(cdi, last_track, 1, &ti); | ||
3371 | if (ti_size < 0) | ||
3372 | goto use_last_written; | ||
3373 | } | 3365 | } |
3374 | 3366 | ||
3375 | /* if next recordable address field is valid, use it. */ | 3367 | /* |
3376 | if (ti.nwa_v && ti_size >= offsetof(typeof(ti), next_writable) | 3368 | * Note: most of the cd_dbg() calls are commented out here, |
3377 | + sizeof(ti.next_writable)) { | 3369 | * because they fill up the sys log when CD players poll |
3378 | *next_writable = be32_to_cpu(ti.next_writable); | 3370 | * the drive. |
3379 | return 0; | 3371 | */ |
3372 | switch (cmd) { | ||
3373 | case CDROMSUBCHNL: | ||
3374 | return cdrom_ioctl_get_subchnl(cdi, argp); | ||
3375 | case CDROMREADTOCHDR: | ||
3376 | return cdrom_ioctl_read_tochdr(cdi, argp); | ||
3377 | case CDROMREADTOCENTRY: | ||
3378 | return cdrom_ioctl_read_tocentry(cdi, argp); | ||
3379 | case CDROMPLAYMSF: | ||
3380 | return cdrom_ioctl_play_msf(cdi, argp); | ||
3381 | case CDROMPLAYTRKIND: | ||
3382 | return cdrom_ioctl_play_trkind(cdi, argp); | ||
3383 | case CDROMVOLCTRL: | ||
3384 | return cdrom_ioctl_volctrl(cdi, argp); | ||
3385 | case CDROMVOLREAD: | ||
3386 | return cdrom_ioctl_volread(cdi, argp); | ||
3387 | case CDROMSTART: | ||
3388 | case CDROMSTOP: | ||
3389 | case CDROMPAUSE: | ||
3390 | case CDROMRESUME: | ||
3391 | return cdrom_ioctl_audioctl(cdi, cmd); | ||
3380 | } | 3392 | } |
3381 | 3393 | ||
3382 | use_last_written: | 3394 | return -ENOSYS; |
3383 | if ((ret = cdrom_get_last_written(cdi, next_writable))) { | ||
3384 | *next_writable = 0; | ||
3385 | return ret; | ||
3386 | } else { | ||
3387 | *next_writable += 7; | ||
3388 | return 0; | ||
3389 | } | ||
3390 | } | 3395 | } |
3391 | 3396 | ||
3392 | EXPORT_SYMBOL(cdrom_get_last_written); | 3397 | EXPORT_SYMBOL(cdrom_get_last_written); |
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 695b9fd41efe..8aba35f46f87 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
@@ -620,6 +620,15 @@ static inline void queue_flag_clear(unsigned int flag, struct request_queue *q) | |||
620 | 620 | ||
621 | #define rq_data_dir(rq) (((rq)->cmd_flags & 1) != 0) | 621 | #define rq_data_dir(rq) (((rq)->cmd_flags & 1) != 0) |
622 | 622 | ||
623 | /* | ||
624 | * Driver can handle struct request, if it either has an old style | ||
625 | * request_fn defined, or is blk-mq based. | ||
626 | */ | ||
627 | static inline bool queue_is_rq_based(struct request_queue *q) | ||
628 | { | ||
629 | return q->request_fn || q->mq_ops; | ||
630 | } | ||
631 | |||
623 | static inline unsigned int blk_queue_cluster(struct request_queue *q) | 632 | static inline unsigned int blk_queue_cluster(struct request_queue *q) |
624 | { | 633 | { |
625 | return q->limits.cluster; | 634 | return q->limits.cluster; |
diff --git a/include/xen/interface/io/blkif.h b/include/xen/interface/io/blkif.h index 32ec05a6572f..c33e1c489eb2 100644 --- a/include/xen/interface/io/blkif.h +++ b/include/xen/interface/io/blkif.h | |||
@@ -86,7 +86,7 @@ typedef uint64_t blkif_sector_t; | |||
86 | * Interface%20manuals/100293068c.pdf | 86 | * Interface%20manuals/100293068c.pdf |
87 | * The backend can optionally provide three extra XenBus attributes to | 87 | * The backend can optionally provide three extra XenBus attributes to |
88 | * further optimize the discard functionality: | 88 | * further optimize the discard functionality: |
89 | * 'discard-aligment' - Devices that support discard functionality may | 89 | * 'discard-alignment' - Devices that support discard functionality may |
90 | * internally allocate space in units that are bigger than the exported | 90 | * internally allocate space in units that are bigger than the exported |
91 | * logical block size. The discard-alignment parameter indicates how many bytes | 91 | * logical block size. The discard-alignment parameter indicates how many bytes |
92 | * the beginning of the partition is offset from the internal allocation unit's | 92 | * the beginning of the partition is offset from the internal allocation unit's |